diff libinterp/corefcn/call-stack.cc @ 28426:9a3deb17b4ea stable

use shared_ptr for stack frames in call stack and for accesss and static links * call-stack.h, call-stack.cc: Use std::shared_ptr<stack_frame> instead of bare pointer for elements of call stack. Change all uses. * stack-frame.h, stack-frame.cc (stack_frame::static_link, stack_frame::access_link): Use std::shared_ptr<stack_frame> instead of bare pointer. Change all uses. (stack_frame::workspace): New function. * ov-fcn-handle.h, ov-fcn-handle.cc (octave_fcn_handle::m_closure_frames): Now a std::shared_ptr<stack_frame> object instead of a list of copied stack frames. Change all uses. (octave_fcn_handle::push_closure_context): Simply store std::shared_ptr to current stack frame. (octave_fcn_handle::workspace): Call stack_frame::workspace to get workspace info when we have closure frames.
author John W. Eaton <jwe@octave.org>
date Sat, 25 Apr 2020 13:17:11 -0400
parents a5be4fc661d6
children 8eb8ba8aff9a
line wrap: on
line diff
--- a/libinterp/corefcn/call-stack.cc	Fri Apr 24 14:21:07 2020 -0400
+++ b/libinterp/corefcn/call-stack.cc	Sat Apr 25 13:17:11 2020 -0400
@@ -94,7 +94,7 @@
 
     if (! m_cs.empty ())
       {
-        const stack_frame *elt = m_cs[m_curr_frame];
+        const std::shared_ptr<stack_frame> elt = m_cs[m_curr_frame];
         retval = elt->line ();
       }
 
@@ -107,7 +107,7 @@
 
     if (! m_cs.empty ())
       {
-        const stack_frame *elt = m_cs[m_curr_frame];
+        const std::shared_ptr<stack_frame> elt = m_cs[m_curr_frame];
         retval = elt->column ();
       }
 
@@ -122,7 +122,7 @@
 
     if (xframe > 0)
       {
-        const stack_frame *elt = m_cs[xframe];
+        const std::shared_ptr<stack_frame> elt = m_cs[xframe];
 
         octave_function *f = elt->function ();
 
@@ -141,7 +141,7 @@
 
     if (xframe > 0)
       {
-        const stack_frame *elt = m_cs[xframe];
+        const std::shared_ptr<stack_frame> elt = m_cs[xframe];
 
         octave_function *f = elt->function ();
 
@@ -165,7 +165,7 @@
 
     if (xframe > 0)
       {
-        const stack_frame *elt = m_cs[xframe];
+        const std::shared_ptr<stack_frame> elt = m_cs[xframe];
 
         octave_function *f = elt->function ();
 
@@ -189,7 +189,7 @@
 
     if (xframe > 0)
       {
-        const stack_frame *elt = m_cs[xframe];
+        const std::shared_ptr<stack_frame> elt = m_cs[xframe];
 
         octave_function *f = elt->function ();
 
@@ -212,7 +212,7 @@
 
     while (i != 0)
       {
-        const stack_frame *elt = m_cs[i--];
+        const std::shared_ptr<stack_frame> elt = m_cs[i--];
 
         octave_function *f = elt->function ();
 
@@ -238,7 +238,7 @@
 
     while (i != 0)
       {
-        const stack_frame *elt = m_cs[i--];
+        const std::shared_ptr<stack_frame> elt = m_cs[i--];
 
         octave_function *f = elt->function ();
 
@@ -268,7 +268,7 @@
 
     while (i != 0)
       {
-        const stack_frame *elt = m_cs[i--];
+        const std::shared_ptr<stack_frame> elt = m_cs[i--];
 
         octave_function *f = elt->function ();
 
@@ -331,7 +331,7 @@
 
     while (p != m_cs.cbegin ())
       {
-        const stack_frame *elt = *(--p);
+        const std::shared_ptr<stack_frame> elt = *(--p);
 
         octave_function *f = elt->function ();
 
@@ -345,11 +345,12 @@
     return retval;
   }
 
-  stack_frame * call_stack::get_static_link (size_t prev_frame) const
+  std::shared_ptr<stack_frame>
+  call_stack::get_static_link (size_t prev_frame) const
   {
     // FIXME: is there a better way?
 
-    stack_frame *slink = nullptr;
+    std::shared_ptr<stack_frame> slink;
 
     if (m_curr_frame > 0)
       {
@@ -373,16 +374,16 @@
     if (m_curr_frame > static_cast<size_t> (m_max_stack_depth))
       error ("max_stack_depth exceeded");
 
-    stack_frame *slink = get_static_link (prev_frame);
+    std::shared_ptr<stack_frame> slink = get_static_link (prev_frame);
 
-    stack_frame *new_frame
-      = stack_frame::create (m_evaluator, scope, m_curr_frame, slink);
+    std::shared_ptr<stack_frame>
+      new_frame (stack_frame::create (m_evaluator, scope, m_curr_frame, slink));
 
     m_cs.push_back (new_frame);
   }
 
   void call_stack::push (octave_user_function *fcn, unwind_protect *up_frame,
-                         stack_frame *closure_frames)
+                         const std::shared_ptr<stack_frame>& closure_frames)
   {
     size_t prev_frame = m_curr_frame;
     m_curr_frame = m_cs.size ();
@@ -391,11 +392,11 @@
     if (m_curr_frame > static_cast<size_t> (m_max_stack_depth))
       error ("max_stack_depth exceeded");
 
-    stack_frame *slink = get_static_link (prev_frame);
+    std::shared_ptr<stack_frame> slink = get_static_link (prev_frame);
 
-    stack_frame *new_frame
-      = stack_frame::create (m_evaluator, fcn, up_frame, m_curr_frame,
-                             slink, closure_frames);
+    std::shared_ptr<stack_frame>
+      new_frame (stack_frame::create (m_evaluator, fcn, up_frame, m_curr_frame,
+                                      slink, closure_frames));
 
     m_cs.push_back (new_frame);
   }
@@ -409,11 +410,11 @@
     if (m_curr_frame > static_cast<size_t> (m_max_stack_depth))
       error ("max_stack_depth exceeded");
 
-    stack_frame *slink = get_static_link (prev_frame);
+    std::shared_ptr<stack_frame> slink = get_static_link (prev_frame);
 
-    stack_frame *new_frame
-      = stack_frame::create (m_evaluator, script, up_frame, m_curr_frame,
-                             slink);
+    std::shared_ptr<stack_frame>
+      new_frame (stack_frame::create (m_evaluator, script, up_frame,
+                                      m_curr_frame, slink));
 
     m_cs.push_back (new_frame);
   }
@@ -427,10 +428,10 @@
     if (m_curr_frame > static_cast<size_t> (m_max_stack_depth))
       error ("max_stack_depth exceeded");
 
-    stack_frame *slink = get_static_link (prev_frame);
+    std::shared_ptr<stack_frame> slink = get_static_link (prev_frame);
 
-    stack_frame *new_frame
-      = stack_frame::create (m_evaluator, fcn, m_curr_frame, slink);
+    std::shared_ptr<stack_frame>
+      new_frame (stack_frame::create (m_evaluator, fcn, m_curr_frame, slink));
 
     m_cs.push_back (new_frame);
   }
@@ -447,7 +448,7 @@
 
         if (verbose)
           {
-            const stack_frame *elt = m_cs[n];
+            const std::shared_ptr<stack_frame> elt = m_cs[n];
 
             elt->display_stopped_in_message (octave_stdout);
           }
@@ -460,7 +461,7 @@
   {
     size_t user_frame = m_curr_frame;
 
-    stack_frame *frm = m_cs[user_frame];
+    std::shared_ptr<stack_frame> frm = m_cs[user_frame];
 
     if (! (frm->is_user_fcn_frame () || frm->is_user_script_frame ()
            || frm->is_scope_frame ()))
@@ -473,7 +474,7 @@
     return user_frame;
   }
 
-  stack_frame *call_stack::current_user_frame (void) const
+  std::shared_ptr<stack_frame> call_stack::current_user_frame (void) const
   {
     size_t frame = find_current_user_frame ();
 
@@ -499,7 +500,7 @@
         return start;
       }
 
-    stack_frame *frm = m_cs[start];
+    std::shared_ptr<stack_frame> frm = m_cs[start];
 
     if (! (frm && (frm->is_user_fcn_frame ()
                    || frm->is_user_script_frame ()
@@ -603,10 +604,10 @@
       m_curr_frame = 0;
   }
 
-  std::list<stack_frame *>
+  std::list<std::shared_ptr<stack_frame>>
   call_stack::backtrace_frames (octave_idx_type& curr_user_frame) const
   {
-    std::list<stack_frame *> frames;
+    std::list<std::shared_ptr<stack_frame>> frames;
 
     // curr_frame is the index to the current frame in the overall call
     // stack, which includes any compiled function frames and scope
@@ -619,7 +620,7 @@
 
     for (size_t n = m_cs.size () - 1; n > 0; n--)
       {
-        stack_frame *frm = m_cs[n];
+        std::shared_ptr<stack_frame> frm = m_cs[n];
 
         if (frm->is_user_script_frame () || frm->is_user_fcn_frame ()
             || frm->is_scope_frame ())
@@ -637,7 +638,7 @@
     return frames;
   }
 
-  std::list<stack_frame *>
+  std::list<std::shared_ptr<stack_frame>>
   call_stack::backtrace_frames (void) const
   {
     octave_idx_type curr_user_frame = -1;
@@ -649,11 +650,12 @@
   call_stack::backtrace_info (octave_idx_type& curr_user_frame,
                               bool print_subfn) const
   {
-    std::list<stack_frame *> frames = backtrace_frames (curr_user_frame);
+    std::list<std::shared_ptr<stack_frame>> frames
+      = backtrace_frames (curr_user_frame);
 
     std::list<frame_info> retval;
 
-    for (const auto *frm : frames)
+    for (const auto& frm : frames)
       {
         if (frm->is_user_script_frame () || frm->is_user_fcn_frame ()
             || frm->is_scope_frame ())
@@ -677,7 +679,8 @@
   octave_map call_stack::backtrace (octave_idx_type& curr_user_frame,
                                     bool print_subfn) const
   {
-    std::list<stack_frame *> frames = backtrace_frames (curr_user_frame);
+    std::list<std::shared_ptr<stack_frame>> frames
+      = backtrace_frames (curr_user_frame);
 
     size_t nframes = frames.size ();
 
@@ -690,7 +693,7 @@
 
     octave_idx_type k = 0;
 
-    for (const auto *frm : frames)
+    for (const auto& frm : frames)
       {
         if (frm->is_user_script_frame () || frm->is_user_fcn_frame ()
             || frm->is_scope_frame ())
@@ -726,15 +729,13 @@
 
     if (m_cs.size () > 1)
       {
-        stack_frame *elt = m_cs.back ();
+        std::shared_ptr<stack_frame> elt = m_cs.back ();
 
-        stack_frame *caller = elt->static_link ();
+        std::shared_ptr<stack_frame> caller = elt->static_link ();
 
         m_curr_frame = caller->index ();
 
         m_cs.pop_back ();
-
-        delete elt;
       }
   }