# HG changeset patch # User John W. Eaton # Date 1515435910 18000 # Node ID 8f2c479eb125642510901cebdfa4f8e43ca38293 # Parent 5a10409695b7505042b5d8b8cd76e8840858cdaf eliminate unnecessary value stack in evaluator * pt-eval.h, pt-eval.cc (tree_evaluator::result_type): New enum. (tree_evaluator::m_result_type, tree_evaluator::m_expr_result_value, tree_evaluator::m_expr_result_value_list): New data members. (tree_evaluator::push_result): New functions. Store either a single octave_value or octave_value_list along with the type (RT_VALUE or RT_VALUE_LIST). (tree_evaluator::evaluate, tree_evaluator::evaluate_n): Use new result values instead of m_value_stack. (tree_evaluator::value_stack): Delete. A stack is not needed for evaluation results. Instead of pushing results on the value stack, call push_result. diff -r 5a10409695b7 -r 8f2c479eb125 libinterp/parse-tree/pt-eval.cc --- a/libinterp/parse-tree/pt-eval.cc Mon Jan 08 16:13:27 2018 -0800 +++ b/libinterp/parse-tree/pt-eval.cc Mon Jan 08 13:25:10 2018 -0500 @@ -78,7 +78,9 @@ void tree_evaluator::reset (void) { - m_value_stack.clear (); + m_result_type = RT_UNDEFINED; + m_expr_result_value = octave_value (); + m_expr_result_value_list = octave_value_list (); m_lvalue_list_stack.clear (); m_nargout_stack.clear (); } @@ -151,7 +153,7 @@ octave_value fh (octave_fcn_binder::maybe_binder (ov_fcn, this)); - m_value_stack.push (ovl (fh)); + push_result (fh); } void @@ -186,7 +188,7 @@ if (etype == octave_value::op_el_or) { expr.matlab_style_short_circuit_warning ("|"); - m_value_stack.push (ovl (octave_value (true))); + push_result (octave_value (true)); return; } } @@ -195,7 +197,7 @@ if (etype == octave_value::op_el_and) { expr.matlab_style_short_circuit_warning ("&"); - m_value_stack.push (ovl (octave_value (false))); + push_result (octave_value (false)); return; } } @@ -207,7 +209,7 @@ result = b.is_true (); } - m_value_stack.push (ovl (octave_value (result))); + push_result (octave_value (result)); return; } } @@ -237,7 +239,7 @@ } } - m_value_stack.push (ovl (val)); + push_result (val); } void @@ -266,7 +268,7 @@ { if (etype == tree_boolean_expression::bool_or) { - m_value_stack.push (ovl (octave_value (true))); + push_result (octave_value (true)); return; } } @@ -274,7 +276,7 @@ { if (etype == tree_boolean_expression::bool_and) { - m_value_stack.push (ovl (octave_value (false))); + push_result (octave_value (false)); return; } } @@ -291,7 +293,7 @@ val = octave_value (result); } - m_value_stack.push (ovl (val)); + push_result (val); } void @@ -320,7 +322,7 @@ } } - m_value_stack.push (ovl (val)); + push_result (val); } void @@ -352,7 +354,7 @@ if (! op_base || ! op_limit) { - m_value_stack.push (ovl (octave_value (val))); + push_result (octave_value (val)); return; } @@ -402,7 +404,7 @@ expr.is_for_cmd_expr ()); } - m_value_stack.push (ovl (val)); + push_result (val); } void @@ -1087,7 +1089,8 @@ feval ("display", args); } - retval = val; + push_result (val); + return; } } else if (sym.is_added_static ()) @@ -1095,7 +1098,7 @@ else expr.eval_undefined_error (); - m_value_stack.push (retval); + push_result (retval); } void @@ -1355,7 +1358,7 @@ { // No more indices, so we are done. - m_value_stack.push (retval); + push_result (retval); return; } } @@ -1542,7 +1545,7 @@ } } - m_value_stack.push (retval); + push_result (retval); } void @@ -1739,7 +1742,7 @@ } } - m_value_stack.push (retval); + push_result (retval); } void @@ -1801,7 +1804,7 @@ retval = val; - m_value_stack.push (retval); + push_result (retval); } void @@ -1966,7 +1969,7 @@ val = retval_list; } - m_value_stack.push (val); + push_result (val); } void @@ -1991,7 +1994,7 @@ if (nargout > 1) error ("invalid number of output arguments for constant expression"); - m_value_stack.push (ovl (expr.value ())); + push_result (expr.value ()); } void @@ -2001,7 +2004,7 @@ octave_value fh = make_fcn_handle (nm); - m_value_stack.push (ovl (fh)); + push_result (fh); } void @@ -2033,7 +2036,7 @@ } } - m_value_stack.push (retval); + push_result (retval); } void @@ -2077,7 +2080,7 @@ } } - m_value_stack.push (ovl (val)); + push_result (val); } void @@ -2120,7 +2123,7 @@ } } - m_value_stack.push (ovl (val)); + push_result (val); } void @@ -2232,7 +2235,7 @@ } } - m_value_stack.push (ovl (val)); + push_result (val); } void diff -r 5a10409695b7 -r 8f2c479eb125 libinterp/parse-tree/pt-eval.h --- a/libinterp/parse-tree/pt-eval.h Mon Jan 08 16:13:27 2018 -0800 +++ b/libinterp/parse-tree/pt-eval.h Mon Jan 08 13:25:10 2018 -0500 @@ -31,6 +31,7 @@ #include #include "call-stack.h" +#include "ov.h" #include "ovl.h" #include "profiler.h" #include "pt-exp.h" @@ -45,6 +46,13 @@ class interpreter; class unwind_protect; + enum result_type + { + RT_UNDEFINED = 0, + RT_VALUE = 1, + RT_VALUE_LIST = 2 + }; + // How to evaluate the code that the parse trees represent. class OCTINTERP_API tree_evaluator : public tree_walker @@ -115,8 +123,10 @@ typedef void (*decl_elt_init_fcn) (tree_decl_elt&); tree_evaluator (interpreter& interp) - : m_interpreter (interp), m_value_stack (), m_lvalue_list_stack (), - m_nargout_stack (), m_call_stack (interp), m_profiler (), + : m_interpreter (interp), m_result_type (RT_UNDEFINED), + m_expr_result_value (), m_expr_result_value_list (), + m_lvalue_list_stack (), m_nargout_stack (), + m_call_stack (interp), m_profiler (), m_max_recursion_depth (256), m_silent_functions (false), m_string_fill_char (' '), m_PS4 ("+ "), m_echo (ECHO_OFF), m_echo_state (false), m_echo_file_name (), m_echo_file_pos (1), @@ -269,28 +279,73 @@ ? nullptr : m_lvalue_list_stack.top ()); } + void push_result (const octave_value& val) + { + m_result_type = RT_VALUE; + m_expr_result_value = val; + } + + void push_result (const octave_value_list& vals) + { + m_result_type = RT_VALUE_LIST; + m_expr_result_value_list = vals; + } + octave_value evaluate (tree_expression *expr, int nargout = 1) { + octave_value retval; + m_nargout_stack.push (nargout); expr->accept (*this); m_nargout_stack.pop (); - octave_value_list tmp = m_value_stack.val_pop (); + switch (m_result_type) + { + case RT_UNDEFINED: + panic_impossible (); + break; - return tmp.empty () ? octave_value () : tmp(0); + case RT_VALUE: + retval = m_expr_result_value; + break; + + case RT_VALUE_LIST: + retval = (m_expr_result_value_list.empty () + ? octave_value () : m_expr_result_value_list(0)); + break; + } + + return retval; } octave_value_list evaluate_n (tree_expression *expr, int nargout = 1) { + octave_value_list retval; + m_nargout_stack.push (nargout); expr->accept (*this); m_nargout_stack.pop (); - return m_value_stack.val_pop (); + switch (m_result_type) + { + case RT_UNDEFINED: + panic_impossible (); + break; + + case RT_VALUE: + retval = ovl (m_expr_result_value); + break; + + case RT_VALUE_LIST: + retval = m_expr_result_value_list; + break; + } + + return retval; } octave_value evaluate (tree_decl_elt *); @@ -424,7 +479,9 @@ interpreter& m_interpreter; - value_stack m_value_stack; + result_type m_result_type; + octave_value m_expr_result_value; + octave_value_list m_expr_result_value_list; value_stack*> m_lvalue_list_stack;