diff libinterp/corefcn/stack-frame.cc @ 29477:34d06c73b48d stable

hold references to closure frames in anon functions if needed (bug #60237) If an anonymous function is created in a scope where there are nested functions it may need to have access to the stack frames that are active when the anonymous function is created (the same as for handles to nested functions) in addition to any captured variables from the immediate stack frame. Similar to the previous change for breaking circular reference cycles for handles to nested functions, we now perform a similar action for anonymous function handles. * ov-fcn-handle.h, ov-fcn-handle.cc (base_anonymous_fcn_handle): New base class for anonymous functions. (anonymous_fcn_handle, weak_anonymous_handle): New classes to represent anonymous function handles. Currently all handles to anonymous functions begin as anonymous_fcn_handle objects but are convert to weak_anonymous_handle objects when the functions where they are created return. * pt-fcn-handle.cc (tree_anon_fcn_handle::evaluate): If handle is created in context containing nested functions, pass current stack frame context to function handle object. * call-stack.h, call-stack.cc (call_stack::push): In overload for anonymous functions that includes local_vars as an argument, also accept closure frames. * pt-eval.h, pt-eval.cc (tree_evaluator::push_stack_frame): Likewise. * stack-frame.h, stack-frame.cc (stack_frame::user_fcn_stack_frame): In constructor for anonymous functions that includes local_vars as an argument, also accept closure frames (access_link) and handle it the same way as for frames created for calls to nested fucntions. * ov.cc (octave_value::break_closure_cycles): Also check for anonymous function handles. * test/bug-60237/bug-60237.tst, test/bug-60237/bug_60237.m, test/bug-60237/module.mk: New files for test. * test/module.mk: Update.
author John W. Eaton <jwe@octave.org>
date Tue, 30 Mar 2021 01:08:00 -0400
parents c74ff452e2bb
children e88444be8468 d13d090cb03a
line wrap: on
line diff
--- a/libinterp/corefcn/stack-frame.cc	Fri Mar 05 16:14:34 2021 -0500
+++ b/libinterp/corefcn/stack-frame.cc	Tue Mar 30 01:08:00 2021 -0400
@@ -412,10 +412,13 @@
                           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)
+                          const local_vars_map& local_vars,
+                          const std::shared_ptr<stack_frame>& access_link = std::shared_ptr<stack_frame> ())
       : base_value_stack_frame (tw, get_num_symbols (fcn), index,
                                 parent_link, static_link,
-                                get_access_link (fcn, static_link)),
+                                (access_link
+                                 ? access_link
+                                 : get_access_link (fcn, static_link))),
         m_fcn (fcn), m_unwind_protect_frame (nullptr)
     {
       // Initialize local variable values.
@@ -1063,9 +1066,10 @@
                                      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)
+                                     const local_vars_map& local_vars,
+                                     const std::shared_ptr<stack_frame>& access_link)
   {
-    return new user_fcn_stack_frame (tw, fcn, index, parent_link, static_link, local_vars);
+    return new user_fcn_stack_frame (tw, fcn, index, parent_link, static_link, local_vars, access_link);
   }
 
   stack_frame * stack_frame::create (tree_evaluator& tw,