diff --git a/inputs/failing/copyCounting/subscriptAssignment.ts b/inputs/passing/copyCounting/subscriptAssignment.ts similarity index 50% rename from inputs/failing/copyCounting/subscriptAssignment.ts rename to inputs/passing/copyCounting/subscriptAssignment.ts index fe4aecb..1f247ab 100644 --- a/inputs/failing/copyCounting/subscriptAssignment.ts +++ b/inputs/passing/copyCounting/subscriptAssignment.ts @@ -1,13 +1,15 @@ //! test_output(2) -// Should be: 1 /// export default function main() { const x = Debug.makeCopyCounter("x"); - let obj: Record = { x }; // Single copy occurs here - obj.y = "y"; // Shouldn't copy, but does + let obj: Record = { x }; // First copy + obj.y = "y"; // No extra copy + + let arr: unknown[] = [x]; // Second copy + arr[1] = "y"; // No extra copy return x.count; } diff --git a/valuescript_vm/src/bytecode_stack_frame.rs b/valuescript_vm/src/bytecode_stack_frame.rs index 8e1e9b6..825790c 100644 --- a/valuescript_vm/src/bytecode_stack_frame.rs +++ b/valuescript_vm/src/bytecode_stack_frame.rs @@ -302,14 +302,18 @@ impl StackFrameTrait for BytecodeStackFrame { Sub => self.apply_binary_op(operations::op_sub)?, SubMov => { - let subscript = self.decoder.decode_vallish(&self.registers); + // TODO: Ideally we would use a reference for the subscript (decode_vallish), but that would + // be an immutable borrow and it conflicts with the mutable borrow for the target. In + // theory, this should still be possible because we only need a mutable borrow to an + // element, not the vec itself. vec.get_many_mut has been considered, but it's not yet + // stable. + let subscript = self.decoder.decode_val(&self.registers); + let value = self.decoder.decode_val(&self.registers); - let register_index = self.decoder.decode_register_index().unwrap(); - let mut target = self.registers[register_index].clone(); // TODO: Lift + let target_index = self.decoder.decode_register_index().unwrap(); - operations::op_submov(&mut target, subscript.get_ref(), value)?; - self.registers[register_index] = target; + operations::op_submov(&mut self.registers[target_index], &subscript, value)?; } SubCall | ConstSubCall | ThisSubCall => {