From d72709642270c3eed897e6889f20ddbb67264888 Mon Sep 17 00:00:00 2001 From: Scott Richmond Date: Wed, 18 Jun 2025 14:12:10 -0400 Subject: [PATCH] VM instructions now take 3 bytes --- src/vm.rs | 66 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 20 deletions(-) diff --git a/src/vm.rs b/src/vm.rs index 2d6cbd9..8555a78 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -57,7 +57,7 @@ impl CallFrame { let Value::Fn(ref function) = self.function else { unreachable!() }; - &function.chunk(self.arity) + function.chunk(self.arity) } } @@ -76,6 +76,11 @@ impl fmt::Display for CallFrame { } } +fn combine_bytes(high: u8, low: u8) -> usize { + let out = ((high as u16) << 8) + low as u16; + out as usize +} + pub struct Vm { pub stack: Vec, pub call_stack: Vec, @@ -205,46 +210,61 @@ impl Vm { self.ip += 2; } Jump => { - let jump_len = self.chunk().bytecode[self.ip + 1]; - self.ip += jump_len as usize + 2; + let high = self.chunk().bytecode[self.ip + 1]; + let low = self.chunk().bytecode[self.ip + 2]; + let jump_len = combine_bytes(high, low); + // let jump_len = self.chunk().bytecode[self.ip + 1]; + self.ip += jump_len + 3; } JumpBack => { - let jump_len = self.chunk().bytecode[self.ip + 1]; - self.ip -= jump_len as usize; + let high = self.chunk().bytecode[self.ip + 1]; + let low = self.chunk().bytecode[self.ip + 2]; + let jump_len = combine_bytes(high, low); + // let jump_len = self.chunk().bytecode[self.ip + 1]; + self.ip -= jump_len; } JumpIfFalse => { - let jump_len = self.chunk().bytecode[self.ip + 1]; + let high = self.chunk().bytecode[self.ip + 1]; + let low = self.chunk().bytecode[self.ip + 2]; + let jump_len = combine_bytes(high, low); + // let jump_len = self.chunk().bytecode[self.ip + 1]; let cond = self.pop(); match cond { Value::Nil | Value::False => { - self.ip += jump_len as usize + 2; + self.ip += jump_len + 3; } _ => { - self.ip += 2; + self.ip += 3; } } } JumpIfTrue => { - let jump_len = self.chunk().bytecode[self.ip + 1]; + let high = self.chunk().bytecode[self.ip + 1]; + let low = self.chunk().bytecode[self.ip + 2]; + let jump_len = combine_bytes(high, low); + // let jump_len = self.chunk().bytecode[self.ip + 1]; let cond = self.pop(); match cond { Value::Nil | Value::False => { - self.ip += 2; + self.ip += 3; } _ => { - self.ip += jump_len as usize + 2; + self.ip += jump_len + 3; } } } JumpIfZero => { - let jump_len = self.chunk().bytecode[self.ip + 1]; + let high = self.chunk().bytecode[self.ip + 1]; + let low = self.chunk().bytecode[self.ip + 2]; + let jump_len = combine_bytes(high, low); + // let jump_len = self.chunk().bytecode[self.ip + 1]; let cond = self.pop(); match cond { Value::Number(x) if x <= 0.0 => { - self.ip += jump_len as usize + 2; + self.ip += jump_len as usize + 3; } Value::Number(..) => { - self.ip += 2; + self.ip += 3; } _ => return self.panic("repeat requires a number"), } @@ -542,19 +562,25 @@ impl Vm { self.ip += 1; } JumpIfNoMatch => { - let jump_len = self.chunk().bytecode[self.ip + 1] as usize; + let high = self.chunk().bytecode[self.ip + 1]; + let low = self.chunk().bytecode[self.ip + 2]; + let jump_len = combine_bytes(high, low); + // let jump_len = self.chunk().bytecode[self.ip + 1] as usize; if !self.matches { - self.ip += jump_len + 2; + self.ip += jump_len + 3; } else { - self.ip += 2; + self.ip += 3; } } JumpIfMatch => { - let jump_len = self.chunk().bytecode[self.ip + 1] as usize; + let high = self.chunk().bytecode[self.ip + 1]; + let low = self.chunk().bytecode[self.ip + 2]; + let jump_len = combine_bytes(high, low); + // let jump_len = self.chunk().bytecode[self.ip + 1] as usize; if self.matches { - self.ip += jump_len + 2; + self.ip += jump_len + 3; } else { - self.ip += 2; + self.ip += 3; } } TypeOf => {