Mercurial > octave
diff libinterp/corefcn/stack-frame.cc @ 28426:9a3deb17b4ea stable
use shared_ptr for stack frames in call stack and for accesss and static links
* call-stack.h, call-stack.cc: Use std::shared_ptr<stack_frame>
instead of bare pointer for elements of call stack. Change all uses.
* stack-frame.h, stack-frame.cc (stack_frame::static_link,
stack_frame::access_link): Use std::shared_ptr<stack_frame>
instead of bare pointer. Change all uses.
(stack_frame::workspace): New function.
* ov-fcn-handle.h, ov-fcn-handle.cc
(octave_fcn_handle::m_closure_frames): Now a
std::shared_ptr<stack_frame> object instead of a list of copied stack
frames. Change all uses.
(octave_fcn_handle::push_closure_context): Simply store
std::shared_ptr to current stack frame.
(octave_fcn_handle::workspace): Call stack_frame::workspace to get
workspace info when we have closure frames.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Sat, 25 Apr 2020 13:17:11 -0400 |
parents | a5be4fc661d6 |
children | 8eb8ba8aff9a |
line wrap: on
line diff
--- a/libinterp/corefcn/stack-frame.cc Fri Apr 24 14:21:07 2020 -0400 +++ b/libinterp/corefcn/stack-frame.cc Sat Apr 25 13:17:11 2020 -0400 @@ -56,7 +56,8 @@ compiled_fcn_stack_frame (void) = delete; compiled_fcn_stack_frame (tree_evaluator& tw, octave_function *fcn, - size_t index, stack_frame *static_link) + size_t index, + const std::shared_ptr<stack_frame>& static_link) : stack_frame (tw, index, static_link, static_link->access_link ()), m_fcn (fcn) { } @@ -177,7 +178,7 @@ script_stack_frame (tree_evaluator& tw, octave_user_script *script, unwind_protect *up_frame, size_t index, - stack_frame *static_link); + const std::shared_ptr<stack_frame>& static_link); script_stack_frame (const script_stack_frame& elt) = default; @@ -189,7 +190,8 @@ bool is_user_script_frame (void) const { return true; } - static stack_frame * get_access_link (stack_frame *static_link); + static std::shared_ptr<stack_frame> + get_access_link (const std::shared_ptr<stack_frame>& static_link); static size_t get_num_symbols (octave_user_script *script); @@ -287,8 +289,9 @@ base_value_stack_frame (void) = delete; base_value_stack_frame (tree_evaluator& tw, size_t num_symbols, - size_t index, stack_frame *static_link, - stack_frame *access_link) + size_t index, + const std::shared_ptr<stack_frame>& static_link, + const std::shared_ptr<stack_frame>& access_link) : stack_frame (tw, index, static_link, access_link), m_values (num_symbols, octave_value ()), m_flags (num_symbols, LOCAL), @@ -392,8 +395,8 @@ user_fcn_stack_frame (tree_evaluator& tw, octave_user_function *fcn, unwind_protect *up_frame, size_t index, - stack_frame *static_link, - stack_frame *access_link = nullptr) + 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 @@ -412,8 +415,9 @@ bool is_user_fcn_frame (void) const { return true; } - static stack_frame * - get_access_link (octave_user_function *fcn, stack_frame *static_link); + static std::shared_ptr<stack_frame> + get_access_link (octave_user_function *fcn, + const std::shared_ptr<stack_frame>& static_link); static size_t get_num_symbols (octave_user_function *fcn) { @@ -478,7 +482,8 @@ scope_stack_frame (void) = delete; scope_stack_frame (tree_evaluator& tw, const symbol_scope& scope, - size_t index, stack_frame *static_link) + size_t index, + const std::shared_ptr<stack_frame>& static_link) : base_value_stack_frame (tw, scope.num_symbols (), index, static_link, nullptr), m_scope (scope) @@ -617,7 +622,7 @@ // link for a compiled_fcn_stack_frame be the same as the static // link? - stack_frame *slink = frame.static_link (); + std::shared_ptr<stack_frame> slink = frame.static_link (); if (slink) slink->accept (*this); @@ -625,7 +630,7 @@ void visit_script_stack_frame (script_stack_frame& frame) { - stack_frame *alink = frame.access_link (); + std::shared_ptr<stack_frame> alink = frame.access_link (); if (alink) alink->accept (*this); @@ -635,7 +640,7 @@ { clean_frame (frame); - stack_frame *alink = frame.access_link (); + std::shared_ptr<stack_frame> alink = frame.access_link (); if (alink) alink->accept (*this); @@ -645,7 +650,7 @@ { clean_frame (frame); - stack_frame *alink = frame.access_link (); + std::shared_ptr<stack_frame> alink = frame.access_link (); if (alink) alink->accept (*this); @@ -859,7 +864,7 @@ // link for a compiled_fcn_stack_frame be the same as the static // link? - stack_frame *slink = frame.static_link (); + std::shared_ptr<stack_frame> slink = frame.static_link (); if (slink) slink->accept (*this); @@ -867,7 +872,7 @@ void visit_script_stack_frame (script_stack_frame& frame) { - stack_frame *alink = frame.access_link (); + std::shared_ptr<stack_frame> alink = frame.access_link (); if (alink) alink->accept (*this); @@ -877,7 +882,7 @@ { append_list (frame); - stack_frame *alink = frame.access_link (); + std::shared_ptr<stack_frame> alink = frame.access_link (); if (alink) alink->accept (*this); @@ -887,7 +892,7 @@ { append_list (frame); - stack_frame *alink = frame.access_link (); + std::shared_ptr<stack_frame> alink = frame.access_link (); if (alink) alink->accept (*this); @@ -1008,7 +1013,8 @@ }; stack_frame * stack_frame::create (tree_evaluator& tw, octave_function *fcn, - size_t index, stack_frame *static_link) + size_t index, + const std::shared_ptr<stack_frame>& static_link) { return new compiled_fcn_stack_frame (tw, fcn, index, static_link); } @@ -1016,7 +1022,7 @@ stack_frame * stack_frame::create (tree_evaluator& tw, octave_user_script *script, unwind_protect *up_frame, size_t index, - stack_frame *static_link) + const std::shared_ptr<stack_frame>& static_link) { return new script_stack_frame (tw, script, up_frame, index, static_link); } @@ -1024,8 +1030,8 @@ stack_frame * stack_frame::create (tree_evaluator& tw, octave_user_function *fcn, unwind_protect *up_frame, size_t index, - stack_frame *static_link, - stack_frame *access_link) + 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); @@ -1033,7 +1039,7 @@ stack_frame * stack_frame::create (tree_evaluator& tw, const symbol_scope& scope, size_t index, - stack_frame *static_link) + const std::shared_ptr<stack_frame>& static_link) { return new scope_stack_frame (tw, scope, index, static_link); } @@ -1120,6 +1126,41 @@ return sia.symbol_info (); } + octave_value stack_frame::workspace (void) + { + std::list<octave_scalar_map> ws_list; + + stack_frame *frame = this; + + while (frame) + { + octave::symbol_info_list symbols = frame->all_variables (); + + octave_scalar_map ws; + + for (const auto& sym_name : symbols.names ()) + { + octave_value val = symbols.varval (sym_name); + + if (val.is_defined ()) + ws.assign (sym_name, val); + } + + ws_list.push_back (ws); + + std::shared_ptr<stack_frame> nxt = frame->access_link (); + frame = nxt.get (); + } + + Cell ws_frames (ws_list.size (), 1); + + octave_idx_type i = 0; + for (const auto& elt : ws_list) + ws_frames(i++) = elt; + + return ws_frames; + } + // FIXME: Should this function also find any variables in parent // scopes accessible through access_links? @@ -1333,14 +1374,14 @@ os << "static link: "; if (m_static_link) - os << m_static_link; + os << m_static_link.get (); else os << "NULL"; os << std::endl; os << "access link: "; if (m_access_link) - os << m_access_link; + os << m_access_link.get (); else os << "NULL"; os << std::endl; @@ -1355,7 +1396,7 @@ return; os << "FOLLOWING ACCESS LINKS:" << std::endl; - const stack_frame *frm = access_link (); + std::shared_ptr<stack_frame> frm = access_link (); while (frm) { frm->display (false); @@ -1391,7 +1432,7 @@ octave_user_script *script, unwind_protect *up_frame, size_t index, - stack_frame *static_link) + 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_lexical_frame_offsets (get_num_symbols (script), 1), @@ -1542,15 +1583,13 @@ // If this is a nested scope, set access_link to nearest parent // stack frame that corresponds to the lexical parent of this scope. - stack_frame * - script_stack_frame::get_access_link (stack_frame *static_link) + std::shared_ptr<stack_frame> + script_stack_frame::get_access_link (const std::shared_ptr<stack_frame>& static_link) { - stack_frame *alink = nullptr; - // If this script is called from another script, set access // link to ultimate parent stack frame. - alink = static_link; + std::shared_ptr<stack_frame> alink = static_link; while (alink->is_user_script_frame ()) { @@ -1817,7 +1856,10 @@ const stack_frame *frame = this; for (size_t i = 0; i < frame_offset; i++) - frame = frame->access_link (); + { + std::shared_ptr<stack_frame> nxt = frame->access_link (); + frame = nxt.get (); + } if (! frame) error ("internal error: invalid access link in function call stack"); @@ -1844,7 +1886,10 @@ const stack_frame *frame = this; for (size_t i = 0; i < frame_offset; i++) - frame = frame->access_link (); + { + std::shared_ptr<stack_frame> nxt = frame->access_link (); + frame = nxt.get (); + } if (! frame) error ("internal error: invalid access link in function call stack"); @@ -1883,7 +1928,10 @@ stack_frame *frame = this; for (size_t i = 0; i < frame_offset; i++) - frame = frame->access_link (); + { + std::shared_ptr<stack_frame> nxt = frame->access_link (); + frame = nxt.get (); + } if (data_offset >= frame->size ()) frame->resize (data_offset+1); @@ -1920,7 +1968,7 @@ if (frame_offset > 1) error ("variables must be made PERSISTENT or GLOBAL in the first scope in which they are used"); - stack_frame *frame = access_link (); + std::shared_ptr<stack_frame> frame = access_link (); if (data_offset >= frame->size ()) frame->resize (data_offset+1); @@ -1988,11 +2036,11 @@ // If this is a nested scope, set access_link to nearest parent // stack frame that corresponds to the lexical parent of this scope. - stack_frame * + std::shared_ptr<stack_frame> user_fcn_stack_frame::get_access_link (octave_user_function *fcn, - stack_frame *static_link) + const std::shared_ptr<stack_frame>& static_link) { - stack_frame *alink = nullptr; + std::shared_ptr<stack_frame> alink; symbol_scope fcn_scope = fcn->scope (); @@ -2083,7 +2131,8 @@ if (sym) return sym; - frame = frame->access_link (); + std::shared_ptr<stack_frame> nxt = frame->access_link (); + frame = nxt.get (); } return symbol_record (); @@ -2139,7 +2188,10 @@ const stack_frame *frame = this; for (size_t i = 0; i < frame_offset; i++) - frame = frame->access_link (); + { + std::shared_ptr<stack_frame> nxt = frame->access_link (); + frame = nxt.get (); + } if (! frame) error ("internal error: invalid access link in function call stack"); @@ -2161,7 +2213,10 @@ const stack_frame *frame = this; for (size_t i = 0; i < frame_offset; i++) - frame = frame->access_link (); + { + std::shared_ptr<stack_frame> nxt = frame->access_link (); + frame = nxt.get (); + } if (! frame) error ("internal error: invalid access link in function call stack"); @@ -2199,7 +2254,10 @@ stack_frame *frame = this; for (size_t i = 0; i < frame_offset; i++) - frame = frame->access_link (); + { + std::shared_ptr<stack_frame> nxt = frame->access_link (); + frame = nxt.get (); + } if (data_offset >= frame->size ()) frame->resize (data_offset+1);