[PATCH] [gdb/python] Convert valpy_call to the "python safety" approach
Tom de Vries <[email protected]>
| Newsgroups | gmane.comp.gdb.patches |
|---|---|
| Message-ID | <[email protected]> |
Update function valpy_call to the "python safety" approach.
I added a wrap_tp_call template to enforce and handle the new prototype of
valpy_call:
...
- valpy_call, /*tp_call*/
+ wrap_tp_call<valpy_call>, /*tp_call*/
...
I also made it explicit that the keywords argument is unused.
I added wrapper function gdbpy_tuple_check to wrap PyTuple_Check. It always
succeeds, so strictly speaking it doesn't need a wrapper, but always using
wrapper function and trusting them to DDRT is easier than remembering which
functions always succeed.
I also added this template:
...
template<typename T>
T
gdbpy_require_nonnull (T val)
{
if (val == nullptr)
throw gdb_python_exception ();
return val;
}
...
to do this simplification:
...
- vargs[i] = convert_value_from_python (item);
+ vargs[i] = gdbpy_require_nonnull (convert_value_from_python (item));
- if (vargs[i] == NULL)
- throw gdb_python_exception ();
...
as a placeholder until convert_value_from_python is converted.
Tested on x86_64-linux.
---
gdb/python/py-safety.h | 9 ++++
gdb/python/py-value.c | 89 +++++++++++++++-------------------------
gdb/python/py-wrappers.h | 18 ++++++++
3 files changed, 61 insertions(+), 55 deletions(-)
diff --git a/gdb/python/py-safety.h b/gdb/python/py-safety.h
index 3294f38c8b6..56f7ddd3b85 100644
--- a/gdb/python/py-safety.h
+++ b/gdb/python/py-safety.h
@@ -343,4 +343,13 @@ wrap_setter (PyObject *arg, PyObject *value, void *closure)
return 0;
}
+/* A function that wraps a "tp_call" method. */
+template<gdbpy_ref<> F (gdbpy_borrowed_ref<>, gdbpy_borrowed_ref<>,
+ gdbpy_opt_borrowed_ref<>)>
+PyObject *
+wrap_tp_call (PyObject *self, PyObject *args, PyObject *keywords)
+{
+ return safety_details::wrapped_function<F> (self, args, keywords);
+}
+
#endif /* GDB_PYTHON_PY_SAFETY_H */
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 5b38110396e..222932a1549 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -1164,43 +1164,32 @@ valpy_setitem (PyObject *self, PyObject *key, PyObject *value)
}
/* Called by the Python interpreter to perform an inferior function
- call on the value. Returns NULL on error, with a python exception set. */
-static PyObject *
-valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
+ call on the value. */
+static gdbpy_ref<>
+valpy_call (gdbpy_borrowed_ref<> self, gdbpy_borrowed_ref<> args,
+ gdbpy_opt_borrowed_ref<> keywords ATTRIBUTE_UNUSED)
{
Py_ssize_t args_count;
- struct value *function = ((value_object *) self)->value;
+ struct value *function = ((value_object *) (PyObject *)self)->value;
struct value **vargs = NULL;
struct type *ftype = NULL;
gdbpy_ref<> result;
- try
- {
- ftype = check_typedef (function->type ());
- }
- catch (const gdb_exception &except)
- {
- return gdbpy_handle_gdb_exception (nullptr, except);
- }
+ ftype = check_typedef (function->type ());
if (ftype->code () != TYPE_CODE_FUNC && ftype->code () != TYPE_CODE_METHOD
&& ftype->code () != TYPE_CODE_INTERNAL_FUNCTION)
- {
- PyErr_SetString (PyExc_RuntimeError,
- _("Value is not callable (not TYPE_CODE_FUNC"
- " or TYPE_CODE_METHOD"
- " or TYPE_CODE_INTERNAL_FUNCTION)."));
- return NULL;
- }
+ gdbpy_err_set_string
+ (PyExc_RuntimeError,
+ _("Value is not callable (not TYPE_CODE_FUNC or TYPE_CODE_METHOD"
+ " or TYPE_CODE_INTERNAL_FUNCTION)."));
- if (! PyTuple_Check (args))
- {
- PyErr_SetString (PyExc_TypeError,
- _("Inferior arguments must be provided in a tuple."));
- return NULL;
- }
+ if (! gdbpy_tuple_check (args))
+ gdbpy_err_set_string
+ (PyExc_TypeError,
+ _("Inferior arguments must be provided in a tuple."));
- args_count = PyTuple_Size (args);
+ args_count = gdbpy_tuple_size (args);
if (args_count > 0)
{
int i;
@@ -1208,39 +1197,29 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
vargs = XALLOCAVEC (struct value *, args_count);
for (i = 0; i < args_count; i++)
{
- PyObject *item = PyTuple_GetItem (args, i);
-
- if (item == NULL)
- return NULL;
-
- vargs[i] = convert_value_from_python (item);
- if (vargs[i] == NULL)
- return NULL;
+ gdbpy_borrowed_ref<> item = gdbpy_tuple_get_item (args, i);
+ vargs[i] = gdbpy_require_nonnull (convert_value_from_python (item));
}
}
- try
- {
- scoped_value_mark free_values;
+ {
+ scoped_value_mark free_values;
- value *return_value;
- if (ftype->code () == TYPE_CODE_INTERNAL_FUNCTION)
- return_value = call_internal_function (gdbpy_enter::get_gdbarch (),
- current_language,
- function, args_count, vargs,
- EVAL_NORMAL);
- else
- return_value
- = call_function_by_hand (function, NULL,
- gdb::make_array_view (vargs, args_count));
- result = value_to_value_object (return_value);
- }
- catch (const gdb_exception &except)
- {
- return gdbpy_handle_gdb_exception (nullptr, except);
- }
+ value *return_value;
+ if (ftype->code () == TYPE_CODE_INTERNAL_FUNCTION)
+ return_value = call_internal_function (gdbpy_enter::get_gdbarch (),
+ current_language,
+ function, args_count, vargs,
+ EVAL_NORMAL);
+ else
+ return_value
+ = call_function_by_hand (function, NULL,
+ gdb::make_array_view (vargs, args_count));
- return result.release ();
+ result = value_to_value_object (return_value);
+ }
+
+ return result;
}
/* Called by the Python interpreter to obtain string representation
@@ -2376,7 +2355,7 @@ PyTypeObject value_object_type = {
0, /*tp_as_sequence*/
&value_object_as_mapping, /*tp_as_mapping*/
valpy_hash, /*tp_hash*/
- valpy_call, /*tp_call*/
+ wrap_tp_call<valpy_call>, /*tp_call*/
valpy_str, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
diff --git a/gdb/python/py-wrappers.h b/gdb/python/py-wrappers.h
index 6c2b5e4d41e..79cc46fbebf 100644
--- a/gdb/python/py-wrappers.h
+++ b/gdb/python/py-wrappers.h
@@ -358,4 +358,22 @@ gdbpy_sequence_concat (gdbpy_borrowed_ref<> first, gdbpy_borrowed_ref<> second)
return result;
}
+/* Wrapper for PyTuple_Check. */
+static inline bool
+gdbpy_tuple_check (gdbpy_borrowed_ref<> p)
+{
+ /* Always succeeds. */
+ return PyTuple_Check (p);
+}
+
+/* Throw gdb_python_exception if VAL is nullptr. */
+template<typename T>
+T
+gdbpy_require_nonnull (T val)
+{
+ if (val == nullptr)
+ throw gdb_python_exception ();
+ return val;
+}
+
#endif /* GDB_PYTHON_PY_WRAPPERS_H */
base-commit: b7f5758529acb1a34dbe025cd3cc593d625e1538
--
2.51.0