OSDN Git Service

* varobj.c (varobj_update): Initialize children_changed.
[pf3gnuchains/sourceware.git] / gdb / varobj.c
index e6cae7f..8f22156 100644 (file)
 
 #include "gdb_assert.h"
 #include "gdb_string.h"
+#include "gdb_regex.h"
 
 #include "varobj.h"
 #include "vec.h"
 #include "gdbthread.h"
 #include "inferior.h"
-#include "typeprint.h"
 
 #if HAVE_PYTHON
 #include "python/python.h"
@@ -60,6 +60,15 @@ char *varobj_format_string[] =
 /* String representations of gdb's known languages */
 char *varobj_language_string[] = { "unknown", "C", "C++", "Java" };
 
+/* True if we want to allow Python-based pretty-printing.  */
+static int pretty_printing = 0;
+
+void
+varobj_enable_pretty_printing (void)
+{
+  pretty_printing = 1;
+}
+
 /* Data structures */
 
 /* Every root variable has one of these structures saved in its
@@ -174,9 +183,31 @@ struct varobj
      frozen.  */
   int not_fetched;
 
+  /* Sub-range of children which the MI consumer has requested.  If
+     FROM < 0 or TO < 0, means that all children have been
+     requested.  */
+  int from;
+  int to;
+
+  /* The pretty-printer constructor.  If NULL, then the default
+     pretty-printer will be looked up.  If None, then no
+     pretty-printer will be installed.  */
+  PyObject *constructor;
+
   /* The pretty-printer that has been constructed.  If NULL, then a
      new printer object is needed, and one will be constructed.  */
   PyObject *pretty_printer;
+
+  /* The iterator returned by the printer's 'children' method, or NULL
+     if not available.  */
+  PyObject *child_iter;
+
+  /* We request one extra item from the iterator, so that we can
+     report to the caller whether there are more items than we have
+     already reported.  However, we don't want to install this value
+     when we read it, because that will mess up future updates.  So,
+     we stash it here instead.  */
+  PyObject *saved_item;
 };
 
 struct cpstack
@@ -237,8 +268,6 @@ static char *cppop (struct cpstack **pstack);
 static int install_new_value (struct varobj *var, struct value *value, 
                              int initial);
 
-static void install_default_visualizer (struct varobj *var);
-
 /* Language-specific routines. */
 
 static enum varobj_languages variable_language (struct varobj *var);
@@ -258,7 +287,7 @@ static char *my_value_of_variable (struct varobj *var,
 
 static char *value_get_print_value (struct value *value,
                                    enum varobj_display_formats format,
-                                   PyObject *value_formatter);
+                                   struct varobj *var);
 
 static int varobj_value_is_changeable_p (struct varobj *var);
 
@@ -425,7 +454,6 @@ static int format_code[] = { 0, 't', 'd', 'x', 'o' };
 
 /* Header of the list of root variable objects */
 static struct varobj_root *rootlist;
-static int rootcount = 0;      /* number of root varobjs in the list */
 
 /* Prime number indicating the number of buckets in the hash table */
 /* A prime large enough to avoid too many colisions */
@@ -446,6 +474,17 @@ is_root_p (struct varobj *var)
   return (var->root->rootvar == var);
 }
 
+#ifdef HAVE_PYTHON
+/* Helper function to install a Python environment suitable for
+   use during operations on VAR.  */
+struct cleanup *
+varobj_ensure_python_env (struct varobj *var)
+{
+  return ensure_python_env (var->root->exp->gdbarch,
+                           var->root->exp->language_defn);
+}
+#endif
+
 /* Creates a varobj (not its children) */
 
 /* Return the full FRAME which corresponds to the given CORE_ADDR
@@ -556,8 +595,15 @@ varobj_create (char *objname,
          we must select the appropriate frame before parsing
          the expression, otherwise the value will not be current.
          Since select_frame is so benign, just call it for all cases. */
-      if (innermost_block && fi != NULL)
+      if (innermost_block)
        {
+         /* User could specify explicit FRAME-ADDR which was not found but
+            EXPRESSION is frame specific and we would not be able to evaluate
+            it correctly next time.  With VALID_BLOCK set we must also set
+            FRAME and THREAD_ID.  */
+         if (fi == NULL)
+           error (_("Failed to find the specified frame"));
+
          var->root->frame = get_frame_id (fi);
          var->root->thread_id = pid_to_thread_id (inferior_ptid);
          old_fi = get_selected_frame (NULL);
@@ -607,7 +653,6 @@ varobj_create (char *objname,
        }
     }
 
-  install_default_visualizer (var);
   discard_cleanups (old_chain);
   return var;
 }
@@ -722,15 +767,8 @@ instantiate_pretty_printer (PyObject *constructor, struct value *value)
 #if HAVE_PYTHON
   PyObject *val_obj = NULL; 
   PyObject *printer;
-  volatile struct gdb_exception except;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
-    {
-      value = value_copy (value);
-    }
-  GDB_PY_HANDLE_EXCEPTION (except);
   val_obj = value_to_value_object (value);
-
   if (! val_obj)
     return NULL;
 
@@ -765,8 +803,7 @@ varobj_set_display_format (struct varobj *var,
       && var->value && !value_lazy (var->value))
     {
       xfree (var->print_value);
-      var->print_value = value_get_print_value (var->value, var->format,
-                                               var->pretty_printer);
+      var->print_value = value_get_print_value (var->value, var->format, var);
     }
 
   return var->format;
@@ -784,15 +821,28 @@ varobj_get_display_hint (struct varobj *var)
   char *result = NULL;
 
 #if HAVE_PYTHON
-  PyGILState_STATE state = PyGILState_Ensure ();
+  struct cleanup *back_to = varobj_ensure_python_env (var);
+
   if (var->pretty_printer)
     result = gdbpy_get_display_hint (var->pretty_printer);
-  PyGILState_Release (state);
+
+  do_cleanups (back_to);
 #endif
 
   return result;
 }
 
+/* Return true if the varobj has items after TO, false otherwise.  */
+
+int
+varobj_has_more (struct varobj *var, int to)
+{
+  if (VEC_length (varobj_p, var->children) > to)
+    return 1;
+  return ((to == -1 || VEC_length (varobj_p, var->children) == to)
+         && var->saved_item != NULL);
+}
+
 /* If the variable object is bound to a specific thread, that
    is its evaluation can always be done in context of a frame
    inside that thread, returns GDB id of the thread -- which
@@ -825,27 +875,100 @@ varobj_get_frozen (struct varobj *var)
   return var->frozen;
 }
 
+/* A helper function that restricts a range to what is actually
+   available in a VEC.  This follows the usual rules for the meaning
+   of FROM and TO -- if either is negative, the entire range is
+   used.  */
+
+static void
+restrict_range (VEC (varobj_p) *children, int *from, int *to)
+{
+  if (*from < 0 || *to < 0)
+    {
+      *from = 0;
+      *to = VEC_length (varobj_p, children);
+    }
+  else
+    {
+      if (*from > VEC_length (varobj_p, children))
+       *from = VEC_length (varobj_p, children);
+      if (*to > VEC_length (varobj_p, children))
+       *to = VEC_length (varobj_p, children);
+      if (*from > *to)
+       *from = *to;
+    }
+}
+
+/* A helper for update_dynamic_varobj_children that installs a new
+   child when needed.  */
+
+static void
+install_dynamic_child (struct varobj *var,
+                      VEC (varobj_p) **changed,
+                      VEC (varobj_p) **new,
+                      VEC (varobj_p) **unchanged,
+                      int *cchanged,
+                      int index,
+                      const char *name,
+                      struct value *value)
+{
+  if (VEC_length (varobj_p, var->children) < index + 1)
+    {
+      /* There's no child yet.  */
+      struct varobj *child = varobj_add_child (var, name, value);
+      if (new)
+       {
+         VEC_safe_push (varobj_p, *new, child);
+         *cchanged = 1;
+       }
+    }
+  else 
+    {
+      varobj_p existing = VEC_index (varobj_p, var->children, index);
+      if (install_new_value (existing, value, 0))
+       {
+         if (changed)
+           VEC_safe_push (varobj_p, *changed, existing);
+       }
+      else if (unchanged)
+       VEC_safe_push (varobj_p, *unchanged, existing);
+    }
+}
+
+#if HAVE_PYTHON
+
+static int
+dynamic_varobj_has_child_method (struct varobj *var)
+{
+  struct cleanup *back_to;
+  PyObject *printer = var->pretty_printer;
+  int result;
+
+  back_to = varobj_ensure_python_env (var);
+  result = PyObject_HasAttr (printer, gdbpy_children_cst);
+  do_cleanups (back_to);
+  return result;
+}
+
+#endif
+
 static int
 update_dynamic_varobj_children (struct varobj *var,
                                VEC (varobj_p) **changed,
-                               VEC (varobj_p) **new_and_unchanged,
-                               int *cchanged)
-
+                               VEC (varobj_p) **new,
+                               VEC (varobj_p) **unchanged,
+                               int *cchanged,
+                               int update_children,
+                               int from,
+                               int to)
 {
 #if HAVE_PYTHON
-  /* FIXME: we *might* want to provide this functionality as
-     a standalone function, so that other interested parties
-     than varobj code can benefit for this.  */
   struct cleanup *back_to;
   PyObject *children;
-  PyObject *iterator;
   int i;
-  int children_changed = 0;
   PyObject *printer = var->pretty_printer;
-  PyGILState_STATE state;
 
-  state = PyGILState_Ensure ();
-  back_to = make_cleanup_py_restore_gil (&state);
+  back_to = varobj_ensure_python_env (var);
 
   *cchanged = 0;
   if (!PyObject_HasAttr (printer, gdbpy_children_cst))
@@ -854,96 +977,106 @@ update_dynamic_varobj_children (struct varobj *var,
       return 0;
     }
 
-  children = PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
-                                        NULL);
-
-  if (!children)
+  if (update_children || !var->child_iter)
     {
-      gdbpy_print_stack ();
-      error (_("Null value returned for children"));
-    }
+      children = PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
+                                            NULL);
 
-  make_cleanup_py_decref (children);
+      if (!children)
+       {
+         gdbpy_print_stack ();
+         error (_("Null value returned for children"));
+       }
 
-  if (!PyIter_Check (children))
-    error (_("Returned value is not iterable"));
+      make_cleanup_py_decref (children);
 
-  iterator = PyObject_GetIter (children);
-  if (!iterator)
-    {
-      gdbpy_print_stack ();
-      error (_("Could not get children iterator"));
+      if (!PyIter_Check (children))
+       error (_("Returned value is not iterable"));
+
+      Py_XDECREF (var->child_iter);
+      var->child_iter = PyObject_GetIter (children);
+      if (!var->child_iter)
+       {
+         gdbpy_print_stack ();
+         error (_("Could not get children iterator"));
+       }
+
+      Py_XDECREF (var->saved_item);
+      var->saved_item = NULL;
+
+      i = 0;
     }
-  make_cleanup_py_decref (iterator);
+  else
+    i = VEC_length (varobj_p, var->children);
 
-  for (i = 0; ; ++i)
+  /* We ask for one extra child, so that MI can report whether there
+     are more children.  */
+  for (; to < 0 || i < to + 1; ++i)
     {
-      PyObject *item = PyIter_Next (iterator);
-      PyObject *py_v;
-      struct value *v;
-      char *name;
-      struct cleanup *inner;
-      
-      if (!item)
-       break;
-      inner = make_cleanup_py_decref (item);
+      PyObject *item;
 
-      if (!PyArg_ParseTuple (item, "sO", &name, &py_v))
-       error (_("Invalid item from the child list"));
-      
-      if (PyObject_TypeCheck (py_v, &value_object_type))
+      /* See if there was a leftover from last time.  */
+      if (var->saved_item)
        {
-         /* If we just call convert_value_from_python for this type,
-            we won't know who owns the result.  For this one case we
-            need to copy the resulting value.  */
-         v = value_object_to_value (py_v);
-         v = value_copy (v);
+         item = var->saved_item;
+         var->saved_item = NULL;
        }
       else
-       v = convert_value_from_python (py_v);
+       item = PyIter_Next (var->child_iter);
 
-      /* TODO: This assume the name of the i-th child never changes.  */
+      if (!item)
+       break;
 
-      /* Now see what to do here.  */
-      if (VEC_length (varobj_p, var->children) < i + 1)
+      /* We don't want to push the extra child on any report list.  */
+      if (to < 0 || i < to)
        {
-         /* There's no child yet.  */
-         struct varobj *child = varobj_add_child (var, name, v);
-         if (new_and_unchanged)
-           VEC_safe_push (varobj_p, *new_and_unchanged, child);
-         children_changed = 1;
+         PyObject *py_v;
+         char *name;
+         struct value *v;
+         struct cleanup *inner;
+         int can_mention = from < 0 || i >= from;
+
+         inner = make_cleanup_py_decref (item);
+
+         if (!PyArg_ParseTuple (item, "sO", &name, &py_v))
+           error (_("Invalid item from the child list"));
+
+         v = convert_value_from_python (py_v);
+         install_dynamic_child (var, can_mention ? changed : NULL,
+                                can_mention ? new : NULL,
+                                can_mention ? unchanged : NULL,
+                                can_mention ? cchanged : NULL, i, name, v);
+         do_cleanups (inner);
        }
-      else 
+      else
        {
-         varobj_p existing = VEC_index (varobj_p, var->children, i);
-         if (install_new_value (existing, v, 0) && changed)
-           {
-             if (changed)
-               VEC_safe_push (varobj_p, *changed, existing);
-           }
-         else
-           {
-             if (new_and_unchanged)
-               VEC_safe_push (varobj_p, *new_and_unchanged, existing);
-           }
-       }
+         Py_XDECREF (var->saved_item);
+         var->saved_item = item;
 
-      do_cleanups (inner);
+         /* We want to truncate the child list just before this
+            element.  */
+         break;
+       }
     }
 
   if (i < VEC_length (varobj_p, var->children))
     {
-      int i;
-      children_changed = 1;
-      for (i = 0; i < VEC_length (varobj_p, var->children); ++i)
-       varobj_delete (VEC_index (varobj_p, var->children, i), NULL, 0);
+      int j;
+      *cchanged = 1;
+      for (j = i; j < VEC_length (varobj_p, var->children); ++j)
+       varobj_delete (VEC_index (varobj_p, var->children, j), NULL, 0);
+      VEC_truncate (varobj_p, var->children, i);
     }
-  VEC_truncate (varobj_p, var->children, i);
+
+  /* If there are fewer children than requested, note that the list of
+     children changed.  */
+  if (to >= 0 && VEC_length (varobj_p, var->children) < to)
+    *cchanged = 1;
+
   var->num_children = VEC_length (varobj_p, var->children);
  
   do_cleanups (back_to);
 
-  *cchanged = children_changed;
   return 1;
 #else
   gdb_assert (0 && "should never be called if Python is not enabled");
@@ -955,20 +1088,27 @@ varobj_get_num_children (struct varobj *var)
 {
   if (var->num_children == -1)
     {
-      int changed;
-      if (!var->pretty_printer
-         || !update_dynamic_varobj_children (var, NULL, NULL, &changed))
+      if (var->pretty_printer)
+       {
+         int dummy;
+
+         /* If we have a dynamic varobj, don't report -1 children.
+            So, try to fetch some children first.  */
+         update_dynamic_varobj_children (var, NULL, NULL, NULL, &dummy,
+                                         0, 0, 0);
+       }
+      else
        var->num_children = number_of_children (var);
     }
 
-  return var->num_children;
+  return var->num_children >= 0 ? var->num_children : 0;
 }
 
 /* Creates a list of the immediate children of a variable object;
    the return code is the number of such children or -1 on error */
 
 VEC (varobj_p)*
-varobj_list_children (struct varobj *var)
+varobj_list_children (struct varobj *var, int *from, int *to)
 {
   struct varobj *child;
   char *name;
@@ -976,12 +1116,16 @@ varobj_list_children (struct varobj *var)
 
   var->children_requested = 1;
 
-  if (var->pretty_printer
+  if (var->pretty_printer)
+    {
       /* This, in theory, can result in the number of children changing without
         frontend noticing.  But well, calling -var-list-children on the same
         varobj twice is not something a sane frontend would do.  */
-      && update_dynamic_varobj_children (var, NULL, NULL, &children_changed))
-    return var->children;
+      update_dynamic_varobj_children (var, NULL, NULL, NULL, &children_changed,
+                                     0, 0, *to);
+      restrict_range (var->children, from, to);
+      return var->children;
+    }
 
   if (var->num_children == -1)
     var->num_children = number_of_children (var);
@@ -1007,10 +1151,10 @@ varobj_list_children (struct varobj *var)
          name = name_of_child (var, i);
          existing = create_child (var, i, name);
          VEC_replace (varobj_p, var->children, i, existing);
-         install_default_visualizer (existing);
        }
     }
 
+  restrict_range (var->children, from, to);
   return var->children;
 }
 
@@ -1021,7 +1165,6 @@ varobj_add_child (struct varobj *var, const char *name, struct value *value)
                                        VEC_length (varobj_p, var->children), 
                                        name, value);
   VEC_safe_push (varobj_p, var->children, v);
-  install_default_visualizer (v);
   return v;
 }
 
@@ -1083,6 +1226,12 @@ varobj_get_attributes (struct varobj *var)
   return attributes;
 }
 
+int
+varobj_pretty_printed_p (struct varobj *var)
+{
+  return var->pretty_printer != NULL;
+}
+
 char *
 varobj_get_formatted_value (struct varobj *var,
                            enum varobj_display_formats format)
@@ -1160,35 +1309,114 @@ varobj_set_value (struct varobj *var, char *expression)
   return 1;
 }
 
-/* Returns a malloc'ed list with all root variable objects */
-int
-varobj_list (struct varobj ***varlist)
+#if HAVE_PYTHON
+
+/* A helper function to install a constructor function and visualizer
+   in a varobj.  */
+
+static void
+install_visualizer (struct varobj *var, PyObject *constructor,
+                   PyObject *visualizer)
 {
-  struct varobj **cv;
-  struct varobj_root *croot;
-  int mycount = rootcount;
+  Py_XDECREF (var->constructor);
+  var->constructor = constructor;
 
-  /* Alloc (rootcount + 1) entries for the result */
-  *varlist = xmalloc ((rootcount + 1) * sizeof (struct varobj *));
+  Py_XDECREF (var->pretty_printer);
+  var->pretty_printer = visualizer;
+
+  Py_XDECREF (var->child_iter);
+  var->child_iter = NULL;
+}
 
-  cv = *varlist;
-  croot = rootlist;
-  while ((croot != NULL) && (mycount > 0))
+/* Install the default visualizer for VAR.  */
+
+static void
+install_default_visualizer (struct varobj *var)
+{
+  if (pretty_printing)
     {
-      *cv = croot->rootvar;
-      mycount--;
-      cv++;
-      croot = croot->next;
+      PyObject *pretty_printer = NULL;
+
+      if (var->value)
+       {
+         pretty_printer = gdbpy_get_varobj_pretty_printer (var->value);
+         if (! pretty_printer)
+           {
+             gdbpy_print_stack ();
+             error (_("Cannot instantiate printer for default visualizer"));
+           }
+       }
+      
+      if (pretty_printer == Py_None)
+       {
+         Py_DECREF (pretty_printer);
+         pretty_printer = NULL;
+       }
+  
+      install_visualizer (var, NULL, pretty_printer);
     }
-  /* Mark the end of the list */
-  *cv = NULL;
+}
+
+/* Instantiate and install a visualizer for VAR using CONSTRUCTOR to
+   make a new object.  */
+
+static void
+construct_visualizer (struct varobj *var, PyObject *constructor)
+{
+  PyObject *pretty_printer;
+
+  Py_INCREF (constructor);
+  if (constructor == Py_None)
+    pretty_printer = NULL;
+  else
+    {
+      pretty_printer = instantiate_pretty_printer (constructor, var->value);
+      if (! pretty_printer)
+       {
+         gdbpy_print_stack ();
+         Py_DECREF (constructor);
+         constructor = Py_None;
+         Py_INCREF (constructor);
+       }
+
+      if (pretty_printer == Py_None)
+       {
+         Py_DECREF (pretty_printer);
+         pretty_printer = NULL;
+       }
+    }
+
+  install_visualizer (var, constructor, pretty_printer);
+}
+
+#endif /* HAVE_PYTHON */
 
-  if (mycount || (croot != NULL))
-    warning
-      ("varobj_list: assertion failed - wrong tally of root vars (%d:%d)",
-       rootcount, mycount);
+/* A helper function for install_new_value.  This creates and installs
+   a visualizer for VAR, if appropriate.  */
 
-  return rootcount;
+static void
+install_new_value_visualizer (struct varobj *var)
+{
+#if HAVE_PYTHON
+  /* If the constructor is None, then we want the raw value.  If VAR
+     does not have a value, just skip this.  */
+  if (var->constructor != Py_None && var->value)
+    {
+      struct cleanup *cleanup;
+      PyObject *pretty_printer = NULL;
+
+      cleanup = varobj_ensure_python_env (var);
+
+      if (!var->constructor)
+       install_default_visualizer (var);
+      else
+       construct_visualizer (var, var->constructor);
+
+      do_cleanups (cleanup);
+    }
+#else
+  /* Do nothing.  */
+#endif
 }
 
 /* Assign a new value to a variable object.  If INITIAL is non-zero,
@@ -1231,10 +1459,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
      that in C++ a reference is not rebindable, it cannot
      meaningfully change.  So, get hold of the real value.  */
   if (value)
-    {
-      value = coerce_ref (value);
-      release_value (value);
-    }
+    value = coerce_ref (value);
 
   if (var->type && TYPE_CODE (var->type) == TYPE_CODE_UNION)
     /* For unions, we need to fetch the value implicitly because
@@ -1281,9 +1506,8 @@ install_new_value (struct varobj *var, struct value *value, int initial)
      values.  Don't get string rendering if the value is
      lazy -- if it is, the code above has decided that the value
      should not be fetched.  */
-  if (value && !value_lazy (value))
-    print_value = value_get_print_value (value, var->format, 
-                                        var->pretty_printer);
+  if (value && !value_lazy (value) && !var->pretty_printer)
+    print_value = value_get_print_value (value, var->format, var);
 
   /* If the type is changeable, compare the old and the new values.
      If this is the initial assignment, we don't have any old value
@@ -1298,7 +1522,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
        {
          changed = 1;
        }
-      else 
+      else if (! var->pretty_printer)
        {
          /* Try to compare the values.  That requires that both
             values are non-lazy.  */
@@ -1343,76 +1567,53 @@ install_new_value (struct varobj *var, struct value *value, int initial)
   if (var->value != NULL && var->value != value)
     value_free (var->value);
   var->value = value;
-  if (var->print_value)
-    xfree (var->print_value);
-  var->print_value = print_value;
+  if (value != NULL)
+    value_incref (value);
   if (value && value_lazy (value) && intentionally_not_fetched)
     var->not_fetched = 1;
   else
     var->not_fetched = 0;
   var->updated = 0;
 
+  install_new_value_visualizer (var);
+
+  /* If we installed a pretty-printer, re-compare the printed version
+     to see if the variable changed.  */
+  if (var->pretty_printer)
+    {
+      xfree (print_value);
+      print_value = value_get_print_value (var->value, var->format, var);
+      if (!var->print_value || strcmp (var->print_value, print_value) != 0)
+       changed = 1;
+    }
+  if (var->print_value)
+    xfree (var->print_value);
+  var->print_value = print_value;
+
   gdb_assert (!var->value || value_type (var->value));
 
   return changed;
 }
 
-static void
-install_visualizer (struct varobj *var, PyObject *visualizer)
+/* Return the requested range for a varobj.  VAR is the varobj.  FROM
+   and TO are out parameters; *FROM and *TO will be set to the
+   selected sub-range of VAR.  If no range was selected using
+   -var-set-update-range, then both will be -1.  */
+void
+varobj_get_child_range (struct varobj *var, int *from, int *to)
 {
-#if HAVE_PYTHON
-  /* If there are any children now, wipe them.  */
-  varobj_delete (var, NULL, 1 /* children only */);
-  var->num_children = -1;
-
-  Py_XDECREF (var->pretty_printer);
-  var->pretty_printer = visualizer;
-
-  install_new_value (var, var->value, 1);
-
-  /* If we removed the visualizer, and the user ever requested the
-     object's children, then we must compute the list of children.
-     Note that we needn't do this when installing a visualizer,
-     because updating will recompute dynamic children.  */
-  if (!visualizer && var->children_requested)
-    varobj_list_children (var);
-#else
-  error (_("Python support required"));
-#endif
+  *from = var->from;
+  *to = var->to;
 }
 
-static void
-install_default_visualizer (struct varobj *var)
+/* Set the selected sub-range of children of VAR to start at index
+   FROM and end at index TO.  If either FROM or TO is less than zero,
+   this is interpreted as a request for all children.  */
+void
+varobj_set_child_range (struct varobj *var, int from, int to)
 {
-#if HAVE_PYTHON
-  struct cleanup *cleanup;
-  PyGILState_STATE state;
-  PyObject *pretty_printer = NULL;
-
-  state = PyGILState_Ensure ();
-  cleanup = make_cleanup_py_restore_gil (&state);
-
-  if (var->value)
-    {
-      pretty_printer = gdbpy_get_varobj_pretty_printer (var->value);
-      if (! pretty_printer)
-       {
-         gdbpy_print_stack ();
-         error (_("Cannot instantiate printer for default visualizer"));
-       }
-    }
-      
-  if (pretty_printer == Py_None)
-    {
-      Py_DECREF (pretty_printer);
-      pretty_printer = NULL;
-    }
-  
-  install_visualizer (var, pretty_printer);
-  do_cleanups (cleanup);
-#else
-  /* No error is right as this function is inserted just as a hook.  */
-#endif
+  var->from = from;
+  var->to = to;
 }
 
 void 
@@ -1421,11 +1622,8 @@ varobj_set_visualizer (struct varobj *var, const char *visualizer)
 #if HAVE_PYTHON
   PyObject *mainmod, *globals, *pretty_printer, *constructor;
   struct cleanup *back_to, *value;
-  PyGILState_STATE state;
-
 
-  state = PyGILState_Ensure ();
-  back_to = make_cleanup_py_restore_gil (&state);
+  back_to = varobj_ensure_python_env (var);
 
   mainmod = PyImport_AddModule ("__main__");
   globals = PyModule_GetDict (mainmod);
@@ -1433,31 +1631,19 @@ varobj_set_visualizer (struct varobj *var, const char *visualizer)
   make_cleanup_py_decref (globals);
 
   constructor = PyRun_String (visualizer, Py_eval_input, globals, globals);
-  
-  /* Do not instantiate NoneType. */
-  if (constructor == Py_None)
-    {
-      pretty_printer = Py_None;
-      Py_INCREF (pretty_printer);
-    }
-  else
-    pretty_printer = instantiate_pretty_printer (constructor, var->value);
-
-  Py_XDECREF (constructor);
 
-  if (! pretty_printer)
+  if (! constructor)
     {
       gdbpy_print_stack ();
       error (_("Could not evaluate visualizer expression: %s"), visualizer);
     }
 
-  if (pretty_printer == Py_None)
-    {
-      Py_DECREF (pretty_printer);
-      pretty_printer = NULL;
-    }
+  construct_visualizer (var, constructor);
+  Py_XDECREF (constructor);
 
-  install_visualizer (var, pretty_printer);
+  /* If there are any children now, wipe them.  */
+  varobj_delete (var, NULL, 1 /* children only */);
+  var->num_children = -1;
 
   do_cleanups (back_to);
 #else
@@ -1568,44 +1754,80 @@ VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit)
 
       /* We probably should not get children of a varobj that has a
         pretty-printer, but for which -var-list-children was never
-        invoked.  Presumably, such varobj is not yet expanded in the
-        UI, so we need not bother getting it.  */
+        invoked.    */
       if (v->pretty_printer)
        {
-         VEC (varobj_p) *changed = 0, *new_and_unchanged = 0;
-         int i, children_changed;
-         varobj_p tmp;
-
-         if (!v->children_requested)
-           continue;
+         VEC (varobj_p) *changed = 0, *new = 0, *unchanged = 0;
+         int i, children_changed = 0;
 
          if (v->frozen)
            continue;
 
+         if (!v->children_requested)
+           {
+             int dummy;
+
+             /* If we initially did not have potential children, but
+                now we do, consider the varobj as changed.
+                Otherwise, if children were never requested, consider
+                it as unchanged -- presumably, such varobj is not yet
+                expanded in the UI, so we need not bother getting
+                it.  */
+             if (!varobj_has_more (v, 0))
+               {
+                 update_dynamic_varobj_children (v, NULL, NULL, NULL,
+                                                 &dummy, 0, 0, 0);
+                 if (varobj_has_more (v, 0))
+                   r.changed = 1;
+               }
+
+             if (r.changed)
+               VEC_safe_push (varobj_update_result, result, &r);
+
+             continue;
+           }
+
          /* If update_dynamic_varobj_children returns 0, then we have
             a non-conforming pretty-printer, so we skip it.  */
-         if (update_dynamic_varobj_children (v, &changed, &new_and_unchanged,
-                                             &children_changed))
+         if (update_dynamic_varobj_children (v, &changed, &new, &unchanged,
+                                             &children_changed, 1,
+                                             v->from, v->to))
            {
-             if (children_changed)
-               r.children_changed = 1;
-             for (i = 0; VEC_iterate (varobj_p, changed, i, tmp); ++i)
+             if (children_changed || new)
                {
-                 varobj_update_result r = {tmp};
-                 r.changed = 1;
-                 r.value_installed = 1;
-                 VEC_safe_push (varobj_update_result, stack, &r);
+                 r.children_changed = 1;
+                 r.new = new;
                }
-             for (i = 0;
-                  VEC_iterate (varobj_p, new_and_unchanged, i, tmp);
-                  ++i)
+             /* Push in reverse order so that the first child is
+                popped from the work stack first, and so will be
+                added to result first.  This does not affect
+                correctness, just "nicer".  */
+             for (i = VEC_length (varobj_p, changed) - 1; i >= 0; --i)
                {
+                 varobj_p tmp = VEC_index (varobj_p, changed, i);
                  varobj_update_result r = {tmp};
+                 r.changed = 1;
                  r.value_installed = 1;
                  VEC_safe_push (varobj_update_result, stack, &r);
                }
+             for (i = VEC_length (varobj_p, unchanged) - 1; i >= 0; --i)
+               {
+                 varobj_p tmp = VEC_index (varobj_p, unchanged, i);
+                 if (!tmp->frozen)
+                   {
+                     varobj_update_result r = {tmp};
+                     r.value_installed = 1;
+                     VEC_safe_push (varobj_update_result, stack, &r);
+                   }
+               }
              if (r.changed || r.children_changed)
                VEC_safe_push (varobj_update_result, result, &r);
+
+             /* Free CHANGED and UNCHANGED, but not NEW, because NEW
+                has been put into the result vector.  */
+             VEC_free (varobj_p, changed);
+             VEC_free (varobj_p, unchanged);
+
              continue;
            }
        }
@@ -1743,7 +1965,6 @@ install_variable (struct varobj *var)
       else
        var->root->next = rootlist;
       rootlist = var->root;
-      rootcount++;
     }
 
   return 1;                    /* OK */
@@ -1820,7 +2041,6 @@ uninstall_variable (struct varobj *var)
          else
            prer->next = cr->next;
        }
-      rootcount--;
     }
 
 }
@@ -1895,7 +2115,12 @@ new_variable (void)
   var->frozen = 0;
   var->not_fetched = 0;
   var->children_requested = 0;
+  var->from = -1;
+  var->to = -1;
+  var->constructor = 0;
   var->pretty_printer = 0;
+  var->child_iter = 0;
+  var->saved_item = 0;
 
   return var;
 }
@@ -1921,6 +2146,18 @@ new_root_variable (void)
 static void
 free_variable (struct varobj *var)
 {
+#if HAVE_PYTHON
+  if (var->pretty_printer)
+    {
+      struct cleanup *cleanup = varobj_ensure_python_env (var);
+      Py_XDECREF (var->constructor);
+      Py_XDECREF (var->pretty_printer);
+      Py_XDECREF (var->child_iter);
+      Py_XDECREF (var->saved_item);
+      do_cleanups (cleanup);
+    }
+#endif
+
   value_free (var->value);
 
   /* Free the expression if this is a root variable. */
@@ -1930,14 +2167,6 @@ free_variable (struct varobj *var)
       xfree (var->root);
     }
 
-#if HAVE_PYTHON
-  {
-    PyGILState_STATE state = PyGILState_Ensure ();
-    Py_XDECREF (var->pretty_printer);
-    PyGILState_Release (state);
-  }
-#endif
-
   xfree (var->name);
   xfree (var->obj_name);
   xfree (var->print_value);
@@ -2171,6 +2400,8 @@ value_of_root (struct varobj **var_handle, int *type_changed)
       else
        {
          tmp_var->obj_name = xstrdup (var->obj_name);
+         tmp_var->from = var->from;
+         tmp_var->to = var->to;
          varobj_delete (var, NULL, 0);
 
          install_variable (tmp_var);
@@ -2205,53 +2436,80 @@ static char *
 my_value_of_variable (struct varobj *var, enum varobj_display_formats format)
 {
   if (var->root->is_valid)
-    return (*var->root->lang->value_of_variable) (var, format);
+    {
+      if (var->pretty_printer)
+       return value_get_print_value (var->value, var->format, var);
+      return (*var->root->lang->value_of_variable) (var, format);
+    }
   else
     return NULL;
 }
 
 static char *
 value_get_print_value (struct value *value, enum varobj_display_formats format,
-                      PyObject *value_formatter)
+                      struct varobj *var)
 {
-  long dummy;
   struct ui_file *stb;
   struct cleanup *old_chain;
-  char *thevalue = NULL;
+  gdb_byte *thevalue = NULL;
   struct value_print_options opts;
+  int len = 0;
 
   if (value == NULL)
     return NULL;
 
 #if HAVE_PYTHON
   {
-    PyGILState_STATE state = PyGILState_Ensure ();
-    if (value_formatter && PyObject_HasAttr (value_formatter,
-                                            gdbpy_to_string_cst))
-      {
-       char *hint;
-       struct value *replacement;
-       int string_print = 0;
+    struct cleanup *back_to = varobj_ensure_python_env (var);
+    PyObject *value_formatter = var->pretty_printer;
 
-       hint = gdbpy_get_display_hint (value_formatter);
-       if (hint)
-         {
-           if (!strcmp (hint, "string"))
-             string_print = 1;
-           xfree (hint);
-         }
+    if (value_formatter)
+      {
+       /* First check to see if we have any children at all.  If so,
+          we simply return {...}.  */
+       if (dynamic_varobj_has_child_method (var))
+         return xstrdup ("{...}");
 
-       thevalue = apply_varobj_pretty_printer (value_formatter,
-                                               &replacement);
-       if (thevalue && !string_print)
+       if (PyObject_HasAttr (value_formatter, gdbpy_to_string_cst))
          {
-           PyGILState_Release (state);
-           return thevalue;
+           char *hint;
+           struct value *replacement;
+           int string_print = 0;
+           PyObject *output = NULL;
+
+           hint = gdbpy_get_display_hint (value_formatter);
+           if (hint)
+             {
+               if (!strcmp (hint, "string"))
+                 string_print = 1;
+               xfree (hint);
+             }
+
+           output = apply_varobj_pretty_printer (value_formatter,
+                                                 &replacement);
+           if (output)
+             {
+               PyObject *py_str
+                 = python_string_to_target_python_string (output);
+               if (py_str)
+                 {
+                   char *s = PyString_AsString (py_str);
+                   len = PyString_Size (py_str);
+                   thevalue = xmemdup (s, len + 1, len + 1);
+                   Py_DECREF (py_str);
+                 }
+               Py_DECREF (output);
+             }
+           if (thevalue && !string_print)
+             {
+               do_cleanups (back_to);
+               return thevalue;
+             }
+           if (replacement)
+             value = replacement;
          }
-       if (replacement)
-         value = replacement;
       }
-    PyGILState_Release (state);
+    do_cleanups (back_to);
   }
 #endif
 
@@ -2266,12 +2524,11 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
       struct gdbarch *gdbarch = get_type_arch (value_type (value));
       make_cleanup (xfree, thevalue);
       LA_PRINT_STRING (stb, builtin_type (gdbarch)->builtin_char,
-                      (gdb_byte *) thevalue, strlen (thevalue),
-                      0, &opts);
+                      thevalue, len, 0, &opts);
     }
   else
     common_val_print (value, stb, 0, &opts, current_language);
-  thevalue = ui_file_xstrdup (stb, &dummy);
+  thevalue = ui_file_xstrdup (stb, NULL);
 
   do_cleanups (old_chain);
   return thevalue;
@@ -2774,8 +3031,7 @@ c_value_of_variable (struct varobj *var, enum varobj_display_formats format)
            if (format == var->format)
              return xstrdup (var->print_value);
            else
-             return value_get_print_value (var->value, format, 
-                                           var->pretty_printer);
+             return value_get_print_value (var->value, format, var);
          }
       }
     }
@@ -2980,10 +3236,7 @@ cplus_describe_child (struct varobj *parent, int index,
            *cname = xstrdup (TYPE_FIELD_NAME (type, index));
 
          if (cvalue && value)
-           {
-             *cvalue = value_cast (TYPE_FIELD_TYPE (type, index), value);
-             release_value (*cvalue);
-           }
+           *cvalue = value_cast (TYPE_FIELD_TYPE (type, index), value);
 
          if (ctype)
            {
@@ -3188,6 +3441,24 @@ java_value_of_variable (struct varobj *var, enum varobj_display_formats format)
 {
   return cplus_value_of_variable (var, format);
 }
+
+/* Iterate all the existing _root_ VAROBJs and call the FUNC callback for them
+   with an arbitrary caller supplied DATA pointer.  */
+
+void
+all_root_varobjs (void (*func) (struct varobj *var, void *data), void *data)
+{
+  struct varobj_root *var_root, *var_root_next;
+
+  /* Iterate "safely" - handle if the callee deletes its passed VAROBJ.  */
+
+  for (var_root = rootlist; var_root != NULL; var_root = var_root_next)
+    {
+      var_root_next = var_root->next;
+
+      (*func) (var_root->rootvar, data);
+    }
+}
 \f
 extern void _initialize_varobj (void);
 void
@@ -3208,51 +3479,45 @@ When non-zero, varobj debugging is enabled."),
                            &setlist, &showlist);
 }
 
-/* Invalidate the varobjs that are tied to locals and re-create the ones that
-   are defined on globals.
-   Invalidated varobjs will be always printed in_scope="invalid".  */
+/* Invalidate varobj VAR if it is tied to locals and re-create it if it is
+   defined on globals.  It is a helper for varobj_invalidate.  */
 
-void 
-varobj_invalidate (void)
+static void
+varobj_invalidate_iter (struct varobj *var, void *unused)
 {
-  struct varobj **all_rootvarobj;
-  struct varobj **varp;
+  /* Floating varobjs are reparsed on each stop, so we don't care if the
+     presently parsed expression refers to something that's gone.  */
+  if (var->root->floating)
+    return;
 
-  if (varobj_list (&all_rootvarobj) > 0)
+  /* global var must be re-evaluated.  */     
+  if (var->root->valid_block == NULL)
     {
-      varp = all_rootvarobj;
-      while (*varp != NULL)
-       {
-         /* Floating varobjs are reparsed on each stop, so we don't care if
-            the presently parsed expression refers to something that's gone.
-            */
-         if ((*varp)->root->floating)
-           continue;
-
-         /* global var must be re-evaluated.  */     
-         if ((*varp)->root->valid_block == NULL)
-           {
-             struct varobj *tmp_var;
-
-             /* Try to create a varobj with same expression.  If we succeed
-                replace the old varobj, otherwise invalidate it.  */
-             tmp_var = varobj_create (NULL, (*varp)->name, (CORE_ADDR) 0,
-                                      USE_CURRENT_FRAME);
-             if (tmp_var != NULL) 
-               { 
-                 tmp_var->obj_name = xstrdup ((*varp)->obj_name);
-                 varobj_delete (*varp, NULL, 0);
-                 install_variable (tmp_var);
-               }
-             else
-               (*varp)->root->is_valid = 0;
-           }
-         else /* locals must be invalidated.  */
-           (*varp)->root->is_valid = 0;
+      struct varobj *tmp_var;
 
-         varp++;
+      /* Try to create a varobj with same expression.  If we succeed
+        replace the old varobj, otherwise invalidate it.  */
+      tmp_var = varobj_create (NULL, var->name, (CORE_ADDR) 0,
+                              USE_CURRENT_FRAME);
+      if (tmp_var != NULL) 
+       { 
+         tmp_var->obj_name = xstrdup (var->obj_name);
+         varobj_delete (var, NULL, 0);
+         install_variable (tmp_var);
        }
+      else
+       var->root->is_valid = 0;
     }
-  xfree (all_rootvarobj);
-  return;
+  else /* locals must be invalidated.  */
+    var->root->is_valid = 0;
+}
+
+/* Invalidate the varobjs that are tied to locals and re-create the ones that
+   are defined on globals.
+   Invalidated varobjs will be always printed in_scope="invalid".  */
+
+void 
+varobj_invalidate (void)
+{
+  all_root_varobjs (varobj_invalidate_iter, NULL);
 }