Remove more uses of explicit reference counting in Python
[deliverable/binutils-gdb.git] / gdb / python / py-value.c
index 8e4d06d8683fd9d45682dfb91ade7c24dc669b36..ebd7ef1a47e8ed95902048a31cf8473ed18c8471 100644 (file)
@@ -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,19 +88,10 @@ valpy_dealloc (PyObject *obj)
   if (self->next)
     self->next->prev = self->prev;
 
-  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);
-    }
+  value_decref (self->value);
 
+  Py_XDECREF (self->address);
+  Py_XDECREF (self->type);
   Py_XDECREF (self->dynamic_type);
 
   Py_TYPE (self)->tp_free (self);
@@ -147,8 +138,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 +207,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 +229,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 +239,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));
+      result = value_to_value_object (value_ref (self_val, refcode));
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -259,6 +250,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 +354,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;
@@ -369,7 +371,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
              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)
@@ -400,32 +402,92 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
    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
     {
       scoped_value_mark free_values;
+      struct type *type, *realtype;
+      CORE_ADDR addr;
+
+      type = value_type (value);
+      realtype = check_typedef (type);
 
-      if (TYPE_CODE (value_type (value)) == TYPE_CODE_PTR)
-       value = value_ind (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;
+       }
 
-      str_obj = gdbpy_create_lazy_string_object (value_address (value), length,
-                                                user_encoding,
-                                                value_type (value));
+      str_obj = gdbpy_create_lazy_string_object (addr, length, user_encoding,
+                                                type);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -446,18 +508,17 @@ static PyObject *
 valpy_string (PyObject *self, PyObject *args, PyObject *kw)
 {
   int length = -1;
-  gdb_byte *buffer;
+  gdb::unique_xmalloc_ptr<gdb_byte> 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
@@ -471,12 +532,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.  */
@@ -566,7 +624,7 @@ value_has_field (struct value *v, PyObject *field)
 {
   struct type *parent_type, *val_type;
   enum type_code type_code;
-  gdbpy_ref type_object (PyObject_GetAttrString (field, "parent_type"));
+  gdbpy_ref<> type_object (PyObject_GetAttrString (field, "parent_type"));
   int has_field = 0;
 
   if (type_object == NULL)
@@ -585,8 +643,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);
@@ -612,7 +669,7 @@ value_has_field (struct value *v, PyObject *field)
 static int
 get_field_flag (PyObject *field, const char *flag_name)
 {
-  gdbpy_ref flag_object (PyObject_GetAttrString (field, flag_name));
+  gdbpy_ref<> flag_object (PyObject_GetAttrString (field, flag_name));
 
   if (flag_object == NULL)
     return -1;
@@ -626,7 +683,7 @@ get_field_flag (PyObject *field, const char *flag_name)
 static struct type *
 get_field_type (PyObject *field)
 {
-  gdbpy_ref ftype_obj (PyObject_GetAttrString (field, "type"));
+  gdbpy_ref<> ftype_obj (PyObject_GetAttrString (field, "type"));
   struct type *ftype;
 
   if (ftype_obj == NULL)
@@ -687,7 +744,7 @@ valpy_getitem (PyObject *self, PyObject *key)
        }
       else
        {
-         gdbpy_ref name_obj (PyObject_GetAttrString (key, "name"));
+         gdbpy_ref<> name_obj (PyObject_GetAttrString (key, "name"));
 
          if (name_obj == NULL)
            return NULL;
@@ -708,7 +765,7 @@ valpy_getitem (PyObject *self, PyObject *key)
 
                  return NULL;
                }
-             gdbpy_ref bitpos_obj (PyObject_GetAttrString (key, "bitpos"));
+             gdbpy_ref<> bitpos_obj (PyObject_GetAttrString (key, "bitpos"));
              if (bitpos_obj == NULL)
                return NULL;
              if (!gdb_py_int_as_long (bitpos_obj.get (), &bitpos))
@@ -741,7 +798,11 @@ valpy_getitem (PyObject *self, PyObject *key)
          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);
        }
@@ -799,7 +860,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
@@ -848,9 +908,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)
@@ -979,7 +1040,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
@@ -1241,12 +1302,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;
@@ -1330,7 +1388,6 @@ valpy_richcompare_throw (PyObject *self, PyObject *other, int op)
   int result;
   struct value *value_other;
   struct value *value_self;
-  struct cleanup *cleanup;
 
   scoped_value_mark free_values;
 
@@ -1431,7 +1488,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);
@@ -1442,7 +1506,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
 
@@ -1456,6 +1523,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)
@@ -1488,10 +1561,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)
     {
@@ -1512,8 +1592,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;
@@ -1573,10 +1652,8 @@ convert_value_from_python (PyObject *obj)
                 ULONGEST instead.  */
              if (PyErr_ExceptionMatches (PyExc_OverflowError))
                {
-                 PyObject *etype, *evalue, *etraceback;
-
-                 PyErr_Fetch (&etype, &evalue, &etraceback);
-                 gdbpy_ref zero (PyInt_FromLong (0));
+                 gdbpy_err_fetch fetched_error;
+                 gdbpy_ref<> zero (PyInt_FromLong (0));
 
                  /* Check whether obj is positive.  */
                  if (PyObject_RichCompareBool (obj, zero.get (), Py_GT) > 0)
@@ -1588,8 +1665,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
@@ -1609,7 +1688,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))
        {
@@ -1640,9 +1723,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
@@ -1673,6 +1754,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
@@ -1693,7 +1851,7 @@ gdbpy_initialize_values (void)
 
 \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,
@@ -1724,8 +1882,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,
This page took 0.052913 seconds and 4 git commands to generate.