/* Python interface to blocks.

   Copyright (C) 2008-2026 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "block.h"
#include "dictionary.h"
#include "symtab.h"
#include "python-internal.h"
#include "objfiles.h"

struct block_object : public PyObject
{
  /* The GDB block structure that represents a frame's code block.  */
  const struct block *block;
  /* The backing object file.  There is no direct relationship in GDB
     between a block and an object file.  When a block is created also
     store a pointer to the object file for later use.  */
  struct objfile *objfile;
};

static_assert (gdb::is_python_allocatable_v<block_object>);

struct block_syms_iterator_object : public PyObject
{
  /* The block.  */
  const struct block *block;
  /* The iterator for that block.  */
  struct block_iterator iter;
  /* Has the iterator been initialized flag.  */
  int initialized_p;
  /* Pointer back to the original source block object.  Needed to
     check if the block is still valid, and has not been invalidated
     when an object file has been freed.  */
  block_object *source;
};

static_assert (gdb::is_python_allocatable_v<block_syms_iterator_object>);

/* Require a valid block.  All access to block_object->block should be
   gated by this call.  */
#define BLPY_REQUIRE_VALID(block_obj, block)		\
  do {							\
    block = block_object_to_block (block_obj);		\
    if (block == NULL)					\
      {							\
	PyErr_SetString (PyExc_RuntimeError,		\
			 _("Block is invalid."));	\
	return NULL;					\
      }							\
  } while (0)

/* Require a valid block.  This macro is called during block iterator
   creation, and at each next call.  */
#define BLPY_ITER_REQUIRE_VALID(block_obj)				\
  do {									\
    if (block_obj->block == NULL)					\
      {									\
	PyErr_SetString (PyExc_RuntimeError,				\
			 _("Source block for iterator is invalid."));	\
	return NULL;							\
      }									\
  } while (0)

extern PyTypeObject block_syms_iterator_object_type;
static const registry<objfile>::key<htab, htab_deleter>
     blpy_objfile_data_key;

static PyObject *
blpy_iter (PyObject *self)
{
  block_syms_iterator_object *block_iter_obj;
  const struct block *block = NULL;

  BLPY_REQUIRE_VALID (self, block);

  block_iter_obj = PyObject_New (block_syms_iterator_object,
				 &block_syms_iterator_object_type);
  if (block_iter_obj == NULL)
      return NULL;

  block_iter_obj->block = block;
  block_iter_obj->initialized_p = 0;
  Py_INCREF (self);
  block_iter_obj->source = (block_object *) self;

  return (PyObject *) block_iter_obj;
}

static PyObject *
blpy_get_start (PyObject *self, void *closure)
{
  const struct block *block = NULL;

  BLPY_REQUIRE_VALID (self, block);

  return gdb_py_object_from_ulongest (block->start ()).release ();
}

static PyObject *
blpy_get_end (PyObject *self, void *closure)
{
  const struct block *block = NULL;

  BLPY_REQUIRE_VALID (self, block);

  return gdb_py_object_from_ulongest (block->end ()).release ();
}

/* Implementation of gdb.Block.ranges.  */

static PyObject *
blpy_get_ranges (PyObject *self, void *closure)
{
  const struct block *block = nullptr;

  BLPY_REQUIRE_VALID (self, block);

  auto ranges = block->ranges ();

  if (ranges.size () == 0)
    return Py_BuildValue ("((" GDB_PY_LLU_ARG GDB_PY_LLU_ARG "))",
			  (gdb_py_ulongest) block->start (),
			  (gdb_py_ulongest) block->end ());
  else
    {
      gdbpy_ref<> ranges_obj (PyTuple_New (ranges.size ()));
      if (ranges_obj == nullptr)
	return nullptr;

      for (int i = 0; i < ranges.size (); i++)
	{
	  gdbpy_ref<> range_obj
	    (Py_BuildValue ("(" GDB_PY_LLU_ARG GDB_PY_LLU_ARG ")",
			    (gdb_py_ulongest) ranges[i].start (),
			    (gdb_py_ulongest) ranges[i].end ()));
	  if (range_obj == nullptr)
	    return nullptr;

	  PyTuple_SetItem (ranges_obj.get (), i, range_obj.release ());
	}

      return ranges_obj.release ();
    }
}

static PyObject *
blpy_get_function (PyObject *self, void *closure)
{
  struct symbol *sym;
  const struct block *block;

  BLPY_REQUIRE_VALID (self, block);

  sym = block->function ();
  if (sym)
    return symbol_to_symbol_object (sym).release ();

  return py_none ().release ();
}

static PyObject *
blpy_get_superblock (PyObject *self, void *closure)
{
  const struct block *block;
  const struct block *super_block;
  block_object *self_obj  = (block_object *) self;

  BLPY_REQUIRE_VALID (self, block);

  super_block = block->superblock ();
  if (super_block)
    return block_to_block_object (super_block, self_obj->objfile).release ();

  return py_none ().release ();
}

/* Implement gdb.Block.subblocks attribute.  Return a list of gdb.Block
   objects that are direct children of this block.  */

static PyObject *
blpy_get_subblocks (PyObject *self, void *closure)
{
  const struct block *block;

  BLPY_REQUIRE_VALID (self, block);

  gdbpy_ref<> list (PyList_New (0));
  if (list == nullptr)
    return nullptr;

  compunit_symtab *cu = block->global_block ()->compunit ();

  for (const struct block *each : cu->blockvector ()->blocks ())
    {
      if (each->superblock () == block)
	{
	  gdbpy_ref<> item = block_to_block_object (each, cu->objfile ());

	  if (item.get () == nullptr
	      || PyList_Append (list.get (), item.get ()) == -1)
	    return nullptr;
	}
    }

  return list.release ();
}

/* Return the global block associated to this block.  */

static PyObject *
blpy_get_global_block (PyObject *self, void *closure)
{
  const struct block *block;
  const struct block *global_block;
  block_object *self_obj  = (block_object *) self;

  BLPY_REQUIRE_VALID (self, block);

  global_block = block->global_block ();

  return block_to_block_object (global_block, self_obj->objfile).release ();
}

/* Return the static block associated to this block.  Return None
   if we cannot get the static block (this is the global block).  */

static PyObject *
blpy_get_static_block (PyObject *self, void *closure)
{
  const struct block *block;
  const struct block *static_block;
  block_object *self_obj  = (block_object *) self;

  BLPY_REQUIRE_VALID (self, block);

  if (block->superblock () == NULL)
    return py_none ().release ();

  static_block = block->static_block ();

  return block_to_block_object (static_block, self_obj->objfile).release ();
}

/* Implementation of gdb.Block.is_global (self) -> Boolean.
   Returns True if this block object is a global block.  */

static PyObject *
blpy_is_global (PyObject *self, void *closure)
{
  const struct block *block;

  BLPY_REQUIRE_VALID (self, block);

  if (block->superblock ())
    return py_false ().release ();

  return py_true ().release ();
}

/* Implementation of gdb.Block.is_static (self) -> Boolean.
   Returns True if this block object is a static block.  */

static PyObject *
blpy_is_static (PyObject *self, void *closure)
{
  const struct block *block;

  BLPY_REQUIRE_VALID (self, block);

  if (block->superblock () != NULL
     && block->superblock ()->superblock () == NULL)
    return py_true ().release ();

  return py_false ().release ();
}

/* Given a string, returns the gdb.Symbol representing that symbol in this
   block.  If such a symbol does not exist, returns NULL with a Python
   exception.  */

static PyObject *
blpy_getitem (PyObject *self, PyObject *key)
{
  const struct block *block;

  BLPY_REQUIRE_VALID (self, block);

  gdb::unique_xmalloc_ptr<char> name = python_string_to_host_string (key);
  if (name == nullptr)
    return nullptr;

  lookup_name_info lookup_name (name.get(), symbol_name_match_type::FULL);

  /* We use an iterator instead of block_lookup_symbol so that we can
     look up symbols irrespective of the domain, matching the
     iterator. It would be confusing if the iterator returns symbols
     you can't find via getitem.  */
  for (struct symbol *sym : block_iterator_range (block, &lookup_name))
    {
      /* Just stop at the first match */
      return symbol_to_symbol_object (sym).release ();
    }

  PyErr_SetObject (PyExc_KeyError, key);
  return nullptr;
}

/* Deleter function for the hash table.  */

static void
block_object_del (void *obj)
{
  block_object *block = (block_object *) obj;
  block->block = nullptr;
  block->objfile = nullptr;
}

/* Hash function for the hash table.  */

static hashval_t
block_object_hash (const void *obj)
{
  const block_object *block = (const block_object *) obj;
  return htab_hash_pointer (block->block);
}

/* Equality function for the hash table.  Note that searches must be
   done with a plain block.  */

static int
block_object_eq (const void *a, const void *b)
{
  const block_object *blocka = (const block_object *) a;
  const block *blockb = (const block *) b;
  return blocka->block == blockb;
}

/* Called when a gdb.Block is destroyed.  This removes it from the
   hash.  */

static void
blpy_dealloc (PyObject *obj)
{
  block_object *block = (block_object *) obj;

  if (block->objfile != nullptr)
    {
      htab_t table = blpy_objfile_data_key.get (block->objfile);
      hashval_t hash = block_object_hash (block);
      /* This will clear the contents of the block as a side
	 effect.  */
      htab_remove_elt_with_hash (table, block->block, hash);
    }

  Py_TYPE (obj)->tp_free (obj);
}

/* Create a new block object (gdb.Block) that encapsulates the struct
   block object from GDB.  */
gdbpy_ref<>
block_to_block_object (const struct block *block, struct objfile *objfile)
{
  htab_t table = blpy_objfile_data_key.get (objfile);
  if (table == nullptr)
    {
      table = htab_create_alloc (10, block_object_hash, block_object_eq,
				 block_object_del, xcalloc, xfree);
      blpy_objfile_data_key.set (objfile, table);
    }

  hashval_t hash = htab_hash_pointer (block);
  block_object *result = (block_object *) htab_find_with_hash (table, block,
							       hash);
  if (result != nullptr)
    return gdbpy_ref<>::new_reference (result);

  result = PyObject_New (block_object, &block_object_type);
  if (result == nullptr)
    return nullptr;

  result->block = block;
  result->objfile = objfile;

  void **slot = htab_find_slot_with_hash (table, block, hash, INSERT);
  *slot = result;

  return gdbpy_ref<> (result);
}

/* Return struct block reference that is wrapped by this object.  */
const struct block *
block_object_to_block (PyObject *obj)
{
  if (! PyObject_TypeCheck (obj, &block_object_type))
    return NULL;
  return ((block_object *) obj)->block;
}

/* Return a reference to the block iterator.  */
static PyObject *
blpy_block_syms_iter (PyObject *self)
{
  block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;

  BLPY_ITER_REQUIRE_VALID (iter_obj->source);

  Py_INCREF (self);
  return self;
}

/* Return the next symbol in the iteration through the block's
   dictionary.  */
static PyObject *
blpy_block_syms_iternext (PyObject *self)
{
  block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
  struct symbol *sym;

  BLPY_ITER_REQUIRE_VALID (iter_obj->source);

  if (!iter_obj->initialized_p)
    {
      sym = block_iterator_first (iter_obj->block,  &(iter_obj->iter));
      iter_obj->initialized_p = 1;
    }
  else
    sym = block_iterator_next (&(iter_obj->iter));

  if (sym == NULL)
    {
      PyErr_SetString (PyExc_StopIteration, _("Symbol is null."));
      return NULL;
    }

  return symbol_to_symbol_object (sym).release ();
}

static void
blpy_block_syms_dealloc (PyObject *obj)
{
  block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) obj;

  Py_XDECREF (iter_obj->source);
  Py_TYPE (obj)->tp_free (obj);
}

/* Implementation of gdb.Block.is_valid (self) -> Boolean.
   Returns True if this block object still exists in GDB.  */

static PyObject *
blpy_is_valid (PyObject *self, PyObject *args)
{
  const struct block *block;

  block = block_object_to_block (self);
  if (block == NULL)
    return py_false ().release ();

  return py_true ().release ();
}

/* Implementation of gdb.BlockIterator.is_valid (self) -> Boolean.
   Returns True if this block iterator object still exists in GDB  */

static PyObject *
blpy_iter_is_valid (PyObject *self, PyObject *args)
{
  block_syms_iterator_object *iter_obj =
    (block_syms_iterator_object *) self;

  if (iter_obj->source->block == NULL)
    return py_false ().release ();

  return py_true ().release ();
}

/* __repr__ implementation for gdb.Block.  */

static PyObject *
blpy_repr (PyObject *self)
{
  const auto block = block_object_to_block (self);
  if (block == nullptr)
    return gdb_py_invalid_object_repr (self);

  const auto name = block->function () ?
    block->function ()->print_name () : "<anonymous>";

  std::string str;
  unsigned int written_symbols = 0;
  const int len = mdict_size (block->multidict ());
  static constexpr int SYMBOLS_TO_SHOW = 5;

  /* Don't use block_iterator_range here as that will find symbols through
     included symtabs (for global and static blocks), while LEN only counts
     symbols that are actually in BLOCK itself.  As this is really only for
     basic debug to allow blocks to be identified, we limit ourselves to
     just printing the symbols that are actually in BLOCK.  */
  for (struct symbol *symbol : block->multidict_symbols ())
    {
      if (written_symbols == SYMBOLS_TO_SHOW)
	{
	  const int remaining = len - SYMBOLS_TO_SHOW;
	  if (remaining == 1)
	    str += string_printf ("... (%d more symbol)", remaining);
	  else
	    str += string_printf ("... (%d more symbols)", remaining);
	  break;
	}
      str += symbol->print_name ();
      if (++written_symbols < len)
	str += ", ";
    }
  return PyUnicode_FromFormat ("<%s %s {%s}>",
			       gdbpy_py_obj_tp_name (self).c_str (),
			       name, str.c_str ());
}

/* Hash function for block objects.  */

static Py_hash_t
blpy_hash (PyObject *self)
{
  /* Python doesn't really expose its pointer hash function, so we use
     our own.  */
  Py_hash_t result = (Py_hash_t) htab_hash_pointer (self);
  /* -1 has a special meaning for Python.  */
  if (result == -1)
    result = -2;
  return result;
}

/* Implements the equality comparison for Block objects.  All other
   comparison operators will throw NotImplemented, as they aren't
   valid for blocks.  */

static PyObject *
blpy_richcompare (PyObject *self, PyObject *other, int op)
{
  if (!PyObject_TypeCheck (other, &block_object_type)
      || (op != Py_EQ && op != Py_NE))
    return py_notimplemented ().release ();

  bool expected = self == other;
  bool equal = op == Py_EQ;
  return PyBool_FromLong (equal == expected);
}

static int
gdbpy_initialize_blocks ()
{
  block_object_type.tp_new = PyType_GenericNew;
  if (gdbpy_type_ready (&block_object_type) < 0)
    return -1;

  block_syms_iterator_object_type.tp_new = PyType_GenericNew;
  if (gdbpy_type_ready (&block_syms_iterator_object_type) < 0)
    return -1;

  return 0;
}

GDBPY_INITIALIZE_FILE (gdbpy_initialize_blocks);



static PyMethodDef block_object_methods[] = {
  { "is_valid", blpy_is_valid, METH_NOARGS,
    "is_valid () -> Boolean.\n\
Return true if this block is valid, false if not." },
  {NULL}  /* Sentinel */
};

static gdb_PyGetSetDef block_object_getset[] = {
  { "start", blpy_get_start, NULL, "Start address of the block.", NULL },
  { "end", blpy_get_end, NULL, "End address of the block.", NULL },
  { "function", blpy_get_function, NULL,
    "Symbol that names the block, or None.", NULL },
  { "superblock", blpy_get_superblock, NULL,
    "Block containing the block, or None.", NULL },
  { "global_block", blpy_get_global_block, NULL,
    "Block containing the global block.", NULL },
  { "static_block", blpy_get_static_block, NULL,
    "Block containing the static block.", NULL },
  { "is_static", blpy_is_static, NULL,
    "Whether this block is a static block.", NULL },
  { "is_global", blpy_is_global, NULL,
    "Whether this block is a global block.", NULL },
  { "subblocks", blpy_get_subblocks, nullptr,
    "List of blocks contained in this block.", nullptr },
  { "ranges", blpy_get_ranges, nullptr,
    "List of address ranges for this block.", nullptr },
  { NULL }  /* Sentinel */
};

static PyMappingMethods block_object_as_mapping = {
  NULL,
  blpy_getitem,
  NULL
};

PyTypeObject block_object_type = {
  PyVarObject_HEAD_INIT (NULL, 0)
  "gdb.Block",			  /*tp_name*/
  sizeof (block_object),	  /*tp_basicsize*/
  0,				  /*tp_itemsize*/
  blpy_dealloc,                   /*tp_dealloc*/
  0,				  /*tp_print*/
  0,				  /*tp_getattr*/
  0,				  /*tp_setattr*/
  0,				  /*tp_compare*/
  blpy_repr,                      /*tp_repr*/
  0,				  /*tp_as_number*/
  0,				  /*tp_as_sequence*/
  &block_object_as_mapping,	  /*tp_as_mapping*/
  blpy_hash,			  /*tp_hash */
  0,				  /*tp_call*/
  0,				  /*tp_str*/
  0,				  /*tp_getattro*/
  0,				  /*tp_setattro*/
  0,				  /*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
  "GDB block object",		  /* tp_doc */
  0,				  /* tp_traverse */
  0,				  /* tp_clear */
  blpy_richcompare,		  /* tp_richcompare */
  0,				  /* tp_weaklistoffset */
  blpy_iter,			  /* tp_iter */
  0,				  /* tp_iternext */
  block_object_methods,		  /* tp_methods */
  0,				  /* tp_members */
  block_object_getset		  /* tp_getset */
};

static PyMethodDef block_iterator_object_methods[] = {
  { "is_valid", blpy_iter_is_valid, METH_NOARGS,
    "is_valid () -> Boolean.\n\
Return true if this block iterator is valid, false if not." },
  {NULL}  /* Sentinel */
};

PyTypeObject block_syms_iterator_object_type = {
  PyVarObject_HEAD_INIT (NULL, 0)
  "gdb.BlockIterator",		  /*tp_name*/
  sizeof (block_syms_iterator_object),	      /*tp_basicsize*/
  0,				  /*tp_itemsize*/
  blpy_block_syms_dealloc,	  /*tp_dealloc*/
  0,				  /*tp_print*/
  0,				  /*tp_getattr*/
  0,				  /*tp_setattr*/
  0,				  /*tp_compare*/
  0,				  /*tp_repr*/
  0,				  /*tp_as_number*/
  0,				  /*tp_as_sequence*/
  0,				  /*tp_as_mapping*/
  0,				  /*tp_hash */
  0,				  /*tp_call*/
  0,				  /*tp_str*/
  0,				  /*tp_getattro*/
  0,				  /*tp_setattro*/
  0,				  /*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
  "GDB block syms iterator object",	      /*tp_doc */
  0,				  /*tp_traverse */
  0,				  /*tp_clear */
  0,				  /*tp_richcompare */
  0,				  /*tp_weaklistoffset */
  blpy_block_syms_iter,           /*tp_iter */
  blpy_block_syms_iternext,	  /*tp_iternext */
  block_iterator_object_methods   /*tp_methods */
};
