diff libinterp/octave-value/ov-usr-fcn.h @ 26825:6e9034836239

allow handles to nested functions to work (bug #39257) * stack-frame.h (stack_frame::set_closure_links): New function. (usr_fcn_stack_frame::usr_fcn_stack_frame): New optional argument, ACCESS_LINK, to allow access link to be set directly when creating stack frames for handles to nested functions. * call-stack.h, call-stack.cc (call_stack::push): New argument, CLOSURE_FRAMES, in method to push user function objects on the call stack to allow call stack context for handles to nested functions to be set. * symscope.h (symbol_scope::symbol_scope_rep::is_parent, symbol_scope::is_parent): New functions. * ov-fcn-handle.h, ov-fcn-handle.cc (octave_fcn_handle::m_closure_frames, octave_fcn_handle::m_is_nested): New data members. (octave_fcn_handle::is_nested): New function. (octave_fcn_handle::~octave_fcn_handle): Delete saved closure frames. (octave_fcn_handle::octave_fcn_handle): Mark handles to nested functions as nested instead of throwing error. (octave_fcn_handle::push_closure_context, octave_fcn_handle::workspace): New functions. (Ffunctions): Handle nested functions. (octave_fcn_handle::call): Pass pointer to first element of closure_frames list to feval when executing a function. * ov-fcn.h, ov-fcn.cc (octave_function::call): New overload with pointer to closure_context stack frames as argument. Provide default implementation. * ov-usr-fcn.h, ov-usr-fcn.cc (octave_user_function::parent_function): New member variable. (octave_user_function::is_parent_function): New function. (octave_user_function::call): Primary definition is now overload that includes closure context. The other form now forwards to the new version. * pt-eval.cc (tree_evaluator::execute_user_function): New arg, CLOSURE_FRAMES. Pass them to the call stack along with the user function. Push current stack frame to any function handles returned from a nested function or the parent of a nested function. * test/nest/nst1.m, test/nest/nst2.m, test/nest/nst3.m: New files. * test/nest/nest.tst: New tests.
author John W. Eaton <jwe@octave.org>
date Sun, 03 Mar 2019 10:19:36 +0000
parents 287eba9ed14b
children 9dd1d8973877
line wrap: on
line diff
--- a/libinterp/octave-value/ov-usr-fcn.h	Sun Mar 03 07:08:52 2019 +0000
+++ b/libinterp/octave-value/ov-usr-fcn.h	Sun Mar 03 10:19:36 2019 +0000
@@ -327,6 +327,8 @@
 
   bool is_nested_function (void) const { return nested_function; }
 
+  bool is_parent_function (void) const { return m_scope.is_parent (); }
+
   void mark_as_legacy_constructor (void) { class_constructor = legacy; }
 
   bool is_legacy_constructor (const std::string& cname = "") const
@@ -361,7 +363,14 @@
 
   octave_value_list
   call (octave::tree_evaluator& tw, int nargout = 0,
-        const octave_value_list& args = octave_value_list ());
+        const octave_value_list& args = octave_value_list ())
+  {
+    return call (tw, nargout, args, nullptr);
+  }
+
+  octave_value_list
+  call (octave::tree_evaluator& tw, int nargout,
+        const octave_value_list& args, octave::stack_frame *);
 
   octave::tree_parameter_list * parameter_list (void) { return param_list; }
 
@@ -446,9 +455,12 @@
   // TRUE means this is an anonymous function.
   bool anonymous_function;
 
-  // TRUE means this is a nested function. (either a child or parent)
+  // TRUE means this is a nested function.
   bool nested_function;
 
+  // TRUE means this function contains a nested function.
+  bool parent_function;
+
   // Enum describing whether this function is the constructor for class object.
   class_method_type class_constructor;