/* 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;
};

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;
};

/* 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),
			       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 */
};
