aboutsummaryrefslogtreecommitdiff
path: root/crates/sloth_vm/src/vm.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/sloth_vm/src/vm.rs')
-rw-r--r--crates/sloth_vm/src/vm.rs55
1 files changed, 36 insertions, 19 deletions
diff --git a/crates/sloth_vm/src/vm.rs b/crates/sloth_vm/src/vm.rs
index ded7aa6..cab797e 100644
--- a/crates/sloth_vm/src/vm.rs
+++ b/crates/sloth_vm/src/vm.rs
@@ -13,20 +13,18 @@ pub struct CallFrame {
}
impl CallFrame {
- #[inline]
- fn function(&self) -> &Function {
- unsafe { &*self.function }
- }
-}
-
-impl From<&Function> for CallFrame {
- fn from(value: &Function) -> Self {
+ fn new(stack_offset: usize, function: &Function) -> Self {
Self {
pointer: 0,
- stack_offset: 0,
- function: value as *const _,
+ stack_offset,
+ function: function as *const _,
}
}
+
+ #[inline]
+ fn function(&self) -> &Function {
+ unsafe { &*self.function }
+ }
}
const CALL_STACK_SIZE: usize = 1024;
@@ -89,8 +87,8 @@ impl VM {
let mut this = Self::init(objects);
// Allocating the root function
- root.chunk.code.push(Opcode::Hlt as u8);
- this.call_stack.push(CallFrame::from(&root));
+ root.chunk.code.push(Opcode::Halt as u8);
+ this.call_stack.push(CallFrame::new(0, &root));
this.objects
.allocate(Object::new(ObjectType::Function(root)));
@@ -104,8 +102,8 @@ impl VM {
match Opcode::from_u8(opcode) {
Opcode::Constant => {
- let idx = self.read_u16();
- let value = self.call_stack.peek().function().chunk.constants[idx as usize];
+ let idx = self.read_u16() as usize;
+ let value = self.call_stack.peek().function().chunk.constants[idx];
self.stack.push(value);
}
@@ -114,9 +112,21 @@ impl VM {
self.stack.push(value);
self.stack.push(value);
}
- Opcode::Del => {
+ Opcode::Pop => {
self.stack.pop();
}
+ Opcode::GetLocal => {
+ let idx = self.read_u16() as usize;
+ let value = self.stack[self.call_stack.peek().stack_offset + idx];
+
+ self.stack.push(value);
+ }
+ Opcode::SetLocal => {
+ let idx = self.read_u16() as usize;
+ let value = self.stack.pop();
+
+ self.stack[self.call_stack.peek().stack_offset + idx] = value;
+ }
Opcode::Add => {
let value = match self.stack.pop2() {
@@ -179,7 +189,7 @@ impl VM {
};
// Push the function onto the call stack
- self.call_stack.push(CallFrame::from(function));
+ self.call_stack.push(CallFrame::new(0, function));
}
Opcode::Return => {
@@ -188,8 +198,7 @@ impl VM {
self.call_stack.pop();
}
- Opcode::Hlt => return false,
- Opcode::Exit => return false,
+ Opcode::Halt => return false,
_ => unimplemented!(),
}
@@ -201,6 +210,14 @@ impl VM {
while self.step() {}
}
+ fn call(&mut self, function: &Function) {
+ self.call_stack.push(CallFrame {
+ pointer: 0,
+ stack_offset: self.stack.top - 1 - (function.arity as usize),
+ function,
+ });
+ }
+
#[inline(always)]
fn read_u8(&mut self) -> u8 {
let frame = self.call_stack.peek_mut();
@@ -274,7 +291,7 @@ mod tests {
name: Some("foo".to_string()),
chunk: Chunk {
constants: vec![Primitive::Integer(7)],
- code: vec![0x00, 0, 0, 0x10, 0x20, 0x51],
+ code: vec![0x00, 0, 0, 0x10, 0x20, 0x52],
},
arity: 0,
})),