changeset 7552:6070c3bd69c4

Arbitrary call stack access for external debuggers changeset
author ryanru@PrinceHumperdinck
date Tue, 04 Mar 2008 17:01:05 -0500
parents 5ed0cb9e9584
children 56be6f31dd4e
files doc/interpreter/contributors.in src/ChangeLog src/error.cc src/input.cc src/ov-usr-fcn.cc src/pt-stmt.cc src/pt-stmt.h src/toplev.cc src/toplev.h
diffstat 9 files changed, 154 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/doc/interpreter/contributors.in	Tue Mar 04 15:07:44 2008 -0500
+++ b/doc/interpreter/contributors.in	Tue Mar 04 17:01:05 2008 -0500
@@ -160,6 +160,7 @@
 Andrew Ross
 Mark van Rossum
 Kevin Ruland
+Ryan Rusaw
 Olli Saarela
 Toni Saarela
 Juhani Saastamoinen
--- a/src/ChangeLog	Tue Mar 04 15:07:44 2008 -0500
+++ b/src/ChangeLog	Tue Mar 04 17:01:05 2008 -0500
@@ -1,3 +1,24 @@
+2008-03-04  Ryan Rusaw  <rrusaw@gmail.com>
+
+	* toplev.h (octave_call_stack::element): New static function.
+	(octave_call_stack::cs): Now std::deque instead of std::list.
+
+	* pt-stmt.cc (curr_statement, curr_caller_statement): Delete.
+	* pt-stmt.h: Delete decls.
+
+	* pt-stmt.h, pt-stmt.cc (tree_statement_stack): New class.
+
+	* pt-stmt.cc (tree_statement::eval): Use tree_statement_stack
+	instead of curr_statement variable.
+
+	* ov-usr-func.cc (octave_user_function::do_multi_index_op):
+	Don't set curr_caller_statement.
+
+	* error.cc (verror, pr_where): Call tree_statement_stack::current_line
+	and tree_statement_stack::current_column instead of 
+	instead of curr_statement->line and curr_statement->column.
+	* input.cc (get_user_input): Likewise.
+
 2008-02-27  John P. Swensen  <jpswensen@gmail.com>
 
 	* debug.cc (get_user_function): Call symtab::find_function instead
--- a/src/error.cc	Tue Mar 04 15:07:44 2008 -0500
+++ b/src/error.cc	Tue Mar 04 17:01:05 2008 -0500
@@ -232,7 +232,7 @@
       Vlast_error_name = std::string ();
       Vlast_error_file = std::string ();
 
-      if (curr_statement)
+      if (tree_statement_stack::current ())
 	{
 	  octave_function *fcn
 	    = octave_call_stack::caller_user_script_or_function ();
@@ -241,8 +241,8 @@
 	    {
 	      Vlast_error_file = fcn->fcn_file_name ();
 	      Vlast_error_name = fcn->name();
-	      Vlast_error_line = curr_statement->line ();
-	      Vlast_error_column = curr_statement->column ();
+	      Vlast_error_line = tree_statement_stack::current_line ();
+	      Vlast_error_column = tree_statement_stack::current_column ();
 	    }
 	}
     }
@@ -422,7 +422,7 @@
 static void
 pr_where (const char *name, bool print_code = true)
 {
-  if (curr_statement)
+  if (tree_statement_stack::current ())
     {
       std::string nm;
 
@@ -439,11 +439,8 @@
 	  if (nm.empty ())
 	    nm = fcn->name ();
 
-	  if (curr_statement)
-	    {
-	      l = curr_statement->line ();
-	      c = curr_statement->column ();
-	    }
+	  l = tree_statement_stack::current_line ();
+	  c = tree_statement_stack::current_column ();
 	}
 
       if (nm.empty ())
@@ -474,7 +471,10 @@
 
 	  tree_print_code tpc (output_buf, ">>> ");
 
-	  curr_statement->accept (tpc);
+	  tree_statement *curr_stmt = tree_statement_stack::current ();
+
+	  if (curr_stmt)
+	    curr_stmt->accept (tpc);
 
 	  output_buf << std::endl;
 
--- a/src/input.cc	Tue Mar 04 15:07:44 2008 -0500
+++ b/src/input.cc	Tue Mar 04 17:01:05 2008 -0500
@@ -608,8 +608,7 @@
 	  if (nm.empty ())
 	    nm = caller->name ();
 
-	  if (curr_statement)
-	    line = curr_statement->line ();
+	  line = tree_statement_stack::current_line ();
 	}
     }
 
@@ -701,7 +700,7 @@
 	    {
 	      tree::break_next = true;
 
-	      tree::last_line = curr_statement->line ();
+	      tree::last_line = tree_statement_stack::current_line ();
 
 	      tree::break_function = octave_call_stack::current ();
 
--- a/src/ov-usr-fcn.cc	Tue Mar 04 15:07:44 2008 -0500
+++ b/src/ov-usr-fcn.cc	Tue Mar 04 17:01:05 2008 -0500
@@ -290,9 +290,6 @@
       unwind_protect::add (symbol_table::clear_variables);
     }
 
-  unwind_protect_ptr (curr_caller_statement);
-  curr_caller_statement = curr_statement;
-
   octave_call_stack::push (this);
 
   unwind_protect::add (octave_call_stack::unwind_pop, 0);
--- a/src/pt-stmt.cc	Tue Mar 04 15:07:44 2008 -0500
+++ b/src/pt-stmt.cc	Tue Mar 04 17:01:05 2008 -0500
@@ -45,12 +45,6 @@
 #include "utils.h"
 #include "variables.h"
 
-// Pointer to the current statement being executed.
-tree_statement *curr_statement = 0;
-
-// Pointer to the current statement being executed in the calling function.
-tree_statement *curr_caller_statement = 0;
-
 // A list of commands to be executed.
 
 tree_statement::~tree_statement (void)
@@ -93,8 +87,8 @@
 
   if (cmd || expr)
     {
-      unwind_protect_ptr (curr_statement);
-      curr_statement = this;
+      unwind_protect::add (tree_statement_stack::unwind_pop, 0);
+      tree_statement_stack::push (this);
 
       maybe_echo_code (in_function_body);
 
@@ -291,6 +285,8 @@
   tw.visit_statement_list (*this);
 }
 
+tree_statement_stack *tree_statement_stack::instance = 0;
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/src/pt-stmt.h	Tue Mar 04 15:07:44 2008 -0500
+++ b/src/pt-stmt.h	Tue Mar 04 17:01:05 2008 -0500
@@ -31,6 +31,8 @@
 
 class tree_walker;
 
+#include <deque>
+
 #include "base-list.h"
 #include "comment-list.h"
 #include "symtab.h"
@@ -158,11 +160,105 @@
   tree_statement_list& operator = (const tree_statement_list&);
 };
 
-// Pointer to the current statement being executed.
-extern tree_statement *curr_statement;
+class tree_statement_stack
+{
+protected:
+
+  tree_statement_stack (void) : tss () { }
+
+public:
+
+  typedef std::deque<tree_statement *>::iterator iterator ;
+
+  static bool instance_ok (void)
+  {
+    bool retval = true;
+
+    if (! instance)
+      instance = new tree_statement_stack ();
+
+    if (! instance)
+      {
+	::error ("unable to create stmt stack object!");
+
+	retval = false;
+      }
+
+    return retval;
+  }
+
+  // Current statement (top of stack).
+  static tree_statement *current (void) { return top (); }
+
+  static int current_line (void)
+  {
+    tree_statement *s = current ();
+    return s ? s->line () : -1;
+  }
+
+  static int current_column (void)
+  {
+    tree_statement *s = current ();
+    return s ? s->column () : -1;
+  }
+
+  // Statement at position N on the call stack (N == 0 is current).
+  static tree_statement *element (size_t n)
+  {
+    return instance_ok () ? instance->do_element (n) : 0;
+  }
 
-// Pointer to the current statement being executed in the calling function.
-extern tree_statement *curr_caller_statement;
+  // Caller statement
+  static tree_statement *caller (void) { return element (1); }
+
+  static void push (tree_statement *f)
+  {
+    if (instance_ok ())
+      instance->do_push (f);
+  }
+
+  static tree_statement *top (void)
+  {
+    return instance_ok () ? instance->do_top (): 0;
+  }
+
+  static void pop (void)
+  {
+    if (instance_ok ())
+      instance->do_pop ();
+  }
+  
+  // A function for popping the top of the call stack that is suitable
+  // for use as an unwind_protect handler.
+  static void unwind_pop (void *) { pop (); }
+
+  static void clear (void)
+  {
+    if (instance_ok ())
+      instance->do_clear ();
+  }
+
+private:
+
+  // The current stmt stack.
+  std::deque<tree_statement *> tss;
+
+  static tree_statement_stack *instance;
+
+  tree_statement *do_element (size_t n) { return tss.size () > n ? tss[n] : 0; }
+
+  void do_push (tree_statement *f) { tss.push_front (f); }
+
+  tree_statement *do_top (void) { return tss.empty () ? 0 : tss.front (); }
+
+  void do_pop (void)
+  {
+    if (! tss.empty ())
+      tss.pop_front ();
+  }
+
+  void do_clear (void) { tss.clear (); }
+};
 
 #endif
 
--- a/src/toplev.cc	Tue Mar 04 15:07:44 2008 -0500
+++ b/src/toplev.cc	Tue Mar 04 17:01:05 2008 -0500
@@ -95,20 +95,6 @@
 
 octave_call_stack *octave_call_stack::instance = 0;
 
-octave_function *
-octave_call_stack::do_caller (void)
-{
-  octave_function *retval = 0;
-
-  if (cs.size () > 1)
-    {
-      iterator p = cs.begin ();
-      retval = *++p;
-    }
-
-  return retval;
-}
-
 octave_user_script *
 octave_call_stack::do_caller_user_script (void)
 {
--- a/src/toplev.h	Tue Mar 04 15:07:44 2008 -0500
+++ b/src/toplev.h	Tue Mar 04 17:01:05 2008 -0500
@@ -26,7 +26,7 @@
 
 #include <cstdio>
 
-#include <list>
+#include <deque>
 #include <string>
 
 class octave_value;
@@ -74,7 +74,7 @@
 
 public:
 
-  typedef std::list<octave_function *>::iterator iterator ;
+  typedef std::deque<octave_function *>::iterator iterator ;
 
   static bool instance_ok (void)
   {
@@ -99,25 +99,32 @@
   // Caller function, may be built-in.
   static octave_function *caller (void)
   {
-    return instance_ok () ? instance->do_caller (): 0;
+    return element (1);
   }
 
+  // Function at location N on the call stack (N == 0 is current), may
+  // be built-in.
+  static octave_function *element (size_t n)
+  {
+    return instance_ok () ? instance->do_element (n) : 0;
+  }
+  
   // First script on the stack.
   static octave_user_script *caller_script (void)
   {
-    return instance_ok () ? instance->do_caller_user_script (): 0;
+    return instance_ok () ? instance->do_caller_user_script () : 0;
   }
 
   // First user-defined function on the stack.
   static octave_user_function *caller_user_function (void)
   {
-    return instance_ok () ? instance->do_caller_user_function (): 0;
+    return instance_ok () ? instance->do_caller_user_function () : 0;
   }
 
   // First user-defined function on the stack.
   static octave_function *caller_user_script_or_function (void)
   {
-    return instance_ok () ? instance->do_caller_user_script_or_function (): 0;
+    return instance_ok () ? instance->do_caller_user_script_or_function () : 0;
   }
 
   static void push (octave_function *f)
@@ -150,15 +157,15 @@
     if (instance_ok ())
       instance->do_clear ();
   }
-  
+
 private:
 
   // The current call stack.
-  std::list<octave_function *> cs;
+  std::deque<octave_function *> cs;
 
   static octave_call_stack *instance;
 
-  octave_function *do_caller (void);
+  octave_function *do_element (size_t n) { return cs.size () > n ? cs[n] : 0; }
 
   octave_user_script *do_caller_user_script (void);