diff options
| author | Cody <cody@codyq.dev> | 2023-04-12 15:21:11 -0500 |
|---|---|---|
| committer | Cody <cody@codyq.dev> | 2023-04-12 15:21:11 -0500 |
| commit | 209328c5fa7d57805cb362e3a792232cb6e39ad0 (patch) | |
| tree | fbfefadc3f14335fa47a14e58987b97b6fac58d9 /crates/sloth_vm/src | |
| parent | 76082958904ada89ab721ac0f3e140f0e0a7abab (diff) | |
| download | sloth-209328c5fa7d57805cb362e3a792232cb6e39ad0.tar.gz | |
Hahaha
Diffstat (limited to 'crates/sloth_vm/src')
| -rw-r--r-- | crates/sloth_vm/src/lib.rs | 23 | ||||
| -rw-r--r-- | crates/sloth_vm/src/vm.rs | 55 |
2 files changed, 58 insertions, 20 deletions
diff --git a/crates/sloth_vm/src/lib.rs b/crates/sloth_vm/src/lib.rs index be134d8..121ea6a 100644 --- a/crates/sloth_vm/src/lib.rs +++ b/crates/sloth_vm/src/lib.rs @@ -11,6 +11,8 @@ pub mod native; pub mod value; pub mod vm; +use std::ops::{Index, IndexMut}; + use value::{Object, ObjectType}; use crate::value::Primitive; @@ -25,8 +27,8 @@ const STACK_SIZE: usize = 1024; #[derive(Debug)] pub struct Stack { - top: usize, stack: [Primitive; STACK_SIZE], + top: usize, } impl Default for Stack { @@ -68,6 +70,25 @@ impl Stack { pub fn peek(&self) -> Primitive { self.stack[self.top - 1] } + + #[inline(always)] + pub fn peek_nth(&self, nth: usize) -> Primitive { + self.stack[self.top - 1 - nth] + } +} + +impl Index<usize> for Stack { + type Output = Primitive; + + fn index(&self, index: usize) -> &Self::Output { + &self.stack[index] + } +} + +impl IndexMut<usize> for Stack { + fn index_mut(&mut self, index: usize) -> &mut Self::Output { + &mut self.stack[index] + } } pub struct ObjectMap { 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, })), |
