/* Python interface to blocks.
- Copyright (C) 2008-2019 Free Software Foundation, Inc.
+ Copyright (C) 2008-2021 Free Software Foundation, Inc.
This file is part of GDB.
#include "symtab.h"
#include "python-internal.h"
#include "objfiles.h"
-#include "symtab.h"
-typedef struct blpy_block_object {
+struct block_object {
PyObject_HEAD
/* The GDB block structure that represents a frame's code block. */
const struct block *block;
struct objfile *objfile;
/* Keep track of all blocks with a doubly-linked list. Needed for
block invalidation if the source object file has been freed. */
- struct blpy_block_object *prev;
- struct blpy_block_object *next;
-} block_object;
+ block_object *prev;
+ block_object *next;
+};
-typedef struct {
+struct block_syms_iterator_object {
PyObject_HEAD
/* The block. */
const struct block *block;
/* 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. */
- struct blpy_block_object *source;
-} block_syms_iterator_object;
+ block_object *source;
+};
/* Require a valid block. All access to block_object->block should be
gated by this call. */
Py_RETURN_FALSE;
}
+/* 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 ALL_BLOCK_SYMBOLS_WITH_NAME 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. */
+ struct block_iterator iter;
+ struct symbol *sym = nullptr;
+ ALL_BLOCK_SYMBOLS_WITH_NAME (block, lookup_name, iter, sym)
+ {
+ /* Just stop at the first match */
+ break;
+ }
+
+ if (sym == nullptr)
+ {
+ PyErr_SetObject (PyExc_KeyError, key);
+ return nullptr;
+ }
+ return symbol_to_symbol_object (sym);
+}
+
static void
blpy_dealloc (PyObject *obj)
{
if (block->next)
block->next->prev = block->prev;
block->block = NULL;
+ Py_TYPE (obj)->tp_free (obj);
}
/* Given a block, and a block_object that has previously been
if (objfile)
{
obj->objfile = objfile;
- obj->next = ((struct blpy_block_object *)
+ obj->next = ((block_object *)
objfile_data (objfile, blpy_objfile_data_key));
if (obj->next)
obj->next->prev = 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.
}
}
+void _initialize_py_block ();
+void
+_initialize_py_block ()
+{
+ /* Register an objfile "free" callback so we can properly
+ invalidate blocks when an object file is about to be
+ deleted. */
+ blpy_objfile_data_key
+ = register_objfile_data_with_cleanup (NULL, del_objfile_blocks);
+}
+
int
gdbpy_initialize_blocks (void)
{
if (PyType_Ready (&block_syms_iterator_object_type) < 0)
return -1;
- /* Register an objfile "free" callback so we can properly
- invalidate blocks when an object file is about to be
- deleted. */
- blpy_objfile_data_key
- = register_objfile_data_with_cleanup (NULL, del_objfile_blocks);
-
if (gdb_pymodule_addobject (gdb_module, "Block",
(PyObject *) &block_object_type) < 0)
return -1;
{ 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*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
+ &block_object_as_mapping, /*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 | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
"GDB block object", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
"GDB block syms iterator object", /*tp_doc */
0, /*tp_traverse */
0, /*tp_clear */