mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-19 14:34:07 +08:00
Add scoped_value_mark
This adds a scoped_value_mark class, that records the value mark in the constructor and then calls value_free_to_mark in the destructor. It then updates various spots in gdb to use this class, rather than a cleanup. It would be better overall to replace "struct value *" with a shared_ptr, maybe eliminating the need for this class (watchpoints would perhaps need some new mechanism as well). However, that's difficult to do. 2017-01-10 Tom Tromey <tom@tromey.com> * python/py-value.c (valpy_dereference, valpy_referenced_value) (valpy_reference_value, valpy_const_value, valpy_get_address) (valpy_get_dynamic_type, valpy_lazy_string, valpy_do_cast) (valpy_getitem, valpy_call, valpy_binop_throw, valpy_negative) (valpy_absolute, valpy_richcompare_throw): Use scoped_value_mark. * dwarf2loc.c (dwarf2_loc_desc_get_symbol_read_needs): Use scoped_value_mark. * dwarf2-frame.c (execute_stack_op): Use scoped_value_mark. * value.h (scoped_value_mark): New class.
This commit is contained in:
parent
906768f970
commit
eb11506932
@ -1,3 +1,15 @@
|
||||
2017-01-10 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* python/py-value.c (valpy_dereference, valpy_referenced_value)
|
||||
(valpy_reference_value, valpy_const_value, valpy_get_address)
|
||||
(valpy_get_dynamic_type, valpy_lazy_string, valpy_do_cast)
|
||||
(valpy_getitem, valpy_call, valpy_binop_throw, valpy_negative)
|
||||
(valpy_absolute, valpy_richcompare_throw): Use scoped_value_mark.
|
||||
* dwarf2loc.c (dwarf2_loc_desc_get_symbol_read_needs): Use
|
||||
scoped_value_mark.
|
||||
* dwarf2-frame.c (execute_stack_op): Use scoped_value_mark.
|
||||
* value.h (scoped_value_mark): New class.
|
||||
|
||||
2017-01-10 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* dwarf2read.c (dwarf2_build_psymtabs): Use psymtab_discarder.
|
||||
|
@ -403,10 +403,9 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size,
|
||||
CORE_ADDR initial, int initial_in_stack_memory)
|
||||
{
|
||||
CORE_ADDR result;
|
||||
struct cleanup *old_chain;
|
||||
|
||||
dwarf_expr_executor ctx;
|
||||
old_chain = make_cleanup_value_free_to_mark (value_mark ());
|
||||
scoped_value_mark free_values;
|
||||
|
||||
ctx.this_frame = this_frame;
|
||||
ctx.gdbarch = get_frame_arch (this_frame);
|
||||
@ -430,8 +429,6 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size,
|
||||
Not implemented: computing unwound register using explicit value operator"));
|
||||
}
|
||||
|
||||
do_cleanups (old_chain);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2790,16 +2790,14 @@ dwarf2_loc_desc_get_symbol_read_needs (const gdb_byte *data, size_t size,
|
||||
struct dwarf2_per_cu_data *per_cu)
|
||||
{
|
||||
int in_reg;
|
||||
struct cleanup *old_chain;
|
||||
struct objfile *objfile = dwarf2_per_cu_objfile (per_cu);
|
||||
|
||||
scoped_value_mark free_values;
|
||||
|
||||
symbol_needs_eval_context ctx;
|
||||
|
||||
ctx.needs = SYMBOL_NEEDS_NONE;
|
||||
ctx.per_cu = per_cu;
|
||||
|
||||
old_chain = make_cleanup_value_free_to_mark (value_mark ());
|
||||
|
||||
ctx.gdbarch = get_objfile_arch (objfile);
|
||||
ctx.addr_size = dwarf2_per_cu_addr_size (per_cu);
|
||||
ctx.ref_addr_size = dwarf2_per_cu_ref_addr_size (per_cu);
|
||||
@ -2820,8 +2818,6 @@ dwarf2_loc_desc_get_symbol_read_needs (const gdb_byte *data, size_t size,
|
||||
in_reg = 1;
|
||||
}
|
||||
|
||||
do_cleanups (old_chain);
|
||||
|
||||
if (in_reg)
|
||||
ctx.needs = SYMBOL_NEEDS_FRAME;
|
||||
return ctx.needs;
|
||||
|
@ -178,11 +178,10 @@ valpy_dereference (PyObject *self, PyObject *args)
|
||||
TRY
|
||||
{
|
||||
struct value *res_val;
|
||||
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
||||
scoped_value_mark free_values;
|
||||
|
||||
res_val = value_ind (((value_object *) self)->value);
|
||||
result = value_to_value_object (res_val);
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
@ -209,7 +208,7 @@ valpy_referenced_value (PyObject *self, PyObject *args)
|
||||
TRY
|
||||
{
|
||||
struct value *self_val, *res_val;
|
||||
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
||||
scoped_value_mark free_values;
|
||||
|
||||
self_val = ((value_object *) self)->value;
|
||||
switch (TYPE_CODE (check_typedef (value_type (self_val))))
|
||||
@ -226,7 +225,6 @@ valpy_referenced_value (PyObject *self, PyObject *args)
|
||||
}
|
||||
|
||||
result = value_to_value_object (res_val);
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
@ -247,12 +245,10 @@ valpy_reference_value (PyObject *self, PyObject *args)
|
||||
TRY
|
||||
{
|
||||
struct value *self_val;
|
||||
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
||||
scoped_value_mark free_values;
|
||||
|
||||
self_val = ((value_object *) self)->value;
|
||||
result = value_to_value_object (value_ref (self_val));
|
||||
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
@ -273,13 +269,11 @@ valpy_const_value (PyObject *self, PyObject *args)
|
||||
TRY
|
||||
{
|
||||
struct value *self_val, *res_val;
|
||||
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
||||
scoped_value_mark free_values;
|
||||
|
||||
self_val = ((value_object *) self)->value;
|
||||
res_val = make_cv_value (1, 0, self_val);
|
||||
result = value_to_value_object (res_val);
|
||||
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
@ -301,12 +295,10 @@ valpy_get_address (PyObject *self, void *closure)
|
||||
TRY
|
||||
{
|
||||
struct value *res_val;
|
||||
struct cleanup *cleanup
|
||||
= make_cleanup_value_free_to_mark (value_mark ());
|
||||
scoped_value_mark free_values;
|
||||
|
||||
res_val = value_addr (val_obj->value);
|
||||
val_obj->address = value_to_value_object (res_val);
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
@ -354,7 +346,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
|
||||
TRY
|
||||
{
|
||||
struct value *val = obj->value;
|
||||
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
||||
scoped_value_mark free_values;
|
||||
|
||||
type = value_type (val);
|
||||
type = check_typedef (type);
|
||||
@ -387,8 +379,6 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
|
||||
/* Re-use object's static type. */
|
||||
type = NULL;
|
||||
}
|
||||
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
@ -428,7 +418,7 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
|
||||
|
||||
TRY
|
||||
{
|
||||
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
||||
scoped_value_mark free_values;
|
||||
|
||||
if (TYPE_CODE (value_type (value)) == TYPE_CODE_PTR)
|
||||
value = value_ind (value);
|
||||
@ -436,8 +426,6 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
|
||||
str_obj = gdbpy_create_lazy_string_object (value_address (value), length,
|
||||
user_encoding,
|
||||
value_type (value));
|
||||
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
@ -514,7 +502,7 @@ valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op)
|
||||
{
|
||||
struct value *val = ((value_object *) self)->value;
|
||||
struct value *res_val;
|
||||
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
||||
scoped_value_mark free_values;
|
||||
|
||||
if (op == UNOP_DYNAMIC_CAST)
|
||||
res_val = value_dynamic_cast (type, val);
|
||||
@ -527,7 +515,6 @@ valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op)
|
||||
}
|
||||
|
||||
result = value_to_value_object (res_val);
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
@ -737,8 +724,8 @@ valpy_getitem (PyObject *self, PyObject *key)
|
||||
TRY
|
||||
{
|
||||
struct value *tmp = self_value->value;
|
||||
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
||||
struct value *res_val = NULL;
|
||||
scoped_value_mark free_values;
|
||||
|
||||
if (field)
|
||||
res_val = value_struct_elt (&tmp, NULL, field.get (), NULL,
|
||||
@ -783,7 +770,6 @@ valpy_getitem (PyObject *self, PyObject *key)
|
||||
|
||||
if (res_val)
|
||||
result = value_to_value_object (res_val);
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
CATCH (ex, RETURN_MASK_ALL)
|
||||
{
|
||||
@ -861,12 +847,11 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
|
||||
|
||||
TRY
|
||||
{
|
||||
struct cleanup *cleanup = make_cleanup_value_free_to_mark (mark);
|
||||
scoped_value_mark free_values;
|
||||
struct value *return_value;
|
||||
|
||||
return_value = call_function_by_hand (function, args_count, vargs);
|
||||
result = value_to_value_object (return_value);
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
@ -1014,11 +999,12 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other)
|
||||
PyObject *result = NULL;
|
||||
|
||||
struct value *arg1, *arg2;
|
||||
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
||||
struct value *res_val = NULL;
|
||||
enum exp_opcode op = OP_NULL;
|
||||
int handled = 0;
|
||||
|
||||
scoped_value_mark free_values;
|
||||
|
||||
/* 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 kind of object, altogether. Because of this, we can't
|
||||
@ -1026,17 +1012,11 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other)
|
||||
python as well. */
|
||||
arg1 = convert_value_from_python (self);
|
||||
if (arg1 == NULL)
|
||||
{
|
||||
do_cleanups (cleanup);
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
|
||||
arg2 = convert_value_from_python (other);
|
||||
if (arg2 == NULL)
|
||||
{
|
||||
do_cleanups (cleanup);
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
@ -1130,7 +1110,6 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other)
|
||||
if (res_val)
|
||||
result = value_to_value_object (res_val);
|
||||
|
||||
do_cleanups (cleanup);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1209,12 +1188,11 @@ valpy_negative (PyObject *self)
|
||||
TRY
|
||||
{
|
||||
/* Perhaps overkill, but consistency has some virtue. */
|
||||
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
||||
scoped_value_mark free_values;
|
||||
struct value *val;
|
||||
|
||||
val = value_neg (((value_object *) self)->value);
|
||||
result = value_to_value_object (val);
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
@ -1239,12 +1217,10 @@ valpy_absolute (PyObject *self)
|
||||
|
||||
TRY
|
||||
{
|
||||
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
||||
scoped_value_mark free_values;
|
||||
|
||||
if (value_less (value, value_zero (value_type (value), not_lval)))
|
||||
isabs = 0;
|
||||
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
@ -1362,15 +1338,14 @@ valpy_richcompare_throw (PyObject *self, PyObject *other, int op)
|
||||
int result;
|
||||
struct value *value_other;
|
||||
struct value *value_self;
|
||||
struct value *mark = value_mark ();
|
||||
struct cleanup *cleanup;
|
||||
|
||||
scoped_value_mark free_values;
|
||||
|
||||
value_other = convert_value_from_python (other);
|
||||
if (value_other == NULL)
|
||||
return -1;
|
||||
|
||||
cleanup = make_cleanup_value_free_to_mark (mark);
|
||||
|
||||
value_self = ((value_object *) self)->value;
|
||||
|
||||
switch (op)
|
||||
@ -1403,7 +1378,6 @@ valpy_richcompare_throw (PyObject *self, PyObject *other, int op)
|
||||
break;
|
||||
}
|
||||
|
||||
do_cleanups (cleanup);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
22
gdb/value.h
22
gdb/value.h
@ -714,6 +714,28 @@ extern struct value *value_mark (void);
|
||||
|
||||
extern void value_free_to_mark (const struct value *mark);
|
||||
|
||||
/* A helper class that uses value_mark at construction time and calls
|
||||
value_free_to_mark in the destructor. This is used to clear out
|
||||
temporary values created during the lifetime of this object. */
|
||||
class scoped_value_mark
|
||||
{
|
||||
public:
|
||||
|
||||
scoped_value_mark ()
|
||||
: m_value (value_mark ())
|
||||
{
|
||||
}
|
||||
|
||||
~scoped_value_mark ()
|
||||
{
|
||||
value_free_to_mark (m_value);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
const struct value *m_value;
|
||||
};
|
||||
|
||||
extern struct value *value_cstring (const char *ptr, ssize_t len,
|
||||
struct type *char_type);
|
||||
extern struct value *value_string (const char *ptr, ssize_t len,
|
||||
|
Loading…
Reference in New Issue
Block a user