Add xmethod interface to the extension language API.
[deliverable/binutils-gdb.git] / gdb / value.c
index d125a0913a916f8034dd6310aa22f2ee4843803a..1cdb1093ed34191e7924361ecf866c4b33041aa6 100644 (file)
@@ -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)
     }
 }
 \f
+/* 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);
+}
+\f
 /* Extract a value as a C number (either long or double).
    Knows how to convert fixed values to double, or
    floating values to long.
This page took 0.025127 seconds and 4 git commands to generate.