changeset 28794:3bd58f479489

maint: merge stable to default.
author John W. Eaton <jwe@octave.org>
date Fri, 25 Sep 2020 12:01:43 -0400
parents 92495ca48bd7 (current diff) c5953e65c6aa (diff)
children 901a92f45ff0
files libinterp/corefcn/stack-frame.h
diffstat 4 files changed, 69 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/call-stack.cc	Thu Sep 24 16:55:54 2020 -0700
+++ b/libinterp/corefcn/call-stack.cc	Fri Sep 25 12:01:43 2020 -0400
@@ -27,8 +27,6 @@
 #  include "config.h"
 #endif
 
-#include <iostream>
-
 #include "lo-regexp.h"
 #include "str-vec.h"
 
@@ -379,7 +377,8 @@
     std::shared_ptr<stack_frame> slink = get_static_link (prev_frame);
 
     std::shared_ptr<stack_frame>
-      new_frame (stack_frame::create (m_evaluator, scope, m_curr_frame, slink));
+      new_frame (stack_frame::create (m_evaluator, scope, m_curr_frame,
+                                      m_cs[prev_frame], slink));
 
     m_cs.push_back (new_frame);
   }
@@ -397,7 +396,8 @@
     std::shared_ptr<stack_frame> slink = get_static_link (prev_frame);
 
     std::shared_ptr<stack_frame>
-      new_frame (stack_frame::create (m_evaluator, fcn, m_curr_frame, slink,
+      new_frame (stack_frame::create (m_evaluator, fcn, m_curr_frame,
+                                      m_cs[prev_frame], slink,
                                       closure_frames));
 
     m_cs.push_back (new_frame);
@@ -416,8 +416,8 @@
     std::shared_ptr<stack_frame> slink = get_static_link (prev_frame);
 
     std::shared_ptr<stack_frame>
-      new_frame (stack_frame::create (m_evaluator, fcn, m_curr_frame, slink,
-                                      local_vars));
+      new_frame (stack_frame::create (m_evaluator, fcn, m_curr_frame,
+                                      m_cs[prev_frame], slink, local_vars));
 
     m_cs.push_back (new_frame);
   }
@@ -435,7 +435,7 @@
 
     std::shared_ptr<stack_frame>
       new_frame (stack_frame::create (m_evaluator, script, m_curr_frame,
-                                      slink));
+                                      m_cs[prev_frame], slink));
 
     m_cs.push_back (new_frame);
   }
@@ -452,7 +452,8 @@
     std::shared_ptr<stack_frame> slink = get_static_link (prev_frame);
 
     std::shared_ptr<stack_frame>
-      new_frame (stack_frame::create (m_evaluator, fcn, m_curr_frame, slink));
+      new_frame (stack_frame::create (m_evaluator, fcn, m_curr_frame,
+                                      m_cs[prev_frame], slink));
 
     m_cs.push_back (new_frame);
   }
@@ -752,7 +753,7 @@
       {
         std::shared_ptr<stack_frame> elt = m_cs.back ();
 
-        std::shared_ptr<stack_frame> caller = elt->static_link ();
+        std::shared_ptr<stack_frame> caller = elt->parent_link ();
 
         m_curr_frame = caller->index ();
 
--- a/libinterp/corefcn/call-stack.h	Thu Sep 24 16:55:54 2020 -0700
+++ b/libinterp/corefcn/call-stack.h	Fri Sep 25 12:01:43 2020 -0400
@@ -308,16 +308,16 @@
 
     tree_evaluator& m_evaluator;
 
-    // The current call stack.
-    // FIXME: maybe we should be using a std::shared_ptr to manage the
-    // individual stack frames?
+    // The list of stack frames.
     stack_frames m_cs;
 
-    // FIXME: Could we eliminate this variable and manage the current
-    // frame in the evaluator class instead?  The current frame might
-    // always be the top of the stack.  Restoring the previous/current
-    // frame would be managed by other means, such as an
-    // unwind_protect frame.
+    // The current frame.  When a new frame is pushed, m_curr_frame
+    // moves to the end of the list of stack frames (also referred to as
+    // the top of the call stack) but may be temporarily moved to
+    // another location by evalin or debugging functions.
+
+    // FIXME: should the current frame be managed by the evaluator
+    // instead?
     size_t m_curr_frame;
 
     int m_max_stack_depth;
--- a/libinterp/corefcn/stack-frame.cc	Thu Sep 24 16:55:54 2020 -0700
+++ b/libinterp/corefcn/stack-frame.cc	Fri Sep 25 12:01:43 2020 -0400
@@ -57,8 +57,10 @@
 
     compiled_fcn_stack_frame (tree_evaluator& tw, octave_function *fcn,
                               size_t index,
+                              const std::shared_ptr<stack_frame>& parent_link,
                               const std::shared_ptr<stack_frame>& static_link)
-      : stack_frame (tw, index, static_link, static_link->access_link ()),
+      : stack_frame (tw, index, parent_link, static_link,
+                     static_link->access_link ()),
         m_fcn (fcn)
     { }
 
@@ -176,6 +178,7 @@
 
     script_stack_frame (tree_evaluator& tw, octave_user_script *script,
                         size_t index,
+                        const std::shared_ptr<stack_frame>& parent_link,
                         const std::shared_ptr<stack_frame>& static_link);
 
     script_stack_frame (const script_stack_frame& elt) = default;
@@ -288,9 +291,10 @@
 
     base_value_stack_frame (tree_evaluator& tw, size_t num_symbols,
                             size_t index,
+                            const std::shared_ptr<stack_frame>& parent_link,
                             const std::shared_ptr<stack_frame>& static_link,
                             const std::shared_ptr<stack_frame>& access_link)
-      : stack_frame (tw, index, static_link, access_link),
+      : stack_frame (tw, index, parent_link, static_link, access_link),
         m_values (num_symbols, octave_value ()),
         m_flags (num_symbols, LOCAL),
         m_auto_vars (NUM_AUTO_VARS, octave_value ())
@@ -393,9 +397,11 @@
 
     user_fcn_stack_frame (tree_evaluator& tw, octave_user_function *fcn,
                           size_t index,
+                          const std::shared_ptr<stack_frame>& parent_link,
                           const std::shared_ptr<stack_frame>& static_link,
                           const std::shared_ptr<stack_frame>& access_link = std::shared_ptr<stack_frame> ())
-      : base_value_stack_frame (tw, get_num_symbols (fcn), index, static_link,
+      : base_value_stack_frame (tw, get_num_symbols (fcn), index,
+                                parent_link, static_link,
                                 (access_link
                                  ? access_link
                                  : get_access_link (fcn, static_link))),
@@ -404,9 +410,11 @@
 
     user_fcn_stack_frame (tree_evaluator& tw, octave_user_function *fcn,
                           size_t index,
+                          const std::shared_ptr<stack_frame>& parent_link,
                           const std::shared_ptr<stack_frame>& static_link,
                           const local_vars_map& local_vars)
-      : base_value_stack_frame (tw, get_num_symbols (fcn), index, static_link,
+      : base_value_stack_frame (tw, get_num_symbols (fcn), index,
+                                parent_link, static_link,
                                 get_access_link (fcn, static_link)),
         m_fcn (fcn), m_unwind_protect_frame (nullptr)
     {
@@ -495,9 +503,10 @@
 
     scope_stack_frame (tree_evaluator& tw, const symbol_scope& scope,
                        size_t index,
+                       const std::shared_ptr<stack_frame>& parent_link,
                        const std::shared_ptr<stack_frame>& static_link)
       : base_value_stack_frame (tw, scope.num_symbols (), index,
-                                static_link, nullptr),
+                                parent_link, static_link, nullptr),
         m_scope (scope)
     { }
 
@@ -1024,40 +1033,45 @@
 
   stack_frame * stack_frame::create (tree_evaluator& tw, octave_function *fcn,
                                      size_t index,
+                                     const std::shared_ptr<stack_frame>& parent_link,
                                      const std::shared_ptr<stack_frame>& static_link)
   {
-    return new compiled_fcn_stack_frame (tw, fcn, index, static_link);
+    return new compiled_fcn_stack_frame (tw, fcn, index, parent_link, static_link);
   }
 
   stack_frame * stack_frame::create (tree_evaluator& tw,
                                      octave_user_script *script,
                                      size_t index,
+                                     const std::shared_ptr<stack_frame>& parent_link,
                                      const std::shared_ptr<stack_frame>& static_link)
   {
-    return new script_stack_frame (tw, script, index, static_link);
+    return new script_stack_frame (tw, script, index, parent_link, static_link);
   }
 
   stack_frame * stack_frame::create (tree_evaluator& tw,
                                      octave_user_function *fcn, size_t index,
+                                     const std::shared_ptr<stack_frame>& parent_link,
                                      const std::shared_ptr<stack_frame>& static_link,
                                      const std::shared_ptr<stack_frame>& access_link)
   {
-    return new user_fcn_stack_frame (tw, fcn, index, static_link, access_link);
+    return new user_fcn_stack_frame (tw, fcn, index, parent_link, static_link, access_link);
   }
 
   stack_frame * stack_frame::create (tree_evaluator& tw,
                                      octave_user_function *fcn, size_t index,
+                                     const std::shared_ptr<stack_frame>& parent_link,
                                      const std::shared_ptr<stack_frame>& static_link,
                                      const local_vars_map& local_vars)
   {
-    return new user_fcn_stack_frame (tw, fcn, index, static_link, local_vars);
+    return new user_fcn_stack_frame (tw, fcn, index, parent_link, static_link, local_vars);
   }
 
   stack_frame * stack_frame::create (tree_evaluator& tw,
                                      const symbol_scope& scope, size_t index,
+                                     const std::shared_ptr<stack_frame>& parent_link,
                                      const std::shared_ptr<stack_frame>& static_link)
   {
-    return new scope_stack_frame (tw, scope, index, static_link);
+    return new scope_stack_frame (tw, scope, index, parent_link, static_link);
   }
 
   // This function is only implemented for user_fcn stack frames and
@@ -1388,6 +1402,13 @@
 
     os << "-- [stack_frame] (" << this << ") --" << std::endl;
 
+    os << "parent link: ";
+    if (m_parent_link)
+      os << m_parent_link.get ();
+    else
+      os << "NULL";
+    os << std::endl;
+
     os << "static link: ";
     if (m_static_link)
       os << m_static_link.get ();
@@ -1441,8 +1462,10 @@
   script_stack_frame::script_stack_frame (tree_evaluator& tw,
                                           octave_user_script *script,
                                           size_t index,
+                                          const std::shared_ptr<stack_frame>& parent_link,
                                           const std::shared_ptr<stack_frame>& static_link)
-    : stack_frame (tw, index, static_link, get_access_link (static_link)),
+    : stack_frame (tw, index, parent_link, static_link,
+                   get_access_link (static_link)),
       m_script (script), m_unwind_protect_frame (nullptr),
       m_lexical_frame_offsets (get_num_symbols (script), 1),
       m_value_offsets (get_num_symbols (script), 0)
--- a/libinterp/corefcn/stack-frame.h	Thu Sep 24 16:55:54 2020 -0700
+++ b/libinterp/corefcn/stack-frame.h	Fri Sep 25 12:01:43 2020 -0400
@@ -140,38 +140,44 @@
     stack_frame (void) = delete;
 
     stack_frame (tree_evaluator& tw, size_t index,
+                 const std::shared_ptr<stack_frame>& parent_link,
                  const std::shared_ptr<stack_frame>& static_link,
                  const std::shared_ptr<stack_frame>& access_link)
       : m_evaluator (tw), m_line (-1), m_column (-1), m_index (index),
-        m_static_link (static_link), m_access_link (access_link),
-        m_dispatch_class ()
+        m_parent_link (parent_link), m_static_link (static_link),
+        m_access_link (access_link), m_dispatch_class ()
     { }
 
     // Compiled function.
     static stack_frame *
     create (tree_evaluator& tw, octave_function *fcn, size_t index,
+            const std::shared_ptr<stack_frame>& parent_link,
             const std::shared_ptr<stack_frame>& static_link);
 
     // Script.
     static stack_frame *
     create (tree_evaluator& tw, octave_user_script *script, size_t index,
+            const std::shared_ptr<stack_frame>& parent_link,
             const std::shared_ptr<stack_frame>& static_link);
 
     // User-defined function.
     static stack_frame *
     create (tree_evaluator& tw, octave_user_function *fcn, size_t index,
+            const std::shared_ptr<stack_frame>& parent_link,
             const std::shared_ptr<stack_frame>& static_link,
             const std::shared_ptr<stack_frame>& access_link = std::shared_ptr<stack_frame> ());
 
     // Anonymous user-defined function with init vars.
     static stack_frame *
     create (tree_evaluator& tw, octave_user_function *fcn, size_t index,
+            const std::shared_ptr<stack_frame>& parent_link,
             const std::shared_ptr<stack_frame>& static_link,
             const local_vars_map& local_vars);
 
     // Scope.
     static stack_frame *
     create (tree_evaluator& tw, const symbol_scope& scope, size_t index,
+            const std::shared_ptr<stack_frame>& parent_link,
             const std::shared_ptr<stack_frame>& static_link);
 
     stack_frame (const stack_frame& elt) = default;
@@ -300,6 +306,9 @@
     }
 
     std::shared_ptr<stack_frame>
+    parent_link (void) const {return m_parent_link; }
+
+    std::shared_ptr<stack_frame>
     static_link (void) const {return m_static_link; }
 
     std::shared_ptr<stack_frame>
@@ -556,8 +565,13 @@
     // Index in call stack.
     size_t m_index;
 
+    // Pointer to the nearest parent frame.  May include compiled
+    // functions.
+    std::shared_ptr<stack_frame> m_parent_link;
+
     // Pointer to the nearest parent frame that contains variable
-    // information (script, function, or scope).
+    // information (script, function, or scope).  This link skips over
+    // compiled function parent frames.
     std::shared_ptr<stack_frame> m_static_link;
 
     // Pointer to the nearest lexical parent frame.  Used to access