X-Git-Url: https://repo.jachan.dev/binutils.git/blobdiff_plain/7b6bb8daaceb9ecf3f42dea57ae82733d6a3b2f6..940da03e32c28144134d0373faf7fd5ea158f1ae:/gdb/python/py-function.c diff --git a/gdb/python/py-function.c b/gdb/python/py-function.c index 47d916b4b9..f3b889452f 100644 --- a/gdb/python/py-function.c +++ b/gdb/python/py-function.c @@ -1,6 +1,6 @@ /* Convenience functions implemented in Python. - Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 2008-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -20,7 +20,6 @@ #include "defs.h" #include "value.h" -#include "exceptions.h" #include "python-internal.h" #include "charset.h" #include "gdbcmd.h" @@ -29,25 +28,29 @@ #include "expression.h" #include "language.h" -static PyTypeObject fnpy_object_type; +extern PyTypeObject fnpy_object_type + CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("PyObject"); -static PyObject * +/* Return a reference to a tuple ARGC elements long. Each element of the + tuple is a PyObject converted from the corresponding element of ARGV. */ + +static gdbpy_ref<> convert_values_to_python (int argc, struct value **argv) { int i; - PyObject *result = PyTuple_New (argc); + gdbpy_ref<> result (PyTuple_New (argc)); + + if (result == NULL) + return NULL; for (i = 0; i < argc; ++i) { - PyObject *elt = value_to_value_object (argv[i]); - if (! elt) - { - Py_DECREF (result); - error (_("Could not convert value to Python object.")); - } - PyTuple_SetItem (result, i, elt); + gdbpy_ref<> elt (value_to_value_object (argv[i])); + if (elt == NULL) + return NULL; + PyTuple_SetItem (result.get (), i, elt.release ()); } return result; } @@ -58,42 +61,39 @@ static struct value * fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language, void *cookie, int argc, struct value **argv) { - struct value *value = NULL; - PyObject *result, *callable, *args; - struct cleanup *cleanup; - - cleanup = ensure_python_env (gdbarch, language); - - args = convert_values_to_python (argc, argv); - - callable = PyObject_GetAttrString ((PyObject *) cookie, "invoke"); - if (! callable) + /* The gdbpy_enter object needs to be placed first, so that it's the last to + be destroyed. */ + gdbpy_enter enter_py (gdbarch, language); + struct value *value; + gdbpy_ref<> result; + gdbpy_ref<> args = convert_values_to_python (argc, argv); + + /* convert_values_to_python can return NULL on error. If we + encounter this, do not call the function, but allow the Python -> + error code conversion below to deal with the Python exception. + Note, that this is different if the function simply does not + have arguments. */ + + if (args != NULL) { - Py_DECREF (args); - error (_("No method named 'invoke' in object.")); - } + gdbpy_ref<> callable (PyObject_GetAttrString ((PyObject *) cookie, + "invoke")); + if (callable == NULL) + error (_("No method named 'invoke' in object.")); - result = PyObject_Call (callable, args, NULL); - Py_DECREF (callable); - Py_DECREF (args); - - if (!result) - { - gdbpy_print_stack (); - error (_("Error while executing Python code.")); + result.reset (PyObject_Call (callable.get (), args.get (), NULL)); } - value = convert_value_from_python (result); + if (result == NULL) + gdbpy_handle_exception (); + + value = convert_value_from_python (result.get ()); if (value == NULL) { - Py_DECREF (result); gdbpy_print_stack (); error (_("Error while executing Python code.")); } - Py_DECREF (result); - do_cleanups (cleanup); - return value; } @@ -103,50 +103,53 @@ fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language, static int fnpy_init (PyObject *self, PyObject *args, PyObject *kwds) { - char *name, *docstring = NULL; + const char *name; + gdb::unique_xmalloc_ptr docstring; if (! PyArg_ParseTuple (args, "s", &name)) return -1; - Py_INCREF (self); + + gdbpy_ref<> self_ref = gdbpy_ref<>::new_reference (self); if (PyObject_HasAttrString (self, "__doc__")) { - PyObject *ds_obj = PyObject_GetAttrString (self, "__doc__"); - if (ds_obj && gdbpy_is_string (ds_obj)) + gdbpy_ref<> ds_obj (PyObject_GetAttrString (self, "__doc__")); + if (ds_obj != NULL) { - docstring = python_string_to_host_string (ds_obj); - if (docstring == NULL) + if (gdbpy_is_string (ds_obj.get ())) { - Py_DECREF (self); - return -1; + docstring = python_string_to_host_string (ds_obj.get ()); + if (docstring == NULL) + return -1; } } } if (! docstring) - docstring = xstrdup (_("This function is not documented.")); + docstring.reset (xstrdup (_("This function is not documented."))); - add_internal_function (name, docstring, fnpy_call, self); + add_internal_function (make_unique_xstrdup (name), std::move (docstring), + fnpy_call, self_ref.release ()); return 0; } /* Initialize internal function support. */ -void +int gdbpy_initialize_functions (void) { + fnpy_object_type.tp_new = PyType_GenericNew; if (PyType_Ready (&fnpy_object_type) < 0) - return; + return -1; - Py_INCREF (&fnpy_object_type); - PyModule_AddObject (gdb_module, "Function", (PyObject *) &fnpy_object_type); + return gdb_pymodule_addobject (gdb_module, "Function", + (PyObject *) &fnpy_object_type); } -static PyTypeObject fnpy_object_type = +PyTypeObject fnpy_object_type = { - PyObject_HEAD_INIT (NULL) - 0, /*ob_size*/ + PyVarObject_HEAD_INIT (NULL, 0) "gdb.Function", /*tp_name*/ sizeof (PyObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ @@ -183,5 +186,4 @@ static PyTypeObject fnpy_object_type = 0, /* tp_dictoffset */ fnpy_init, /* tp_init */ 0, /* tp_alloc */ - PyType_GenericNew /* tp_new */ };