GDB (which uses target arithmetic). */
/* Python's integer type corresponds to C's long type. */
-#define builtin_type_pyint builtin_type (current_gdbarch)->builtin_long
+#define builtin_type_pyint builtin_type (python_gdbarch)->builtin_long
/* Python's float type corresponds to C's double type. */
-#define builtin_type_pyfloat builtin_type (current_gdbarch)->builtin_double
+#define builtin_type_pyfloat builtin_type (python_gdbarch)->builtin_double
/* Python's long type corresponds to C's long long type. */
-#define builtin_type_pylong builtin_type (current_gdbarch)->builtin_long_long
+#define builtin_type_pylong builtin_type (python_gdbarch)->builtin_long_long
#define builtin_type_pybool \
- language_bool_type (current_language, current_gdbarch)
+ language_bool_type (python_language, python_gdbarch)
+
+#define builtin_type_pychar \
+ language_string_char_type (python_language, python_gdbarch)
typedef struct {
PyObject_HEAD
struct value *value;
- int owned_by_gdb;
+ PyObject *address;
+ PyObject *type;
} value_object;
/* Called by the Python interpreter when deallocating a value object. */
value_remove_from_list (&values_in_python, self->value);
- if (!self->owned_by_gdb)
- value_free (self->value);
+ value_free (self->value);
+
+ if (self->address)
+ /* Use braces to appease gcc warning. *sigh* */
+ {
+ Py_DECREF (self->address);
+ }
+
+ if (self->type)
+ {
+ Py_DECREF (self->type);
+ }
+
self->ob_type->tp_free (self);
}
}
value_obj->value = value;
- value_obj->owned_by_gdb = 0;
+ value_obj->address = NULL;
+ value_obj->type = NULL;
release_value (value);
value_prepend_to_list (&values_in_python, value);
/* Return "&value". */
static PyObject *
-valpy_address (PyObject *self, PyObject *args)
+valpy_get_address (PyObject *self, void *closure)
{
struct value *res_val = NULL; /* Initialize to appease gcc warning. */
+ value_object *val_obj = (value_object *) self;
volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ if (!val_obj->address)
{
- res_val = value_addr (((value_object *) self)->value);
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ res_val = value_addr (val_obj->value);
+ }
+ if (except.reason < 0)
+ {
+ val_obj->address = Py_None;
+ Py_INCREF (Py_None);
+ }
+ else
+ val_obj->address = value_to_value_object (res_val);
}
- GDB_PY_HANDLE_EXCEPTION (except);
- return value_to_value_object (res_val);
+ Py_INCREF (val_obj->address);
+
+ return val_obj->address;
+}
+
+/* Return type of the value. */
+static PyObject *
+valpy_get_type (PyObject *self, void *closure)
+{
+ value_object *obj = (value_object *) self;
+ if (!obj->type)
+ {
+ obj->type = type_to_type_object (value_type (obj->value));
+ if (!obj->type)
+ {
+ obj->type = Py_None;
+ Py_INCREF (obj->type);
+ }
+ }
+ Py_INCREF (obj->type);
+ return obj->type;
}
/* Implementation of gdb.Value.string ([encoding] [, errors]) -> string
return unicode;
}
+/* Cast a value to a given type. */
+static PyObject *
+valpy_cast (PyObject *self, PyObject *args)
+{
+ PyObject *type_obj;
+ struct type *type;
+ struct value *res_val = NULL; /* Initialize to appease gcc warning. */
+ volatile struct gdb_exception except;
+
+ if (! PyArg_ParseTuple (args, "O", &type_obj))
+ return NULL;
+
+ type = type_object_to_type (type_obj);
+ if (! type)
+ {
+ PyErr_SetString (PyExc_RuntimeError, "argument must be a Type");
+ return NULL;
+ }
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ res_val = value_cast (type, ((value_object *) self)->value);
+ }
+ GDB_PY_HANDLE_EXCEPTION (except);
+
+ return value_to_value_object (res_val);
+}
+
static Py_ssize_t
valpy_length (PyObject *self)
{
if (idx == NULL)
return NULL;
- res_val = value_subscript (tmp, idx);
+ res_val = value_subscript (tmp, value_as_long (idx));
}
}
if (field)
TRY_CATCH (except, RETURN_MASK_ALL)
{
common_val_print (((value_object *) self)->value, stb, 0,
- &opts, current_language);
+ &opts, python_language);
s = ui_file_xstrdup (stb, &dummy);
}
GDB_PY_HANDLE_EXCEPTION (except);
CHECK_TYPEDEF (rtype);
rtype = STRIP_REFERENCE (rtype);
- if (TYPE_CODE (ltype) == TYPE_CODE_PTR)
- res_val = value_ptradd (arg1, arg2);
- else if (TYPE_CODE (rtype) == TYPE_CODE_PTR)
- res_val = value_ptradd (arg2, arg1);
+ if (TYPE_CODE (ltype) == TYPE_CODE_PTR
+ && is_integral_type (rtype))
+ res_val = value_ptradd (arg1, value_as_long (arg2));
+ else if (TYPE_CODE (rtype) == TYPE_CODE_PTR
+ && is_integral_type (ltype))
+ res_val = value_ptradd (arg2, value_as_long (arg1));
else
res_val = value_binop (arg1, arg2, BINOP_ADD);
}
CHECK_TYPEDEF (rtype);
rtype = STRIP_REFERENCE (rtype);
- if (TYPE_CODE (ltype) == TYPE_CODE_PTR)
- {
- if (TYPE_CODE (rtype) == TYPE_CODE_PTR)
- /* A ptrdiff_t for the target would be preferable
- here. */
- res_val = value_from_longest (builtin_type_pyint,
- value_ptrdiff (arg1, arg2));
- else
- res_val = value_ptrsub (arg1, arg2);
- }
+ if (TYPE_CODE (ltype) == TYPE_CODE_PTR
+ && TYPE_CODE (rtype) == TYPE_CODE_PTR)
+ /* A ptrdiff_t for the target would be preferable here. */
+ res_val = value_from_longest (builtin_type_pyint,
+ value_ptrdiff (arg1, arg2));
+ else if (TYPE_CODE (ltype) == TYPE_CODE_PTR
+ && is_integral_type (rtype))
+ res_val = value_ptradd (arg1, - value_as_long (arg2));
else
res_val = value_binop (arg1, arg2, BINOP_SUB);
}
static PyObject *
valpy_absolute (PyObject *self)
{
- if (value_less (((value_object *) self)->value,
- value_from_longest (builtin_type_int8, 0)))
+ struct value *value = ((value_object *) self)->value;
+ if (value_less (value, value_zero (value_type (value), not_lval)))
return valpy_negative (self);
else
return valpy_positive (self);
return value_as_double (self_value->value) != 0;
else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT)
return !decimal_is_zero (value_contents (self_value->value),
- TYPE_LENGTH (type));
+ TYPE_LENGTH (type),
+ gdbarch_byte_order (get_type_arch (type)));
else
{
PyErr_SetString (PyExc_TypeError, _("Attempted truth testing on invalid "
if (val_obj != NULL)
{
val_obj->value = val;
- val_obj->owned_by_gdb = 0;
+ val_obj->address = NULL;
+ val_obj->type = NULL;
release_value (val);
value_prepend_to_list (&values_in_python, val);
}
return (PyObject *) val_obj;
}
+/* Returns value structure corresponding to the given value object. */
+struct value *
+value_object_to_value (PyObject *self)
+{
+ value_object *real;
+ if (! PyObject_TypeCheck (self, &value_object_type))
+ return NULL;
+ real = (value_object *) self;
+ return real->value;
+}
+
/* Try to convert a Python value to a gdb value. If the value cannot
be converted, set a Python exception and return NULL. */
if (s != NULL)
{
old = make_cleanup (xfree, s);
- value = value_from_string (s);
+ value = value_cstring (s, strlen (s), builtin_type_pychar);
do_cleanups (old);
}
}
values_in_python = NULL;
}
+\f
+
static PyGetSetDef value_object_getset[] = {
+ { "address", valpy_get_address, NULL, "The address of the value.",
+ NULL },
{ "is_optimized_out", valpy_get_is_optimized_out, NULL,
"Boolean telling whether the value is optimized out (i.e., not available).",
NULL },
+ { "type", valpy_get_type, NULL, "Type of the value.", NULL },
{NULL} /* Sentinel */
};
static PyMethodDef value_object_methods[] = {
- { "address", valpy_address, METH_NOARGS, "Return the address of the value." },
+ { "cast", valpy_cast, METH_VARARGS, "Cast the value to the supplied type." },
{ "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." },
{ "string", (PyCFunction) valpy_string, METH_VARARGS | METH_KEYWORDS,
"string ([encoding] [, errors]) -> string\n\