Mercurial > octave
changeset 32326:084fc89a253b
VM Fix compound subassignment of globals (bug #64702)
Also fix some other places with the same potential problem.
* libinterp/parse-tree/pt-bytecode-vm.cc: Ref, deref properly
* test/compile/bytecode.tst: Update tests
* test/compile/bytecode_global_1.m
author | Petter T. |
---|---|
date | Fri, 22 Sep 2023 09:58:42 +0200 |
parents | 9d758cacf7ca |
children | 55ea70c8d00a |
files | libinterp/parse-tree/pt-bytecode-vm.cc test/compile/bytecode.tst test/compile/bytecode_global_1.m |
diffstat | 3 files changed, 39 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/parse-tree/pt-bytecode-vm.cc Fri Sep 22 20:28:30 2023 -0400 +++ b/libinterp/parse-tree/pt-bytecode-vm.cc Fri Sep 22 09:58:42 2023 +0200 @@ -1160,7 +1160,10 @@ 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)); + if (OCTAVE_UNLIKELY (bsp[j].ov.is_ref ())) + ret.append (bsp[j].ov.ref_rep ()->deref ()); + else + ret.append (std::move (bsp[j].ov)); bsp[j].ov.~octave_value (); } // Destroy rest of return values, if any @@ -5035,8 +5038,13 @@ if (cntr == 0 && ov.is_nil () && has_slot) { // Put a function cache object in the slot and in the local ov - ov = bsp[slot].ov = - octave_value (new octave_fcn_cache (name_data[slot])); + ov = octave_value (new octave_fcn_cache (name_data[slot])); + + if (OCTAVE_UNLIKELY (bsp[slot].ov.is_ref ())) + bsp[slot].ov.ref_rep ()->set_value (ov); + else + bsp[slot].ov = ov; + } if (cntr == 0 && ov.has_function_cache () && has_slot) @@ -5697,12 +5705,14 @@ // Clear it to make assigns not need a new copy. lhs = octave_value {}; - bool is_ref = lhs_slot.is_ref (); - - if (is_ref) - lhs_slot.ref_rep ()->ref ().make_unique (); - - lhs_slot.assign (op, type, idx, rhs); + if (OCTAVE_UNLIKELY (lhs_slot.is_ref ())) + { + octave_value &ov_ref = lhs_slot.ref_rep ()->ref (); + ov_ref.make_unique (); + ov_ref.assign (op, type, idx, rhs); + } + else + lhs_slot.assign (op, type, idx, rhs); // Push a dummy octave_value. Always poped by a POP opcode. PUSH_OV (octave_value {});
--- a/test/compile/bytecode.tst Fri Sep 22 20:28:30 2023 -0400 +++ b/test/compile/bytecode.tst Fri Sep 22 09:58:42 2023 +0200 @@ -311,7 +311,7 @@ %!test %! __enable_vm_eval__ (0, "local"); %! clear all -%! key = "double 0 0 1 1 1 1 1 2 2 2 400 100 0 1 3 double 1 1 1 2 double 1 2 1 1 11 eclass:double 1 1 3 4 double 1 2 400 100 1 1 1 1 3 4 1 1 5 6 1 1 1 2 double 1 2 1 2 double 1 2 1 1 3 4 eclass:double 1 2 3 4 double 1 2 0 0 1 1 3 4 1 1 5 6 1 0 2 double 2 double 11 2 6 4 5 double 1 5 11 double 1 1 22 double 1 1 33 double 1 1 3 double 1 1 4 double 1 1 10 double 1 1 2 3 double 1 2 3 double 1 1 2 double 1 1 55 double 1 1 7 double 1 1 0 "; +%! key = "double 0 0 1 1 1 1 1 2 2 2 400 100 0 1 3 double 1 1 1 2 double 1 2 1 1 11 eclass:double 1 1 3 4 double 1 2 400 100 1 1 1 1 3 4 1 1 5 6 1 1 1 2 double 1 2 1 2 double 1 2 1 1 3 4 eclass:double 1 2 3 4 double 1 2 0 0 1 1 3 4 1 1 5 6 1 0 2 double 2 double 11 2 6 4 5 double 1 5 11 double 1 1 22 double 1 1 33 double 1 1 3 double 1 1 4 double 1 1 10 double 1 1 2 3 double 1 2 3 double 1 1 2 double 1 1 55 double 1 1 7 double 1 1 0 11 12 4 11 12 4 "; %! %! __compile__ bytecode_global_1 clear; %! clear global a;
--- a/test/compile/bytecode_global_1.m Fri Sep 22 20:28:30 2023 -0400 +++ b/test/compile/bytecode_global_1.m Fri Sep 22 09:58:42 2023 +0200 @@ -123,6 +123,23 @@ clear global c __printf_assert__ ("%d ", length (who ('global','c'))); + % Assure some different subassignment operators are working + global s; + s = [1 2 3 4]; + s(1) = 11; %SUBASSIGN_ID + s(2) += 10; %SUBASSIGN_CHAINED + s(3) = []; %SUBASSIGN_ID + + __printf_assert__ ("%d ", s); + + global t; + t.s = [1 2 3 4]; + t.s(1) = 11; %SUBASSIGN_CHAINED + t.s(2) += 10; %SUBASSIGN_CHAINED + t.s(3) = []; %SUBASSIGN_CHAINED + + __printf_assert__ ("%d ", t.s); + clear global d clear global e clear global f @@ -135,6 +152,8 @@ clear global o clear global p clear global r + clear global s + clear global t end function [q w e] = returns3()