forked from Imagelibrary/binutils-gdb
* 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:
@@ -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
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
30
gdb/value.c
30
gdb/value.c
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 *);
|
||||||
|
|||||||
11
gdb/varobj.c
11
gdb/varobj.c
@@ -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. */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user