aboutsummaryrefslogtreecommitdiff
path: root/gdb/value.c
diff options
context:
space:
mode:
authorSiva Chandra <sivachandra@chromium.org>2014-05-20 06:30:29 -0700
committerSiva Chandra <sivachandra@chromium.org>2014-06-03 09:49:26 -0700
commite81e7f5e38bf0da52d9e88a94e4df9aeecd80357 (patch)
treea6c3151a1f58f8e8453236891c12e6a0234c9e47 /gdb/value.c
parentef370185fcf955b1273c2c6bcbe0b406ec1cbd83 (diff)
downloadgdb-e81e7f5e38bf0da52d9e88a94e4df9aeecd80357.zip
gdb-e81e7f5e38bf0da52d9e88a94e4df9aeecd80357.tar.gz
gdb-e81e7f5e38bf0da52d9e88a94e4df9aeecd80357.tar.bz2
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.
Diffstat (limited to 'gdb/value.c')
-rw-r--r--gdb/value.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/gdb/value.c b/gdb/value.c
index d125a09..1cdb109 100644
--- a/gdb/value.c
+++ b/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.