Fix some bugs to get language working with new 64-bit instructions
This commit is contained in:
parent
ac1ee793ab
commit
1409698fdd
@ -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)?;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 || {
|
||||
|
||||
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)
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user