aboutsummaryrefslogtreecommitdiff
path: root/gdb/python/py-xmethods.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/python/py-xmethods.c')
-rw-r--r--gdb/python/py-xmethods.c154
1 files changed, 67 insertions, 87 deletions
diff --git a/gdb/python/py-xmethods.c b/gdb/python/py-xmethods.c
index 750f263..f4064c2 100644
--- a/gdb/python/py-xmethods.c
+++ b/gdb/python/py-xmethods.c
@@ -37,54 +37,60 @@ static const char matchers_attr_str[] = "xmethods";
static PyObject *py_match_method_name = NULL;
static PyObject *py_get_arg_types_method_name = NULL;
-struct gdbpy_worker_data
+struct python_xmethod_worker : xmethod_worker
{
- PyObject *worker;
- PyObject *this_type;
-};
+ python_xmethod_worker (PyObject *worker, PyObject *this_type);
+ ~python_xmethod_worker ();
-static struct xmethod_worker *new_python_xmethod_worker (PyObject *item,
- PyObject *py_obj_type);
+ DISABLE_COPY_AND_ASSIGN (python_xmethod_worker);
-/* Implementation of free_xmethod_worker_data for Python. */
+ /* Implementation of xmethod_worker::invoke for Python. */
-void
-gdbpy_free_xmethod_worker_data (const struct extension_language_defn *extlang,
- void *data)
-{
- struct gdbpy_worker_data *worker_data = (struct gdbpy_worker_data *) data;
+ value *invoke (value *obj, value **args, int nargs) override;
+
+ /* Implementation of xmethod_worker::clone for Python. */
+
+ xmethod_worker_up clone () override;
+
+ /* Implementation of xmethod_worker::do_get_arg_types for Python. */
+
+ ext_lang_rc do_get_arg_types (int *nargs, type ***arg_types) override;
+
+ /* Implementation of xmethod_worker::do_get_result_type for Python.
- gdb_assert (worker_data->worker != NULL && worker_data->this_type != NULL);
+ For backward compatibility with 7.9, which did not support getting the
+ result type, if the get_result_type operation is not provided by WORKER
+ then EXT_LANG_RC_OK is returned and NULL is returned in *RESULT_TYPE. */
+ ext_lang_rc do_get_result_type (value *obj, value **args, int nargs,
+ type **result_type_ptr) override;
+
+private:
+
+ PyObject *m_py_worker;
+ PyObject *m_this_type;
+};
+
+python_xmethod_worker::~python_xmethod_worker ()
+{
/* We don't do much here, but we still need the GIL. */
gdbpy_enter enter_py (get_current_arch (), current_language);
- Py_DECREF (worker_data->worker);
- Py_DECREF (worker_data->this_type);
- xfree (worker_data);
+ Py_DECREF (m_py_worker);
+ Py_DECREF (m_this_type);
}
-/* Implementation of clone_xmethod_worker_data for Python. */
+/* See declaration. */
-void *
-gdbpy_clone_xmethod_worker_data (const struct extension_language_defn *extlang,
- void *data)
+xmethod_worker_up
+python_xmethod_worker::clone ()
{
- struct gdbpy_worker_data *worker_data
- = (struct gdbpy_worker_data *) data, *new_data;
-
- gdb_assert (worker_data->worker != NULL && worker_data->this_type != NULL);
-
/* We don't do much here, but we still need the GIL. */
gdbpy_enter enter_py (get_current_arch (), current_language);
- new_data = XCNEW (struct gdbpy_worker_data);
- new_data->worker = worker_data->worker;
- new_data->this_type = worker_data->this_type;
- Py_INCREF (new_data->worker);
- Py_INCREF (new_data->this_type);
+ xmethod_worker *worker = new python_xmethod_worker (m_py_worker, m_this_type);
- return new_data;
+ return xmethod_worker_up (worker);
}
/* Invoke the "match" method of the MATCHER and return a new reference
@@ -130,10 +136,9 @@ enum ext_lang_rc
gdbpy_get_matching_xmethod_workers
(const struct extension_language_defn *extlang,
struct type *obj_type, const char *method_name,
- xmethod_worker_vec **dm_vec)
+ std::vector<xmethod_worker_up> *dm_vec)
{
struct objfile *objfile;
- VEC (xmethod_worker_ptr) *worker_vec = NULL;
PyObject *py_progspace;
gdb_assert (obj_type != NULL && method_name != NULL);
@@ -282,39 +287,33 @@ gdbpy_get_matching_xmethod_workers
break;
}
- worker = new_python_xmethod_worker (py_worker.get (),
+ worker = new python_xmethod_worker (py_worker.get (),
py_type.get ());
- VEC_safe_push (xmethod_worker_ptr, worker_vec, worker);
+
+ dm_vec->emplace_back (worker);
}
}
else
{
struct xmethod_worker *worker;
- worker = new_python_xmethod_worker (match_result.get (),
+ worker = new python_xmethod_worker (match_result.get (),
py_type.get ());
- VEC_safe_push (xmethod_worker_ptr, worker_vec, worker);
+ dm_vec->emplace_back (worker);
}
}
- *dm_vec = worker_vec;
-
return EXT_LANG_RC_OK;
}
-/* Implementation of get_xmethod_arg_types for Python. */
+/* See declaration. */
-enum ext_lang_rc
-gdbpy_get_xmethod_arg_types (const struct extension_language_defn *extlang,
- struct xmethod_worker *worker,
- int *nargs, struct type ***arg_types)
+ext_lang_rc
+python_xmethod_worker::do_get_arg_types (int *nargs, type ***arg_types)
{
/* The gdbpy_enter object needs to be placed first, so that it's the last to
be destroyed. */
gdbpy_enter enter_py (get_current_arch (), current_language);
- struct gdbpy_worker_data *worker_data
- = (struct gdbpy_worker_data *) worker->data;
- PyObject *py_worker = worker_data->worker;
struct type *obj_type;
int i = 1, arg_count;
gdbpy_ref<> list_iter;
@@ -324,7 +323,7 @@ gdbpy_get_xmethod_arg_types (const struct extension_language_defn *extlang,
*nargs = -1;
gdbpy_ref<> get_arg_types_method
- (PyObject_GetAttrString (py_worker, get_arg_types_method_name));
+ (PyObject_GetAttrString (m_py_worker, get_arg_types_method_name));
if (get_arg_types_method == NULL)
{
gdbpy_print_stack ();
@@ -332,7 +331,7 @@ gdbpy_get_xmethod_arg_types (const struct extension_language_defn *extlang,
}
gdbpy_ref<> py_argtype_list
- (PyObject_CallMethodObjArgs (py_worker, py_get_arg_types_method_name,
+ (PyObject_CallMethodObjArgs (m_py_worker, py_get_arg_types_method_name,
NULL));
if (py_argtype_list == NULL)
{
@@ -418,7 +417,7 @@ gdbpy_get_xmethod_arg_types (const struct extension_language_defn *extlang,
/* Add the type of 'this' as the first argument. The 'this' pointer should
be a 'const' value. Hence, create a 'const' variant of the 'this' pointer
type. */
- obj_type = type_object_to_type (worker_data->this_type);
+ obj_type = type_object_to_type (m_this_type);
(type_array.get ())[0] = make_cv_type (1, 0, lookup_pointer_type (obj_type),
NULL);
*nargs = i;
@@ -427,18 +426,12 @@ gdbpy_get_xmethod_arg_types (const struct extension_language_defn *extlang,
return EXT_LANG_RC_OK;
}
-/* Implementation of get_xmethod_result_type for Python. */
+/* See declaration. */
-enum ext_lang_rc
-gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
- struct xmethod_worker *worker,
- struct value *obj,
- struct value **args, int nargs,
- struct type **result_type_ptr)
+ext_lang_rc
+python_xmethod_worker::do_get_result_type (value *obj, value **args, int nargs,
+ type **result_type_ptr)
{
- struct gdbpy_worker_data *worker_data
- = (struct gdbpy_worker_data *) worker->data;
- PyObject *py_worker = worker_data->worker;
struct type *obj_type, *this_type;
int i;
@@ -447,7 +440,7 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
/* First see if there is a get_result_type method.
If not this could be an old xmethod (pre 7.9.1). */
gdbpy_ref<> get_result_type_method
- (PyObject_GetAttrString (py_worker, get_result_type_method_name));
+ (PyObject_GetAttrString (m_py_worker, get_result_type_method_name));
if (get_result_type_method == NULL)
{
PyErr_Clear ();
@@ -456,7 +449,7 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
}
obj_type = check_typedef (value_type (obj));
- this_type = check_typedef (type_object_to_type (worker_data->this_type));
+ this_type = check_typedef (type_object_to_type (m_this_type));
if (TYPE_CODE (obj_type) == TYPE_CODE_PTR)
{
struct type *this_ptr = lookup_pointer_type (this_type);
@@ -528,24 +521,20 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
return EXT_LANG_RC_OK;
}
-/* Implementation of invoke_xmethod for Python. */
+/* See declaration. */
struct value *
-gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
- struct xmethod_worker *worker,
- struct value *obj, struct value **args, int nargs)
+python_xmethod_worker::invoke (struct value *obj, struct value **args,
+ int nargs)
{
+ gdbpy_enter enter_py (get_current_arch (), current_language);
+
int i;
struct type *obj_type, *this_type;
struct value *res = NULL;
- struct gdbpy_worker_data *worker_data
- = (struct gdbpy_worker_data *) worker->data;
- PyObject *xmethod_worker = worker_data->worker;
-
- gdbpy_enter enter_py (get_current_arch (), current_language);
obj_type = check_typedef (value_type (obj));
- this_type = check_typedef (type_object_to_type (worker_data->this_type));
+ this_type = check_typedef (type_object_to_type (m_this_type));
if (TYPE_CODE (obj_type) == TYPE_CODE_PTR)
{
struct type *this_ptr = lookup_pointer_type (this_type);
@@ -597,7 +586,7 @@ gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
PyTuple_SET_ITEM (py_arg_tuple.get (), i + 1, py_value_arg);
}
- gdbpy_ref<> py_result (PyObject_CallObject (xmethod_worker,
+ gdbpy_ref<> py_result (PyObject_CallObject (m_py_worker,
py_arg_tuple.get ()));
if (py_result == NULL)
{
@@ -623,24 +612,15 @@ gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
return res;
}
-/* Creates a new Python xmethod_worker object.
- The new object has data of type 'struct gdbpy_worker_data' composed
- with the components PY_WORKER and THIS_TYPE. */
-
-static struct xmethod_worker *
-new_python_xmethod_worker (PyObject *py_worker, PyObject *this_type)
+python_xmethod_worker::python_xmethod_worker (PyObject *py_worker,
+ PyObject *this_type)
+: xmethod_worker (&extension_language_python),
+ m_py_worker (py_worker), m_this_type (this_type)
{
- struct gdbpy_worker_data *data;
-
- gdb_assert (py_worker != NULL && this_type != NULL);
+ gdb_assert (m_py_worker != NULL && m_this_type != NULL);
- data = XCNEW (struct gdbpy_worker_data);
- data->worker = py_worker;
- data->this_type = this_type;
Py_INCREF (py_worker);
Py_INCREF (this_type);
-
- return new_xmethod_worker (&extension_language_python, data);
}
int