Mercurial > octave
changeset 28429:8eb8ba8aff9a stable
refactor octave_function call method
This change is a step toward keeping stack frames for closures
(handles to nested functions) separate from the functions themselves.
* call-stack.h, call-stack.cc
(call_stack::curr_fcn_unwind_protect_frame: No longer const.
Update all uses.
(call_stack::push): Dliminate unwind protect frame argument. Change
all uses.
* stack-frame.h, stack-frame.cc (script_stack_frame,
user_fcn_stack_frame): Create uniwnd_protect_frame only if needed.
* ov-builtin.h, ov-builtin.cc (octave_builtin::execute):
New function that executes function without pushing stack frame.
(octave_builtin::call): Delete.
* ov-class.h, ov-class.cc (octave_inline_fcn::execute):
New function.
(octave_inline_fcn::call): Call execute.
* ov-classdef.h, ov-classdef.cc (octave_classdef_meta::execute):
New function.
(octave_classdef_meta::call): Call execute.
(octave_classdef_superclass_ref::execute): New function.
(octave_classdef_superclass_ref::call): Call execute.
* ov-fcn-handle.cc (octave_fcn_handle::call): When calling a function
that has closure_frames, push stack frame here instead of inside
octave_user_function object.
* ov-fcn.h (octave_function::execute): New pure virtual function.
* ov-fcn.h, ov-fcn.cc (octave_function::call): Define only one
variant, without closure frames as an argument. Default version
simply pushes stack frame and calls execute.
* ov-mex-fcn.h, ov-mex-fcn.cc (octave_mex_function::execute):
Rename from call. Don't push stack frame here.
* ov-usr-fcn.h, ov-usr-fcn.cc (octave_user_script::call,
octave_user_function::call): Push stack frame and call execute.
(octave_user_script::execute, octave_user_function::execute):
New function.
* pt-eval.h, pt-eval.cc (tree_evaluator::push_stack_frame): Eliminate
unwind protect frame argument. Change all uses.
(tree_evaluator::execute_user_script): Update.
(tree_evaluator::execute_user_function): Update. Don't push stack
frame here.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Mon, 30 Mar 2020 10:43:47 -0400 |
parents | e9a12be5fd79 |
children | 5bfa8e018704 |
files | libinterp/corefcn/call-stack.cc libinterp/corefcn/call-stack.h libinterp/corefcn/stack-frame.cc libinterp/corefcn/stack-frame.h libinterp/octave-value/ov-builtin.cc libinterp/octave-value/ov-builtin.h libinterp/octave-value/ov-class.cc libinterp/octave-value/ov-classdef.cc libinterp/octave-value/ov-classdef.h libinterp/octave-value/ov-fcn-handle.cc libinterp/octave-value/ov-fcn.cc libinterp/octave-value/ov-fcn.h libinterp/octave-value/ov-mex-fcn.cc libinterp/octave-value/ov-mex-fcn.h libinterp/octave-value/ov-usr-fcn.cc libinterp/octave-value/ov-usr-fcn.h libinterp/parse-tree/pt-eval.cc libinterp/parse-tree/pt-eval.h |
diffstat | 18 files changed, 207 insertions(+), 180 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/call-stack.cc Mon Mar 23 15:44:30 2020 -0400 +++ b/libinterp/corefcn/call-stack.cc Mon Mar 30 10:43:47 2020 -0400 @@ -181,7 +181,7 @@ return -1; } - unwind_protect * call_stack::curr_fcn_unwind_protect_frame (void) const + unwind_protect * call_stack::curr_fcn_unwind_protect_frame (void) { // Start at current frame. @@ -382,7 +382,7 @@ m_cs.push_back (new_frame); } - void call_stack::push (octave_user_function *fcn, unwind_protect *up_frame, + void call_stack::push (octave_user_function *fcn, const std::shared_ptr<stack_frame>& closure_frames) { size_t prev_frame = m_curr_frame; @@ -395,13 +395,13 @@ std::shared_ptr<stack_frame> slink = get_static_link (prev_frame); std::shared_ptr<stack_frame> - new_frame (stack_frame::create (m_evaluator, fcn, up_frame, m_curr_frame, - slink, closure_frames)); + new_frame (stack_frame::create (m_evaluator, fcn, m_curr_frame, slink, + closure_frames)); m_cs.push_back (new_frame); } - void call_stack::push (octave_user_script *script, unwind_protect *up_frame) + void call_stack::push (octave_user_script *script) { size_t prev_frame = m_curr_frame; m_curr_frame = m_cs.size (); @@ -413,8 +413,8 @@ std::shared_ptr<stack_frame> slink = get_static_link (prev_frame); std::shared_ptr<stack_frame> - new_frame (stack_frame::create (m_evaluator, script, up_frame, - m_curr_frame, slink)); + new_frame (stack_frame::create (m_evaluator, script, m_curr_frame, + slink)); m_cs.push_back (new_frame); }
--- a/libinterp/corefcn/call-stack.h Mon Mar 23 15:44:30 2020 -0400 +++ b/libinterp/corefcn/call-stack.h Mon Mar 30 10:43:47 2020 -0400 @@ -125,7 +125,7 @@ // User code caller. octave_user_code * current_user_code (void) const; - unwind_protect * curr_fcn_unwind_protect_frame (void) const; + unwind_protect * curr_fcn_unwind_protect_frame (void); // Line in user code caller. int current_user_code_line (void) const; @@ -157,10 +157,10 @@ void push (const symbol_scope& scope); - void push (octave_user_function *fcn, unwind_protect *up_frame, + void push (octave_user_function *fcn, const std::shared_ptr<stack_frame>& closure_frames = std::shared_ptr<stack_frame> ()); - void push (octave_user_script *script, unwind_protect *up_frame); + void push (octave_user_script *script); void push (octave_function *fcn);
--- a/libinterp/corefcn/stack-frame.cc Mon Mar 23 15:44:30 2020 -0400 +++ b/libinterp/corefcn/stack-frame.cc Mon Mar 30 10:43:47 2020 -0400 @@ -177,14 +177,17 @@ script_stack_frame (void) = delete; script_stack_frame (tree_evaluator& tw, octave_user_script *script, - unwind_protect *up_frame, size_t index, + size_t index, const std::shared_ptr<stack_frame>& static_link); script_stack_frame (const script_stack_frame& elt) = default; script_stack_frame& operator = (const script_stack_frame& elt) = delete; - ~script_stack_frame (void) = default; + ~script_stack_frame (void) + { + delete m_unwind_protect_frame; + } script_stack_frame * dup (void) const; @@ -206,8 +209,7 @@ octave_function * function (void) const { return m_script; } - unwind_protect * - unwind_protect_frame (void) const { return m_unwind_protect_frame; } + unwind_protect * unwind_protect_frame (void); symbol_record lookup_symbol (const std::string& name) const; @@ -394,14 +396,14 @@ user_fcn_stack_frame (void) = delete; user_fcn_stack_frame (tree_evaluator& tw, octave_user_function *fcn, - unwind_protect *up_frame, size_t index, + size_t index, 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, (access_link ? access_link : get_access_link (fcn, static_link))), - m_fcn (fcn), m_unwind_protect_frame (up_frame) + m_fcn (fcn), m_unwind_protect_frame (nullptr) { } user_fcn_stack_frame (const user_fcn_stack_frame& elt) = default; @@ -409,7 +411,10 @@ user_fcn_stack_frame& operator = (const user_fcn_stack_frame& elt) = delete; - ~user_fcn_stack_frame (void) = default; + ~user_fcn_stack_frame (void) + { + delete m_unwind_protect_frame; + } user_fcn_stack_frame * dup (void) const; @@ -432,8 +437,7 @@ octave_function * function (void) const { return m_fcn; } - unwind_protect * - unwind_protect_frame (void) const { return m_unwind_protect_frame; } + unwind_protect * unwind_protect_frame (void); symbol_record lookup_symbol (const std::string& name) const; @@ -1021,20 +1025,18 @@ stack_frame * stack_frame::create (tree_evaluator& tw, octave_user_script *script, - unwind_protect *up_frame, size_t index, + size_t index, const std::shared_ptr<stack_frame>& static_link) { - return new script_stack_frame (tw, script, up_frame, index, static_link); + return new script_stack_frame (tw, script, index, static_link); } stack_frame * stack_frame::create (tree_evaluator& tw, - octave_user_function *fcn, - unwind_protect *up_frame, size_t index, + octave_user_function *fcn, size_t index, const std::shared_ptr<stack_frame>& static_link, const std::shared_ptr<stack_frame>& access_link) { - return new user_fcn_stack_frame (tw, fcn, up_frame, index, static_link, - access_link); + return new user_fcn_stack_frame (tw, fcn, index, static_link, access_link); } stack_frame * stack_frame::create (tree_evaluator& tw, @@ -1430,11 +1432,10 @@ script_stack_frame::script_stack_frame (tree_evaluator& tw, octave_user_script *script, - unwind_protect *up_frame, size_t index, const std::shared_ptr<stack_frame>& static_link) : stack_frame (tw, index, static_link, get_access_link (static_link)), - m_script (script), m_unwind_protect_frame (up_frame), + 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) { @@ -1602,6 +1603,14 @@ return alink; } + unwind_protect * script_stack_frame::unwind_protect_frame (void) + { + if (! m_unwind_protect_frame) + m_unwind_protect_frame = new unwind_protect (); + + return m_unwind_protect_frame; + } + symbol_record script_stack_frame::lookup_symbol (const std::string& name) const { symbol_scope scope = get_scope (); @@ -2118,6 +2127,14 @@ } } + unwind_protect * user_fcn_stack_frame::unwind_protect_frame (void) + { + if (! m_unwind_protect_frame) + m_unwind_protect_frame = new unwind_protect (); + + return m_unwind_protect_frame; + } + symbol_record user_fcn_stack_frame::lookup_symbol (const std::string& name) const { const stack_frame *frame = this;
--- a/libinterp/corefcn/stack-frame.h Mon Mar 23 15:44:30 2020 -0400 +++ b/libinterp/corefcn/stack-frame.h Mon Mar 30 10:43:47 2020 -0400 @@ -154,14 +154,12 @@ // Script. static stack_frame * - create (tree_evaluator& tw, octave_user_script *script, - unwind_protect *up_frame, size_t index, + create (tree_evaluator& tw, octave_user_script *script, size_t index, const std::shared_ptr<stack_frame>& static_link); // User-defined function. static stack_frame * - create (tree_evaluator& tw, octave_user_function *fcn, - unwind_protect *up_frame, size_t index, + create (tree_evaluator& tw, octave_user_function *fcn, size_t index, const std::shared_ptr<stack_frame>& static_link, const std::shared_ptr<stack_frame>& access_link = std::shared_ptr<stack_frame> ()); @@ -232,8 +230,7 @@ virtual octave_function * function (void) const { return nullptr; } - virtual unwind_protect * - unwind_protect_frame (void) const { return nullptr; } + virtual unwind_protect * unwind_protect_frame (void) { return nullptr; } symbol_info_list make_symbol_info_list (const std::list<symbol_record>& symrec_list) const;
--- a/libinterp/octave-value/ov-builtin.cc Mon Mar 23 15:44:30 2020 -0400 +++ b/libinterp/octave-value/ov-builtin.cc Mon Mar 30 10:43:47 2020 -0400 @@ -43,20 +43,14 @@ "built-in function"); octave_value_list -octave_builtin::call (octave::tree_evaluator& tw, int nargout, - const octave_value_list& args) +octave_builtin::execute (octave::tree_evaluator& tw, int nargout, + const octave_value_list& args) { octave_value_list retval; if (args.has_magic_colon ()) error ("invalid use of colon in function argument list"); - octave::unwind_protect frame; - - tw.push_stack_frame (this); - - frame.add_method (tw, &octave::tree_evaluator::pop_stack_frame); - octave::profiler& profiler = tw.get_profiler (); octave::profiler::enter<octave_builtin> block (profiler, *this);
--- a/libinterp/octave-value/ov-builtin.h Mon Mar 23 15:44:30 2020 -0400 +++ b/libinterp/octave-value/ov-builtin.h Mon Mar 30 10:43:47 2020 -0400 @@ -96,14 +96,9 @@ bool is_builtin_function (void) const { return true; } - // We don't need to override both forms of the call method. The using - // declaration will avoid warnings about partially-overloaded virtual - // functions. - using octave_function::call; - octave_value_list - call (octave::tree_evaluator& tw, int nargout = 0, - const octave_value_list& args = octave_value_list ()); + execute (octave::tree_evaluator& tw, int nargout = 0, + const octave_value_list& args = octave_value_list ()); octave::jit_type * to_jit (void) const;
--- a/libinterp/octave-value/ov-class.cc Mon Mar 23 15:44:30 2020 -0400 +++ b/libinterp/octave-value/ov-class.cc Mon Mar 30 10:43:47 2020 -0400 @@ -2065,14 +2065,19 @@ ~octave_inline_fcn (void) = default; - // We don't need to override both forms of the call method. The using - // declaration will avoid warnings about partially-overloaded virtual - // functions. - using octave_function::call; + // Override default call method because we ultimately use feval to + // execute the inline function and that will push a stack frame. 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 execute (tw, nargout, args); + } + + octave_value_list + execute (octave::tree_evaluator& tw, int nargout = 0, + const octave_value_list& args = octave_value_list ()); private: @@ -2121,8 +2126,8 @@ }; octave_value_list -octave_inline_fcn::call (octave::tree_evaluator& tw, int nargout, - const octave_value_list& args) +octave_inline_fcn::execute (octave::tree_evaluator& tw, int nargout, + const octave_value_list& args) { octave::interpreter& interp = tw.get_interpreter ();
--- a/libinterp/octave-value/ov-classdef.cc Mon Mar 23 15:44:30 2020 -0400 +++ b/libinterp/octave-value/ov-classdef.cc Mon Mar 30 10:43:47 2020 -0400 @@ -410,8 +410,9 @@ } octave_value_list -octave_classdef_superclass_ref::call (octave::tree_evaluator& tw, - int nargout, const octave_value_list& idx) +octave_classdef_superclass_ref::execute (octave::tree_evaluator& tw, + int nargout, + const octave_value_list& idx) { octave_value_list retval;
--- a/libinterp/octave-value/ov-classdef.h Mon Mar 23 15:44:30 2020 -0400 +++ b/libinterp/octave-value/ov-classdef.h Mon Mar 30 10:43:47 2020 -0400 @@ -195,14 +195,18 @@ return object.meta_subsref (type, idx, nargout); } - // We don't need to override both forms of the call method. The using - // declaration will avoid warnings about partially-overloaded virtual - // functions. - using octave_function::call; + // Override default call method because we don't push a new stack + // frame for this operation on classdef_meta objects. - octave_value_list call (octave::tree_evaluator&, int nargout, + octave_value_list call (octave::tree_evaluator& tw, int nargout, const octave_value_list& args) { + return execute (tw, nargout, args); + } + + octave_value_list execute (octave::tree_evaluator&, int nargout, + const octave_value_list& args) + { // Emulate ()-type meta subsref std::list<octave_value_list> idx (1, args); @@ -241,13 +245,17 @@ octave_function * function_value (bool = false) { return this; } - // We don't need to override both forms of the call method. The using - // declaration will avoid warnings about partially-overloaded virtual - // functions. - using octave_function::call; + // Override default call method because we don't push a new stack + // frame for this operation on classdef_superclass_ref objects. - octave_value_list - call (octave::tree_evaluator& tw, int nargout, const octave_value_list& idx); + octave_value_list call (octave::tree_evaluator& tw, int nargout, + const octave_value_list& args) + { + return execute (tw, nargout, args); + } + + octave_value_list execute (octave::tree_evaluator& tw, int nargout, + const octave_value_list& idx); private:
--- a/libinterp/octave-value/ov-fcn-handle.cc Mon Mar 23 15:44:30 2020 -0400 +++ b/libinterp/octave-value/ov-fcn-handle.cc Mon Mar 30 10:43:47 2020 -0400 @@ -360,16 +360,33 @@ octave::tree_evaluator& tw = interp.get_evaluator (); - octave_function *of = fcn_to_call.function_value (); - - octave::unwind_protect frame; - - frame.add_method (tw, &octave::tree_evaluator::set_dispatch_class, - std::string ()); + octave::unwind_action act2 ([&tw] () { tw.set_dispatch_class (""); }); tw.set_dispatch_class (m_dispatch_class); - return of->call (tw, nargout, args, m_closure_frames); + if (m_closure_frames) + { + if (! fcn_to_call.is_user_function ()) + { + std::string tname = fcn_to_call.type_name (); + error ("internal error: closure frames associated with '%s' object", + tname.c_str ()); + } + + octave_user_function *oct_usr_fcn = fcn_to_call.user_function_value (); + + tw.push_stack_frame (oct_usr_fcn, m_closure_frames); + + octave::unwind_action act1 ([&tw] () { tw.pop_stack_frame (); }); + + return oct_usr_fcn->execute (tw, nargout, args); + } + else + { + octave_function *oct_fcn = fcn_to_call.function_value (); + + return oct_fcn->call (tw, nargout, args); + } } dim_vector
--- a/libinterp/octave-value/ov-fcn.cc Mon Mar 23 15:44:30 2020 -0400 +++ b/libinterp/octave-value/ov-fcn.cc Mon Mar 30 10:43:47 2020 -0400 @@ -27,10 +27,12 @@ # include "config.h" #endif +#include "unwind-prot.h" + #include "error.h" #include "ovl.h" #include "ov-fcn.h" - +#include "pt-eval.h" octave_base_value * octave_function::clone (void) const @@ -46,11 +48,11 @@ octave_value_list octave_function::call (octave::tree_evaluator& tw, int nargout, - const octave_value_list& args, - const std::shared_ptr<octave::stack_frame>& closure_context) + const octave_value_list& args) { - if (closure_context) - panic_impossible (); + tw.push_stack_frame (this); - return call (tw, nargout, args); + octave::unwind_action act ([&tw] () { tw.pop_stack_frame (); }); + + return execute (tw, nargout, args); }
--- a/libinterp/octave-value/ov-fcn.h Mon Mar 23 15:44:30 2020 -0400 +++ b/libinterp/octave-value/ov-fcn.h Mon Mar 30 10:43:47 2020 -0400 @@ -223,14 +223,16 @@ virtual bool accepts_postfix_index (char type) const { return (type == '('); } + // Push new stack frame (if necessary) and execute function. virtual octave_value_list call (octave::tree_evaluator& tw, int nargout = 0, - const octave_value_list& args = octave_value_list ()) = 0; + const octave_value_list& args = octave_value_list ()); + // Execute function without pushing new stack frame (assumes that has + // already been done). virtual octave_value_list - call (octave::tree_evaluator& tw, int nargout, - const octave_value_list& args, - const std::shared_ptr<octave::stack_frame>& closure_context); + execute (octave::tree_evaluator& tw, int nargout = 0, + const octave_value_list& args = octave_value_list ()) = 0; protected:
--- a/libinterp/octave-value/ov-mex-fcn.cc Mon Mar 23 15:44:30 2020 -0400 +++ b/libinterp/octave-value/ov-mex-fcn.cc Mon Mar 30 10:43:47 2020 -0400 @@ -90,20 +90,14 @@ int nargout); octave_value_list -octave_mex_function::call (octave::tree_evaluator& tw, int nargout, - const octave_value_list& args) +octave_mex_function::execute (octave::tree_evaluator& tw, int nargout, + const octave_value_list& args) { octave_value_list retval; if (args.has_magic_colon ()) error ("invalid use of colon in function argument list"); - octave::unwind_protect frame; - - tw.push_stack_frame (this); - - frame.add_method (tw, &octave::tree_evaluator::pop_stack_frame); - octave::profiler& profiler = tw.get_profiler (); octave::profiler::enter<octave_mex_function> block (profiler, *this);
--- a/libinterp/octave-value/ov-mex-fcn.h Mon Mar 23 15:44:30 2020 -0400 +++ b/libinterp/octave-value/ov-mex-fcn.h Mon Mar 30 10:43:47 2020 -0400 @@ -88,14 +88,9 @@ bool is_mex_function (void) const { return true; } - // We don't need to override both forms of the call method. The using - // declaration will avoid warnings about partially-overloaded virtual - // functions. - using octave_function::call; - octave_value_list - call (octave::tree_evaluator& tw, int nargout = 0, - const octave_value_list& args = octave_value_list ()); + execute (octave::tree_evaluator& tw, int nargout = 0, + const octave_value_list& args = octave_value_list ()); void atexit (void (*fcn) (void)) { m_exit_fcn_ptr = fcn; }
--- a/libinterp/octave-value/ov-usr-fcn.cc Mon Mar 23 15:44:30 2020 -0400 +++ b/libinterp/octave-value/ov-usr-fcn.cc Mon Mar 30 10:43:47 2020 -0400 @@ -173,10 +173,26 @@ : octave_user_code (fnm, nm, scope, nullptr, ds) { } +// We must overload the call method so that we call the proper +// push_stack_frame method, which is overloaded for pointers to +// octave_function, octave_user_function, and octave_user_script +// objects. + octave_value_list octave_user_script::call (octave::tree_evaluator& tw, int nargout, const octave_value_list& args) { + tw.push_stack_frame (this); + + octave::unwind_action act ([&tw] () { tw.pop_stack_frame (); }); + + return execute (tw, nargout, args); +} + +octave_value_list +octave_user_script::execute (octave::tree_evaluator& tw, int nargout, + const octave_value_list& args) +{ return tw.execute_user_script (*this, nargout, args); } @@ -459,12 +475,27 @@ return retval; } +// We must overload the call method so that we call the proper +// push_stack_frame method, which is overloaded for pointers to +// octave_function, octave_user_function, and octave_user_script +// objects. + octave_value_list octave_user_function::call (octave::tree_evaluator& tw, int nargout, - const octave_value_list& args, - const std::shared_ptr<octave::stack_frame>& closure_frames) + const octave_value_list& args) { - return tw.execute_user_function (*this, nargout, args, closure_frames); + tw.push_stack_frame (this); + + octave::unwind_action act ([&tw] () { tw.pop_stack_frame (); }); + + return execute (tw, nargout, args); +} + +octave_value_list +octave_user_function::execute (octave::tree_evaluator& tw, int nargout, + const octave_value_list& args) +{ + return tw.execute_user_function (*this, nargout, args); } void
--- a/libinterp/octave-value/ov-usr-fcn.h Mon Mar 23 15:44:30 2020 -0400 +++ b/libinterp/octave-value/ov-usr-fcn.h Mon Mar 30 10:43:47 2020 -0400 @@ -186,15 +186,19 @@ bool is_user_script (void) const { return true; } - // We don't need to override both forms of the call method. The using - // declaration will avoid warnings about partially-overloaded virtual - // functions. - using octave_user_code::call; + // We must overload the call method so that we call the proper + // push_stack_frame method, which is overloaded for pointers to + // octave_function, octave_user_function, and octave_user_script + // objects. octave_value_list call (octave::tree_evaluator& tw, int nargout = 0, const octave_value_list& args = octave_value_list ()); + octave_value_list + execute (octave::tree_evaluator& tw, int nargout = 0, + const octave_value_list& args = octave_value_list ()); + void accept (octave::tree_walker& tw); private: @@ -372,17 +376,18 @@ ? (cname.empty () ? true : cname == dispatch_class ()) : false); } + // We must overload the call method so that we call the proper + // push_stack_frame method, which is overloaded for pointers to + // octave_function, octave_user_function, and octave_user_script + // objects. + octave_value_list call (octave::tree_evaluator& tw, int nargout = 0, - const octave_value_list& args = octave_value_list ()) - { - return call (tw, nargout, args, nullptr); - } + const octave_value_list& args = octave_value_list ()); octave_value_list - call (octave::tree_evaluator& tw, int nargout, - const octave_value_list& args, - const std::shared_ptr<octave::stack_frame>&); + execute (octave::tree_evaluator& tw, int nargout = 0, + const octave_value_list& args = octave_value_list ()); octave::tree_parameter_list * parameter_list (void) { return param_list; }
--- a/libinterp/parse-tree/pt-eval.cc Mon Mar 23 15:44:30 2020 -0400 +++ b/libinterp/parse-tree/pt-eval.cc Mon Mar 30 10:43:47 2020 -0400 @@ -1529,16 +1529,14 @@ } void tree_evaluator::push_stack_frame (octave_user_function *fcn, - unwind_protect *up_frame, const std::shared_ptr<stack_frame>& closure_frames) { - m_call_stack.push (fcn, up_frame, closure_frames); + m_call_stack.push (fcn, closure_frames); } - void tree_evaluator::push_stack_frame (octave_user_script *script, - unwind_protect *up_frame) + void tree_evaluator::push_stack_frame (octave_user_script *script) { - m_call_stack.push (script, up_frame); + m_call_stack.push (script); } void tree_evaluator::push_stack_frame (octave_function *fcn) @@ -1583,7 +1581,7 @@ return m_call_stack.current_user_code (); } - unwind_protect * tree_evaluator::curr_fcn_unwind_protect_frame (void) const + unwind_protect * tree_evaluator::curr_fcn_unwind_protect_frame (void) { return m_call_stack.curr_fcn_unwind_protect_frame (); } @@ -2330,26 +2328,15 @@ if (! cmd_list) return retval; - unwind_protect frame; - if (m_call_stack.size () >= static_cast<size_t> (m_max_recursion_depth)) error ("max_recursion_depth exceeded"); - m_call_stack.push (&user_script, &frame); - - // Set pointer to the current unwind_protect frame to allow - // certain builtins register simple cleanup in a very optimized manner. - // This is *not* intended as a general-purpose on-cleanup mechanism, - - frame.add_method (m_call_stack, &call_stack::pop); - - frame.protect_var (m_statement_context); - m_statement_context = SC_SCRIPT; + unwind_protect_var<stmt_list_type> upv (m_statement_context, SC_SCRIPT); profiler::enter<octave_user_script> block (m_profiler, user_script); if (echo ()) - push_echo_state (frame, tree_evaluator::ECHO_SCRIPTS, file_name); + push_echo_state (tree_evaluator::ECHO_SCRIPTS, file_name); cmd_list->accept (*this); @@ -2372,8 +2359,7 @@ octave_value_list tree_evaluator::execute_user_function (octave_user_function& user_function, int nargout, - const octave_value_list& xargs, - const std::shared_ptr<stack_frame>& closure_frames) + const octave_value_list& xargs) { octave_value_list retval; @@ -2405,18 +2391,9 @@ return retval; #endif - unwind_protect frame; - if (m_call_stack.size () >= static_cast<size_t> (m_max_recursion_depth)) error ("max_recursion_depth exceeded"); - // Save old and set current symbol table context, for - // eval_undefined_error(). - - m_call_stack.push (&user_function, &frame, closure_frames); - - frame.add_method (m_call_stack, &call_stack::pop); - bind_auto_fcn_vars (xargs.name_tags (), args.length (), nargout, user_function.takes_varargs (), user_function.all_va_args (args)); @@ -2443,37 +2420,23 @@ define_parameter_list_from_arg_vector (ret_list, ret_args); } - // Force parameter list to be undefined when this function exits. - // Doing so decrements the reference counts on the values of local - // variables that are also named function parameters. - - // if (param_list) - // frame.add_method (this, &tree_evaluator::undefine_parameter_list, - // param_list); - - // Force return list to be undefined when this function exits. - // Doing so decrements the reference counts on the values of local - // variables that are also named values returned by this function. - - // if (ret_list) - // frame.add_method (this, &tree_evaluator::undefine_parameter_list, - // ret_list); - - frame.add_method (&user_function, - &octave_user_function::restore_warning_states); + unwind_action act2 ([&user_function] () { + user_function.restore_warning_states (); + }); // Evaluate the commands that make up the function. - frame.protect_var (m_statement_context); - m_statement_context = SC_FUNCTION; - - frame.add_method (m_call_stack, &call_stack::clear_current_frame_values); + unwind_protect_var<stmt_list_type> upv (m_statement_context, SC_FUNCTION); + + unwind_action act1 ([this] () { + m_call_stack.clear_current_frame_values (); + }); { profiler::enter<octave_user_function> block (m_profiler, user_function); if (echo ()) - push_echo_state (frame, tree_evaluator::ECHO_FUNCTIONS, + push_echo_state (tree_evaluator::ECHO_FUNCTIONS, user_function.fcn_file_name ()); if (user_function.is_special_expr ()) @@ -3552,13 +3515,17 @@ } void - tree_evaluator::push_echo_state (unwind_protect& frame, int type, - const std::string& file_name, + tree_evaluator::push_echo_state (int type, const std::string& file_name, size_t pos) { - push_echo_state_cleanup (frame); - - set_echo_state (type, file_name, pos); + unwind_protect *frame = m_call_stack.curr_fcn_unwind_protect_frame (); + + if (frame) + { + push_echo_state_cleanup (*frame); + + set_echo_state (type, file_name, pos); + } } void
--- a/libinterp/parse-tree/pt-eval.h Mon Mar 23 15:44:30 2020 -0400 +++ b/libinterp/parse-tree/pt-eval.h Mon Mar 30 10:43:47 2020 -0400 @@ -211,8 +211,7 @@ octave_value_list execute_user_function (octave_user_function& user_function, - int nargout, const octave_value_list& args, - const std::shared_ptr<stack_frame>& closure_frames = std::shared_ptr<stack_frame> ()); + int nargout, const octave_value_list& args); void visit_octave_user_function_header (octave_user_function&); @@ -377,11 +376,9 @@ void push_stack_frame (const symbol_scope& scope); void push_stack_frame (octave_user_function *fcn, - unwind_protect *up_frame, const std::shared_ptr<stack_frame>& closure_frames = std::shared_ptr<stack_frame> ()); - void push_stack_frame (octave_user_script *script, - unwind_protect *up_frame); + void push_stack_frame (octave_user_script *script); void push_stack_frame (octave_function *fcn); @@ -413,7 +410,7 @@ octave_user_code * current_user_code (void) const; - unwind_protect * curr_fcn_unwind_protect_frame (void) const; + unwind_protect * curr_fcn_unwind_protect_frame (void); // Current function that we are debugging. octave_user_code * debug_user_code (void) const; @@ -706,8 +703,8 @@ std::list<octave_lvalue> make_lvalue_list (tree_argument_list *); - void push_echo_state (unwind_protect& frame, int type, - const std::string& file_name, size_t pos = 1); + void push_echo_state (int type, const std::string& file_name, + size_t pos = 1); private: