# HG changeset patch # User John W. Eaton # Date 1601224151 14400 # Node ID ac5461b59b9337f7c2eca4549be77db381cdb9e0 # Parent 901a92f45ff0c8a0b4be0aacd99b2305a350e51e# Parent 7e0712b3388fb1636aa568b1d4c43f4b6494445b maint: merge stable to default. diff -r 901a92f45ff0 -r ac5461b59b93 libinterp/corefcn/call-stack.cc --- a/libinterp/corefcn/call-stack.cc Sat Sep 26 11:50:17 2020 +0200 +++ b/libinterp/corefcn/call-stack.cc Sun Sep 27 12:29:11 2020 -0400 @@ -345,117 +345,122 @@ return retval; } - std::shared_ptr - call_stack::get_static_link (size_t prev_frame) const + void call_stack::get_new_frame_index_and_links + (size_t& new_frame_idx, std::shared_ptr& parent_link, + std::shared_ptr& static_link) const { // FIXME: is there a better way? - std::shared_ptr slink; + size_t prev_frame_idx = m_curr_frame; + + new_frame_idx = m_cs.size (); - if (m_curr_frame > 0) - { - octave_function *t_fcn = m_cs[prev_frame]->function (); + // m_max_stack_depth should never be less than zero. + if (new_frame_idx > static_cast (m_max_stack_depth)) + error ("max_stack_depth exceeded"); + + // There can't be any links to previous frames if this is the first + // frame on the stack. - slink = (t_fcn - ? (t_fcn->is_user_code () - ? m_cs[prev_frame] : m_cs[prev_frame]->static_link ()) - : m_cs[prev_frame]); - } + if (new_frame_idx == 0) + return; + + parent_link = m_cs[prev_frame_idx]; - return slink; + octave_function *t_fcn = parent_link->function (); + + static_link = (t_fcn + ? (t_fcn->is_user_code () + ? parent_link : parent_link->static_link ()) + : parent_link); } void call_stack::push (const symbol_scope& scope) { - size_t prev_frame = m_curr_frame; - m_curr_frame = m_cs.size (); + size_t new_frame_idx; + std::shared_ptr parent_link; + std::shared_ptr static_link; - // m_max_stack_depth should never be less than zero. - if (m_curr_frame > static_cast (m_max_stack_depth)) - error ("max_stack_depth exceeded"); - - std::shared_ptr slink = get_static_link (prev_frame); + get_new_frame_index_and_links (new_frame_idx, parent_link, static_link); std::shared_ptr - new_frame (stack_frame::create (m_evaluator, scope, m_curr_frame, - m_cs[prev_frame], slink)); + new_frame (stack_frame::create (m_evaluator, scope, new_frame_idx, + parent_link, static_link)); m_cs.push_back (new_frame); + + m_curr_frame = new_frame_idx; } void call_stack::push (octave_user_function *fcn, const std::shared_ptr& closure_frames) { - size_t prev_frame = m_curr_frame; - m_curr_frame = m_cs.size (); + size_t new_frame_idx; + std::shared_ptr parent_link; + std::shared_ptr static_link; - // m_max_stack_depth should never be less than zero. - if (m_curr_frame > static_cast (m_max_stack_depth)) - error ("max_stack_depth exceeded"); - - std::shared_ptr slink = get_static_link (prev_frame); + get_new_frame_index_and_links (new_frame_idx, parent_link, static_link); std::shared_ptr - new_frame (stack_frame::create (m_evaluator, fcn, m_curr_frame, - m_cs[prev_frame], slink, + new_frame (stack_frame::create (m_evaluator, fcn, new_frame_idx, + parent_link, static_link, closure_frames)); m_cs.push_back (new_frame); + + m_curr_frame = new_frame_idx; } void call_stack::push (octave_user_function *fcn, const stack_frame::local_vars_map& local_vars) { - size_t prev_frame = m_curr_frame; - m_curr_frame = m_cs.size (); + size_t new_frame_idx; + std::shared_ptr parent_link; + std::shared_ptr static_link; - // m_max_stack_depth should never be less than zero. - if (m_curr_frame > static_cast (m_max_stack_depth)) - error ("max_stack_depth exceeded"); - - std::shared_ptr slink = get_static_link (prev_frame); + get_new_frame_index_and_links (new_frame_idx, parent_link, static_link); std::shared_ptr - new_frame (stack_frame::create (m_evaluator, fcn, m_curr_frame, - m_cs[prev_frame], slink, local_vars)); + new_frame (stack_frame::create (m_evaluator, fcn, new_frame_idx, + parent_link, static_link, local_vars)); m_cs.push_back (new_frame); + + m_curr_frame = new_frame_idx; } void call_stack::push (octave_user_script *script) { - size_t prev_frame = m_curr_frame; - m_curr_frame = m_cs.size (); + size_t new_frame_idx; + std::shared_ptr parent_link; + std::shared_ptr static_link; - // m_max_stack_depth should never be less than zero. - if (m_curr_frame > static_cast (m_max_stack_depth)) - error ("max_stack_depth exceeded"); - - std::shared_ptr slink = get_static_link (prev_frame); + get_new_frame_index_and_links (new_frame_idx, parent_link, static_link); std::shared_ptr - new_frame (stack_frame::create (m_evaluator, script, m_curr_frame, - m_cs[prev_frame], slink)); + new_frame (stack_frame::create (m_evaluator, script, new_frame_idx, + parent_link, static_link)); m_cs.push_back (new_frame); + + m_curr_frame = new_frame_idx; } void call_stack::push (octave_function *fcn) { - size_t prev_frame = m_curr_frame; - m_curr_frame = m_cs.size (); + size_t new_frame_idx; + std::shared_ptr parent_link; + std::shared_ptr static_link; - // m_max_stack_depth should never be less than zero. - if (m_curr_frame > static_cast (m_max_stack_depth)) - error ("max_stack_depth exceeded"); - - std::shared_ptr slink = get_static_link (prev_frame); + get_new_frame_index_and_links (new_frame_idx, parent_link, static_link); std::shared_ptr - new_frame (stack_frame::create (m_evaluator, fcn, m_curr_frame, - m_cs[prev_frame], slink)); + new_frame (stack_frame::create (m_evaluator, fcn, new_frame_idx, + parent_link, static_link)); m_cs.push_back (new_frame); + + m_curr_frame = new_frame_idx; } bool call_stack::goto_frame (size_t n, bool verbose) diff -r 901a92f45ff0 -r ac5461b59b93 libinterp/corefcn/call-stack.h --- a/libinterp/corefcn/call-stack.h Sat Sep 26 11:50:17 2020 +0200 +++ b/libinterp/corefcn/call-stack.h Sun Sep 27 12:29:11 2020 -0400 @@ -153,8 +153,6 @@ // Return TRUE if all elements on the call stack are scripts. bool all_scripts (void) const; - std::shared_ptr get_static_link (size_t prev_frame) const; - void push (const symbol_scope& scope); void push (octave_user_function *fcn, @@ -306,6 +304,10 @@ private: + void get_new_frame_index_and_links + (size_t& new_frame_idx, std::shared_ptr& parent_link, + std::shared_ptr& static_link) const; + tree_evaluator& m_evaluator; // The list of stack frames.