From 0ee1f473cefa71c2cbb0100cd545b48b5dde53bc Mon Sep 17 00:00:00 2001 From: Andrew Morris Date: Wed, 5 Apr 2023 10:31:05 +1000 Subject: [PATCH] this_subcall --- valuescript_common/src/instruction_byte.rs | 2 ++ valuescript_compiler/src/asm.rs | 9 +++++++++ valuescript_compiler/src/assembler.rs | 3 ++- valuescript_compiler/src/assembly_parser.rs | 7 +++++++ valuescript_compiler/src/instruction_mutates_this.rs | 3 ++- valuescript_compiler/src/link_module.rs | 3 ++- valuescript_vm/src/bytecode_stack_frame.rs | 12 ++++++------ 7 files changed, 30 insertions(+), 9 deletions(-) diff --git a/valuescript_common/src/instruction_byte.rs b/valuescript_common/src/instruction_byte.rs index 3604673..1bd85c4 100644 --- a/valuescript_common/src/instruction_byte.rs +++ b/valuescript_common/src/instruction_byte.rs @@ -51,6 +51,7 @@ pub enum InstructionByte { UnsetCatch = 0x30, ConstSubCall = 0x31, RequireMutableThis = 0x32, + ThisSubCall = 0x33, } impl InstructionByte { @@ -109,6 +110,7 @@ impl InstructionByte { 0x30 => UnsetCatch, 0x31 => ConstSubCall, 0x32 => RequireMutableThis, + 0x33 => ThisSubCall, _ => panic!("Unrecognized instruction: {}", byte), }; diff --git a/valuescript_compiler/src/asm.rs b/valuescript_compiler/src/asm.rs index 9ddd482..f4e175b 100644 --- a/valuescript_compiler/src/asm.rs +++ b/valuescript_compiler/src/asm.rs @@ -289,6 +289,7 @@ pub enum Instruction { UnsetCatch, ConstSubCall(Value, Value, Value, Register), RequireMutableThis, + ThisSubCall(Value, Value, Value, Register), } impl std::fmt::Display for Instruction { @@ -437,6 +438,13 @@ impl std::fmt::Display for Instruction { ) } Instruction::RequireMutableThis => write!(f, "require_mutable_this"), + Instruction::ThisSubCall(obj, subscript, args, register) => { + write!( + f, + "this_subcall {} {} {} {}", + obj, subscript, args, register + ) + } } } } @@ -498,6 +506,7 @@ impl Instruction { UnsetCatch => InstructionByte::UnsetCatch, ConstSubCall(..) => InstructionByte::ConstSubCall, RequireMutableThis => InstructionByte::RequireMutableThis, + ThisSubCall(..) => InstructionByte::ThisSubCall, } } } diff --git a/valuescript_compiler/src/assembler.rs b/valuescript_compiler/src/assembler.rs index 738a4dd..010b130 100644 --- a/valuescript_compiler/src/assembler.rs +++ b/valuescript_compiler/src/assembler.rs @@ -212,7 +212,8 @@ impl Assembler { } Apply(arg1, arg2, arg3, dst) | SubCall(arg1, arg2, arg3, dst) - | ConstSubCall(arg1, arg2, arg3, dst) => { + | ConstSubCall(arg1, arg2, arg3, dst) + | ThisSubCall(arg1, arg2, arg3, dst) => { self.value(arg1); self.value(arg2); self.value(arg3); diff --git a/valuescript_compiler/src/assembly_parser.rs b/valuescript_compiler/src/assembly_parser.rs index da29bb9..d0af449 100644 --- a/valuescript_compiler/src/assembly_parser.rs +++ b/valuescript_compiler/src/assembly_parser.rs @@ -226,6 +226,7 @@ impl<'a> AssemblyParser<'a> { ("unset_catch", InstructionByte::UnsetCatch), ("const_subcall", InstructionByte::ConstSubCall), ("require_mutable_this", InstructionByte::RequireMutableThis), + ("this_subcall", InstructionByte::ThisSubCall), ]); for (word, instruction) in instruction_word_map { @@ -678,6 +679,12 @@ impl<'a> AssemblyParser<'a> { self.assemble_register(), ), RequireMutableThis => Instruction::RequireMutableThis, + ThisSubCall => Instruction::ThisSubCall( + self.assemble_value(), + self.assemble_value(), + self.assemble_value(), + self.assemble_register(), + ), } } diff --git a/valuescript_compiler/src/instruction_mutates_this.rs b/valuescript_compiler/src/instruction_mutates_this.rs index 4fe5bc8..64c113a 100644 --- a/valuescript_compiler/src/instruction_mutates_this.rs +++ b/valuescript_compiler/src/instruction_mutates_this.rs @@ -47,7 +47,8 @@ pub fn instruction_mutates_this(instruction: &Instruction) -> bool { | Import(_, reg) | ImportStar(_, reg) | SetCatch(_, reg) - | ConstSubCall(_, _, _, reg) => reg == &Register::This, + | ConstSubCall(_, _, _, reg) + | ThisSubCall(_, _, _, reg) => reg == &Register::This, Apply(_, ctx, _, reg) | SubCall(ctx, _, _, reg) => { reg == &Register::This diff --git a/valuescript_compiler/src/link_module.rs b/valuescript_compiler/src/link_module.rs index a7ebd61..5c5feec 100644 --- a/valuescript_compiler/src/link_module.rs +++ b/valuescript_compiler/src/link_module.rs @@ -282,7 +282,8 @@ where } Apply(arg1, arg2, arg3, _) | SubCall(arg1, arg2, arg3, _) - | ConstSubCall(arg1, arg2, arg3, _) => { + | ConstSubCall(arg1, arg2, arg3, _) + | ThisSubCall(arg1, arg2, arg3, _) => { self.value(Some(owner), arg1); self.value(Some(owner), arg2); self.value(Some(owner), arg3); diff --git a/valuescript_vm/src/bytecode_stack_frame.rs b/valuescript_vm/src/bytecode_stack_frame.rs index 3e2b949..35a2edd 100644 --- a/valuescript_vm/src/bytecode_stack_frame.rs +++ b/valuescript_vm/src/bytecode_stack_frame.rs @@ -280,7 +280,10 @@ impl StackFrameTrait for BytecodeStackFrame { self.registers[register_index] = target; } - SubCall | ConstSubCall => { + SubCall | ConstSubCall | ThisSubCall => { + let const_call = instruction_byte == InstructionByte::ConstSubCall + || (instruction_byte == InstructionByte::ThisSubCall && self.const_this); + let mut obj = match self.decoder.peek_type() { BytecodeType::Register => { self.decoder.decode_type(); @@ -308,7 +311,7 @@ impl StackFrameTrait for BytecodeStackFrame { self.transfer_parameters(&mut new_frame); new_frame.write_this( - instruction_byte == ConstSubCall, + const_call, match &obj { ThisArg::Register(reg_i) => self.registers[reg_i.clone()].clone(), ThisArg::Val(val) => val.clone(), @@ -329,10 +332,7 @@ impl StackFrameTrait for BytecodeStackFrame { let res = match &mut obj { ThisArg::Register(reg_i) => native_fn( - ThisWrapper::new( - instruction_byte == ConstSubCall, - self.registers.get_mut(reg_i.clone()).unwrap(), - ), + ThisWrapper::new(const_call, self.registers.get_mut(reg_i.clone()).unwrap()), params, )?, ThisArg::Val(val) => native_fn(ThisWrapper::new(true, val), params)?,