/* Python interface to values.
- Copyright (C) 2008-2016 Free Software Foundation, Inc.
+ Copyright (C) 2008-2018 Free Software Foundation, Inc.
This file is part of GDB.
#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"
#include "python.h"
#include "python-internal.h"
+#include "py-ref.h"
/* Even though Python scalar types directly map to host types, we use
target types here to remain consistent with the values system in
TRY
{
struct value *res_val;
- struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+ scoped_value_mark free_values;
res_val = value_ind (((value_object *) self)->value);
result = value_to_value_object (res_val);
- do_cleanups (cleanup);
}
CATCH (except, RETURN_MASK_ALL)
{
TRY
{
struct value *self_val, *res_val;
- struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+ scoped_value_mark free_values;
self_val = ((value_object *) self)->value;
switch (TYPE_CODE (check_typedef (value_type (self_val))))
res_val = value_ind (self_val);
break;
case TYPE_CODE_REF:
+ case TYPE_CODE_RVALUE_REF:
res_val = coerce_ref (self_val);
break;
default:
}
result = value_to_value_object (res_val);
- do_cleanups (cleanup);
}
CATCH (except, RETURN_MASK_ALL)
{
/* 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;
TRY
{
struct value *self_val;
- struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+ scoped_value_mark free_values;
self_val = ((value_object *) self)->value;
- result = value_to_value_object (value_ref (self_val));
-
- do_cleanups (cleanup);
+ result = value_to_value_object (value_ref (self_val, refcode));
}
CATCH (except, RETURN_MASK_ALL)
{
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 *
TRY
{
struct value *self_val, *res_val;
- struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+ scoped_value_mark free_values;
self_val = ((value_object *) self)->value;
res_val = make_cv_value (1, 0, self_val);
result = value_to_value_object (res_val);
-
- do_cleanups (cleanup);
}
CATCH (except, RETURN_MASK_ALL)
{
TRY
{
struct value *res_val;
- struct cleanup *cleanup
- = make_cleanup_value_free_to_mark (value_mark ());
+ scoped_value_mark free_values;
res_val = value_addr (val_obj->value);
val_obj->address = value_to_value_object (res_val);
- do_cleanups (cleanup);
}
CATCH (except, RETURN_MASK_ALL)
{
TRY
{
struct value *val = obj->value;
- struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+ scoped_value_mark free_values;
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;
if (was_pointer)
type = lookup_pointer_type (type);
else
- type = lookup_reference_type (type);
+ type = lookup_lvalue_reference_type (type);
}
}
else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
/* Re-use object's static type. */
type = NULL;
}
-
- do_cleanups (cleanup);
}
CATCH (except, RETURN_MASK_ALL)
{
A lazy string is a pointer to a string with an optional encoding and
length. If ENCODING is not given, encoding is set to None. If an
ENCODING is provided the encoding parameter is set to ENCODING, but
- the string is not encoded. If LENGTH is provided then the length
- parameter is set to LENGTH, otherwise length will be set to -1 (first
- null of appropriate with). */
+ the string is not encoded.
+ If LENGTH is provided then the length parameter is set to LENGTH.
+ Otherwise if the value is an array of known length then the array's length
+ is used. Otherwise the length will be set to -1 (meaning first null of
+ appropriate with).
+
+ Note: In order to not break any existing uses this allows creating
+ lazy strings from anything. PR 20769. E.g.,
+ gdb.parse_and_eval("my_int_variable").lazy_string().
+ "It's easier to relax restrictions than it is to impose them after the
+ fact." So we should be flagging any unintended uses as errors, but it's
+ perhaps too late for that. */
+
static PyObject *
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)
+ {
+ PyErr_SetString (PyExc_ValueError, _("Invalid length."));
+ return NULL;
+ }
+
TRY
{
- struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+ scoped_value_mark free_values;
+ struct type *type, *realtype;
+ CORE_ADDR addr;
- if (TYPE_CODE (value_type (value)) == TYPE_CODE_PTR)
- value = value_ind (value);
+ type = value_type (value);
+ realtype = check_typedef (type);
- str_obj = gdbpy_create_lazy_string_object (value_address (value), length,
- user_encoding,
- value_type (value));
+ switch (TYPE_CODE (realtype))
+ {
+ case TYPE_CODE_ARRAY:
+ {
+ LONGEST array_length = -1;
+ LONGEST low_bound, high_bound;
+
+ /* PR 20786: There's no way to specify an array of length zero.
+ Record a length of [0,-1] which is how Ada does it. Anything
+ we do is broken, but this one possible solution. */
+ if (get_array_bounds (realtype, &low_bound, &high_bound))
+ array_length = high_bound - low_bound + 1;
+ if (length == -1)
+ length = array_length;
+ else if (array_length == -1)
+ {
+ type = lookup_array_range_type (TYPE_TARGET_TYPE (realtype),
+ 0, length - 1);
+ }
+ else if (length != array_length)
+ {
+ /* We need to create a new array type with the
+ specified length. */
+ if (length > array_length)
+ error (_("Length is larger than array size."));
+ type = lookup_array_range_type (TYPE_TARGET_TYPE (realtype),
+ low_bound,
+ low_bound + length - 1);
+ }
+ addr = value_address (value);
+ break;
+ }
+ case TYPE_CODE_PTR:
+ /* If a length is specified we defer creating an array of the
+ specified width until we need to. */
+ addr = value_as_address (value);
+ break;
+ default:
+ /* Should flag an error here. PR 20769. */
+ addr = value_address (value);
+ break;
+ }
- do_cleanups (cleanup);
+ str_obj = gdbpy_create_lazy_string_object (addr, length, user_encoding,
+ type);
}
CATCH (except, RETURN_MASK_ALL)
{
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
{
struct value *val = ((value_object *) self)->value;
struct value *res_val;
- struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+ scoped_value_mark free_values;
if (op == UNOP_DYNAMIC_CAST)
res_val = value_dynamic_cast (type, val);
}
result = value_to_value_object (res_val);
- do_cleanups (cleanup);
}
CATCH (except, RETURN_MASK_ALL)
{
{
struct type *parent_type, *val_type;
enum type_code type_code;
- PyObject *type_object = PyObject_GetAttrString (field, "parent_type");
+ gdbpy_ref<> type_object (PyObject_GetAttrString (field, "parent_type"));
int has_field = 0;
if (type_object == NULL)
return -1;
- parent_type = type_object_to_type (type_object);
- Py_DECREF (type_object);
+ parent_type = type_object_to_type (type_object.get ());
if (parent_type == NULL)
{
PyErr_SetString (PyExc_TypeError,
{
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);
static int
get_field_flag (PyObject *field, const char *flag_name)
{
- int flag_value;
- PyObject *flag_object = PyObject_GetAttrString (field, flag_name);
+ gdbpy_ref<> flag_object (PyObject_GetAttrString (field, flag_name));
if (flag_object == NULL)
return -1;
- flag_value = PyObject_IsTrue (flag_object);
- Py_DECREF (flag_object);
-
- return flag_value;
+ return PyObject_IsTrue (flag_object.get ());
}
/* Return the "type" attribute of a gdb.Field object.
static struct type *
get_field_type (PyObject *field)
{
- PyObject *ftype_obj = PyObject_GetAttrString (field, "type");
+ gdbpy_ref<> ftype_obj (PyObject_GetAttrString (field, "type"));
struct type *ftype;
if (ftype_obj == NULL)
return NULL;
- ftype = type_object_to_type (ftype_obj);
- Py_DECREF (ftype_obj);
+ ftype = type_object_to_type (ftype_obj.get ());
if (ftype == NULL)
PyErr_SetString (PyExc_TypeError,
_("'type' attribute of gdb.Field object is not a "
{
struct gdb_exception except = exception_none;
value_object *self_value = (value_object *) self;
- char *field = NULL;
+ gdb::unique_xmalloc_ptr<char> field;
struct type *base_class_type = NULL, *field_type = NULL;
long bitpos = -1;
PyObject *result = NULL;
}
else
{
- PyObject *name_obj = PyObject_GetAttrString (key, "name");
+ gdbpy_ref<> name_obj (PyObject_GetAttrString (key, "name"));
if (name_obj == NULL)
return NULL;
if (name_obj != Py_None)
{
- field = python_string_to_host_string (name_obj);
- Py_DECREF (name_obj);
+ field = python_string_to_host_string (name_obj.get ());
if (field == NULL)
return NULL;
}
else
{
- PyObject *bitpos_obj;
- int valid;
-
- Py_DECREF (name_obj);
-
if (!PyObject_HasAttrString (key, "bitpos"))
{
PyErr_SetString (PyExc_AttributeError,
return NULL;
}
- bitpos_obj = PyObject_GetAttrString (key, "bitpos");
+ gdbpy_ref<> bitpos_obj (PyObject_GetAttrString (key, "bitpos"));
if (bitpos_obj == NULL)
return NULL;
- valid = gdb_py_int_as_long (bitpos_obj, &bitpos);
- Py_DECREF (bitpos_obj);
- if (!valid)
+ if (!gdb_py_int_as_long (bitpos_obj.get (), &bitpos))
return NULL;
field_type = get_field_type (key);
TRY
{
struct value *tmp = self_value->value;
- struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
struct value *res_val = NULL;
+ scoped_value_mark free_values;
if (field)
- res_val = value_struct_elt (&tmp, NULL, field, 0, NULL);
+ res_val = value_struct_elt (&tmp, NULL, field.get (), NULL,
+ "struct/class/union");
else if (bitpos >= 0)
res_val = value_struct_elt_bitpos (&tmp, bitpos, field_type,
"struct/class/union");
if (TYPE_CODE (val_type) == TYPE_CODE_PTR)
res_val = value_cast (lookup_pointer_type (base_class_type), tmp);
else if (TYPE_CODE (val_type) == TYPE_CODE_REF)
- res_val = value_cast (lookup_reference_type (base_class_type), tmp);
+ 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);
}
if (res_val)
result = value_to_value_object (res_val);
- do_cleanups (cleanup);
}
CATCH (ex, RETURN_MASK_ALL)
{
}
END_CATCH
- xfree (field);
GDB_PY_HANDLE_EXCEPTION (except);
return result;
struct value *function = ((value_object *) self)->value;
struct value **vargs = NULL;
struct type *ftype = NULL;
- struct value *mark = value_mark ();
PyObject *result = NULL;
TRY
TRY
{
- struct cleanup *cleanup = make_cleanup_value_free_to_mark (mark);
+ scoped_value_mark free_values;
struct value *return_value;
- return_value = call_function_by_hand (function, args_count, vargs);
+ return_value = call_function_by_hand (function, NULL,
+ args_count, vargs);
result = value_to_value_object (return_value);
- do_cleanups (cleanup);
}
CATCH (except, RETURN_MASK_ALL)
{
static PyObject *
valpy_str (PyObject *self)
{
- char *s = NULL;
- PyObject *result;
struct value_print_options opts;
get_user_print_options (&opts);
opts.deref_ref = 0;
+ string_file stb;
+
TRY
{
- struct ui_file *stb = mem_fileopen ();
- struct cleanup *old_chain = make_cleanup_ui_file_delete (stb);
-
- common_val_print (((value_object *) self)->value, stb, 0,
+ common_val_print (((value_object *) self)->value, &stb, 0,
&opts, python_language);
- s = ui_file_xstrdup (stb, NULL);
-
- do_cleanups (old_chain);
}
CATCH (except, RETURN_MASK_ALL)
{
}
END_CATCH
- result = PyUnicode_Decode (s, strlen (s), host_charset (), NULL);
- xfree (s);
-
- return result;
+ return PyUnicode_Decode (stb.c_str (), stb.size (), host_charset (), NULL);
}
/* Implements gdb.Value.is_optimized_out. */
/* 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
PyObject *result = NULL;
struct value *arg1, *arg2;
- struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
struct value *res_val = NULL;
enum exp_opcode op = OP_NULL;
int handled = 0;
+ scoped_value_mark free_values;
+
/* If the gdb.Value object is the second operand, then it will be
passed to us as the OTHER argument, and SELF will be an entirely
different kind of object, altogether. Because of this, we can't
python as well. */
arg1 = convert_value_from_python (self);
if (arg1 == NULL)
- {
- do_cleanups (cleanup);
- return NULL;
- }
+ return NULL;
arg2 = convert_value_from_python (other);
if (arg2 == NULL)
- {
- do_cleanups (cleanup);
- return NULL;
- }
+ return NULL;
switch (opcode)
{
if (res_val)
result = value_to_value_object (res_val);
- do_cleanups (cleanup);
return result;
}
TRY
{
/* Perhaps overkill, but consistency has some virtue. */
- struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+ scoped_value_mark free_values;
struct value *val;
val = value_neg (((value_object *) self)->value);
result = value_to_value_object (val);
- do_cleanups (cleanup);
}
CATCH (except, RETURN_MASK_ALL)
{
TRY
{
- struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+ scoped_value_mark free_values;
if (value_less (value, value_zero (value_type (value), not_lval)))
isabs = 0;
-
- do_cleanups (cleanup);
}
CATCH (except, RETURN_MASK_ALL)
{
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;
int result;
struct value *value_other;
struct value *value_self;
- struct value *mark = value_mark ();
- struct cleanup *cleanup;
+
+ scoped_value_mark free_values;
value_other = convert_value_from_python (other);
if (value_other == NULL)
return -1;
- cleanup = make_cleanup_value_free_to_mark (mark);
-
value_self = ((value_object *) self)->value;
switch (op)
break;
}
- do_cleanups (cleanup);
return result;
}
}
END_CATCH
- return gdb_py_long_from_longest (l);
+ if (TYPE_UNSIGNED (type))
+ return gdb_py_long_from_ulongest (l);
+ else
+ return gdb_py_long_from_longest (l);
}
/* Implements conversion to float. */
{
type = check_typedef (type);
- if (TYPE_CODE (type) != TYPE_CODE_FLT)
+ if (TYPE_CODE (type) != TYPE_CODE_FLT || !is_floating_value (value))
error (_("Cannot convert value to float."));
- d = value_as_double (value);
+ d = target_float_to_host_double (value_contents (value), type);
}
CATCH (except, RETURN_MASK_ALL)
{
ULONGEST instead. */
if (PyErr_ExceptionMatches (PyExc_OverflowError))
{
- PyObject *etype, *evalue, *etraceback, *zero;
+ PyObject *etype, *evalue, *etraceback;
PyErr_Fetch (&etype, &evalue, &etraceback);
- zero = PyInt_FromLong (0);
+ gdbpy_ref<> zero (PyInt_FromLong (0));
/* Check whether obj is positive. */
- if (PyObject_RichCompareBool (obj, zero, Py_GT) > 0)
+ if (PyObject_RichCompareBool (obj, zero.get (), Py_GT) > 0)
{
ULONGEST ul;
else
/* There's nothing we can do. */
PyErr_Restore (etype, evalue, etraceback);
-
- Py_DECREF (zero);
}
}
else
value = value_from_longest (builtin_type_pylong, l);
}
+#if PY_MAJOR_VERSION == 2
else if (PyInt_Check (obj))
{
long l = PyInt_AsLong (obj);
if (! PyErr_Occurred ())
value = value_from_longest (builtin_type_pyint, l);
}
+#endif
else if (PyFloat_Check (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))
{
- char *s;
-
- s = python_string_to_target_string (obj);
+ gdb::unique_xmalloc_ptr<char> s
+ = python_string_to_target_string (obj);
if (s != NULL)
- {
- struct cleanup *old;
-
- old = make_cleanup (xfree, s);
- value = value_cstring (s, strlen (s), builtin_type_pychar);
- do_cleanups (old);
- }
+ value = value_cstring (s.get (), strlen (s.get ()),
+ builtin_type_pychar);
}
else if (PyObject_TypeCheck (obj, &value_object_type))
value = value_copy (((value_object *) obj)->value);
\f
-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,
{ "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,
NULL, /* nb_inplace_xor */
NULL, /* nb_inplace_or */
NULL, /* nb_floor_divide */
- valpy_divide /* nb_true_divide */
+ valpy_divide, /* nb_true_divide */
+ NULL, /* nb_inplace_floor_divide */
+ NULL, /* nb_inplace_true_divide */
+#ifndef HAVE_LIBPYTHON2_4
+ /* This was added in Python 2.5. */
+ valpy_long, /* nb_index */
+#endif /* HAVE_LIBPYTHON2_4 */
};
static PyMappingMethods value_object_as_mapping = {