# HG changeset patch # User John W. Eaton # Date 1554137885 0 # Node ID f27002104c5bf9876cb5b0642849566875a9d7a9 # Parent dffdabfd02138fd21c0d1e56d639c56b6c9c3fba eliminate direct access to call_stack in error functions * pt-eval.h, pt-eval.cc (tree_evaluator::backtrace_frames, tree_evaluator::backtrace, tree_evaluator::empty_backtrace, tree_evaluator::current_function_name, tree_evaluator::in_user_code, tree_evaluator::get_current_frame_number_from_call_stack): New functions. * error.cc (initialize_las_error_stack): Delete. (verror, pr_where, maybe_enter_debugger, error_1, warning_1, Frethrow, Flasterror): Eliminate direct access to call stack. diff -r dffdabfd0213 -r f27002104c5b libinterp/corefcn/error.cc --- a/libinterp/corefcn/error.cc Tue Jun 25 22:10:14 2019 +0200 +++ b/libinterp/corefcn/error.cc Mon Apr 01 16:58:05 2019 +0000 @@ -35,7 +35,6 @@ #include "bp-table.h" #include "builtin-defun-decls.h" -#include "call-stack.h" #include "defun.h" #include "error.h" #include "input.h" @@ -138,9 +137,9 @@ static void pr_where (std::ostream& os, const char *who) { - octave::call_stack& cs = octave::__get_call_stack__ ("pr_where"); - - std::list call_stack_frames = cs.backtrace_frames (); + octave::tree_evaluator& tw = octave::__get_evaluator__ ("pr_where"); + + std::list call_stack_frames = tw.backtrace_frames (); // Print the error message only if it is different from the previous one; // Makes the output more concise and readable. @@ -394,9 +393,9 @@ static octave_map init_error_stack (interpreter& interp) { - call_stack& cs = interp.get_call_stack (); - - return cs.empty_backtrace (); + tree_evaluator& tw = interp.get_evaluator (); + + return tw.empty_backtrace (); } error_system::error_system (interpreter& interp) @@ -643,7 +642,7 @@ msg_string += std::string (name) + ": "; } - call_stack& cs = m_interpreter.get_call_stack (); + tree_evaluator& tw = m_interpreter.get_evaluator (); // If with_fcn is specified, we'll attempt to prefix the message with the name // of the current executing function. But we'll do so only if: @@ -651,19 +650,14 @@ // 2. it is not already there (including the following colon) if (with_cfn) { - octave_function *curfcn = cs.current (); - if (curfcn) + std::string cfn = tw.current_function_name (); + + if (! cfn.empty ()) { - std::string cfn = curfcn->name (); - if (! cfn.empty ()) - { - cfn += ':'; - if (cfn.length () > base_msg.length () - || base_msg.compare (0, cfn.length (), cfn) != 0) - { - msg_string += cfn + ' '; - } - } + cfn += ':'; + if (cfn.length () > base_msg.length () + || base_msg.compare (0, cfn.length (), cfn) != 0) + msg_string += cfn + ' '; } } @@ -675,13 +669,8 @@ last_error_id (id); last_error_message (base_msg); - - octave_user_code *fcn = cs.current_user_code (); - - if (fcn) - last_error_stack (cs.backtrace ()); - else - last_error_stack (init_error_stack (m_interpreter)); + last_error_stack (tw.in_user_code () + ? tw.backtrace () : tw.empty_backtrace ()); } if (! buffer_error_messages () || debug_on_caught ()) @@ -694,7 +683,6 @@ void error_system::maybe_enter_debugger (execution_exception& e, bool show_stack_trace) { - call_stack& cs = m_interpreter.get_call_stack (); tree_evaluator& tw = m_interpreter.get_evaluator (); bp_table& bptab = tw.get_bp_table (); @@ -704,7 +692,7 @@ && bptab.debug_on_err (last_error_id ())) || (debug_on_caught () && bptab.debug_on_caught (last_error_id ()))) - && cs.current_user_code ()) + && tw.in_user_code ()) { unwind_protect frame; @@ -792,11 +780,9 @@ { verror (true, os, name, id, fmt, args, with_cfn); - call_stack& cs = m_interpreter.get_call_stack (); - - bool in_user_code = cs.current_user_code () != nullptr; - - if (in_user_code && ! discard_error_messages ()) + tree_evaluator& tw = m_interpreter.get_evaluator (); + + if (tw.in_user_code () && ! discard_error_messages ()) show_stack_trace = true; } } @@ -844,16 +830,15 @@ else vwarning ("warning", id, fmt, args); - call_stack& cs = m_interpreter.get_call_stack (); - - bool in_user_code = cs.current_user_code () != nullptr; + tree_evaluator& tw = m_interpreter.get_evaluator (); + + bool in_user_code = tw.in_user_code (); if (! fmt_suppresses_backtrace && in_user_code && backtrace_on_warning () && ! discard_warning_messages ()) pr_where (std::cerr, "warning"); - tree_evaluator& tw = m_interpreter.get_evaluator (); bp_table& bptab = tw.get_bp_table (); if ((application::interactive () @@ -2093,7 +2078,7 @@ if (nargin == 1) { - octave::call_stack& cs = interp.get_call_stack (); + octave::tree_evaluator& tw = interp.get_evaluator (); if (args(0).is_string ()) { @@ -2103,7 +2088,7 @@ es.last_error_message (""); es.last_error_id (""); - es.last_error_stack (cs.empty_backtrace ()); + es.last_error_stack (tw.empty_backtrace ()); } else if (args(0).isstruct ()) { @@ -2174,7 +2159,7 @@ es.last_error_id (new_error_id); if (initialize_stack) - es.last_error_stack (cs.empty_backtrace ()); + es.last_error_stack (tw.empty_backtrace ()); else if (new_err.contains ("stack")) { new_err_stack.setfield ("file", new_error_file); @@ -2185,7 +2170,7 @@ es.last_error_stack (new_err_stack); } else - es.last_error_stack (cs.backtrace ()); + es.last_error_stack (tw.backtrace ()); } else error ("lasterror: argument must be a structure or a string"); diff -r dffdabfd0213 -r f27002104c5b libinterp/parse-tree/pt-eval.cc --- a/libinterp/parse-tree/pt-eval.cc Tue Jun 25 22:10:14 2019 +0200 +++ b/libinterp/parse-tree/pt-eval.cc Mon Apr 01 16:58:05 2019 +0000 @@ -1869,6 +1869,35 @@ return false; } + std::list + tree_evaluator::backtrace_frames (octave_idx_type& curr_user_frame) const + { + return m_call_stack.backtrace_frames (curr_user_frame); + } + + std::list + tree_evaluator::backtrace_frames (void) const + { + return m_call_stack.backtrace_frames (); + } + + octave_map + tree_evaluator::backtrace (octave_idx_type& curr_user_frame, + bool print_subfn) const + { + return m_call_stack.backtrace (curr_user_frame, print_subfn); + } + + octave_map tree_evaluator::backtrace (void) + { + return m_call_stack.backtrace (); + } + + octave_map tree_evaluator::empty_backtrace (void) const + { + return m_call_stack.empty_backtrace (); + } + void tree_evaluator::push_dummy_scope (const std::string& name) { symbol_scope dummy_scope (name + "$dummy"); @@ -2118,6 +2147,23 @@ return user_code; } + std::string + tree_evaluator::current_function_name (void) const + { + octave_function *curfcn = m_call_stack.current (); + + if (curfcn) + return curfcn->name (); + + return ""; + } + + bool + tree_evaluator::in_user_code (void) const + { + return m_call_stack.current_user_code () != nullptr; + } + void tree_evaluator::visit_decl_command (tree_decl_command& cmd) { diff -r dffdabfd0213 -r f27002104c5b libinterp/parse-tree/pt-eval.h --- a/libinterp/parse-tree/pt-eval.h Tue Jun 25 22:10:14 2019 +0200 +++ b/libinterp/parse-tree/pt-eval.h Mon Apr 01 16:58:05 2019 +0000 @@ -474,6 +474,18 @@ return m_call_stack.get_current_stack_frame (); } + std::list + backtrace_frames (octave_idx_type& curr_user_frame) const; + + std::list backtrace_frames () const; + + octave_map backtrace (octave_idx_type& curr_user_frame, + bool print_subfn = true) const; + + octave_map backtrace (); + + octave_map empty_backtrace (void) const; + void push_dummy_scope (const std::string& name); void pop_scope (void); @@ -515,6 +527,10 @@ octave_user_code * get_user_code (const std::string& fname = "", const std::string& class_name = ""); + std::string current_function_name (void) const; + + bool in_user_code (void) const; + octave_map get_autoload_map (void) const; std::string lookup_autoload (const std::string& nm) const; @@ -571,6 +587,11 @@ return val; } + size_t current_call_stack_frame_number (void) const + { + return m_call_stack.current_frame (); + } + bool debug_mode (void) const { return m_debug_mode; } bool debug_mode (bool flag)