# HG changeset patch # User John W. Eaton # Date 1612387185 18000 # Wed Feb 03 16:19:45 2021 -0500 # Branch stable # Node ID 2a45c772ce939305eec3ff41e4105e11d9b703b1 # Parent 72e75857a5c69a7ff255bbbe961359c3d31422dd track stack frame index of caller (bug #59847) * stack-frame.h, stack-frame.cc (stack_frame::m_caller_index): New data member. (stack_frame::caller_index): New function. (stack_frame::create): New argument, caller_index. Update constructors for all derived stack_frame types. * call-stack.cc (call_stack::push): Also pass index of current frame to stack_frame::create function. (call_stack::goto_caller_frame): Use caller index from stack frame corresponding to current user frame instead of performing dbup action. diff --git a/libinterp/corefcn/call-stack.cc b/libinterp/corefcn/call-stack.cc --- a/libinterp/corefcn/call-stack.cc +++ b/libinterp/corefcn/call-stack.cc @@ -385,7 +385,7 @@ namespace octave std::shared_ptr new_frame (stack_frame::create (m_evaluator, scope, new_frame_idx, - parent_link, static_link)); + m_curr_frame, parent_link, static_link)); m_cs.push_back (new_frame); @@ -403,7 +403,7 @@ namespace octave std::shared_ptr new_frame (stack_frame::create (m_evaluator, fcn, new_frame_idx, - parent_link, static_link, + m_curr_frame, parent_link, static_link, closure_frames)); m_cs.push_back (new_frame); @@ -422,7 +422,8 @@ namespace octave std::shared_ptr new_frame (stack_frame::create (m_evaluator, fcn, new_frame_idx, - parent_link, static_link, local_vars)); + m_curr_frame, parent_link, static_link, + local_vars)); m_cs.push_back (new_frame); @@ -439,7 +440,7 @@ namespace octave std::shared_ptr new_frame (stack_frame::create (m_evaluator, script, new_frame_idx, - parent_link, static_link)); + m_curr_frame, parent_link, static_link)); m_cs.push_back (new_frame); @@ -456,7 +457,7 @@ namespace octave std::shared_ptr new_frame (stack_frame::create (m_evaluator, fcn, new_frame_idx, - parent_link, static_link)); + m_curr_frame, parent_link, static_link)); m_cs.push_back (new_frame); @@ -618,11 +619,7 @@ namespace octave { size_t start = find_current_user_frame (); - // FIXME: is this supposed to be an error? - if (start == 0) - error ("already at top level"); - - m_curr_frame = dbupdown (start, -1, false); + m_curr_frame = m_cs[start]->caller_index (); } void call_stack::goto_base_frame (void) @@ -758,9 +755,9 @@ namespace octave { std::shared_ptr elt = m_cs.back (); - std::shared_ptr caller = elt->parent_link (); + std::shared_ptr parent = elt->parent_link (); - m_curr_frame = caller->index (); + m_curr_frame = parent->index (); m_cs.pop_back (); } diff --git a/libinterp/corefcn/stack-frame.cc b/libinterp/corefcn/stack-frame.cc --- a/libinterp/corefcn/stack-frame.cc +++ b/libinterp/corefcn/stack-frame.cc @@ -56,10 +56,10 @@ namespace octave compiled_fcn_stack_frame (void) = delete; compiled_fcn_stack_frame (tree_evaluator& tw, octave_function *fcn, - size_t index, + size_t index, size_t caller_index, const std::shared_ptr& parent_link, const std::shared_ptr& static_link) - : stack_frame (tw, index, parent_link, static_link, + : stack_frame (tw, index, caller_index, parent_link, static_link, static_link->access_link ()), m_fcn (fcn) { } @@ -177,7 +177,7 @@ namespace octave script_stack_frame (void) = delete; script_stack_frame (tree_evaluator& tw, octave_user_script *script, - size_t index, + size_t index, size_t caller_index, const std::shared_ptr& parent_link, const std::shared_ptr& static_link); @@ -290,11 +290,12 @@ namespace octave base_value_stack_frame (void) = delete; base_value_stack_frame (tree_evaluator& tw, size_t num_symbols, - size_t index, + size_t index, size_t caller_index, const std::shared_ptr& parent_link, const std::shared_ptr& static_link, const std::shared_ptr& access_link) - : stack_frame (tw, index, parent_link, static_link, access_link), + : stack_frame (tw, index, caller_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 ()) @@ -396,11 +397,11 @@ namespace octave user_fcn_stack_frame (void) = delete; user_fcn_stack_frame (tree_evaluator& tw, octave_user_function *fcn, - size_t index, + size_t index, size_t caller_index, const std::shared_ptr& parent_link, const std::shared_ptr& static_link, const std::shared_ptr& access_link = std::shared_ptr ()) - : base_value_stack_frame (tw, get_num_symbols (fcn), index, + : base_value_stack_frame (tw, get_num_symbols (fcn), index, caller_index, parent_link, static_link, (access_link ? access_link @@ -409,11 +410,11 @@ namespace octave { } user_fcn_stack_frame (tree_evaluator& tw, octave_user_function *fcn, - size_t index, + size_t index, size_t caller_index, const std::shared_ptr& parent_link, const std::shared_ptr& static_link, const local_vars_map& local_vars) - : base_value_stack_frame (tw, get_num_symbols (fcn), index, + : base_value_stack_frame (tw, get_num_symbols (fcn), index, caller_index, parent_link, static_link, get_access_link (fcn, static_link)), m_fcn (fcn), m_unwind_protect_frame (nullptr) @@ -502,10 +503,10 @@ namespace octave scope_stack_frame (void) = delete; scope_stack_frame (tree_evaluator& tw, const symbol_scope& scope, - size_t index, + size_t index, size_t caller_index, const std::shared_ptr& parent_link, const std::shared_ptr& static_link) - : base_value_stack_frame (tw, scope.num_symbols (), index, + : base_value_stack_frame (tw, scope.num_symbols (), index, caller_index, parent_link, static_link, nullptr), m_scope (scope) { } @@ -1032,46 +1033,49 @@ namespace octave }; stack_frame * stack_frame::create (tree_evaluator& tw, octave_function *fcn, - size_t index, + size_t index, size_t caller_index, const std::shared_ptr& parent_link, const std::shared_ptr& static_link) { - return new compiled_fcn_stack_frame (tw, fcn, index, parent_link, static_link); + return new compiled_fcn_stack_frame (tw, fcn, index, caller_index, parent_link, static_link); } stack_frame * stack_frame::create (tree_evaluator& tw, octave_user_script *script, - size_t index, + size_t index, size_t caller_index, const std::shared_ptr& parent_link, const std::shared_ptr& static_link) { - return new script_stack_frame (tw, script, index, parent_link, static_link); + return new script_stack_frame (tw, script, index, caller_index, parent_link, static_link); } stack_frame * stack_frame::create (tree_evaluator& tw, octave_user_function *fcn, size_t index, + size_t caller_index, const std::shared_ptr& parent_link, const std::shared_ptr& static_link, const std::shared_ptr& access_link) { - return new user_fcn_stack_frame (tw, fcn, index, parent_link, static_link, access_link); + return new user_fcn_stack_frame (tw, fcn, index, caller_index, parent_link, static_link, access_link); } stack_frame * stack_frame::create (tree_evaluator& tw, octave_user_function *fcn, size_t index, + size_t caller_index, const std::shared_ptr& parent_link, const std::shared_ptr& static_link, const local_vars_map& local_vars) { - return new user_fcn_stack_frame (tw, fcn, index, parent_link, static_link, local_vars); + return new user_fcn_stack_frame (tw, fcn, index, caller_index, parent_link, static_link, local_vars); } stack_frame * stack_frame::create (tree_evaluator& tw, const symbol_scope& scope, size_t index, + size_t caller_index, const std::shared_ptr& parent_link, const std::shared_ptr& static_link) { - return new scope_stack_frame (tw, scope, index, parent_link, static_link); + return new scope_stack_frame (tw, scope, index, caller_index, parent_link, static_link); } // This function is only implemented and should only be called for @@ -1425,6 +1429,7 @@ namespace octave os << "line: " << m_line << std::endl; os << "column: " << m_column << std::endl; os << "index: " << m_index << std::endl; + os << "caller_index: " << m_caller_index << std::endl; os << std::endl; @@ -1460,10 +1465,10 @@ namespace octave script_stack_frame::script_stack_frame (tree_evaluator& tw, octave_user_script *script, - size_t index, + size_t index, size_t caller_index, const std::shared_ptr& parent_link, const std::shared_ptr& static_link) - : stack_frame (tw, index, parent_link, static_link, + : stack_frame (tw, index, caller_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), diff --git a/libinterp/corefcn/stack-frame.h b/libinterp/corefcn/stack-frame.h --- a/libinterp/corefcn/stack-frame.h +++ b/libinterp/corefcn/stack-frame.h @@ -139,11 +139,12 @@ namespace octave stack_frame (void) = delete; - stack_frame (tree_evaluator& tw, size_t index, + stack_frame (tree_evaluator& tw, size_t index, size_t caller_index, const std::shared_ptr& parent_link, const std::shared_ptr& static_link, const std::shared_ptr& access_link) : m_evaluator (tw), m_line (-1), m_column (-1), m_index (index), + m_caller_index (caller_index), m_parent_link (parent_link), m_static_link (static_link), m_access_link (access_link), m_dispatch_class () { } @@ -151,18 +152,21 @@ namespace octave // Compiled function. static stack_frame * create (tree_evaluator& tw, octave_function *fcn, size_t index, + size_t caller_index, const std::shared_ptr& parent_link, const std::shared_ptr& static_link); // Script. static stack_frame * create (tree_evaluator& tw, octave_user_script *script, size_t index, + size_t caller_index, const std::shared_ptr& parent_link, const std::shared_ptr& static_link); // User-defined function. static stack_frame * create (tree_evaluator& tw, octave_user_function *fcn, size_t index, + size_t caller_index, const std::shared_ptr& parent_link, const std::shared_ptr& static_link, const std::shared_ptr& access_link = std::shared_ptr ()); @@ -170,6 +174,7 @@ namespace octave // Anonymous user-defined function with init vars. static stack_frame * create (tree_evaluator& tw, octave_user_function *fcn, size_t index, + size_t caller_index, const std::shared_ptr& parent_link, const std::shared_ptr& static_link, const local_vars_map& local_vars); @@ -177,6 +182,7 @@ namespace octave // Scope. static stack_frame * create (tree_evaluator& tw, const symbol_scope& scope, size_t index, + size_t caller_index, const std::shared_ptr& parent_link, const std::shared_ptr& static_link); @@ -199,6 +205,8 @@ namespace octave size_t index (void) const { return m_index; } + size_t caller_index (void) const { return m_caller_index; } + void line (int l) { m_line = l; } int line (void) const { return m_line; } @@ -565,6 +573,11 @@ namespace octave // Index in call stack. size_t m_index; + // Index in the call stack for the stack frame corresponding to the + // caller. Used by the evalin and assignin functions to move to the + // caller frame. + size_t m_caller_index; + // Pointer to the nearest parent frame. May include compiled // functions. std::shared_ptr m_parent_link;