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:
Tom Tromey 2012-01-03 19:27:52 +00:00
parent dd28faae1a
commit 888fe1e1d8
2 changed files with 86 additions and 24 deletions

View file

@ -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.

View file

@ -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);