From 209328c5fa7d57805cb362e3a792232cb6e39ad0 Mon Sep 17 00:00:00 2001 From: Cody Date: Wed, 12 Apr 2023 15:21:11 -0500 Subject: Hahaha --- crates/sloth_bytecode/src/lib.rs | 17 ++++++++----- crates/sloth_vm/src/lib.rs | 23 ++++++++++++++++- crates/sloth_vm/src/vm.rs | 55 ++++++++++++++++++++++++++-------------- 3 files changed, 69 insertions(+), 26 deletions(-) (limited to 'crates') diff --git a/crates/sloth_bytecode/src/lib.rs b/crates/sloth_bytecode/src/lib.rs index df91c41..992c24f 100644 --- a/crates/sloth_bytecode/src/lib.rs +++ b/crates/sloth_bytecode/src/lib.rs @@ -45,7 +45,12 @@ opcodes! { 0x02 Push "Push a value to a variable", 0x10 Dup "Duplicate a value on the stack", - 0x11 Del "Delete a value from the stack", + 0x11 Pop "Pop a value from the stack", + + 0x12 GetGlobal "Get a global value", + 0x13 SetGlobal "Set a global value", + 0x14 GetLocal "Get a local value", + 0x15 SetLocal "Set a local value", 0x20 Add "Add the last 2 values on the stack", 0x21 Sub "Subtract the last 2 values on the stack", @@ -56,14 +61,14 @@ opcodes! { 0x30 Eq "Check if the last 2 values on the stack are equal", 0x31 Ne "Check if the last 2 values on the stack are not equal", - 0x40 Jmp "Jump to a specific point in the program", - 0x41 JmpIf "Jump to a specific point in the program if true is on the stack", + 0x40 Jump "Jump to a specific point in the program", + 0x41 JumpIf "Jump to a specific point in the program if true is on the stack", 0x50 Call "Call function on stack", - 0x51 Return "Return from function on stack", + 0x51 CallNative "Call native function", + 0x52 Return "Return from function on stack", - 0xE0 Hlt "Halt the program", - 0xE1 Exit "Exit the program", + 0xE0 Halt "Halt the program", 0xF0 VMReturn "[DEBUG] Pop value from stack and return it fromthe program", 0xF1 VMPrint "[DEBUG] Print value to console" 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 for Stack { + type Output = Primitive; + + fn index(&self, index: usize) -> &Self::Output { + &self.stack[index] + } +} + +impl IndexMut 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, })), -- cgit v1.2.3