| Index: gdb/python/py-value.c
|
| diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
|
| index 19423eaf532127ed9bdaf3e776b759f549a5b111..6f67bdb2eb7ddc989714b2469ec775a103edd701 100644
|
| --- a/gdb/python/py-value.c
|
| +++ b/gdb/python/py-value.c
|
| @@ -1,6 +1,6 @@
|
| /* Python interface to values.
|
|
|
| - Copyright (C) 2008-2012 Free Software Foundation, Inc.
|
| + Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
|
|
|
| This file is part of GDB.
|
|
|
| @@ -28,6 +28,7 @@
|
| #include "infcall.h"
|
| #include "expression.h"
|
| #include "cp-abi.h"
|
| +#include "python.h"
|
|
|
| #ifdef HAVE_PYTHON
|
|
|
| @@ -150,7 +151,7 @@ valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *keywords)
|
| }
|
|
|
| value_obj->value = value;
|
| - value_incref (value);
|
| + release_value_or_incref (value);
|
| value_obj->address = NULL;
|
| value_obj->type = NULL;
|
| value_obj->dynamic_type = NULL;
|
| @@ -174,23 +175,68 @@ preserve_python_values (struct objfile *objfile, htab_t copied_types)
|
| static PyObject *
|
| valpy_dereference (PyObject *self, PyObject *args)
|
| {
|
| - struct value *res_val = NULL; /* Initialize to appease gcc warning. */
|
| volatile struct gdb_exception except;
|
| + PyObject *result = NULL;
|
|
|
| TRY_CATCH (except, RETURN_MASK_ALL)
|
| {
|
| + struct value *res_val;
|
| + struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
| +
|
| res_val = value_ind (((value_object *) self)->value);
|
| + result = value_to_value_object (res_val);
|
| + do_cleanups (cleanup);
|
| }
|
| GDB_PY_HANDLE_EXCEPTION (except);
|
|
|
| - return value_to_value_object (res_val);
|
| + return result;
|
| +}
|
| +
|
| +/* Given a value of a pointer type or a reference type, return the value
|
| + referenced. The difference between this function and valpy_dereference is
|
| + that the latter applies * unary operator to a value, which need not always
|
| + result in the value referenced. For example, for a value which is a reference
|
| + to an 'int' pointer ('int *'), valpy_dereference will result in a value of
|
| + type 'int' while valpy_referenced_value will result in a value of type
|
| + 'int *'. */
|
| +
|
| +static PyObject *
|
| +valpy_referenced_value (PyObject *self, PyObject *args)
|
| +{
|
| + volatile struct gdb_exception except;
|
| + PyObject *result = NULL;
|
| +
|
| + TRY_CATCH (except, RETURN_MASK_ALL)
|
| + {
|
| + struct value *self_val, *res_val;
|
| + struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
| +
|
| + self_val = ((value_object *) self)->value;
|
| + switch (TYPE_CODE (check_typedef (value_type (self_val))))
|
| + {
|
| + case TYPE_CODE_PTR:
|
| + res_val = value_ind (self_val);
|
| + break;
|
| + case TYPE_CODE_REF:
|
| + res_val = coerce_ref (self_val);
|
| + break;
|
| + default:
|
| + error(_("Trying to get the referenced value from a value which is "
|
| + "neither a pointer nor a reference."));
|
| + }
|
| +
|
| + result = value_to_value_object (res_val);
|
| + do_cleanups (cleanup);
|
| + }
|
| + GDB_PY_HANDLE_EXCEPTION (except);
|
| +
|
| + return result;
|
| }
|
|
|
| /* Return "&value". */
|
| static PyObject *
|
| valpy_get_address (PyObject *self, void *closure)
|
| {
|
| - struct value *res_val = NULL; /* Initialize to appease gcc warning. */
|
| value_object *val_obj = (value_object *) self;
|
| volatile struct gdb_exception except;
|
|
|
| @@ -198,15 +244,19 @@ valpy_get_address (PyObject *self, void *closure)
|
| {
|
| TRY_CATCH (except, RETURN_MASK_ALL)
|
| {
|
| + struct value *res_val;
|
| + struct cleanup *cleanup
|
| + = make_cleanup_value_free_to_mark (value_mark ());
|
| +
|
| res_val = value_addr (val_obj->value);
|
| + val_obj->address = value_to_value_object (res_val);
|
| + do_cleanups (cleanup);
|
| }
|
| if (except.reason < 0)
|
| {
|
| val_obj->address = Py_None;
|
| Py_INCREF (Py_None);
|
| }
|
| - else
|
| - val_obj->address = value_to_value_object (res_val);
|
| }
|
|
|
| Py_XINCREF (val_obj->address);
|
| @@ -248,6 +298,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
|
| TRY_CATCH (except, RETURN_MASK_ALL)
|
| {
|
| struct value *val = obj->value;
|
| + struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
|
|
| type = value_type (val);
|
| CHECK_TYPEDEF (type);
|
| @@ -277,6 +328,8 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
|
| /* Re-use object's static type. */
|
| type = NULL;
|
| }
|
| +
|
| + do_cleanups (cleanup);
|
| }
|
| GDB_PY_HANDLE_EXCEPTION (except);
|
|
|
| @@ -311,7 +364,7 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
|
| struct value *value = ((value_object *) self)->value;
|
| const char *user_encoding = NULL;
|
| static char *keywords[] = { "encoding", "length", NULL };
|
| - PyObject *str_obj;
|
| + PyObject *str_obj = NULL;
|
| volatile struct gdb_exception except;
|
|
|
| if (!PyArg_ParseTupleAndKeywords (args, kw, "|s" GDB_PY_LL_ARG, keywords,
|
| @@ -320,16 +373,20 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
|
|
|
| TRY_CATCH (except, RETURN_MASK_ALL)
|
| {
|
| + struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
| +
|
| if (TYPE_CODE (value_type (value)) == TYPE_CODE_PTR)
|
| value = value_ind (value);
|
| +
|
| + str_obj = gdbpy_create_lazy_string_object (value_address (value), length,
|
| + user_encoding,
|
| + value_type (value));
|
| +
|
| + do_cleanups (cleanup);
|
| }
|
| GDB_PY_HANDLE_EXCEPTION (except);
|
|
|
| - str_obj = gdbpy_create_lazy_string_object (value_address (value), length,
|
| - user_encoding,
|
| - value_type (value));
|
| -
|
| - return (PyObject *) str_obj;
|
| + return str_obj;
|
| }
|
|
|
| /* Implementation of gdb.Value.string ([encoding] [, errors]
|
| @@ -376,9 +433,8 @@ valpy_string (PyObject *self, PyObject *args, PyObject *kw)
|
| static PyObject *
|
| valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op)
|
| {
|
| - PyObject *type_obj;
|
| + PyObject *type_obj, *result = NULL;
|
| struct type *type;
|
| - struct value *res_val = NULL; /* Initialize to appease gcc warning. */
|
| volatile struct gdb_exception except;
|
|
|
| if (! PyArg_ParseTuple (args, "O", &type_obj))
|
| @@ -395,6 +451,8 @@ valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op)
|
| TRY_CATCH (except, RETURN_MASK_ALL)
|
| {
|
| struct value *val = ((value_object *) self)->value;
|
| + struct value *res_val;
|
| + struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
|
|
| if (op == UNOP_DYNAMIC_CAST)
|
| res_val = value_dynamic_cast (type, val);
|
| @@ -405,10 +463,13 @@ valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op)
|
| gdb_assert (op == UNOP_CAST);
|
| res_val = value_cast (type, val);
|
| }
|
| +
|
| + result = value_to_value_object (res_val);
|
| + do_cleanups (cleanup);
|
| }
|
| GDB_PY_HANDLE_EXCEPTION (except);
|
|
|
| - return value_to_value_object (res_val);
|
| + return result;
|
| }
|
|
|
| /* Implementation of the "cast" method. */
|
| @@ -451,8 +512,8 @@ valpy_getitem (PyObject *self, PyObject *key)
|
| {
|
| value_object *self_value = (value_object *) self;
|
| char *field = NULL;
|
| - struct value *res_val = NULL;
|
| volatile struct gdb_exception except;
|
| + PyObject *result = NULL;
|
|
|
| if (gdbpy_is_string (key))
|
| {
|
| @@ -464,6 +525,8 @@ valpy_getitem (PyObject *self, PyObject *key)
|
| TRY_CATCH (except, RETURN_MASK_ALL)
|
| {
|
| struct value *tmp = self_value->value;
|
| + struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
| + struct value *res_val = NULL;
|
|
|
| if (field)
|
| res_val = value_struct_elt (&tmp, NULL, field, 0, NULL);
|
| @@ -489,12 +552,16 @@ valpy_getitem (PyObject *self, PyObject *key)
|
| res_val = value_subscript (tmp, value_as_long (idx));
|
| }
|
| }
|
| +
|
| + if (res_val)
|
| + result = value_to_value_object (res_val);
|
| + do_cleanups (cleanup);
|
| }
|
|
|
| xfree (field);
|
| GDB_PY_HANDLE_EXCEPTION (except);
|
|
|
| - return res_val ? value_to_value_object (res_val) : NULL;
|
| + return result;
|
| }
|
|
|
| static int
|
| @@ -510,12 +577,13 @@ valpy_setitem (PyObject *self, PyObject *key, PyObject *value)
|
| static PyObject *
|
| valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
|
| {
|
| - struct value *return_value = NULL;
|
| Py_ssize_t args_count;
|
| volatile struct gdb_exception except;
|
| struct value *function = ((value_object *) self)->value;
|
| struct value **vargs = NULL;
|
| struct type *ftype = NULL;
|
| + struct value *mark = value_mark ();
|
| + PyObject *result = NULL;
|
|
|
| TRY_CATCH (except, RETURN_MASK_ALL)
|
| {
|
| @@ -558,11 +626,16 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
|
|
|
| TRY_CATCH (except, RETURN_MASK_ALL)
|
| {
|
| + struct cleanup *cleanup = make_cleanup_value_free_to_mark (mark);
|
| + struct value *return_value;
|
| +
|
| return_value = call_function_by_hand (function, args_count, vargs);
|
| + result = value_to_value_object (return_value);
|
| + do_cleanups (cleanup);
|
| }
|
| GDB_PY_HANDLE_EXCEPTION (except);
|
|
|
| - return value_to_value_object (return_value);
|
| + return result;
|
| }
|
|
|
| /* Called by the Python interpreter to obtain string representation
|
| @@ -687,12 +760,14 @@ enum valpy_opcode
|
| static PyObject *
|
| valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other)
|
| {
|
| - struct value *res_val = NULL; /* Initialize to appease gcc warning. */
|
| volatile struct gdb_exception except;
|
| + PyObject *result = NULL;
|
|
|
| TRY_CATCH (except, RETURN_MASK_ALL)
|
| {
|
| struct value *arg1, *arg2;
|
| + struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
| + struct value *res_val = NULL;
|
|
|
| /* If the gdb.Value object is the second operand, then it will be passed
|
| to us as the OTHER argument, and SELF will be an entirely different
|
| @@ -778,10 +853,15 @@ valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other)
|
| res_val = value_binop (arg1, arg2, BINOP_BITWISE_XOR);
|
| break;
|
| }
|
| +
|
| + if (res_val)
|
| + result = value_to_value_object (res_val);
|
| +
|
| + do_cleanups (cleanup);
|
| }
|
| GDB_PY_HANDLE_EXCEPTION (except);
|
|
|
| - return res_val ? value_to_value_object (res_val) : NULL;
|
| + return result;
|
| }
|
|
|
| static PyObject *
|
| @@ -833,16 +913,22 @@ valpy_power (PyObject *self, PyObject *other, PyObject *unused)
|
| static PyObject *
|
| valpy_negative (PyObject *self)
|
| {
|
| - struct value *val = NULL;
|
| volatile struct gdb_exception except;
|
| + PyObject *result = NULL;
|
|
|
| TRY_CATCH (except, RETURN_MASK_ALL)
|
| {
|
| + /* Perhaps overkill, but consistency has some virtue. */
|
| + struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
| + struct value *val;
|
| +
|
| val = value_neg (((value_object *) self)->value);
|
| + result = value_to_value_object (val);
|
| + do_cleanups (cleanup);
|
| }
|
| GDB_PY_HANDLE_EXCEPTION (except);
|
|
|
| - return value_to_value_object (val);
|
| + return result;
|
| }
|
|
|
| static PyObject *
|
| @@ -860,8 +946,12 @@ valpy_absolute (PyObject *self)
|
|
|
| TRY_CATCH (except, RETURN_MASK_ALL)
|
| {
|
| + struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
| +
|
| if (value_less (value, value_zero (value_type (value), not_lval)))
|
| isabs = 0;
|
| +
|
| + do_cleanups (cleanup);
|
| }
|
| GDB_PY_HANDLE_EXCEPTION (except);
|
|
|
| @@ -961,7 +1051,6 @@ static PyObject *
|
| valpy_richcompare (PyObject *self, PyObject *other, int op)
|
| {
|
| int result = 0;
|
| - struct value *value_other;
|
| volatile struct gdb_exception except;
|
|
|
| if (other == Py_None)
|
| @@ -985,6 +1074,9 @@ valpy_richcompare (PyObject *self, PyObject *other, int op)
|
|
|
| TRY_CATCH (except, RETURN_MASK_ALL)
|
| {
|
| + struct value *value_other, *mark = value_mark ();
|
| + struct cleanup *cleanup;
|
| +
|
| value_other = convert_value_from_python (other);
|
| if (value_other == NULL)
|
| {
|
| @@ -992,6 +1084,8 @@ valpy_richcompare (PyObject *self, PyObject *other, int op)
|
| break;
|
| }
|
|
|
| + cleanup = make_cleanup_value_free_to_mark (mark);
|
| +
|
| switch (op) {
|
| case Py_LT:
|
| result = value_less (((value_object *) self)->value, value_other);
|
| @@ -1020,6 +1114,8 @@ valpy_richcompare (PyObject *self, PyObject *other, int op)
|
| result = -1;
|
| break;
|
| }
|
| +
|
| + do_cleanups (cleanup);
|
| }
|
| GDB_PY_HANDLE_EXCEPTION (except);
|
|
|
| @@ -1123,7 +1219,7 @@ value_to_value_object (struct value *val)
|
| if (val_obj != NULL)
|
| {
|
| val_obj->value = val;
|
| - value_incref (val);
|
| + release_value_or_incref (val);
|
| val_obj->address = NULL;
|
| val_obj->type = NULL;
|
| val_obj->dynamic_type = NULL;
|
| @@ -1154,7 +1250,6 @@ struct value *
|
| convert_value_from_python (PyObject *obj)
|
| {
|
| struct value *value = NULL; /* -Wall */
|
| - struct cleanup *old;
|
| volatile struct gdb_exception except;
|
| int cmp;
|
|
|
| @@ -1223,6 +1318,8 @@ convert_value_from_python (PyObject *obj)
|
| s = python_string_to_target_string (obj);
|
| if (s != NULL)
|
| {
|
| + struct cleanup *old;
|
| +
|
| old = make_cleanup (xfree, s);
|
| value = value_cstring (s, strlen (s), builtin_type_pychar);
|
| do_cleanups (old);
|
| @@ -1324,6 +1421,8 @@ Cast the value to the supplied type, as if by the C++\n\
|
| reinterpret_cast operator."
|
| },
|
| { "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." },
|
| + { "referenced_value", valpy_referenced_value, METH_NOARGS,
|
| + "Return the value referenced by a TYPE_CODE_REF or TYPE_CODE_PTR value." },
|
| { "lazy_string", (PyCFunction) valpy_lazy_string,
|
| METH_VARARGS | METH_KEYWORDS,
|
| "lazy_string ([encoding] [, length]) -> lazy_string\n\
|
|
|