From 1409698fdd0a9ec7bbd54f917edfd393c0cf81c4 Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 13 Jan 2025 10:37:54 -0500 Subject: [PATCH] Fix some bugs to get language working with new 64-bit instructions --- dust-lang/src/chunk/disassembler.rs | 10 +- dust-lang/src/instruction/mod.rs | 2 +- dust-lang/src/instruction/operation.rs | 30 +++--- dust-lang/src/vm/mod.rs | 14 ++- dust-lang/src/vm/run_action.rs | 134 +++++++++++++++++++++++-- dust-lang/src/vm/thread.rs | 3 +- 6 files changed, 156 insertions(+), 37 deletions(-) diff --git a/dust-lang/src/chunk/disassembler.rs b/dust-lang/src/chunk/disassembler.rs index 817f4e2..ac209cd 100644 --- a/dust-lang/src/chunk/disassembler.rs +++ b/dust-lang/src/chunk/disassembler.rs @@ -46,11 +46,11 @@ use colored::{ColoredString, Colorize}; use crate::{Chunk, Local}; const INSTRUCTION_COLUMNS: [(&str, usize); 4] = - [("i", 5), ("POSITION", 12), ("OPERATION", 17), ("INFO", 36)]; + [("i", 5), ("POSITION", 12), ("OPERATION", 17), ("INFO", 41)]; const INSTRUCTION_BORDERS: [&str; 3] = [ - "╭─────┬────────────┬─────────────────┬────────────────────────────────────╮", - "├─────┼────────────┼─────────────────┼────────────────────────────────────┤", - "╰─────┴────────────┴─────────────────┴────────────────────────────────────╯", + "╭─────┬────────────┬─────────────────┬─────────────────────────────────────────╮", + "├─────┼────────────┼─────────────────┼─────────────────────────────────────────┤", + "╰─────┴────────────┴─────────────────┴─────────────────────────────────────────╯", ]; const LOCAL_COLUMNS: [(&str, usize); 5] = [ @@ -286,7 +286,7 @@ impl<'a, W: Write> Disassembler<'a, W> { .unwrap_or("stripped".to_string()); let operation = instruction.operation().to_string(); let info = instruction.disassembly_info(); - let row = format!("│{index:^5}│{position:^12}│{operation:^17}│{info:^36}│"); + let row = format!("│{index:^5}│{position:^12}│{operation:^17}│{info:^41}│"); self.write_center_border(&row)?; } diff --git a/dust-lang/src/instruction/mod.rs b/dust-lang/src/instruction/mod.rs index 6b55724..424819c 100644 --- a/dust-lang/src/instruction/mod.rs +++ b/dust-lang/src/instruction/mod.rs @@ -220,7 +220,7 @@ impl Instruction { } pub fn d_field(&self) -> bool { - (self.0 >> 54) & 1 == 0 + (self.0 >> 54) & 1 != 0 } pub fn b_type(&self) -> TypeCode { diff --git a/dust-lang/src/instruction/operation.rs b/dust-lang/src/instruction/operation.rs index 4c4a708..5617f9c 100644 --- a/dust-lang/src/instruction/operation.rs +++ b/dust-lang/src/instruction/operation.rs @@ -26,31 +26,31 @@ impl Operation { // Arithmetic pub const ADD: Operation = Operation(9); - pub const SUBTRACT: Operation = Operation(16); - pub const MULTIPLY: Operation = Operation(19); - pub const DIVIDE: Operation = Operation(22); - pub const MODULO: Operation = Operation(25); + pub const SUBTRACT: Operation = Operation(10); + pub const MULTIPLY: Operation = Operation(11); + pub const DIVIDE: Operation = Operation(12); + pub const MODULO: Operation = Operation(13); // Comparison - pub const EQUAL: Operation = Operation(28); - pub const LESS: Operation = Operation(36); - pub const LESS_EQUAL: Operation = Operation(41); + pub const EQUAL: Operation = Operation(14); + pub const LESS: Operation = Operation(15); + pub const LESS_EQUAL: Operation = Operation(16); // Unary operations - pub const NEGATE: Operation = Operation(46); - pub const NOT: Operation = Operation(48); + pub const NEGATE: Operation = Operation(17); + pub const NOT: Operation = Operation(18); // Logical operations - pub const TEST: Operation = Operation(49); - pub const TEST_SET: Operation = Operation(50); + pub const TEST: Operation = Operation(19); + pub const TEST_SET: Operation = Operation(20); // Function calls - pub const CALL: Operation = Operation(51); - pub const CALL_NATIVE: Operation = Operation(52); + pub const CALL: Operation = Operation(21); + pub const CALL_NATIVE: Operation = Operation(22); // Control flow - pub const JUMP: Operation = Operation(53); - pub const RETURN: Operation = Operation(54); + pub const JUMP: Operation = Operation(23); + pub const RETURN: Operation = Operation(24); } impl Operation { diff --git a/dust-lang/src/vm/mod.rs b/dust-lang/src/vm/mod.rs index 4cb6b1d..0e44c78 100644 --- a/dust-lang/src/vm/mod.rs +++ b/dust-lang/src/vm/mod.rs @@ -48,10 +48,16 @@ impl Vm { .unwrap_or_else(|| "anonymous".to_string()); let mut main_thread = Thread::new(Arc::new(self.main_chunk)); let (tx, rx) = bounded(1); - let _ = Builder::new().name(thread_name).spawn(move || { - let value_option = main_thread.run(); - let _ = tx.send(value_option); - }); + + Builder::new() + .name(thread_name) + .spawn(move || { + let value_option = main_thread.run(); + let _ = tx.send(value_option); + }) + .unwrap() + .join() + .unwrap(); rx.recv().unwrap_or(None) } diff --git a/dust-lang/src/vm/run_action.rs b/dust-lang/src/vm/run_action.rs index 25a4527..167419a 100644 --- a/dust-lang/src/vm/run_action.rs +++ b/dust-lang/src/vm/run_action.rs @@ -44,13 +44,13 @@ pub const RUNNER_LOGIC_TABLE: [RunnerLogic; 25] = [ multiply, divide, modulo, - test, - test_set, equal, less, less_equal, negate, not, + test, + test_set, call, call_native, jump, @@ -535,9 +535,65 @@ pub fn equal(instruction: Instruction, data: &mut ThreadData) -> bool { right, right_type, } = instruction.into(); - let left = data.get_argument_unchecked(left); - let right = data.get_argument_unchecked(right); - let is_equal = left.equals(right); + let is_equal = match (left_type, right_type) { + (TypeCode::INTEGER, TypeCode::INTEGER) => { + let left = unsafe { + data.get_argument_unchecked(left) + .as_integer() + .unwrap_unchecked() + }; + let right = unsafe { + data.get_argument_unchecked(right) + .as_integer() + .unwrap_unchecked() + }; + + left == right + } + (TypeCode::FLOAT, TypeCode::FLOAT) => { + let left = unsafe { + data.get_argument_unchecked(left) + .as_float() + .unwrap_unchecked() + }; + let right = unsafe { + data.get_argument_unchecked(right) + .as_float() + .unwrap_unchecked() + }; + + left == right + } + (TypeCode::BOOLEAN, TypeCode::BOOLEAN) => { + let left = unsafe { + data.get_argument_unchecked(left) + .as_boolean() + .unwrap_unchecked() + }; + let right = unsafe { + data.get_argument_unchecked(right) + .as_boolean() + .unwrap_unchecked() + }; + + left == right + } + (TypeCode::STRING, TypeCode::STRING) => { + let left = unsafe { + data.get_argument_unchecked(left) + .as_string() + .unwrap_unchecked() + }; + let right = unsafe { + data.get_argument_unchecked(right) + .as_string() + .unwrap_unchecked() + }; + + left == right + } + _ => panic!("VM Error: Cannot compare values"), + }; if is_equal == comparator { let current_call = data.call_stack.last_mut_unchecked(); @@ -558,9 +614,37 @@ pub fn less(instruction: Instruction, data: &mut ThreadData) -> bool { right, right_type, } = instruction.into(); - let left = data.get_argument_unchecked(left); - let right = data.get_argument_unchecked(right); - let is_less = left < right; + let is_less = match (left_type, right_type) { + (TypeCode::INTEGER, TypeCode::INTEGER) => { + let left = unsafe { + data.get_argument_unchecked(left) + .as_integer() + .unwrap_unchecked() + }; + let right = unsafe { + data.get_argument_unchecked(right) + .as_integer() + .unwrap_unchecked() + }; + + left < right + } + (TypeCode::FLOAT, TypeCode::FLOAT) => { + let left = unsafe { + data.get_argument_unchecked(left) + .as_float() + .unwrap_unchecked() + }; + let right = unsafe { + data.get_argument_unchecked(right) + .as_float() + .unwrap_unchecked() + }; + + left < right + } + _ => panic!("VM Error: Cannot compare values"), + }; if is_less == comparator { let current_call = data.call_stack.last_mut_unchecked(); @@ -581,9 +665,37 @@ pub fn less_equal(instruction: Instruction, data: &mut ThreadData) -> bool { right, right_type, } = instruction.into(); - let left = data.get_argument_unchecked(left); - let right = data.get_argument_unchecked(right); - let is_less_or_equal = left <= right; + let is_less_or_equal = match (left_type, right_type) { + (TypeCode::INTEGER, TypeCode::INTEGER) => { + let left = unsafe { + data.get_argument_unchecked(left) + .as_integer() + .unwrap_unchecked() + }; + let right = unsafe { + data.get_argument_unchecked(right) + .as_integer() + .unwrap_unchecked() + }; + + left <= right + } + (TypeCode::FLOAT, TypeCode::FLOAT) => { + let left = unsafe { + data.get_argument_unchecked(left) + .as_float() + .unwrap_unchecked() + }; + let right = unsafe { + data.get_argument_unchecked(right) + .as_float() + .unwrap_unchecked() + }; + + left <= right + } + _ => panic!("VM Error: Cannot compare values"), + }; if is_less_or_equal == comparator { let current_call = data.call_stack.last_mut_unchecked(); diff --git a/dust-lang/src/vm/thread.rs b/dust-lang/src/vm/thread.rs index 30b84a6..c605066 100644 --- a/dust-lang/src/vm/thread.rs +++ b/dust-lang/src/vm/thread.rs @@ -25,7 +25,8 @@ impl Thread { ); let mut call_stack = Stack::with_capacity(self.chunk.prototypes.len() + 1); - let main_call = FunctionCall::new(self.chunk.clone(), 0); + let mut main_call = FunctionCall::new(self.chunk.clone(), 0); + main_call.ip = 1; // The first action is already known call_stack.push(main_call);