]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/python/py-value.c
gdb: building inferior strings from within GDB
[thirdparty/binutils-gdb.git] / gdb / python / py-value.c
index c2db2d58b0db373f54492c501e706e1b2060de01..933af92a664bb73a9c792036696b293d08f660e3 100644 (file)
@@ -18,6 +18,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "top.h"               /* For quit_force ().  */
 #include "charset.h"
 #include "value.h"
 #include "language.h"
@@ -53,9 +54,6 @@
 #define builtin_type_pybool \
   language_bool_type (current_language, gdbpy_enter::get_gdbarch ())
 
-#define builtin_type_pychar \
-  language_string_char_type (current_language, gdbpy_enter::get_gdbarch ())
-
 struct value_object {
   PyObject_HEAD
   struct value_object *next;
@@ -228,7 +226,7 @@ gdbpy_preserve_values (const struct extension_language_defn *extlang,
   value_object *iter;
 
   for (iter = values_in_python; iter; iter = iter->next)
-    preserve_one_value (iter->value, objfile, copied_types);
+    iter->value->preserve (objfile, copied_types);
 }
 
 /* Given a value of a pointer type, apply the C unary * operator to it.  */
@@ -371,6 +369,10 @@ valpy_get_address (PyObject *self, void *closure)
          res_val = value_addr (val_obj->value);
          val_obj->address = value_to_value_object (res_val);
        }
+      catch (const gdb_exception_forced_quit &except)
+       {
+         quit_force (NULL, 0);
+       }
       catch (const gdb_exception &except)
        {
          val_obj->address = Py_None;
@@ -1197,7 +1199,7 @@ valpy_get_is_optimized_out (PyObject *self, void *closure)
 
   try
     {
-      opt = value_optimized_out (value);
+      opt = value->optimized_out ();
     }
   catch (const gdb_exception &except)
     {
@@ -1537,7 +1539,7 @@ valpy_nonzero (PyObject *self)
        nonzero = !!value_as_long (self_value->value);
       else if (is_floating_value (self_value->value))
        nonzero = !target_float_is_zero
-         (value_contents (self_value->value).data (), type);
+         (self_value->value->contents ().data (), type);
       else
        /* All other values are True.  */
        nonzero = 1;
@@ -1559,18 +1561,20 @@ valpy_nonzero (PyObject *self)
 static PyObject *
 valpy_invert (PyObject *self)
 {
-  struct value *val = NULL;
+  PyObject *result = nullptr;
 
   try
     {
-      val = value_complement (((value_object *) self)->value);
+      scoped_value_mark free_values;
+      struct value *val = value_complement (((value_object *) self)->value);
+      result = value_to_value_object (val);
     }
   catch (const gdb_exception &except)
     {
       GDB_PY_HANDLE_EXCEPTION (except);
     }
 
-  return value_to_value_object (val);
+  return result;
 }
 
 /* Implements left shift for value objects.  */
@@ -1755,7 +1759,7 @@ valpy_float (PyObject *self)
       type = check_typedef (type);
 
       if (type->code () == TYPE_CODE_FLT && is_floating_value (value))
-       d = target_float_to_host_double (value_contents (value).data (), type);
+       d = target_float_to_host_double (value->contents ().data (), type);
       else if (type->code () == TYPE_CODE_INT)
        {
          /* Note that valpy_long accepts TYPE_CODE_PTR and some
@@ -1774,32 +1778,10 @@ valpy_float (PyObject *self)
   return PyFloat_FromDouble (d);
 }
 
-/* Returns an object for a value which is released from the all_values chain,
-   so its lifetime is not bound to the execution of a command.  */
-PyObject *
-value_to_value_object (struct value *val)
-{
-  value_object *val_obj;
-
-  val_obj = PyObject_New (value_object, &value_object_type);
-  if (val_obj != NULL)
-    {
-      val_obj->value = release_value (val).release ();
-      val_obj->next = nullptr;
-      val_obj->prev = nullptr;
-      val_obj->address = NULL;
-      val_obj->type = NULL;
-      val_obj->dynamic_type = NULL;
-      note_value (val_obj);
-    }
-
-  return (PyObject *) val_obj;
-}
-
-/* Returns an object for a value, but without releasing it from the
+/* Returns an object for a value, without releasing it from the
    all_values chain.  */
 PyObject *
-value_to_value_object_no_release (struct value *val)
+value_to_value_object (struct value *val)
 {
   value_object *val_obj;
 
@@ -1896,17 +1878,18 @@ convert_value_from_python (PyObject *obj)
          gdb::unique_xmalloc_ptr<char> s
            = python_string_to_target_string (obj);
          if (s != NULL)
-           value = value_cstring (s.get (), strlen (s.get ()),
-                                  builtin_type_pychar);
+           value
+             = current_language->value_string (gdbpy_enter::get_gdbarch (),
+                                               s.get (), strlen (s.get ()));
        }
       else if (PyObject_TypeCheck (obj, &value_object_type))
-       value = value_copy (((value_object *) obj)->value);
+       value = ((value_object *) obj)->value->copy ();
       else if (gdbpy_is_lazy_string (obj))
        {
          PyObject *result;
 
          result = PyObject_CallMethodObjArgs (obj, gdbpy_value_cst,  NULL);
-         value = value_copy (((value_object *) result)->value);
+         value = ((value_object *) result)->value->copy ();
        }
       else
        PyErr_Format (PyExc_TypeError,
@@ -1926,21 +1909,23 @@ PyObject *
 gdbpy_history (PyObject *self, PyObject *args)
 {
   int i;
-  struct value *res_val = NULL;          /* Initialize to appease gcc warning.  */
 
   if (!PyArg_ParseTuple (args, "i", &i))
     return NULL;
 
+  PyObject *result = nullptr;
   try
     {
-      res_val = access_value_history (i);
+      scoped_value_mark free_values;
+      struct value *res_val = access_value_history (i);
+      result = value_to_value_object (res_val);
     }
   catch (const gdb_exception &except)
     {
       GDB_PY_HANDLE_EXCEPTION (except);
     }
 
-  return value_to_value_object (res_val);
+  return result;
 }
 
 /* Add a gdb.Value into GDB's history, and return (as an integer) the
@@ -1959,7 +1944,7 @@ gdbpy_add_history (PyObject *self, PyObject *args)
 
   try
     {
-      int idx = record_latest_value (value);
+      int idx = value->record_latest ();
       return gdb_py_object_from_longest (idx).release ();
     }
   catch (const gdb_exception &except)
@@ -1988,15 +1973,23 @@ gdbpy_convenience_variable (PyObject *self, PyObject *args)
   if (!PyArg_ParseTuple (args, "s", &varname))
     return NULL;
 
+  PyObject *result = nullptr;
+  bool found = false;
   try
     {
       struct internalvar *var = lookup_only_internalvar (varname);
 
       if (var != NULL)
        {
+         scoped_value_mark free_values;
          res_val = value_of_internalvar (gdbpy_enter::get_gdbarch (), var);
          if (res_val->type ()->code () == TYPE_CODE_VOID)
            res_val = NULL;
+         else
+           {
+             found = true;
+             result = value_to_value_object (res_val);
+           }
        }
     }
   catch (const gdb_exception &except)
@@ -2004,10 +1997,10 @@ gdbpy_convenience_variable (PyObject *self, PyObject *args)
       GDB_PY_HANDLE_EXCEPTION (except);
     }
 
-  if (res_val == NULL)
+  if (result == nullptr && !found)
     Py_RETURN_NONE;
 
-  return value_to_value_object (res_val);
+  return result;
 }
 
 /* Set the value of a convenience variable.  */
@@ -2061,7 +2054,7 @@ gdbpy_is_value_object (PyObject *obj)
   return PyObject_TypeCheck (obj, &value_object_type);
 }
 
-int
+static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
 gdbpy_initialize_values (void)
 {
   if (PyType_Ready (&value_object_type) < 0)
@@ -2071,6 +2064,8 @@ gdbpy_initialize_values (void)
                                 (PyObject *) &value_object_type);
 }
 
+GDBPY_INITIALIZE_FILE (gdbpy_initialize_values);
+
 \f
 
 static gdb_PyGetSetDef value_object_getset[] = {
@@ -2109,7 +2104,7 @@ reinterpret_cast operator."
   { "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." },
+    "Return a 'const' qualified version of the same value." },
   { "lazy_string", (PyCFunction) valpy_lazy_string,
     METH_VARARGS | METH_KEYWORDS,
     "lazy_string ([encoding]  [, length]) -> lazy_string\n\