1
0

Refine chunk poisoning and optimize taking values from registers

This commit is contained in:
Jeff 2024-11-06 15:08:51 -05:00
parent 87f597624a
commit d587d87ed7

View File

@ -72,9 +72,15 @@ impl Vm {
Operation::Move => { Operation::Move => {
let to_register = instruction.a(); let to_register = instruction.a();
let from_register = instruction.b(); let from_register = instruction.b();
let from_register_has_value = self
.stack
.get(from_register as usize)
.is_some_and(|register| !matches!(register, Register::Empty));
if from_register_has_value {
self.set_pointer(to_register, from_register, position)?; self.set_pointer(to_register, from_register, position)?;
} }
}
Operation::Close => { Operation::Close => {
let from_register = instruction.b(); let from_register = instruction.b();
let to_register = instruction.c(); let to_register = instruction.c();
@ -434,8 +440,9 @@ impl Vm {
value: Value, value: Value,
position: Span, position: Span,
) -> Result<(), VmError> { ) -> Result<(), VmError> {
let length = self.stack.len();
self.last_assigned_register = Some(to_register); self.last_assigned_register = Some(to_register);
let length = self.stack.len();
let to_register = to_register as usize; let to_register = to_register as usize;
if length == Self::STACK_LIMIT { if length == Self::STACK_LIMIT {
@ -481,8 +488,9 @@ impl Vm {
from_register: u8, from_register: u8,
position: Span, position: Span,
) -> Result<(), VmError> { ) -> Result<(), VmError> {
let length = self.stack.len();
self.last_assigned_register = Some(to_register); self.last_assigned_register = Some(to_register);
let length = self.stack.len();
let to_register = to_register as usize; let to_register = to_register as usize;
if length == Self::STACK_LIMIT { if length == Self::STACK_LIMIT {
@ -528,8 +536,9 @@ impl Vm {
constant_index: u8, constant_index: u8,
position: Span, position: Span,
) -> Result<(), VmError> { ) -> Result<(), VmError> {
let length = self.stack.len();
self.last_assigned_register = Some(to_register); self.last_assigned_register = Some(to_register);
let length = self.stack.len();
let to_register = to_register as usize; let to_register = to_register as usize;
if length == Self::STACK_LIMIT { if length == Self::STACK_LIMIT {
@ -598,27 +607,32 @@ impl Vm {
} }
let register = replace(&mut self.stack[index], Register::Empty); let register = replace(&mut self.stack[index], Register::Empty);
let value = match register {
match register { Register::Value(value) => value,
Register::Value(value) => Ok(value), Register::Pointer(register_index) => self.empty_register(register_index, position)?,
Register::Pointer(register_index) => {
let value = self.empty_register(register_index, position)?;
Ok(value)
}
Register::Constant(constant_index) => { Register::Constant(constant_index) => {
let constants = &mut self.chunk.constants_mut(); let constant_index = constant_index as usize;
constants.push(Value::integer(0)); if constant_index >= self.chunk.constants().len() {
return Err(VmError::Chunk {
error: ChunkError::ConstantIndexOutOfBounds {
index: constant_index,
},
position,
});
}
let constant = &mut self.chunk.constants_mut()[constant_index];
replace(constant, Value::integer(0))
}
Register::Empty => return Err(VmError::EmptyRegister { index, position }),
};
let value = constants.swap_remove(constant_index as usize);
self.chunk.is_poisoned = true; self.chunk.is_poisoned = true;
Ok(value) Ok(value)
} }
Register::Empty => Err(VmError::EmptyRegister { index, position }),
}
}
fn read(&mut self, position: Span) -> Result<&(Instruction, Span), VmError> { fn read(&mut self, position: Span) -> Result<&(Instruction, Span), VmError> {
self.chunk self.chunk