changeset 32259:2f93bc7f3cf7

VM fix problem with chained assignmenent not pushing rhs 'a = b.c.d = 3' erroneously yielded 'a == b' * parse-tree/pt-bytecode-walk.cc: Push proper value to stack * test/compile/bytecode.tst: Update tests * test/compile/bytecode_subsasgn.m:
author Petter T.
date Tue, 08 Aug 2023 16:00:56 +0200
parents 58a78f3d29f6
children 5d9311556111
files libinterp/parse-tree/pt-bytecode-walk.cc test/compile/bytecode.tst test/compile/bytecode_subsasgn.m
diffstat 3 files changed, 19 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/parse-tree/pt-bytecode-walk.cc	Mon Aug 07 15:53:59 2023 +0200
+++ b/libinterp/parse-tree/pt-bytecode-walk.cc	Tue Aug 08 16:00:56 2023 +0200
@@ -2817,7 +2817,10 @@
       CHECK_NONNULL (rhs);
       rhs->accept (*this);
 
-      // rhs is on the stack now
+      // rhs is on the stack now. If the assignment is nested we need to DUP rhs.
+      // E.g. "a = b.c.d = 3" => a = 3 or "a = length (b.c.d = 3)" => a = 1
+      if (DEPTH () != 1)
+        PUSH_CODE (INSTR::DUP);
 
       if (e->is_identifier ())
         {
@@ -2965,9 +2968,6 @@
       // Now we got the value that is subassigned to, on the stack
       if (e->is_identifier ())
         {
-          if (DEPTH () != 1) // Duplicate value for chained assignments
-            PUSH_CODE (INSTR::DUP);
-
           // Write the subassigned value back to the slot
           int slot = SLOT (e->name ());
           MAYBE_PUSH_WIDE_OPEXT (slot);
--- a/test/compile/bytecode.tst	Mon Aug 07 15:53:59 2023 +0200
+++ b/test/compile/bytecode.tst	Tue Aug 08 16:00:56 2023 +0200
@@ -178,7 +178,7 @@
 %! __enable_vm_eval__ (0, "local");
 %! clear all
 %! clear functions  % persistent variables in bytecode_subsasgn
-%! key = "3 5 9 8 11 13 1 2 3 4 5 6 77 88 99 1010 1 2 3 987 987 6 77 88 99 1010 0 0 0 0 0 13 double 3 2 4 2 3 cell 1 3 6 7 2 3 1 4 5 1 3 5 2 4 6 7 7 7 7 7 7 1 2 3 1 3 3 2 3 2 3 1 3 1 2 3 4 4 4 3 4 5 6 1 5 3 4 1 5 -1 4 1 5 -1 8 ";
+%! key = "3 5 9 8 11 13 1 2 3 4 5 6 77 88 99 1010 1 2 3 987 987 6 77 88 99 1010 0 0 0 0 0 13 double 3 2 4 2 3 cell 1 3 6 7 2 3 1 4 5 1 3 5 2 4 6 7 7 7 7 7 7 1 2 3 1 3 3 2 3 2 3 1 3 1 2 3 4 4 4 3 4 5 6 1 5 3 4 1 5 -1 4 1 5 -1 8 3 3 3 3 3 3 3 3 ";
 %!
 %! __compile bytecode_subsasgn clear;
 %! bytecode_subsasgn ();
--- a/test/compile/bytecode_subsasgn.m	Mon Aug 07 15:53:59 2023 +0200
+++ b/test/compile/bytecode_subsasgn.m	Tue Aug 08 16:00:56 2023 +0200
@@ -92,4 +92,18 @@
   C.A = A;
   C.A(4) *= 2;
   __printf_assert__ ("%d ", C.A);
+
+  % Chained assignments
+  AA = BB.c = 3;
+  __printf_assert__ ("%d ", AA);
+  CC = DD.c.d = 3;
+  __printf_assert__ ("%d ", DD.c.d);
+  __printf_assert__ ("%d ", CC);
+  EE.a = FF.c.d = 3;
+  __printf_assert__ ("%d ", EE.a);
+  GG = HH.a = II.a.b = JJ.a.b.c = 3;
+  __printf_assert__ ("%d ", GG);
+  __printf_assert__ ("%d ", HH.a);
+  __printf_assert__ ("%d ", II.a.b);
+  __printf_assert__ ("%d ", JJ.a.b.c);
 end