forked from Imagelibrary/binutils-gdb
Add xmethod interface to the extension language API.
* defs.h (enum lval_type): New enumerator "lval_xcallable". * extension-priv.h (struct extension_language_ops): Add the xmethod interface. * extension.c (new_xmethod_worker, clone_xmethod_worker, get_matching_xmethod_workers, get_xmethod_argtypes, invoke_xmethod, free_xmethod_worker, free_xmethod_worker_vec): New functions. * extension.h: #include "common/vec.h". New function declarations. (struct xmethod_worker): New struct. (VEC (xmethod_worker_ptr)): New vector type. (xmethod_worker_ptr): New typedef. (xmethod_worker_vec): Likewise. * gdbtypes.c (gdbtypes_post_init): Initialize "xmethod" field of builtin_type. * gdbtypes.h (enum type_code): New enumerator TYPE_CODE_XMETHOD. (struct builtin_type): New field "xmethod". * valarith.c (value_ptradd): Assert that the value argument is not lval_xcallable. * valops.c (value_must_coerce_to_target): Return 0 for lval_xcallable values. * value.c (struct value): New field XM_WORKER in the field LOCATION. (value_address, value_raw_address): Return 0 for lval_xcallable values. (set_value_address): Assert that the value is not an lval_xcallable. (value_free): Free the associated xmethod worker when freeing lval_xcallable values. (set_value_component_location): Assert that the WHOLE value is not lval_xcallable. (value_of_xmethod, call_xmethod): New functions. * value.h: Declare "struct xmethod_worker". Declare new functions value_of_xmethod, call_xmethod.
This commit is contained in:
47
gdb/value.c
47
gdb/value.c
@@ -230,6 +230,9 @@ struct value
|
||||
/* Pointer to internal variable. */
|
||||
struct internalvar *internalvar;
|
||||
|
||||
/* Pointer to xmethod worker. */
|
||||
struct xmethod_worker *xm_worker;
|
||||
|
||||
/* If lval == lval_computed, this is a set of function pointers
|
||||
to use to access and describe the value, and a closure pointer
|
||||
for them to use. */
|
||||
@@ -1340,7 +1343,8 @@ CORE_ADDR
|
||||
value_address (const struct value *value)
|
||||
{
|
||||
if (value->lval == lval_internalvar
|
||||
|| value->lval == lval_internalvar_component)
|
||||
|| value->lval == lval_internalvar_component
|
||||
|| value->lval == lval_xcallable)
|
||||
return 0;
|
||||
if (value->parent != NULL)
|
||||
return value_address (value->parent) + value->offset;
|
||||
@@ -1352,7 +1356,8 @@ CORE_ADDR
|
||||
value_raw_address (struct value *value)
|
||||
{
|
||||
if (value->lval == lval_internalvar
|
||||
|| value->lval == lval_internalvar_component)
|
||||
|| value->lval == lval_internalvar_component
|
||||
|| value->lval == lval_xcallable)
|
||||
return 0;
|
||||
return value->location.address;
|
||||
}
|
||||
@@ -1361,7 +1366,8 @@ void
|
||||
set_value_address (struct value *value, CORE_ADDR addr)
|
||||
{
|
||||
gdb_assert (value->lval != lval_internalvar
|
||||
&& value->lval != lval_internalvar_component);
|
||||
&& value->lval != lval_internalvar_component
|
||||
&& value->lval != lval_xcallable);
|
||||
value->location.address = addr;
|
||||
}
|
||||
|
||||
@@ -1433,6 +1439,8 @@ value_free (struct value *val)
|
||||
if (funcs->free_closure)
|
||||
funcs->free_closure (val);
|
||||
}
|
||||
else if (VALUE_LVAL (val) == lval_xcallable)
|
||||
free_xmethod_worker (val->location.xm_worker);
|
||||
|
||||
xfree (val->contents);
|
||||
VEC_free (range_s, val->unavailable);
|
||||
@@ -1623,6 +1631,8 @@ void
|
||||
set_value_component_location (struct value *component,
|
||||
const struct value *whole)
|
||||
{
|
||||
gdb_assert (whole->lval != lval_xcallable);
|
||||
|
||||
if (whole->lval == lval_internalvar)
|
||||
VALUE_LVAL (component) = lval_internalvar_component;
|
||||
else
|
||||
@@ -2456,6 +2466,37 @@ show_convenience (char *ignore, int from_tty)
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the TYPE_CODE_XMETHOD value corresponding to WORKER. */
|
||||
|
||||
struct value *
|
||||
value_of_xmethod (struct xmethod_worker *worker)
|
||||
{
|
||||
if (worker->value == NULL)
|
||||
{
|
||||
struct value *v;
|
||||
|
||||
v = allocate_value (builtin_type (target_gdbarch ())->xmethod);
|
||||
v->lval = lval_xcallable;
|
||||
v->location.xm_worker = worker;
|
||||
v->modifiable = 0;
|
||||
worker->value = v;
|
||||
}
|
||||
|
||||
return worker->value;
|
||||
}
|
||||
|
||||
/* Call the xmethod corresponding to the TYPE_CODE_XMETHOD value METHOD. */
|
||||
|
||||
struct value *
|
||||
call_xmethod (struct value *method, int argc, struct value **argv)
|
||||
{
|
||||
gdb_assert (TYPE_CODE (value_type (method)) == TYPE_CODE_XMETHOD
|
||||
&& method->lval == lval_xcallable && argc > 0);
|
||||
|
||||
return invoke_xmethod (method->location.xm_worker,
|
||||
argv[0], argv + 1, argc - 1);
|
||||
}
|
||||
|
||||
/* Extract a value as a C number (either long or double).
|
||||
Knows how to convert fixed values to double, or
|
||||
floating values to long.
|
||||
|
||||
Reference in New Issue
Block a user