# HG changeset patch # User Petter T. # Date 1697577850 -7200 # Node ID f593161d7b40c71b53deca60f0b473006ea39189 # Parent 2e949fd64073d485e1e69d3f86724d8767d3ed92 Support nargout -1 in matrixes and cell constructs in VM (bug #64775) Also bar propagation of nargout -1 in entry points in calls to VM functions, as in execute_user_function() etc. * pt-bytecode-vm.cc: Bar nargout -1 in call * pt-bytecode-walk.cc: Unknown nargout for cell, matrix. No "simple" opcode if nargout -1 subsref. diff -r 2e949fd64073 -r f593161d7b40 libinterp/parse-tree/pt-bytecode-vm.cc --- a/libinterp/parse-tree/pt-bytecode-vm.cc Tue Oct 17 23:16:31 2023 +0200 +++ b/libinterp/parse-tree/pt-bytecode-vm.cc Tue Oct 17 23:24:10 2023 +0200 @@ -7509,6 +7509,10 @@ vm::call (tree_evaluator& tw, int nargout, const octave_value_list& xargs, octave_user_code *fn, std::shared_ptr context) { + // If number of outputs unknown, pass nargout=1 to the function being called + if (nargout < 0) + nargout = 1; + CHECK_PANIC (fn); CHECK_PANIC (fn->is_compiled ()); diff -r 2e949fd64073 -r f593161d7b40 libinterp/parse-tree/pt-bytecode-walk.cc --- a/libinterp/parse-tree/pt-bytecode-walk.cc Tue Oct 17 23:16:31 2023 +0200 +++ b/libinterp/parse-tree/pt-bytecode-walk.cc Tue Oct 17 23:24:10 2023 +0200 @@ -3984,6 +3984,7 @@ visit_matrix (tree_matrix &m) { INC_DEPTH (); + m_unknown_nargout++; bool is_rectangle = true; std::vector row_lengths; @@ -4060,6 +4061,7 @@ maybe_emit_bind_ans_and_disp (m); DEC_DEPTH (); + m_unknown_nargout--; } void @@ -4067,6 +4069,7 @@ visit_cell (tree_cell &m) { INC_DEPTH (); + m_unknown_nargout++; auto p = m.begin (); int n_cols = -1; @@ -4118,6 +4121,7 @@ maybe_emit_bind_ans_and_disp (m); DEC_DEPTH (); + m_unknown_nargout--; } void @@ -5069,10 +5073,25 @@ size_t n_chained = type_tags.size (); CHECK (n_chained); + // TODO: Kludge alert. Mirror the behaviour in ov_classdef::subsref + // where under certain conditions a magic number nargout of -1 is + // expected to maybe return a cs-list. "-1" in this context + // does not have the same meaning as in the VM, where it means + // a varargout with only one return symbol 'varargout'. + bool m1_magic_nargout = false; + if (m_unknown_nargout) + { + if ((type_tags.size () >= 1 && (type_tags[0] == '{' || type_tags[0] == '.')) || + (type_tags.size () >= 2 && (type_tags[0] == '(' && type_tags[1] == '.'))) + { + m1_magic_nargout = true; + } + } + // For un-chained index expressions we use specialized // op-codes that has e.g. nargout and type '(','{' and '.' // encoded in the op-code it self to speed things up. - if (n_chained == 1) + if (n_chained == 1 && !m1_magic_nargout) { simple_visit_index_expression (expr); return; @@ -5184,21 +5203,6 @@ arg_name_entry.m_ip_start = CODE_SIZE (); - // TODO: Kludge alert. Mirror the behaviour in ov_classdef::subsref - // where under certain conditions a magic number nargout of -1 is - // expected to maybe return a cs-list. "-1" in this context - // does not have the same meaning as in the VM, where it means - // a varargout with only one return symbol 'varargout'. - bool m1_magic_nargout = false; - if (m_unknown_nargout) - { - if ((v_types.size () >= 1 && (v_types[0] == '{' || v_types[0] == '.')) || - (v_types.size () >= 2 && (v_types[0] == '(' && v_types[1] == '.'))) - { - m1_magic_nargout = true; - } - } - if (first_expression && first_expression->is_identifier ()) { int slot = SLOT (first_expression->name ());