Introduce gdbpy_enter_varobj and use it
authorTom Tromey <tom@tromey.com>
Tue, 8 Nov 2016 23:18:24 +0000 (16:18 -0700)
committerTom Tromey <tom@tromey.com>
Wed, 11 Jan 2017 02:13:51 +0000 (19:13 -0700)
This introduces gdbpy_enter_varobj, a subclass of gdbpy_enter; then
changes one function in py-varobj.c to use it.  gdbpy_enter_varobj
takes a varobj as an argument, similar to varobj_ensure_python_env.

2017-01-10  Tom Tromey  <tom@tromey.com>

* varobj.c (gdbpy_enter_varobj): New constructor.
* python/python-internal.h (gdbpy_enter_varobj): New class.
* python/py-varobj.c (py_varobj_get_iterator): Use
gdbpy_enter_varobj.

gdb/ChangeLog
gdb/python/py-varobj.c
gdb/python/python-internal.h
gdb/varobj.c

index 318c7845ca7ef9f1cccd11e339939bdfd2fcc75e..6bca72d57fbaae5ce537f4f47f832586ddbef724 100644 (file)
@@ -1,3 +1,10 @@
+2017-01-10  Tom Tromey  <tom@tromey.com>
+
+       * varobj.c (gdbpy_enter_varobj): New constructor.
+       * python/python-internal.h (gdbpy_enter_varobj): New class.
+       * python/py-varobj.c (py_varobj_get_iterator): Use
+       gdbpy_enter_varobj.
+
 2017-01-10  Tom Tromey  <tom@tromey.com>
 
        * python/py-xmethods.c (gdbpy_get_xmethod_result_type): Use
index c8684bd7e0b09b53f809b60eb558197dfd511231..ffdfa30a69fe0b22a51a23a9e38f6afefc943b7e 100644 (file)
@@ -17,6 +17,7 @@
 #include "python-internal.h"
 #include "varobj.h"
 #include "varobj-iter.h"
+#include "py-ref.h"
 
 /* A dynamic varobj iterator "class" for python pretty-printed
    varobjs.  This inherits struct varobj_iter.  */
@@ -167,28 +168,23 @@ py_varobj_iter_new (struct varobj *var, PyObject *pyiter)
 struct varobj_iter *
 py_varobj_get_iterator (struct varobj *var, PyObject *printer)
 {
-  PyObject *children;
   PyObject *iter;
   struct py_varobj_iter *py_iter;
-  struct cleanup *back_to = varobj_ensure_python_env (var);
+
+  gdbpy_enter_varobj enter_py (var);
 
   if (!PyObject_HasAttr (printer, gdbpy_children_cst))
-    {
-      do_cleanups (back_to);
-      return NULL;
-    }
+    return NULL;
 
-  children = PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
-                                        NULL);
+  gdbpy_ref children (PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
+                                                 NULL));
   if (children == NULL)
     {
       gdbpy_print_stack ();
       error (_("Null value returned for children"));
     }
 
-  make_cleanup_py_decref (children);
-
-  iter = PyObject_GetIter (children);
+  iter = PyObject_GetIter (children.get ());
   if (iter == NULL)
     {
       gdbpy_print_stack ();
@@ -197,7 +193,5 @@ py_varobj_get_iterator (struct varobj *var, PyObject *printer)
 
   py_iter = py_varobj_iter_new (var, iter);
 
-  do_cleanups (back_to);
-
   return &py_iter->base;
 }
index a3b9b745edb39528db901eeb15a1703d6d922441..41275bb7d3e543664d138c6ced8697c0d1427fac 100644 (file)
@@ -526,6 +526,18 @@ class gdbpy_enter
   PyObject *m_error_type, *m_error_value, *m_error_traceback;
 };
 
+/* Like gdbpy_enter, but takes a varobj.  This is a subclass just to
+   make constructor delegation a little nicer.  */
+class gdbpy_enter_varobj : public gdbpy_enter
+{
+ public:
+
+  /* This is defined in varobj.c, where it can access varobj
+     internals.  */
+  gdbpy_enter_varobj (const struct varobj *var);
+
+};
+
 struct cleanup *ensure_python_env (struct gdbarch *gdbarch,
                                   const struct language_defn *language);
 
index 509cc7b71904d7916bad6b3ec7b95dcd61d018d2..49df6f97fbe1eeac71a81a53d59a250052394f87 100644 (file)
@@ -233,6 +233,13 @@ varobj_ensure_python_env (const struct varobj *var)
   return ensure_python_env (var->root->exp->gdbarch,
                            var->root->exp->language_defn);
 }
+
+/* See python-internal.h.  */
+gdbpy_enter_varobj::gdbpy_enter_varobj (const struct varobj *var)
+: gdbpy_enter (var->root->exp->gdbarch, var->root->exp->language_defn)
+{
+}
+
 #endif
 
 /* Return the full FRAME which corresponds to the given CORE_ADDR