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 {
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<Value>,
pub call_stack: Vec<CallFrame>,
@ -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 => {