VM instructions now take 3 bytes

This commit is contained in:
Scott Richmond 2025-06-18 14:12:10 -04:00
parent 979afdbcb9
commit d727096422

View File

@ -57,7 +57,7 @@ impl CallFrame {
let Value::Fn(ref function) = self.function else { let Value::Fn(ref function) = self.function else {
unreachable!() 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 struct Vm {
pub stack: Vec<Value>, pub stack: Vec<Value>,
pub call_stack: Vec<CallFrame>, pub call_stack: Vec<CallFrame>,
@ -205,46 +210,61 @@ impl Vm {
self.ip += 2; self.ip += 2;
} }
Jump => { Jump => {
let jump_len = self.chunk().bytecode[self.ip + 1]; let high = self.chunk().bytecode[self.ip + 1];
self.ip += jump_len as usize + 2; 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 => { JumpBack => {
let jump_len = self.chunk().bytecode[self.ip + 1]; let high = self.chunk().bytecode[self.ip + 1];
self.ip -= jump_len as usize; 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 => { 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(); let cond = self.pop();
match cond { match cond {
Value::Nil | Value::False => { Value::Nil | Value::False => {
self.ip += jump_len as usize + 2; self.ip += jump_len + 3;
} }
_ => { _ => {
self.ip += 2; self.ip += 3;
} }
} }
} }
JumpIfTrue => { 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(); let cond = self.pop();
match cond { match cond {
Value::Nil | Value::False => { Value::Nil | Value::False => {
self.ip += 2; self.ip += 3;
} }
_ => { _ => {
self.ip += jump_len as usize + 2; self.ip += jump_len + 3;
} }
} }
} }
JumpIfZero => { 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(); let cond = self.pop();
match cond { match cond {
Value::Number(x) if x <= 0.0 => { Value::Number(x) if x <= 0.0 => {
self.ip += jump_len as usize + 2; self.ip += jump_len as usize + 3;
} }
Value::Number(..) => { Value::Number(..) => {
self.ip += 2; self.ip += 3;
} }
_ => return self.panic("repeat requires a number"), _ => return self.panic("repeat requires a number"),
} }
@ -542,19 +562,25 @@ impl Vm {
self.ip += 1; self.ip += 1;
} }
JumpIfNoMatch => { 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 { if !self.matches {
self.ip += jump_len + 2; self.ip += jump_len + 3;
} else { } else {
self.ip += 2; self.ip += 3;
} }
} }
JumpIfMatch => { 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 { if self.matches {
self.ip += jump_len + 2; self.ip += jump_len + 3;
} else { } else {
self.ip += 2; self.ip += 3;
} }
} }
TypeOf => { TypeOf => {