PR python/12533:
* python/py-value.c (valpy_dereference, valpy_get_address valpy_get_dynamic_type, valpy_lazy_string, valpy_do_cast) (valpy_getitem, valpy_call, valpy_binop, valpy_negative) (valpy_absolute, valpy_richcompare): Free intermediate values.
This commit is contained in:
parent
dd28faae1a
commit
888fe1e1d8
2 changed files with 86 additions and 24 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
2012-01-03 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
|
PR python/12533:
|
||||||
|
* python/py-value.c (valpy_dereference, valpy_get_address
|
||||||
|
valpy_get_dynamic_type, valpy_lazy_string, valpy_do_cast)
|
||||||
|
(valpy_getitem, valpy_call, valpy_binop, valpy_negative)
|
||||||
|
(valpy_absolute, valpy_richcompare): Free intermediate values.
|
||||||
|
|
||||||
2011-01-03 Joel Brobecker <brobecker@adacore.com>
|
2011-01-03 Joel Brobecker <brobecker@adacore.com>
|
||||||
|
|
||||||
* ada-lang.c: Reformat the copyright notice.
|
* ada-lang.c: Reformat the copyright notice.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* Python interface to values.
|
/* Python interface to values.
|
||||||
|
|
||||||
Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
|
Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GDB.
|
This file is part of GDB.
|
||||||
|
|
||||||
|
@ -174,23 +174,27 @@ preserve_python_values (struct objfile *objfile, htab_t copied_types)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
valpy_dereference (PyObject *self, PyObject *args)
|
valpy_dereference (PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
struct value *res_val = NULL; /* Initialize to appease gcc warning. */
|
|
||||||
volatile struct gdb_exception except;
|
volatile struct gdb_exception except;
|
||||||
|
PyObject *result = NULL;
|
||||||
|
|
||||||
TRY_CATCH (except, RETURN_MASK_ALL)
|
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);
|
res_val = value_ind (((value_object *) self)->value);
|
||||||
|
result = value_to_value_object (res_val);
|
||||||
|
do_cleanups (cleanup);
|
||||||
}
|
}
|
||||||
GDB_PY_HANDLE_EXCEPTION (except);
|
GDB_PY_HANDLE_EXCEPTION (except);
|
||||||
|
|
||||||
return value_to_value_object (res_val);
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return "&value". */
|
/* Return "&value". */
|
||||||
static PyObject *
|
static PyObject *
|
||||||
valpy_get_address (PyObject *self, void *closure)
|
valpy_get_address (PyObject *self, void *closure)
|
||||||
{
|
{
|
||||||
struct value *res_val = NULL; /* Initialize to appease gcc warning. */
|
|
||||||
value_object *val_obj = (value_object *) self;
|
value_object *val_obj = (value_object *) self;
|
||||||
volatile struct gdb_exception except;
|
volatile struct gdb_exception except;
|
||||||
|
|
||||||
|
@ -198,15 +202,19 @@ valpy_get_address (PyObject *self, void *closure)
|
||||||
{
|
{
|
||||||
TRY_CATCH (except, RETURN_MASK_ALL)
|
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);
|
res_val = value_addr (val_obj->value);
|
||||||
|
val_obj->address = value_to_value_object (res_val);
|
||||||
|
do_cleanups (cleanup);
|
||||||
}
|
}
|
||||||
if (except.reason < 0)
|
if (except.reason < 0)
|
||||||
{
|
{
|
||||||
val_obj->address = Py_None;
|
val_obj->address = Py_None;
|
||||||
Py_INCREF (Py_None);
|
Py_INCREF (Py_None);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
val_obj->address = value_to_value_object (res_val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_XINCREF (val_obj->address);
|
Py_XINCREF (val_obj->address);
|
||||||
|
@ -248,6 +256,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
|
||||||
TRY_CATCH (except, RETURN_MASK_ALL)
|
TRY_CATCH (except, RETURN_MASK_ALL)
|
||||||
{
|
{
|
||||||
struct value *val = obj->value;
|
struct value *val = obj->value;
|
||||||
|
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
||||||
|
|
||||||
type = value_type (val);
|
type = value_type (val);
|
||||||
CHECK_TYPEDEF (type);
|
CHECK_TYPEDEF (type);
|
||||||
|
@ -277,6 +286,8 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
|
||||||
/* Re-use object's static type. */
|
/* Re-use object's static type. */
|
||||||
type = NULL;
|
type = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_cleanups (cleanup);
|
||||||
}
|
}
|
||||||
GDB_PY_HANDLE_EXCEPTION (except);
|
GDB_PY_HANDLE_EXCEPTION (except);
|
||||||
|
|
||||||
|
@ -311,7 +322,7 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
|
||||||
struct value *value = ((value_object *) self)->value;
|
struct value *value = ((value_object *) self)->value;
|
||||||
const char *user_encoding = NULL;
|
const char *user_encoding = NULL;
|
||||||
static char *keywords[] = { "encoding", "length", NULL };
|
static char *keywords[] = { "encoding", "length", NULL };
|
||||||
PyObject *str_obj;
|
PyObject *str_obj = NULL;
|
||||||
volatile struct gdb_exception except;
|
volatile struct gdb_exception except;
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords (args, kw, "|s" GDB_PY_LL_ARG, keywords,
|
if (!PyArg_ParseTupleAndKeywords (args, kw, "|s" GDB_PY_LL_ARG, keywords,
|
||||||
|
@ -320,16 +331,20 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
|
||||||
|
|
||||||
TRY_CATCH (except, RETURN_MASK_ALL)
|
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)
|
if (TYPE_CODE (value_type (value)) == TYPE_CODE_PTR)
|
||||||
value = value_ind (value);
|
value = value_ind (value);
|
||||||
}
|
|
||||||
GDB_PY_HANDLE_EXCEPTION (except);
|
|
||||||
|
|
||||||
str_obj = gdbpy_create_lazy_string_object (value_address (value), length,
|
str_obj = gdbpy_create_lazy_string_object (value_address (value), length,
|
||||||
user_encoding,
|
user_encoding,
|
||||||
value_type (value));
|
value_type (value));
|
||||||
|
|
||||||
return (PyObject *) str_obj;
|
do_cleanups (cleanup);
|
||||||
|
}
|
||||||
|
GDB_PY_HANDLE_EXCEPTION (except);
|
||||||
|
|
||||||
|
return str_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implementation of gdb.Value.string ([encoding] [, errors]
|
/* Implementation of gdb.Value.string ([encoding] [, errors]
|
||||||
|
@ -376,9 +391,8 @@ valpy_string (PyObject *self, PyObject *args, PyObject *kw)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op)
|
valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op)
|
||||||
{
|
{
|
||||||
PyObject *type_obj;
|
PyObject *type_obj, *result = NULL;
|
||||||
struct type *type;
|
struct type *type;
|
||||||
struct value *res_val = NULL; /* Initialize to appease gcc warning. */
|
|
||||||
volatile struct gdb_exception except;
|
volatile struct gdb_exception except;
|
||||||
|
|
||||||
if (! PyArg_ParseTuple (args, "O", &type_obj))
|
if (! PyArg_ParseTuple (args, "O", &type_obj))
|
||||||
|
@ -395,6 +409,8 @@ valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op)
|
||||||
TRY_CATCH (except, RETURN_MASK_ALL)
|
TRY_CATCH (except, RETURN_MASK_ALL)
|
||||||
{
|
{
|
||||||
struct value *val = ((value_object *) self)->value;
|
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)
|
if (op == UNOP_DYNAMIC_CAST)
|
||||||
res_val = value_dynamic_cast (type, val);
|
res_val = value_dynamic_cast (type, val);
|
||||||
|
@ -405,10 +421,13 @@ valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op)
|
||||||
gdb_assert (op == UNOP_CAST);
|
gdb_assert (op == UNOP_CAST);
|
||||||
res_val = value_cast (type, val);
|
res_val = value_cast (type, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = value_to_value_object (res_val);
|
||||||
|
do_cleanups (cleanup);
|
||||||
}
|
}
|
||||||
GDB_PY_HANDLE_EXCEPTION (except);
|
GDB_PY_HANDLE_EXCEPTION (except);
|
||||||
|
|
||||||
return value_to_value_object (res_val);
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implementation of the "cast" method. */
|
/* Implementation of the "cast" method. */
|
||||||
|
@ -451,8 +470,8 @@ valpy_getitem (PyObject *self, PyObject *key)
|
||||||
{
|
{
|
||||||
value_object *self_value = (value_object *) self;
|
value_object *self_value = (value_object *) self;
|
||||||
char *field = NULL;
|
char *field = NULL;
|
||||||
struct value *res_val = NULL;
|
|
||||||
volatile struct gdb_exception except;
|
volatile struct gdb_exception except;
|
||||||
|
PyObject *result = NULL;
|
||||||
|
|
||||||
if (gdbpy_is_string (key))
|
if (gdbpy_is_string (key))
|
||||||
{
|
{
|
||||||
|
@ -464,6 +483,8 @@ valpy_getitem (PyObject *self, PyObject *key)
|
||||||
TRY_CATCH (except, RETURN_MASK_ALL)
|
TRY_CATCH (except, RETURN_MASK_ALL)
|
||||||
{
|
{
|
||||||
struct value *tmp = self_value->value;
|
struct value *tmp = self_value->value;
|
||||||
|
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
||||||
|
struct value *res_val = NULL;
|
||||||
|
|
||||||
if (field)
|
if (field)
|
||||||
res_val = value_struct_elt (&tmp, NULL, field, 0, NULL);
|
res_val = value_struct_elt (&tmp, NULL, field, 0, NULL);
|
||||||
|
@ -489,12 +510,16 @@ valpy_getitem (PyObject *self, PyObject *key)
|
||||||
res_val = value_subscript (tmp, value_as_long (idx));
|
res_val = value_subscript (tmp, value_as_long (idx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (res_val)
|
||||||
|
result = value_to_value_object (res_val);
|
||||||
|
do_cleanups (cleanup);
|
||||||
}
|
}
|
||||||
|
|
||||||
xfree (field);
|
xfree (field);
|
||||||
GDB_PY_HANDLE_EXCEPTION (except);
|
GDB_PY_HANDLE_EXCEPTION (except);
|
||||||
|
|
||||||
return res_val ? value_to_value_object (res_val) : NULL;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -510,12 +535,13 @@ valpy_setitem (PyObject *self, PyObject *key, PyObject *value)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
|
valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
|
||||||
{
|
{
|
||||||
struct value *return_value = NULL;
|
|
||||||
Py_ssize_t args_count;
|
Py_ssize_t args_count;
|
||||||
volatile struct gdb_exception except;
|
volatile struct gdb_exception except;
|
||||||
struct value *function = ((value_object *) self)->value;
|
struct value *function = ((value_object *) self)->value;
|
||||||
struct value **vargs = NULL;
|
struct value **vargs = NULL;
|
||||||
struct type *ftype = NULL;
|
struct type *ftype = NULL;
|
||||||
|
struct value *mark = value_mark ();
|
||||||
|
PyObject *result = NULL;
|
||||||
|
|
||||||
TRY_CATCH (except, RETURN_MASK_ALL)
|
TRY_CATCH (except, RETURN_MASK_ALL)
|
||||||
{
|
{
|
||||||
|
@ -558,11 +584,16 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
|
||||||
|
|
||||||
TRY_CATCH (except, RETURN_MASK_ALL)
|
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);
|
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);
|
GDB_PY_HANDLE_EXCEPTION (except);
|
||||||
|
|
||||||
return value_to_value_object (return_value);
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called by the Python interpreter to obtain string representation
|
/* Called by the Python interpreter to obtain string representation
|
||||||
|
@ -687,12 +718,14 @@ enum valpy_opcode
|
||||||
static PyObject *
|
static PyObject *
|
||||||
valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other)
|
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;
|
volatile struct gdb_exception except;
|
||||||
|
PyObject *result = NULL;
|
||||||
|
|
||||||
TRY_CATCH (except, RETURN_MASK_ALL)
|
TRY_CATCH (except, RETURN_MASK_ALL)
|
||||||
{
|
{
|
||||||
struct value *arg1, *arg2;
|
struct value *arg1, *arg2;
|
||||||
|
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
||||||
|
struct value *res_val;
|
||||||
|
|
||||||
/* If the gdb.Value object is the second operand, then it will be passed
|
/* 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
|
to us as the OTHER argument, and SELF will be an entirely different
|
||||||
|
@ -778,10 +811,15 @@ valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other)
|
||||||
res_val = value_binop (arg1, arg2, BINOP_BITWISE_XOR);
|
res_val = value_binop (arg1, arg2, BINOP_BITWISE_XOR);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (res_val)
|
||||||
|
result = value_to_value_object (res_val);
|
||||||
|
|
||||||
|
do_cleanups (cleanup);
|
||||||
}
|
}
|
||||||
GDB_PY_HANDLE_EXCEPTION (except);
|
GDB_PY_HANDLE_EXCEPTION (except);
|
||||||
|
|
||||||
return res_val ? value_to_value_object (res_val) : NULL;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -833,16 +871,22 @@ valpy_power (PyObject *self, PyObject *other, PyObject *unused)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
valpy_negative (PyObject *self)
|
valpy_negative (PyObject *self)
|
||||||
{
|
{
|
||||||
struct value *val = NULL;
|
|
||||||
volatile struct gdb_exception except;
|
volatile struct gdb_exception except;
|
||||||
|
PyObject *result = NULL;
|
||||||
|
|
||||||
TRY_CATCH (except, RETURN_MASK_ALL)
|
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);
|
val = value_neg (((value_object *) self)->value);
|
||||||
|
result = value_to_value_object (val);
|
||||||
|
do_cleanups (cleanup);
|
||||||
}
|
}
|
||||||
GDB_PY_HANDLE_EXCEPTION (except);
|
GDB_PY_HANDLE_EXCEPTION (except);
|
||||||
|
|
||||||
return value_to_value_object (val);
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -860,8 +904,12 @@ valpy_absolute (PyObject *self)
|
||||||
|
|
||||||
TRY_CATCH (except, RETURN_MASK_ALL)
|
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)))
|
if (value_less (value, value_zero (value_type (value), not_lval)))
|
||||||
isabs = 0;
|
isabs = 0;
|
||||||
|
|
||||||
|
do_cleanups (cleanup);
|
||||||
}
|
}
|
||||||
GDB_PY_HANDLE_EXCEPTION (except);
|
GDB_PY_HANDLE_EXCEPTION (except);
|
||||||
|
|
||||||
|
@ -961,7 +1009,6 @@ static PyObject *
|
||||||
valpy_richcompare (PyObject *self, PyObject *other, int op)
|
valpy_richcompare (PyObject *self, PyObject *other, int op)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
struct value *value_other;
|
|
||||||
volatile struct gdb_exception except;
|
volatile struct gdb_exception except;
|
||||||
|
|
||||||
if (other == Py_None)
|
if (other == Py_None)
|
||||||
|
@ -985,6 +1032,9 @@ valpy_richcompare (PyObject *self, PyObject *other, int op)
|
||||||
|
|
||||||
TRY_CATCH (except, RETURN_MASK_ALL)
|
TRY_CATCH (except, RETURN_MASK_ALL)
|
||||||
{
|
{
|
||||||
|
struct value *value_other, *mark = value_mark ();
|
||||||
|
struct cleanup *cleanup;
|
||||||
|
|
||||||
value_other = convert_value_from_python (other);
|
value_other = convert_value_from_python (other);
|
||||||
if (value_other == NULL)
|
if (value_other == NULL)
|
||||||
{
|
{
|
||||||
|
@ -992,6 +1042,8 @@ valpy_richcompare (PyObject *self, PyObject *other, int op)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cleanup = make_cleanup_value_free_to_mark (mark);
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case Py_LT:
|
case Py_LT:
|
||||||
result = value_less (((value_object *) self)->value, value_other);
|
result = value_less (((value_object *) self)->value, value_other);
|
||||||
|
@ -1020,6 +1072,8 @@ valpy_richcompare (PyObject *self, PyObject *other, int op)
|
||||||
result = -1;
|
result = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_cleanups (cleanup);
|
||||||
}
|
}
|
||||||
GDB_PY_HANDLE_EXCEPTION (except);
|
GDB_PY_HANDLE_EXCEPTION (except);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue