diff options
author | Siva Chandra <sivachandra@chromium.org> | 2014-05-20 06:30:29 -0700 |
---|---|---|
committer | Siva Chandra <sivachandra@chromium.org> | 2014-06-03 09:49:26 -0700 |
commit | e81e7f5e38bf0da52d9e88a94e4df9aeecd80357 (patch) | |
tree | a6c3151a1f58f8e8453236891c12e6a0234c9e47 /gdb/value.c | |
parent | ef370185fcf955b1273c2c6bcbe0b406ec1cbd83 (diff) | |
download | gdb-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.c | 47 |
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. |