X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fpython%2Fpy-value.c;h=9cc56e6cd1d1494a83b91cdcb9831cf14d8d271f;hb=5c329e6ab4c7bba9b83155571b150756210001df;hp=c848f0f65d57220977481c54fc26812f5bcf2721;hpb=a65cfae5f8b268158c23a862e7a996d15bbcef0e;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c index c848f0f65d..9cc56e6cd1 100644 --- a/gdb/python/py-value.c +++ b/gdb/python/py-value.c @@ -1,6 +1,6 @@ /* Python interface to values. - Copyright (C) 2008-2017 Free Software Foundation, Inc. + Copyright (C) 2008-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -21,7 +21,7 @@ #include "charset.h" #include "value.h" #include "language.h" -#include "dfp.h" +#include "target-float.h" #include "valprint.h" #include "infcall.h" #include "expression.h" @@ -88,7 +88,7 @@ valpy_dealloc (PyObject *obj) if (self->next) self->next->prev = self->prev; - value_free (self->value); + value_decref (self->value); if (self->address) /* Use braces to appease gcc warning. *sigh* */ @@ -147,8 +147,7 @@ valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *keywords) return NULL; } - value_obj->value = value; - release_value_or_incref (value); + value_obj->value = release_value (value).release (); value_obj->address = NULL; value_obj->type = NULL; value_obj->dynamic_type = NULL; @@ -217,6 +216,7 @@ valpy_referenced_value (PyObject *self, PyObject *args) res_val = value_ind (self_val); break; case TYPE_CODE_REF: + case TYPE_CODE_RVALUE_REF: res_val = coerce_ref (self_val); break; default: @@ -238,7 +238,7 @@ valpy_referenced_value (PyObject *self, PyObject *args) /* Return a value which is a reference to the value. */ static PyObject * -valpy_reference_value (PyObject *self, PyObject *args) +valpy_reference_value (PyObject *self, PyObject *args, enum type_code refcode) { PyObject *result = NULL; @@ -248,7 +248,7 @@ valpy_reference_value (PyObject *self, PyObject *args) scoped_value_mark free_values; self_val = ((value_object *) self)->value; - result = value_to_value_object (value_ref (self_val, TYPE_CODE_REF)); + result = value_to_value_object (value_ref (self_val, refcode)); } CATCH (except, RETURN_MASK_ALL) { @@ -259,6 +259,18 @@ valpy_reference_value (PyObject *self, PyObject *args) return result; } +static PyObject * +valpy_lvalue_reference_value (PyObject *self, PyObject *args) +{ + return valpy_reference_value (self, args, TYPE_CODE_REF); +} + +static PyObject * +valpy_rvalue_reference_value (PyObject *self, PyObject *args) +{ + return valpy_reference_value (self, args, TYPE_CODE_RVALUE_REF); +} + /* Return a "const" qualified version of the value. */ static PyObject * @@ -351,8 +363,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure) type = value_type (val); type = check_typedef (type); - if (((TYPE_CODE (type) == TYPE_CODE_PTR) - || (TYPE_CODE (type) == TYPE_CODE_REF)) + if (((TYPE_CODE (type) == TYPE_CODE_PTR) || TYPE_IS_REFERENCE (type)) && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT)) { struct value *target; @@ -419,11 +430,11 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw) gdb_py_longest length = -1; struct value *value = ((value_object *) self)->value; const char *user_encoding = NULL; - static char *keywords[] = { "encoding", "length", NULL }; + static const char *keywords[] = { "encoding", "length", NULL }; PyObject *str_obj = NULL; - if (!PyArg_ParseTupleAndKeywords (args, kw, "|s" GDB_PY_LL_ARG, keywords, - &user_encoding, &length)) + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "|s" GDB_PY_LL_ARG, + keywords, &user_encoding, &length)) return NULL; if (length < -1) @@ -506,18 +517,17 @@ static PyObject * valpy_string (PyObject *self, PyObject *args, PyObject *kw) { int length = -1; - gdb_byte *buffer; + gdb::unique_xmalloc_ptr buffer; struct value *value = ((value_object *) self)->value; - PyObject *unicode; const char *encoding = NULL; const char *errors = NULL; const char *user_encoding = NULL; const char *la_encoding = NULL; struct type *char_type; - static char *keywords[] = { "encoding", "errors", "length", NULL }; + static const char *keywords[] = { "encoding", "errors", "length", NULL }; - if (!PyArg_ParseTupleAndKeywords (args, kw, "|ssi", keywords, - &user_encoding, &errors, &length)) + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "|ssi", keywords, + &user_encoding, &errors, &length)) return NULL; TRY @@ -531,12 +541,9 @@ valpy_string (PyObject *self, PyObject *args, PyObject *kw) END_CATCH encoding = (user_encoding && *user_encoding) ? user_encoding : la_encoding; - unicode = PyUnicode_Decode ((const char *) buffer, - length * TYPE_LENGTH (char_type), - encoding, errors); - xfree (buffer); - - return unicode; + return PyUnicode_Decode ((const char *) buffer.get (), + length * TYPE_LENGTH (char_type), + encoding, errors); } /* A helper function that implements the various cast operators. */ @@ -645,8 +652,7 @@ value_has_field (struct value *v, PyObject *field) { val_type = value_type (v); val_type = check_typedef (val_type); - if (TYPE_CODE (val_type) == TYPE_CODE_REF - || TYPE_CODE (val_type) == TYPE_CODE_PTR) + if (TYPE_IS_REFERENCE (val_type) || TYPE_CODE (val_type) == TYPE_CODE_PTR) val_type = check_typedef (TYPE_TARGET_TYPE (val_type)); type_code = TYPE_CODE (val_type); @@ -803,6 +809,9 @@ valpy_getitem (PyObject *self, PyObject *key) else if (TYPE_CODE (val_type) == TYPE_CODE_REF) res_val = value_cast (lookup_lvalue_reference_type (base_class_type), tmp); + else if (TYPE_CODE (val_type) == TYPE_CODE_RVALUE_REF) + res_val = value_cast (lookup_rvalue_reference_type (base_class_type), + tmp); else res_val = value_cast (base_class_type, tmp); } @@ -860,7 +869,6 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords) struct value *function = ((value_object *) self)->value; struct value **vargs = NULL; struct type *ftype = NULL; - struct value *mark = value_mark (); PyObject *result = NULL; TRY @@ -909,9 +917,10 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords) TRY { scoped_value_mark free_values; - struct value *return_value; - return_value = call_function_by_hand (function, args_count, vargs); + value *return_value + = call_function_by_hand (function, NULL, + gdb::make_array_view (vargs, args_count)); result = value_to_value_object (return_value); } CATCH (except, RETURN_MASK_ALL) @@ -1040,7 +1049,7 @@ enum valpy_opcode /* If TYPE is a reference, return the target; otherwise return TYPE. */ #define STRIP_REFERENCE(TYPE) \ - ((TYPE_CODE (TYPE) == TYPE_CODE_REF) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE)) + (TYPE_IS_REFERENCE (TYPE) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE)) /* Helper for valpy_binop. Returns a value object which is the result of applying the operation specified by OPCODE to the given @@ -1302,12 +1311,9 @@ valpy_nonzero (PyObject *self) if (is_integral_type (type) || TYPE_CODE (type) == TYPE_CODE_PTR) nonzero = !!value_as_long (self_value->value); - else if (TYPE_CODE (type) == TYPE_CODE_FLT) - nonzero = value_as_double (self_value->value) != 0; - else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT) - nonzero = !decimal_is_zero (value_contents (self_value->value), - TYPE_LENGTH (type), - gdbarch_byte_order (get_type_arch (type))); + else if (is_floating_value (self_value->value)) + nonzero = !target_float_is_zero (value_contents (self_value->value), + type); else /* All other values are True. */ nonzero = 1; @@ -1491,7 +1497,14 @@ valpy_int (PyObject *self) TRY { - if (!is_integral_type (type)) + if (is_floating_value (value)) + { + type = builtin_type_pylong; + value = value_cast (type, value); + } + + if (!is_integral_type (type) + && TYPE_CODE (type) != TYPE_CODE_PTR) error (_("Cannot convert value to int.")); l = value_as_long (value); @@ -1502,7 +1515,10 @@ valpy_int (PyObject *self) } END_CATCH - return gdb_py_object_from_longest (l); + if (TYPE_UNSIGNED (type)) + return gdb_py_object_from_ulongest (l).release (); + else + return gdb_py_object_from_longest (l).release (); } #endif @@ -1516,6 +1532,12 @@ valpy_long (PyObject *self) TRY { + if (is_floating_value (value)) + { + type = builtin_type_pylong; + value = value_cast (type, value); + } + type = check_typedef (type); if (!is_integral_type (type) @@ -1548,10 +1570,17 @@ valpy_float (PyObject *self) { type = check_typedef (type); - if (TYPE_CODE (type) != TYPE_CODE_FLT) + if (TYPE_CODE (type) == TYPE_CODE_FLT && is_floating_value (value)) + d = target_float_to_host_double (value_contents (value), type); + else if (TYPE_CODE (type) == TYPE_CODE_INT) + { + /* Note that valpy_long accepts TYPE_CODE_PTR and some + others here here -- but casting a pointer or bool to a + float seems wrong. */ + d = value_as_long (value); + } + else error (_("Cannot convert value to float.")); - - d = value_as_double (value); } CATCH (except, RETURN_MASK_ALL) { @@ -1572,8 +1601,7 @@ value_to_value_object (struct value *val) val_obj = PyObject_New (value_object, &value_object_type); if (val_obj != NULL) { - val_obj->value = val; - release_value_or_incref (val); + val_obj->value = release_value (val).release (); val_obj->address = NULL; val_obj->type = NULL; val_obj->dynamic_type = NULL; @@ -1633,9 +1661,7 @@ convert_value_from_python (PyObject *obj) ULONGEST instead. */ if (PyErr_ExceptionMatches (PyExc_OverflowError)) { - PyObject *etype, *evalue, *etraceback; - - PyErr_Fetch (&etype, &evalue, &etraceback); + gdbpy_err_fetch fetched_error; gdbpy_ref<> zero (PyInt_FromLong (0)); /* Check whether obj is positive. */ @@ -1648,8 +1674,10 @@ convert_value_from_python (PyObject *obj) value = value_from_ulongest (builtin_type_upylong, ul); } else - /* There's nothing we can do. */ - PyErr_Restore (etype, evalue, etraceback); + { + /* There's nothing we can do. */ + fetched_error.restore (); + } } } else @@ -1669,7 +1697,11 @@ convert_value_from_python (PyObject *obj) double d = PyFloat_AsDouble (obj); if (! PyErr_Occurred ()) - value = value_from_double (builtin_type_pyfloat, d); + { + value = allocate_value (builtin_type_pyfloat); + target_float_from_host_double (value_contents_raw (value), + value_type (value), d); + } } else if (gdbpy_is_string (obj)) { @@ -1700,9 +1732,7 @@ convert_value_from_python (PyObject *obj) } CATCH (except, RETURN_MASK_ALL) { - PyErr_Format (except.reason == RETURN_QUIT - ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, - "%s", except.message); + gdbpy_convert_exception (except); return NULL; } END_CATCH @@ -1733,6 +1763,83 @@ gdbpy_history (PyObject *self, PyObject *args) return value_to_value_object (res_val); } +/* Return the value of a convenience variable. */ +PyObject * +gdbpy_convenience_variable (PyObject *self, PyObject *args) +{ + const char *varname; + struct value *res_val = NULL; + + if (!PyArg_ParseTuple (args, "s", &varname)) + return NULL; + + TRY + { + struct internalvar *var = lookup_only_internalvar (varname); + + if (var != NULL) + { + res_val = value_of_internalvar (python_gdbarch, var); + if (TYPE_CODE (value_type (res_val)) == TYPE_CODE_VOID) + res_val = NULL; + } + } + CATCH (except, RETURN_MASK_ALL) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + END_CATCH + + if (res_val == NULL) + Py_RETURN_NONE; + + return value_to_value_object (res_val); +} + +/* Set the value of a convenience variable. */ +PyObject * +gdbpy_set_convenience_variable (PyObject *self, PyObject *args) +{ + const char *varname; + PyObject *value_obj; + struct value *value = NULL; + + if (!PyArg_ParseTuple (args, "sO", &varname, &value_obj)) + return NULL; + + /* None means to clear the variable. */ + if (value_obj != Py_None) + { + value = convert_value_from_python (value_obj); + if (value == NULL) + return NULL; + } + + TRY + { + if (value == NULL) + { + struct internalvar *var = lookup_only_internalvar (varname); + + if (var != NULL) + clear_internalvar (var); + } + else + { + struct internalvar *var = lookup_internalvar (varname); + + set_internalvar (var, value); + } + } + CATCH (except, RETURN_MASK_ALL) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + END_CATCH + + Py_RETURN_NONE; +} + /* Returns 1 in OBJ is a gdb.Value object, 0 otherwise. */ int @@ -1753,7 +1860,7 @@ gdbpy_initialize_values (void) -static PyGetSetDef value_object_getset[] = { +static gdb_PyGetSetDef value_object_getset[] = { { "address", valpy_get_address, NULL, "The address of the value.", NULL }, { "is_optimized_out", valpy_get_is_optimized_out, NULL, @@ -1784,8 +1891,10 @@ reinterpret_cast operator." { "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." }, { "referenced_value", valpy_referenced_value, METH_NOARGS, "Return the value referenced by a TYPE_CODE_REF or TYPE_CODE_PTR value." }, - { "reference_value", valpy_reference_value, METH_NOARGS, + { "reference_value", valpy_lvalue_reference_value, METH_NOARGS, "Return a value of type TYPE_CODE_REF referencing this value." }, + { "rvalue_reference_value", valpy_rvalue_reference_value, METH_NOARGS, + "Return a value of type TYPE_CODE_RVALUE_REF referencing this value." }, { "const_value", valpy_const_value, METH_NOARGS, "Return a 'const' qualied version of the same value." }, { "lazy_string", (PyCFunction) valpy_lazy_string,