changeset 32198:77cda48abf10

VM: Fix problem with returning too many or too few octave_values (patch #10363). * libinterp/parse-tree/pt-bytecode-vm.cc (vm::execute_code): Don't try to display() undefined values in cs-lists.
author Petter T. <petter.vilhelm@gmail.com>
date Thu, 15 Jun 2023 16:04:22 +0200
parents aa038131581c
children 9f37b2b153d5
files libinterp/parse-tree/pt-bytecode-vm.cc
diffstat 1 files changed, 20 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/parse-tree/pt-bytecode-vm.cc	Sat Jun 24 01:19:50 2023 +0200
+++ b/libinterp/parse-tree/pt-bytecode-vm.cc	Thu Jun 15 16:04:22 2023 +0200
@@ -1104,14 +1104,23 @@
       {
         CHECK (m_output_ignore_data == nullptr); // This can't be active
 
+        // Collect return values in octave_value_list.
+        // Skip %nargout, the first value, which is an integer.
+        // n_returns_callee includes %nargout, but root_nargout doesn't.
+
         octave_value_list ret;
 
-        // Skip nargout, the first value, which is an integer
-        for (int i = 1; i < n_returns_callee; i++)
-        {
-          ret.append(std::move (bsp[i].ov));
-          bsp[i].ov.~octave_value ();
-        }
+        int j;
+        // nargout 0 should still give one return value, if there is one
+        int n_root_wanted = std::max (root_nargout, 1);
+        for (j = 1; j < n_returns_callee && j < (n_root_wanted + 1); j++)
+          {
+            ret.append (std::move (bsp[j].ov));
+            bsp[j].ov.~octave_value ();
+          }
+        // Destroy rest of return values, if any
+        for (; j < n_returns_callee; j++)
+          bsp[j].ov.~octave_value ();
 
         //Note: Stack frame object popped by caller
         CHECK_STACK (0);
@@ -1576,7 +1585,11 @@
 
             for (int i = 0; i < ovl.length (); i++)
               {
-                octave_value_list el_ovl = octave_value_list {ovl(i)};
+                octave_value el_ov = ovl(i);
+                // We are not printing undefined elements
+                if (el_ov.is_undefined ())
+                  continue;
+                octave_value_list el_ovl {el_ov};
                 el_ovl.stash_name_tags (string_vector ("ans"));
                 m_tw->set_active_bytecode_ip (ip - code); // Needed if display calls inputname()