# HG changeset patch # User ryanru@PrinceHumperdinck # Date 1204668065 18000 # Node ID 6070c3bd69c44a75b8c5a0f72056df36cf348564 # Parent 5ed0cb9e95848b1f8ceb641dfd344cc10f80179d Arbitrary call stack access for external debuggers changeset diff --git a/doc/interpreter/contributors.in b/doc/interpreter/contributors.in --- a/doc/interpreter/contributors.in +++ b/doc/interpreter/contributors.in @@ -160,6 +160,7 @@ Andrew Ross Mark van Rossum Kevin Ruland +Ryan Rusaw Olli Saarela Toni Saarela Juhani Saastamoinen diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,24 @@ +2008-03-04 Ryan Rusaw + + * 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 * debug.cc (get_user_function): Call symtab::find_function instead diff --git a/src/error.cc b/src/error.cc --- a/src/error.cc +++ b/src/error.cc @@ -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; diff --git a/src/input.cc b/src/input.cc --- a/src/input.cc +++ b/src/input.cc @@ -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 (); diff --git a/src/ov-usr-fcn.cc b/src/ov-usr-fcn.cc --- a/src/ov-usr-fcn.cc +++ b/src/ov-usr-fcn.cc @@ -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); diff --git a/src/pt-stmt.cc b/src/pt-stmt.cc --- a/src/pt-stmt.cc +++ b/src/pt-stmt.cc @@ -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++ *** diff --git a/src/pt-stmt.h b/src/pt-stmt.h --- a/src/pt-stmt.h +++ b/src/pt-stmt.h @@ -31,6 +31,8 @@ class tree_walker; +#include + #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::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 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 diff --git a/src/toplev.cc b/src/toplev.cc --- a/src/toplev.cc +++ b/src/toplev.cc @@ -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) { diff --git a/src/toplev.h b/src/toplev.h --- a/src/toplev.h +++ b/src/toplev.h @@ -26,7 +26,7 @@ #include -#include +#include #include class octave_value; @@ -74,7 +74,7 @@ public: - typedef std::list::iterator iterator ; + typedef std::deque::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 cs; + std::deque 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);