Mercurial > octave
diff libinterp/octave-value/ov-usr-fcn.h @ 26661:cf9e10ce3351
move variable values from symbol_record objects to stack_frame objects
Apologies for the massive commit. I see no way to untangle these
changes into a set of smaller incremental changes in a way that would
be more useful.
Previously, handling data for recursive function calls was managed by
a stack of values in the symbol_record class and an auxiliary integer
variable was used for managing the recursion depth (context_id). Now,
values for local variables are in the stack_frame class and recursion
is handled naturally by the call_stack as a new stack frame is added
to the call_stack object for any call to a function or a script.
Values for internal function call information (nargin, nargout, etc.)
are now stored specially in the stack_frame object. Values for global
variables are now stored in a map in the call_stack object. Values
for persistent variables are stored in the corresponding
octave_user_function object. Access to non-local variables inside
nested functions is managed through pointers to stack_frame objects
for the parent function scopes. The new implementation more closely
resembles the techniques described in standard compiler literature.
These changes should make it easier to create proper closures and
finally solve bug #39257 (handles to nested functions are not yet
supported). They may also make it easier to implement JIT compiler,
though that is probably still a long way off.
The new stack-frame.h file has some details about the new
implementation of stack frames that should help in understanding how
things work now.
Describing each change to each file and function will probably not
provide much greater understanding of the changes and would be quite
tedious to write so I am omitting them.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Mon, 28 Jan 2019 18:01:46 +0000 |
parents | 00f796120a6d |
children | 287eba9ed14b |
line wrap: on
line diff
--- a/libinterp/octave-value/ov-usr-fcn.h Sat Jan 26 15:53:29 2019 +0000 +++ b/libinterp/octave-value/ov-usr-fcn.h Mon Jan 28 18:01:46 2019 +0000 @@ -28,7 +28,6 @@ #include <ctime> #include <string> -#include <stack> #include "comment-list.h" #include "ovl.h" @@ -44,6 +43,7 @@ namespace octave { class file_info; + class stack_frame; class tree_parameter_list; class tree_statement_list; class tree_evaluator; @@ -67,8 +67,7 @@ : octave_function (nm, ds), m_scope (scope), file_name (fnm), t_parsed (static_cast<time_t> (0)), t_checked (static_cast<time_t> (0)), - m_call_depth (-1), m_file_info (nullptr), - cmd_list (cmds) + m_file_info (nullptr), cmd_list (cmds) { } public: @@ -113,13 +112,6 @@ return octave_value (); } - // XXX FIXME - int call_depth (void) const { return m_call_depth; } - - void set_call_depth (int val) { m_call_depth = val; } - - void increment_call_depth (void) { ++m_call_depth; } - virtual std::map<std::string, octave_value> subfunctions (void) const; octave::tree_statement_list * body (void) { return cmd_list; } @@ -143,9 +135,6 @@ // parsed again. octave::sys::time t_checked; - // Used to keep track of recursion depth. - int m_call_depth; - // Cached text of function or script code with line offsets // calculated. octave::file_info *m_file_info; @@ -197,9 +186,6 @@ void accept (octave::tree_walker& tw); - // XXX FIXME - void set_call_depth (int val) { octave_user_code::set_call_depth (val); } - private: DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA @@ -212,10 +198,13 @@ { public: + typedef std::map<std::string, octave_value> local_vars_map; + octave_user_function (const octave::symbol_scope& scope = octave::symbol_scope (), octave::tree_parameter_list *pl = nullptr, octave::tree_parameter_list *rl = nullptr, - octave::tree_statement_list *cl = nullptr); + octave::tree_statement_list *cl = nullptr, + const local_vars_map& lviv = local_vars_map ()); // No copying! @@ -225,12 +214,6 @@ ~octave_user_function (void); - octave::symbol_record::context_id active_context () const - { - return is_anonymous_function () - ? 0 : static_cast<octave::symbol_record::context_id>(m_call_depth); - } - octave_function * function_value (bool = false) { return this; } octave_user_function * user_function_value (bool = false) { return this; } @@ -380,6 +363,11 @@ octave::comment_list * trailing_comment (void) { return trail_comm; } + const local_vars_map& local_var_init_vals (void) const + { + return m_local_var_init_vals; + } + // If is_special_expr is true, retrieve the sigular expression that forms the // body. May be null (even if is_special_expr is true). octave::tree_expression * special_expr (void); @@ -396,9 +384,6 @@ octave_value dump (void) const; - // XXX FIXME - void set_call_depth (int val) { octave_user_code::set_call_depth (val); } - private: enum class_ctor_type @@ -417,6 +402,9 @@ // this function. octave::tree_parameter_list *ret_list; + // For anonymous function values inherited from parent scope. + local_vars_map m_local_var_init_vals; + // The comments preceding the FUNCTION token. octave::comment_list *lead_comm;