* varobj.c (update_dynamic_varobj_children): Don't use

value_copy.
	* value.h: (preserve_one_value): Declare.
	(value_prepend_to_list, value_remove_from_list): Remove.
	* value.c (preserve_one_value): No longer static.
	(preserve_values): Call preserve_python_values.
	(value_prepend_to_list): Remove.
	(value_remove_from_list): Remove.
	* python/python.h (values_in_python): Don't declare.
	(preserve_python_values): Declare.
	* python/python-value.c (values_in_python): Change type.  Move
	lower.  Now static.
	(struct value_object): Add struct tag.
	<next, prev>: New fields.
	(valpy_dealloc): Update.
	(note_value): New function.
	(valpy_new): Use value_incref, note_value.
	(preserve_python_values): New function.
	(valpy_positive): Don't use value_copy.
	(value_to_value_object): Use value_incref, note_value.
	(convert_value_from_python): Update comment.
This commit is contained in:
Tom Tromey
2009-08-13 18:39:20 +00:00
parent ecd0ada520
commit 4e7a5ef5a8
6 changed files with 90 additions and 65 deletions

View File

@@ -1,3 +1,27 @@
2009-08-13 Tom Tromey <tromey@redhat.com>
* varobj.c (update_dynamic_varobj_children): Don't use
value_copy.
* value.h: (preserve_one_value): Declare.
(value_prepend_to_list, value_remove_from_list): Remove.
* value.c (preserve_one_value): No longer static.
(preserve_values): Call preserve_python_values.
(value_prepend_to_list): Remove.
(value_remove_from_list): Remove.
* python/python.h (values_in_python): Don't declare.
(preserve_python_values): Declare.
* python/python-value.c (values_in_python): Change type. Move
lower. Now static.
(struct value_object): Add struct tag.
<next, prev>: New fields.
(valpy_dealloc): Update.
(note_value): New function.
(valpy_new): Use value_incref, note_value.
(preserve_python_values): New function.
(valpy_positive): Don't use value_copy.
(value_to_value_object): Use value_incref, note_value.
(convert_value_from_python): Update comment.
2009-08-13 Pedro Alves <pedro@codesourcery.com> 2009-08-13 Pedro Alves <pedro@codesourcery.com>
* remote.c (remote_pid_to_str): If printing a process id and we * remote.c (remote_pid_to_str): If printing a process id and we

View File

@@ -26,15 +26,6 @@
#include "dfp.h" #include "dfp.h"
#include "valprint.h" #include "valprint.h"
/* List of all values which are currently exposed to Python. It is
maintained so that when an objfile is discarded, preserve_values
can copy the values' types if needed. This is declared
unconditionally to reduce the number of uses of HAVE_PYTHON in the
generic code. */
/* This variable is unnecessarily initialized to NULL in order to
work around a linker bug on MacOS. */
struct value *values_in_python = NULL;
#ifdef HAVE_PYTHON #ifdef HAVE_PYTHON
#include "python-internal.h" #include "python-internal.h"
@@ -58,20 +49,38 @@ struct value *values_in_python = NULL;
#define builtin_type_pychar \ #define builtin_type_pychar \
language_string_char_type (python_language, python_gdbarch) language_string_char_type (python_language, python_gdbarch)
typedef struct { typedef struct value_object {
PyObject_HEAD PyObject_HEAD
struct value_object *next;
struct value_object *prev;
struct value *value; struct value *value;
PyObject *address; PyObject *address;
PyObject *type; PyObject *type;
} value_object; } value_object;
/* List of all values which are currently exposed to Python. It is
maintained so that when an objfile is discarded, preserve_values
can copy the values' types if needed. */
/* This variable is unnecessarily initialized to NULL in order to
work around a linker bug on MacOS. */
static value_object *values_in_python = NULL;
/* Called by the Python interpreter when deallocating a value object. */ /* Called by the Python interpreter when deallocating a value object. */
static void static void
valpy_dealloc (PyObject *obj) valpy_dealloc (PyObject *obj)
{ {
value_object *self = (value_object *) obj; value_object *self = (value_object *) obj;
value_remove_from_list (&values_in_python, self->value); /* Remove SELF from the global list. */
if (self->prev)
self->prev->next = self->next;
else
{
gdb_assert (values_in_python == self);
values_in_python = self->next;
}
if (self->next)
self->next->prev = self->prev;
value_free (self->value); value_free (self->value);
@@ -89,6 +98,17 @@ valpy_dealloc (PyObject *obj)
self->ob_type->tp_free (self); self->ob_type->tp_free (self);
} }
/* Helper to push a Value object on the global list. */
static void
note_value (value_object *value_obj)
{
value_obj->next = values_in_python;
if (value_obj->next)
value_obj->next->prev = value_obj;
value_obj->prev = NULL;
values_in_python = value_obj;
}
/* Called when a new gdb.Value object needs to be allocated. */ /* Called when a new gdb.Value object needs to be allocated. */
static PyObject * static PyObject *
valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *keywords) valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *keywords)
@@ -119,14 +139,25 @@ valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *keywords)
} }
value_obj->value = value; value_obj->value = value;
value_incref (value);
value_obj->address = NULL; value_obj->address = NULL;
value_obj->type = NULL; value_obj->type = NULL;
release_value (value); note_value (value_obj);
value_prepend_to_list (&values_in_python, value);
return (PyObject *) value_obj; return (PyObject *) value_obj;
} }
/* Iterate over all the Value objects, calling preserve_one_value on
each. */
void
preserve_python_values (struct objfile *objfile, htab_t copied_types)
{
value_object *iter;
for (iter = values_in_python; iter; iter = iter->next)
preserve_one_value (iter->value, objfile, copied_types);
}
/* Given a value of a pointer type, apply the C unary * operator to it. */ /* Given a value of a pointer type, apply the C unary * operator to it. */
static PyObject * static PyObject *
valpy_dereference (PyObject *self, PyObject *args) valpy_dereference (PyObject *self, PyObject *args)
@@ -543,9 +574,7 @@ valpy_negative (PyObject *self)
static PyObject * static PyObject *
valpy_positive (PyObject *self) valpy_positive (PyObject *self)
{ {
struct value *copy = value_copy (((value_object *) self)->value); return value_to_value_object (((value_object *) self)->value);
return value_to_value_object (copy);
} }
static PyObject * static PyObject *
@@ -800,16 +829,17 @@ value_to_value_object (struct value *val)
if (val_obj != NULL) if (val_obj != NULL)
{ {
val_obj->value = val; val_obj->value = val;
value_incref (val);
val_obj->address = NULL; val_obj->address = NULL;
val_obj->type = NULL; val_obj->type = NULL;
release_value (val); note_value (val_obj);
value_prepend_to_list (&values_in_python, val);
} }
return (PyObject *) val_obj; return (PyObject *) val_obj;
} }
/* Returns value structure corresponding to the given value object. */ /* Returns a borrowed reference to the struct value corresponding to
the given value object. */
struct value * struct value *
value_object_to_value (PyObject *self) value_object_to_value (PyObject *self)
{ {
@@ -821,7 +851,8 @@ value_object_to_value (PyObject *self)
} }
/* Try to convert a Python value to a gdb value. If the value cannot /* Try to convert a Python value to a gdb value. If the value cannot
be converted, set a Python exception and return NULL. */ be converted, set a Python exception and return NULL. Returns a
reference to a new value on the all_values chain. */
struct value * struct value *
convert_value_from_python (PyObject *obj) convert_value_from_python (PyObject *obj)
@@ -1019,4 +1050,12 @@ PyTypeObject value_object_type = {
valpy_new /* tp_new */ valpy_new /* tp_new */
}; };
#else
void
preserve_python_values (struct objfile *objfile, htab_t copied_types)
{
/* Nothing. */
}
#endif /* HAVE_PYTHON */ #endif /* HAVE_PYTHON */

View File

@@ -22,8 +22,6 @@
#include "value.h" #include "value.h"
extern struct value *values_in_python;
void eval_python_from_control_command (struct command_line *); void eval_python_from_control_command (struct command_line *);
int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr, int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
@@ -32,4 +30,6 @@ int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
const struct value_print_options *options, const struct value_print_options *options,
const struct language_defn *language); const struct language_defn *language);
void preserve_python_values (struct objfile *objfile, htab_t copied_types);
#endif /* GDB_PYTHON_H */ #endif /* GDB_PYTHON_H */

View File

@@ -312,31 +312,6 @@ allocate_repeat_value (struct type *type, int count)
return allocate_value (array_type); return allocate_value (array_type);
} }
/* Needed if another module needs to maintain its on list of values. */
void
value_prepend_to_list (struct value **head, struct value *val)
{
val->next = *head;
*head = val;
}
/* Needed if another module needs to maintain its on list of values. */
void
value_remove_from_list (struct value **head, struct value *val)
{
struct value *prev;
if (*head == val)
*head = (*head)->next;
else
for (prev = *head; prev->next; prev = prev->next)
if (prev->next == val)
{
prev->next = val->next;
break;
}
}
struct value * struct value *
allocate_computed_value (struct type *type, allocate_computed_value (struct type *type,
struct lval_funcs *funcs, struct lval_funcs *funcs,
@@ -1430,7 +1405,7 @@ add_internal_function (const char *name, const char *doc,
/* Update VALUE before discarding OBJFILE. COPIED_TYPES is used to /* Update VALUE before discarding OBJFILE. COPIED_TYPES is used to
prevent cycles / duplicates. */ prevent cycles / duplicates. */
static void void
preserve_one_value (struct value *value, struct objfile *objfile, preserve_one_value (struct value *value, struct objfile *objfile,
htab_t copied_types) htab_t copied_types)
{ {
@@ -1490,8 +1465,7 @@ preserve_values (struct objfile *objfile)
for (var = internalvars; var; var = var->next) for (var = internalvars; var; var = var->next)
preserve_one_internalvar (var, objfile, copied_types); preserve_one_internalvar (var, objfile, copied_types);
for (val = values_in_python; val; val = val->next) preserve_python_values (objfile, copied_types);
preserve_one_value (val, objfile, copied_types);
htab_delete (copied_types); htab_delete (copied_types);
} }

View File

@@ -41,11 +41,6 @@ struct value_print_options;
struct value; struct value;
/* Needed if another module needs to maintain its own list of values. */
void value_prepend_to_list (struct value **head, struct value *val);
void value_remove_from_list (struct value **head, struct value *val);
/* Values are stored in a chain, so that they can be deleted easily /* Values are stored in a chain, so that they can be deleted easily
over calls to the inferior. Values assigned to internal variables, over calls to the inferior. Values assigned to internal variables,
put into the value history or exposed to Python are taken off this put into the value history or exposed to Python are taken off this
@@ -664,6 +659,8 @@ extern void preserve_values (struct objfile *);
extern struct value *value_copy (struct value *); extern struct value *value_copy (struct value *);
extern void preserve_one_value (struct value *, struct objfile *, htab_t);
/* From valops.c */ /* From valops.c */
extern struct value *varying_to_slice (struct value *); extern struct value *varying_to_slice (struct value *);

View File

@@ -899,16 +899,7 @@ update_dynamic_varobj_children (struct varobj *var,
if (!PyArg_ParseTuple (item, "sO", &name, &py_v)) if (!PyArg_ParseTuple (item, "sO", &name, &py_v))
error (_("Invalid item from the child list")); error (_("Invalid item from the child list"));
if (PyObject_TypeCheck (py_v, &value_object_type)) v = convert_value_from_python (py_v);
{
/* If we just call convert_value_from_python for this type,
we won't know who owns the result. For this one case we
need to copy the resulting value. */
v = value_object_to_value (py_v);
v = value_copy (v);
}
else
v = convert_value_from_python (py_v);
/* TODO: This assume the name of the i-th child never changes. */ /* TODO: This assume the name of the i-th child never changes. */