changeset 27199:f27002104c5b

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.
author John W. Eaton <jwe@octave.org>
date Mon, 01 Apr 2019 16:58:05 +0000
parents dffdabfd0213
children dc1edf932248
files libinterp/corefcn/error.cc libinterp/parse-tree/pt-eval.cc libinterp/parse-tree/pt-eval.h
diffstat 3 files changed, 94 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- 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<octave::stack_frame *> call_stack_frames = cs.backtrace_frames ();
+  octave::tree_evaluator& tw = octave::__get_evaluator__ ("pr_where");
+
+  std::list<octave::stack_frame *> 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");
--- 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<stack_frame *>
+  tree_evaluator::backtrace_frames (octave_idx_type& curr_user_frame) const
+  {
+    return m_call_stack.backtrace_frames (curr_user_frame);
+  }
+
+  std::list<stack_frame *>
+  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)
   {
--- 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<stack_frame *>
+    backtrace_frames (octave_idx_type& curr_user_frame) const;
+
+    std::list<stack_frame *> 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)