changeset 32418:f593161d7b40

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.
author Petter T. <petter.vilhelm@gmail.com>
date Tue, 17 Oct 2023 23:24:10 +0200
parents 2e949fd64073
children 777e62ee2f7f
files libinterp/parse-tree/pt-bytecode-vm.cc libinterp/parse-tree/pt-bytecode-walk.cc
diffstat 2 files changed, 24 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- 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<stack_frame> 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 ());
 
--- 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<int> 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 ());