Fill out more VM actions
This commit is contained in:
parent
b0f7ca7992
commit
0292a01162
@ -3,15 +3,16 @@ use std::ops::Add;
|
||||
use tracing::trace;
|
||||
|
||||
use crate::{
|
||||
instruction::InstructionFields,
|
||||
vm::{call_frame::RuntimeValue, Thread},
|
||||
DustString,
|
||||
DustString, Instruction,
|
||||
};
|
||||
|
||||
pub fn add_bytes(_: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let destination_index = instruction.a_field as usize;
|
||||
let left_index = instruction.b_field as usize;
|
||||
let right_index = instruction.c_field as usize;
|
||||
use super::Cache;
|
||||
|
||||
pub fn add_bytes(_: &mut usize, instruction: &Instruction, thread: &mut Thread, _: &mut Cache) {
|
||||
let destination_index = instruction.a_field() as usize;
|
||||
let left_index = instruction.b_field() as usize;
|
||||
let right_index = instruction.c_field() as usize;
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = current_frame.get_byte_from_register(left_index).clone();
|
||||
@ -26,12 +27,17 @@ pub fn add_bytes(_: &mut usize, instruction: &InstructionFields, thread: &mut Th
|
||||
.set_inner(sum);
|
||||
}
|
||||
|
||||
pub fn add_characters(_: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let destination_index = instruction.a_field as usize;
|
||||
let left_index = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
pub fn add_characters(
|
||||
_: &mut usize,
|
||||
instruction: &Instruction,
|
||||
thread: &mut Thread,
|
||||
_: &mut Cache,
|
||||
) {
|
||||
let destination_index = instruction.a_field() as usize;
|
||||
let left_index = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
@ -60,12 +66,12 @@ pub fn add_characters(_: &mut usize, instruction: &InstructionFields, thread: &m
|
||||
.set(concatenated);
|
||||
}
|
||||
|
||||
pub fn add_floats(_: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let destination = instruction.a_field as usize;
|
||||
let left = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
pub fn add_floats(_: &mut usize, instruction: &Instruction, thread: &mut Thread, _: &mut Cache) {
|
||||
let destination = instruction.a_field() as usize;
|
||||
let left = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
@ -90,12 +96,12 @@ pub fn add_floats(_: &mut usize, instruction: &InstructionFields, thread: &mut T
|
||||
.set_inner(sum);
|
||||
}
|
||||
|
||||
pub fn add_integers(_: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let destination = instruction.a_field as usize;
|
||||
let left = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
pub fn add_integers(_: &mut usize, instruction: &Instruction, thread: &mut Thread, _: &mut Cache) {
|
||||
let destination = instruction.a_field() as usize;
|
||||
let left = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
@ -120,12 +126,12 @@ pub fn add_integers(_: &mut usize, instruction: &InstructionFields, thread: &mut
|
||||
.set_inner(sum);
|
||||
}
|
||||
|
||||
pub fn add_strings(_: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let destination = instruction.a_field as usize;
|
||||
let left = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
pub fn add_strings(_: &mut usize, instruction: &Instruction, thread: &mut Thread, _: &mut Cache) {
|
||||
let destination = instruction.a_field() as usize;
|
||||
let left = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
@ -148,12 +154,17 @@ pub fn add_strings(_: &mut usize, instruction: &InstructionFields, thread: &mut
|
||||
.set_inner(concatenated);
|
||||
}
|
||||
|
||||
pub fn add_character_string(_: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let destination = instruction.a_field as usize;
|
||||
let left = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
pub fn add_character_string(
|
||||
_: &mut usize,
|
||||
instruction: &Instruction,
|
||||
thread: &mut Thread,
|
||||
_: &mut Cache,
|
||||
) {
|
||||
let destination = instruction.a_field() as usize;
|
||||
let left = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
@ -176,12 +187,17 @@ pub fn add_character_string(_: &mut usize, instruction: &InstructionFields, thre
|
||||
.set_inner(concatenated);
|
||||
}
|
||||
|
||||
pub fn add_string_character(_: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let destination = instruction.a_field as usize;
|
||||
let left = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
pub fn add_string_character(
|
||||
_: &mut usize,
|
||||
instruction: &Instruction,
|
||||
thread: &mut Thread,
|
||||
_: &mut Cache,
|
||||
) {
|
||||
let destination = instruction.a_field() as usize;
|
||||
let left = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
@ -206,22 +222,22 @@ pub fn add_string_character(_: &mut usize, instruction: &InstructionFields, thre
|
||||
|
||||
pub fn optimized_add_integer(
|
||||
_: &mut usize,
|
||||
instruction: &InstructionFields,
|
||||
instruction: &Instruction,
|
||||
thread: &mut Thread,
|
||||
cache: &mut Option<[RuntimeValue<i64>; 3]>,
|
||||
cache: &mut Cache,
|
||||
) {
|
||||
if let Some([destination, left, right]) = cache {
|
||||
if let Cache::IntegerMath([destination, left, right]) = cache {
|
||||
trace!("OPTIMIZED_ADD using integer cache");
|
||||
|
||||
let sum = left.add(right);
|
||||
|
||||
*destination.borrow_mut() = sum;
|
||||
} else {
|
||||
let destination_index = instruction.a_field as usize;
|
||||
let left_index = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right_index = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let destination_index = instruction.a_field() as usize;
|
||||
let left_index = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right_index = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
let value = current_frame.get_integer_constant_mut(left_index).to_rc();
|
||||
@ -266,6 +282,6 @@ pub fn optimized_add_integer(
|
||||
value
|
||||
};
|
||||
|
||||
*cache = Some([destination, left_value, right_value]);
|
||||
*cache = Cache::IntegerMath([destination, left_value, right_value]);
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,18 @@
|
||||
use tracing::trace;
|
||||
|
||||
use crate::{
|
||||
instruction::InstructionFields,
|
||||
vm::{RuntimeValue, Thread},
|
||||
};
|
||||
use crate::{vm::Thread, Instruction};
|
||||
|
||||
pub fn equal_booleans(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left_index = instruction.b_field as usize;
|
||||
let right_index = instruction.c_field as usize;
|
||||
let comparator = instruction.d_field;
|
||||
use super::Cache;
|
||||
|
||||
pub fn equal_booleans(
|
||||
ip: &mut usize,
|
||||
instruction: &Instruction,
|
||||
thread: &mut Thread,
|
||||
_: &mut Cache,
|
||||
) {
|
||||
let left_index = instruction.b_field() as usize;
|
||||
let right_index = instruction.c_field() as usize;
|
||||
let comparator = instruction.d_field();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = current_frame.get_boolean_from_register(left_index);
|
||||
@ -20,10 +24,10 @@ pub fn equal_booleans(ip: &mut usize, instruction: &InstructionFields, thread: &
|
||||
}
|
||||
}
|
||||
|
||||
pub fn equal_bytes(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left = instruction.b_field as usize;
|
||||
let right = instruction.c_field as usize;
|
||||
let comparator = instruction.d_field;
|
||||
pub fn equal_bytes(ip: &mut usize, instruction: &Instruction, thread: &mut Thread, _: &mut Cache) {
|
||||
let left = instruction.b_field() as usize;
|
||||
let right = instruction.c_field() as usize;
|
||||
let comparator = instruction.d_field();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = current_frame.get_byte_from_register(left);
|
||||
@ -35,12 +39,17 @@ pub fn equal_bytes(ip: &mut usize, instruction: &InstructionFields, thread: &mut
|
||||
}
|
||||
}
|
||||
|
||||
pub fn equal_characters(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left_index = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right_index = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
pub fn equal_characters(
|
||||
ip: &mut usize,
|
||||
instruction: &Instruction,
|
||||
thread: &mut Thread,
|
||||
_: &mut Cache,
|
||||
) {
|
||||
let left_index = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right_index = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
let comparator = instruction.d_field();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
@ -60,12 +69,12 @@ pub fn equal_characters(ip: &mut usize, instruction: &InstructionFields, thread:
|
||||
}
|
||||
}
|
||||
|
||||
pub fn equal_floats(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
pub fn equal_floats(ip: &mut usize, instruction: &Instruction, thread: &mut Thread, _: &mut Cache) {
|
||||
let left = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
let comparator = instruction.d_field();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
@ -85,12 +94,17 @@ pub fn equal_floats(ip: &mut usize, instruction: &InstructionFields, thread: &mu
|
||||
}
|
||||
}
|
||||
|
||||
pub fn equal_integers(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
pub fn equal_integers(
|
||||
ip: &mut usize,
|
||||
instruction: &Instruction,
|
||||
thread: &mut Thread,
|
||||
_: &mut Cache,
|
||||
) {
|
||||
let left = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
let comparator = instruction.d_field();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
@ -110,12 +124,17 @@ pub fn equal_integers(ip: &mut usize, instruction: &InstructionFields, thread: &
|
||||
}
|
||||
}
|
||||
|
||||
pub fn equal_strings(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
pub fn equal_strings(
|
||||
ip: &mut usize,
|
||||
instruction: &Instruction,
|
||||
thread: &mut Thread,
|
||||
_: &mut Cache,
|
||||
) {
|
||||
let left = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
let comparator = instruction.d_field();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
@ -137,11 +156,11 @@ pub fn equal_strings(ip: &mut usize, instruction: &InstructionFields, thread: &m
|
||||
|
||||
pub fn optimized_equal_integers(
|
||||
ip: &mut usize,
|
||||
instruction: &InstructionFields,
|
||||
instruction: &Instruction,
|
||||
thread: &mut Thread,
|
||||
cache: &mut Option<[RuntimeValue<i64>; 3]>,
|
||||
cache: &mut Cache,
|
||||
) {
|
||||
if let Some([_, left, right]) = cache {
|
||||
if let Cache::IntegerComparison([left, right]) = cache {
|
||||
trace!("equal_INTEGERS_OPTIMIZED using cache");
|
||||
|
||||
let is_equal = left == right;
|
||||
@ -150,11 +169,11 @@ pub fn optimized_equal_integers(
|
||||
*ip += 1;
|
||||
}
|
||||
} else {
|
||||
let left_index = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right_index = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
let left_index = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right_index = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
let comparator = instruction.d_field();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
@ -193,6 +212,6 @@ pub fn optimized_equal_integers(
|
||||
*ip += 1;
|
||||
}
|
||||
|
||||
*cache = Some([RuntimeValue::Raw(0), left_value, right_value]);
|
||||
*cache = Cache::IntegerComparison([left_value, right_value]);
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
use tracing::trace;
|
||||
|
||||
use crate::{instruction::InstructionFields, vm::Thread};
|
||||
use crate::{vm::Thread, Instruction};
|
||||
|
||||
pub fn jump(ip: &mut usize, instruction: &InstructionFields, _: &mut Thread) {
|
||||
let offset = instruction.b_field as usize;
|
||||
let is_positive = instruction.c_field != 0;
|
||||
use super::Cache;
|
||||
|
||||
pub fn jump(ip: &mut usize, instruction: &Instruction, _: &mut Thread, _: &mut Cache) {
|
||||
let offset = instruction.b_field() as usize;
|
||||
let is_positive = instruction.c_field() != 0;
|
||||
|
||||
if is_positive {
|
||||
trace!("JUMP +{}", offset);
|
||||
@ -18,3 +20,29 @@ pub fn jump(ip: &mut usize, instruction: &InstructionFields, _: &mut Thread) {
|
||||
*ip -= offset + 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn optimized_jump_forward(
|
||||
ip: &mut usize,
|
||||
instruction: &Instruction,
|
||||
_: &mut Thread,
|
||||
_: &mut Cache,
|
||||
) {
|
||||
let offset = instruction.b_field() as usize;
|
||||
|
||||
trace!("JUMP +{}", offset);
|
||||
|
||||
*ip += offset;
|
||||
}
|
||||
|
||||
pub fn optimized_jump_backward(
|
||||
ip: &mut usize,
|
||||
instruction: &Instruction,
|
||||
_: &mut Thread,
|
||||
_: &mut Cache,
|
||||
) {
|
||||
let offset = instruction.b_field() as usize;
|
||||
|
||||
trace!("JUMP -{}", offset);
|
||||
|
||||
*ip -= offset + 1;
|
||||
}
|
||||
|
@ -1,14 +1,18 @@
|
||||
use tracing::trace;
|
||||
|
||||
use crate::{
|
||||
instruction::InstructionFields,
|
||||
vm::{RuntimeValue, Thread},
|
||||
};
|
||||
use crate::{vm::Thread, Instruction};
|
||||
|
||||
pub fn less_booleans(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left_index = instruction.b_field as usize;
|
||||
let right_index = instruction.c_field as usize;
|
||||
let comparator = instruction.d_field;
|
||||
use super::Cache;
|
||||
|
||||
pub fn less_booleans(
|
||||
ip: &mut usize,
|
||||
instruction: &Instruction,
|
||||
thread: &mut Thread,
|
||||
_: &mut Cache,
|
||||
) {
|
||||
let left_index = instruction.b_field() as usize;
|
||||
let right_index = instruction.c_field() as usize;
|
||||
let comparator = instruction.d_field();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = current_frame.get_boolean_from_register(left_index);
|
||||
@ -20,10 +24,10 @@ pub fn less_booleans(ip: &mut usize, instruction: &InstructionFields, thread: &m
|
||||
}
|
||||
}
|
||||
|
||||
pub fn less_bytes(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left = instruction.b_field as usize;
|
||||
let right = instruction.c_field as usize;
|
||||
let comparator = instruction.d_field;
|
||||
pub fn less_bytes(ip: &mut usize, instruction: &Instruction, thread: &mut Thread, _: &mut Cache) {
|
||||
let left = instruction.b_field() as usize;
|
||||
let right = instruction.c_field() as usize;
|
||||
let comparator = instruction.d_field();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = current_frame.get_byte_from_register(left);
|
||||
@ -35,12 +39,17 @@ pub fn less_bytes(ip: &mut usize, instruction: &InstructionFields, thread: &mut
|
||||
}
|
||||
}
|
||||
|
||||
pub fn less_characters(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left_index = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right_index = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
pub fn less_characters(
|
||||
ip: &mut usize,
|
||||
instruction: &Instruction,
|
||||
thread: &mut Thread,
|
||||
_: &mut Cache,
|
||||
) {
|
||||
let left_index = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right_index = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
let comparator = instruction.d_field();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
@ -60,12 +69,12 @@ pub fn less_characters(ip: &mut usize, instruction: &InstructionFields, thread:
|
||||
}
|
||||
}
|
||||
|
||||
pub fn less_floats(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
pub fn less_floats(ip: &mut usize, instruction: &Instruction, thread: &mut Thread, _: &mut Cache) {
|
||||
let left = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
let comparator = instruction.d_field();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
@ -85,12 +94,17 @@ pub fn less_floats(ip: &mut usize, instruction: &InstructionFields, thread: &mut
|
||||
}
|
||||
}
|
||||
|
||||
pub fn less_integers(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
pub fn less_integers(
|
||||
ip: &mut usize,
|
||||
instruction: &Instruction,
|
||||
thread: &mut Thread,
|
||||
_: &mut Cache,
|
||||
) {
|
||||
let left = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
let comparator = instruction.d_field();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
@ -110,12 +124,12 @@ pub fn less_integers(ip: &mut usize, instruction: &InstructionFields, thread: &m
|
||||
}
|
||||
}
|
||||
|
||||
pub fn less_strings(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
pub fn less_strings(ip: &mut usize, instruction: &Instruction, thread: &mut Thread, _: &mut Cache) {
|
||||
let left = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
let comparator = instruction.d_field();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
@ -137,11 +151,11 @@ pub fn less_strings(ip: &mut usize, instruction: &InstructionFields, thread: &mu
|
||||
|
||||
pub fn optimized_less_integers(
|
||||
ip: &mut usize,
|
||||
instruction: &InstructionFields,
|
||||
instruction: &Instruction,
|
||||
thread: &mut Thread,
|
||||
cache: &mut Option<[RuntimeValue<i64>; 3]>,
|
||||
cache: &mut Cache,
|
||||
) {
|
||||
if let Some([_, left, right]) = cache {
|
||||
if let Cache::IntegerComparison([left, right]) = cache {
|
||||
trace!("OPTIMIZED_LESS using integer cache");
|
||||
|
||||
let is_less_than = left < right;
|
||||
@ -150,11 +164,11 @@ pub fn optimized_less_integers(
|
||||
*ip += 1;
|
||||
}
|
||||
} else {
|
||||
let left_index = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right_index = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
let left_index = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right_index = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
let comparator = instruction.d_field();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
@ -193,6 +207,6 @@ pub fn optimized_less_integers(
|
||||
*ip += 1;
|
||||
}
|
||||
|
||||
*cache = Some([RuntimeValue::Raw(0), left_value, right_value]);
|
||||
*cache = Cache::IntegerComparison([left_value, right_value]);
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,18 @@
|
||||
use tracing::trace;
|
||||
|
||||
use crate::{
|
||||
instruction::InstructionFields,
|
||||
vm::{RuntimeValue, Thread},
|
||||
};
|
||||
use crate::{vm::Thread, Instruction};
|
||||
|
||||
pub fn less_equal_booleans(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left_index = instruction.b_field as usize;
|
||||
let right_index = instruction.c_field as usize;
|
||||
let comparator = instruction.d_field;
|
||||
use super::Cache;
|
||||
|
||||
pub fn less_equal_booleans(
|
||||
ip: &mut usize,
|
||||
instruction: &Instruction,
|
||||
thread: &mut Thread,
|
||||
_: &mut Cache,
|
||||
) {
|
||||
let left_index = instruction.b_field() as usize;
|
||||
let right_index = instruction.c_field() as usize;
|
||||
let comparator = instruction.d_field();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = current_frame.get_boolean_from_register(left_index);
|
||||
@ -20,10 +24,15 @@ pub fn less_equal_booleans(ip: &mut usize, instruction: &InstructionFields, thre
|
||||
}
|
||||
}
|
||||
|
||||
pub fn less_equal_bytes(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left = instruction.b_field as usize;
|
||||
let right = instruction.c_field as usize;
|
||||
let comparator = instruction.d_field;
|
||||
pub fn less_equal_bytes(
|
||||
ip: &mut usize,
|
||||
instruction: &Instruction,
|
||||
thread: &mut Thread,
|
||||
_: &mut Cache,
|
||||
) {
|
||||
let left = instruction.b_field() as usize;
|
||||
let right = instruction.c_field() as usize;
|
||||
let comparator = instruction.d_field();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = current_frame.get_byte_from_register(left);
|
||||
@ -35,12 +44,17 @@ pub fn less_equal_bytes(ip: &mut usize, instruction: &InstructionFields, thread:
|
||||
}
|
||||
}
|
||||
|
||||
pub fn less_equal_characters(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left_index = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right_index = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
pub fn less_equal_characters(
|
||||
ip: &mut usize,
|
||||
instruction: &Instruction,
|
||||
thread: &mut Thread,
|
||||
_: &mut Cache,
|
||||
) {
|
||||
let left_index = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right_index = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
let comparator = instruction.d_field();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
@ -60,12 +74,17 @@ pub fn less_equal_characters(ip: &mut usize, instruction: &InstructionFields, th
|
||||
}
|
||||
}
|
||||
|
||||
pub fn less_equal_floats(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
pub fn less_equal_floats(
|
||||
ip: &mut usize,
|
||||
instruction: &Instruction,
|
||||
thread: &mut Thread,
|
||||
_: &mut Cache,
|
||||
) {
|
||||
let left = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
let comparator = instruction.d_field();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
@ -85,12 +104,17 @@ pub fn less_equal_floats(ip: &mut usize, instruction: &InstructionFields, thread
|
||||
}
|
||||
}
|
||||
|
||||
pub fn less_equal_integers(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
pub fn less_equal_integers(
|
||||
ip: &mut usize,
|
||||
instruction: &Instruction,
|
||||
thread: &mut Thread,
|
||||
_: &mut Cache,
|
||||
) {
|
||||
let left = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
let comparator = instruction.d_field();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
@ -110,12 +134,17 @@ pub fn less_equal_integers(ip: &mut usize, instruction: &InstructionFields, thre
|
||||
}
|
||||
}
|
||||
|
||||
pub fn less_equal_strings(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
pub fn less_equal_strings(
|
||||
ip: &mut usize,
|
||||
instruction: &Instruction,
|
||||
thread: &mut Thread,
|
||||
_: &mut Cache,
|
||||
) {
|
||||
let left = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
let comparator = instruction.d_field();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
@ -137,11 +166,11 @@ pub fn less_equal_strings(ip: &mut usize, instruction: &InstructionFields, threa
|
||||
|
||||
pub fn optimized_less_equal_integers(
|
||||
ip: &mut usize,
|
||||
instruction: &InstructionFields,
|
||||
instruction: &Instruction,
|
||||
thread: &mut Thread,
|
||||
cache: &mut Option<[RuntimeValue<i64>; 3]>,
|
||||
cache: &mut Cache,
|
||||
) {
|
||||
if let Some([_, left, right]) = cache {
|
||||
if let Cache::IntegerComparison([left, right]) = cache {
|
||||
trace!("LESS_INTEGERS_OPTIMIZED using cache");
|
||||
|
||||
let is_less_than_or_equal = left <= right;
|
||||
@ -150,11 +179,11 @@ pub fn optimized_less_equal_integers(
|
||||
*ip += 1;
|
||||
}
|
||||
} else {
|
||||
let left_index = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right_index = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
let left_index = instruction.b_field() as usize;
|
||||
let left_is_constant = instruction.b_is_constant();
|
||||
let right_index = instruction.c_field() as usize;
|
||||
let right_is_constant = instruction.c_is_constant();
|
||||
let comparator = instruction.d_field();
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
@ -193,6 +222,6 @@ pub fn optimized_less_equal_integers(
|
||||
*ip += 1;
|
||||
}
|
||||
|
||||
*cache = Some([RuntimeValue::Raw(0), left_value, right_value]);
|
||||
*cache = Cache::IntegerComparison([left_value, right_value]);
|
||||
}
|
||||
}
|
||||
|
@ -8,8 +8,11 @@ use add::{
|
||||
add_bytes, add_character_string, add_characters, add_floats, add_integers,
|
||||
add_string_character, add_strings, optimized_add_integer,
|
||||
};
|
||||
use equal::optimized_equal_integers;
|
||||
use jump::jump;
|
||||
use equal::{
|
||||
equal_booleans, equal_bytes, equal_characters, equal_floats, equal_integers, equal_strings,
|
||||
optimized_equal_integers,
|
||||
};
|
||||
use jump::{jump, optimized_jump_backward, optimized_jump_forward};
|
||||
use less::{
|
||||
less_booleans, less_bytes, less_characters, less_floats, less_integers, less_strings,
|
||||
optimized_less_integers,
|
||||
@ -23,16 +26,11 @@ use tracing::info;
|
||||
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
|
||||
use crate::{
|
||||
instruction::{InstructionFields, TypeCode},
|
||||
AbstractList, ConcreteValue, Operation, Value,
|
||||
};
|
||||
use crate::{instruction::TypeCode, AbstractList, ConcreteValue, Instruction, Operation, Value};
|
||||
|
||||
use super::{call_frame::RuntimeValue, thread::Thread, Pointer};
|
||||
|
||||
pub type ActionLogic = fn(&mut usize, &InstructionFields, &mut Thread);
|
||||
pub type OptimizedActionLogicIntegers =
|
||||
fn(&mut usize, &InstructionFields, &mut Thread, &mut Option<[RuntimeValue<i64>; 3]>);
|
||||
pub type ActionLogic = fn(&mut usize, &Instruction, &mut Thread, &mut Cache);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ActionSequence {
|
||||
@ -40,35 +38,43 @@ pub struct ActionSequence {
|
||||
}
|
||||
|
||||
impl ActionSequence {
|
||||
pub fn new(instructions: Vec<InstructionFields>) -> Self {
|
||||
let mut actions = Vec::with_capacity(instructions.len());
|
||||
let mut instructions_reversed = instructions.into_iter().rev();
|
||||
pub fn new<T: IntoIterator<Item = Instruction> + DoubleEndedIterator<Item = Instruction>>(
|
||||
instructions: T,
|
||||
) -> Self {
|
||||
let mut actions = Vec::new();
|
||||
let mut instructions_reversed = instructions.rev();
|
||||
|
||||
while let Some(instruction) = instructions_reversed.next() {
|
||||
if instruction.operation == Operation::JUMP {
|
||||
let backward_offset = instruction.b_field as usize;
|
||||
let is_positive = instruction.c_field != 0;
|
||||
if instruction.operation() == Operation::JUMP {
|
||||
let backward_offset = instruction.b_field() as usize;
|
||||
let is_positive = instruction.c_field() != 0;
|
||||
|
||||
if !is_positive {
|
||||
let mut loop_actions = Vec::with_capacity(backward_offset + 1);
|
||||
let jump_action = Action::optimized(&instruction);
|
||||
let mut loop_actions = Vec::with_capacity(backward_offset);
|
||||
let jump_action = Action::optimized(instruction);
|
||||
|
||||
loop_actions.push(jump_action);
|
||||
|
||||
for _ in 0..backward_offset {
|
||||
let instruction = instructions_reversed.next().unwrap();
|
||||
let action = Action::optimized(&instruction);
|
||||
let action = Action::optimized(instruction);
|
||||
|
||||
loop_actions.push(action);
|
||||
}
|
||||
|
||||
loop_actions.reverse();
|
||||
|
||||
let r#loop = Action::r#loop(ActionSequence {
|
||||
let cache = Cache::LoopActions(ActionSequence {
|
||||
actions: loop_actions,
|
||||
});
|
||||
|
||||
actions.push(r#loop);
|
||||
let action = Action {
|
||||
instruction,
|
||||
logic: r#loop,
|
||||
cache,
|
||||
};
|
||||
|
||||
actions.push(action);
|
||||
|
||||
continue;
|
||||
}
|
||||
@ -97,27 +103,12 @@ impl ActionSequence {
|
||||
|
||||
info!("Run {action}");
|
||||
|
||||
match action {
|
||||
Action::Unoptimized { logic, instruction } => {
|
||||
logic(&mut local_ip, &*instruction, thread);
|
||||
}
|
||||
Action::Loop { actions } => {
|
||||
actions.run(thread);
|
||||
}
|
||||
Action::OptimizedIntegers {
|
||||
logic,
|
||||
instruction,
|
||||
cache,
|
||||
} => {
|
||||
logic(&mut local_ip, &*instruction, thread, cache);
|
||||
}
|
||||
Action::OptimizedJumpForward { offset } => {
|
||||
local_ip += *offset;
|
||||
}
|
||||
Action::OptimizedJumpBackward { offset } => {
|
||||
local_ip -= *offset + 1;
|
||||
}
|
||||
}
|
||||
(action.logic)(
|
||||
&mut local_ip,
|
||||
&action.instruction,
|
||||
thread,
|
||||
&mut action.cache,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -139,30 +130,23 @@ impl Display for ActionSequence {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Action {
|
||||
Unoptimized {
|
||||
logic: ActionLogic,
|
||||
instruction: InstructionFields,
|
||||
},
|
||||
Loop {
|
||||
actions: ActionSequence,
|
||||
},
|
||||
OptimizedIntegers {
|
||||
logic: OptimizedActionLogicIntegers,
|
||||
instruction: InstructionFields,
|
||||
cache: Option<[RuntimeValue<i64>; 3]>,
|
||||
},
|
||||
OptimizedJumpForward {
|
||||
offset: usize,
|
||||
},
|
||||
OptimizedJumpBackward {
|
||||
offset: usize,
|
||||
},
|
||||
pub struct Action {
|
||||
instruction: Instruction,
|
||||
logic: ActionLogic,
|
||||
cache: Cache,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Cache {
|
||||
Empty,
|
||||
IntegerMath([RuntimeValue<i64>; 3]),
|
||||
IntegerComparison([RuntimeValue<i64>; 2]),
|
||||
LoopActions(ActionSequence),
|
||||
}
|
||||
|
||||
impl Action {
|
||||
pub fn unoptimized(instruction: InstructionFields) -> Self {
|
||||
let logic = match instruction.operation {
|
||||
pub fn unoptimized(instruction: Instruction) -> Self {
|
||||
let logic = match instruction.operation() {
|
||||
Operation::POINT => point,
|
||||
Operation::CLOSE => close,
|
||||
Operation::LOAD_ENCODED => load_encoded,
|
||||
@ -170,7 +154,7 @@ impl Action {
|
||||
Operation::LOAD_LIST => load_list,
|
||||
Operation::LOAD_FUNCTION => load_function,
|
||||
Operation::LOAD_SELF => load_self,
|
||||
Operation::ADD => match (instruction.b_type, instruction.c_type) {
|
||||
Operation::ADD => match (instruction.b_type(), instruction.c_type()) {
|
||||
(TypeCode::INTEGER, TypeCode::INTEGER) => add_integers,
|
||||
(TypeCode::FLOAT, TypeCode::FLOAT) => add_floats,
|
||||
(TypeCode::BYTE, TypeCode::BYTE) => add_bytes,
|
||||
@ -186,16 +170,16 @@ impl Action {
|
||||
Operation::MODULO => modulo,
|
||||
Operation::NEGATE => negate,
|
||||
Operation::NOT => not,
|
||||
Operation::EQUAL => match (instruction.b_type, instruction.c_type) {
|
||||
(TypeCode::BOOLEAN, TypeCode::BOOLEAN) => equal::equal_booleans,
|
||||
(TypeCode::BYTE, TypeCode::BYTE) => equal::equal_bytes,
|
||||
(TypeCode::CHARACTER, TypeCode::CHARACTER) => equal::equal_characters,
|
||||
(TypeCode::FLOAT, TypeCode::FLOAT) => equal::equal_floats,
|
||||
(TypeCode::INTEGER, TypeCode::INTEGER) => equal::equal_integers,
|
||||
(TypeCode::STRING, TypeCode::STRING) => equal::equal_strings,
|
||||
Operation::EQUAL => match (instruction.b_type(), instruction.c_type()) {
|
||||
(TypeCode::BOOLEAN, TypeCode::BOOLEAN) => equal_booleans,
|
||||
(TypeCode::BYTE, TypeCode::BYTE) => equal_bytes,
|
||||
(TypeCode::CHARACTER, TypeCode::CHARACTER) => equal_characters,
|
||||
(TypeCode::FLOAT, TypeCode::FLOAT) => equal_floats,
|
||||
(TypeCode::INTEGER, TypeCode::INTEGER) => equal_integers,
|
||||
(TypeCode::STRING, TypeCode::STRING) => equal_strings,
|
||||
_ => todo!(),
|
||||
},
|
||||
Operation::LESS => match (instruction.b_type, instruction.c_type) {
|
||||
Operation::LESS => match (instruction.b_type(), instruction.c_type()) {
|
||||
(TypeCode::BOOLEAN, TypeCode::BOOLEAN) => less_booleans,
|
||||
(TypeCode::BYTE, TypeCode::BYTE) => less_bytes,
|
||||
(TypeCode::CHARACTER, TypeCode::CHARACTER) => less_characters,
|
||||
@ -204,7 +188,7 @@ impl Action {
|
||||
(TypeCode::STRING, TypeCode::STRING) => less_strings,
|
||||
_ => todo!(),
|
||||
},
|
||||
Operation::LESS_EQUAL => match (instruction.b_type, instruction.c_type) {
|
||||
Operation::LESS_EQUAL => match (instruction.b_type(), instruction.c_type()) {
|
||||
(TypeCode::BOOLEAN, TypeCode::BOOLEAN) => less_equal_booleans,
|
||||
(TypeCode::BYTE, TypeCode::BYTE) => less_equal_bytes,
|
||||
(TypeCode::CHARACTER, TypeCode::CHARACTER) => less_equal_characters,
|
||||
@ -222,100 +206,80 @@ impl Action {
|
||||
_ => todo!(),
|
||||
};
|
||||
|
||||
Action::Unoptimized { logic, instruction }
|
||||
}
|
||||
|
||||
pub fn optimized(instruction: &InstructionFields) -> Self {
|
||||
match instruction.operation {
|
||||
Operation::ADD => match (instruction.b_type, instruction.c_type) {
|
||||
(TypeCode::INTEGER, TypeCode::INTEGER) => Action::OptimizedIntegers {
|
||||
logic: optimized_add_integer,
|
||||
instruction: *instruction,
|
||||
cache: None,
|
||||
},
|
||||
_ => todo!(),
|
||||
},
|
||||
Operation::EQUAL => match (instruction.b_type, instruction.c_type) {
|
||||
(TypeCode::INTEGER, TypeCode::INTEGER) => Action::OptimizedIntegers {
|
||||
logic: optimized_equal_integers,
|
||||
instruction: *instruction,
|
||||
cache: None,
|
||||
},
|
||||
_ => todo!(),
|
||||
},
|
||||
Operation::LESS => match (instruction.b_type, instruction.c_type) {
|
||||
(TypeCode::INTEGER, TypeCode::INTEGER) => Action::OptimizedIntegers {
|
||||
logic: optimized_less_integers,
|
||||
instruction: *instruction,
|
||||
cache: None,
|
||||
},
|
||||
_ => todo!(),
|
||||
},
|
||||
Operation::LESS_EQUAL => match (instruction.b_type, instruction.c_type) {
|
||||
(TypeCode::INTEGER, TypeCode::INTEGER) => Action::OptimizedIntegers {
|
||||
logic: optimized_less_equal_integers,
|
||||
instruction: *instruction,
|
||||
cache: None,
|
||||
},
|
||||
_ => todo!(),
|
||||
},
|
||||
Operation::JUMP => {
|
||||
let offset = instruction.b_field as usize;
|
||||
let is_positive = instruction.c_field != 0;
|
||||
|
||||
if is_positive {
|
||||
Action::OptimizedJumpForward { offset }
|
||||
} else {
|
||||
Action::OptimizedJumpBackward { offset }
|
||||
}
|
||||
}
|
||||
_ => todo!(),
|
||||
Action {
|
||||
instruction,
|
||||
logic,
|
||||
cache: Cache::Empty,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn r#loop(actions: ActionSequence) -> Self {
|
||||
Action::Loop { actions }
|
||||
pub fn optimized(instruction: Instruction) -> Self {
|
||||
let logic = match instruction.operation() {
|
||||
Operation::JUMP => match instruction.c_field() {
|
||||
0 => optimized_jump_backward,
|
||||
_ => optimized_jump_forward,
|
||||
},
|
||||
Operation::ADD => match (instruction.b_type(), instruction.c_type()) {
|
||||
(TypeCode::INTEGER, TypeCode::INTEGER) => optimized_add_integer,
|
||||
_ => todo!(),
|
||||
},
|
||||
Operation::EQUAL => match (instruction.b_type(), instruction.c_type()) {
|
||||
(TypeCode::INTEGER, TypeCode::INTEGER) => optimized_equal_integers,
|
||||
_ => todo!(),
|
||||
},
|
||||
Operation::LESS => match (instruction.b_type(), instruction.c_type()) {
|
||||
(TypeCode::INTEGER, TypeCode::INTEGER) => optimized_less_integers,
|
||||
_ => todo!(),
|
||||
},
|
||||
Operation::LESS_EQUAL => match (instruction.b_type(), instruction.c_type()) {
|
||||
(TypeCode::INTEGER, TypeCode::INTEGER) => optimized_less_equal_integers,
|
||||
_ => todo!(),
|
||||
},
|
||||
_ => todo!(),
|
||||
};
|
||||
|
||||
Action {
|
||||
instruction,
|
||||
logic,
|
||||
cache: Cache::Empty,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Action {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Action::Unoptimized { instruction, .. } => {
|
||||
write!(f, "{}", instruction.operation)
|
||||
}
|
||||
Action::Loop { actions } => {
|
||||
write!(f, "LOOP: {actions}")
|
||||
}
|
||||
Action::OptimizedIntegers { instruction, .. } => {
|
||||
write!(f, "OPTIMIZED_{}", instruction.operation)
|
||||
}
|
||||
Action::OptimizedJumpForward { offset } => {
|
||||
write!(f, "JUMP +{offset}")
|
||||
}
|
||||
Action::OptimizedJumpBackward { offset } => {
|
||||
write!(f, "JUMP -{offset}")
|
||||
}
|
||||
if let Cache::LoopActions(actions) = &self.cache {
|
||||
write!(f, "LOOP: {actions}")?;
|
||||
} else {
|
||||
write!(f, "{}", self.instruction.operation())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn point(_: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
fn r#loop(_: &mut usize, _: &Instruction, thread: &mut Thread, cache: &mut Cache) {
|
||||
if let Cache::LoopActions(actions) = cache {
|
||||
actions.run(thread);
|
||||
}
|
||||
}
|
||||
|
||||
fn point(_: &mut usize, instruction: &Instruction, thread: &mut Thread, _: &mut Cache) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn close(_: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
fn close(_: &mut usize, instruction: &Instruction, thread: &mut Thread, _: &mut Cache) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn load_encoded(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let destination = instruction.a_field;
|
||||
let value_type = instruction.b_type;
|
||||
let jump_next = instruction.c_field != 0;
|
||||
fn load_encoded(ip: &mut usize, instruction: &Instruction, thread: &mut Thread, _: &mut Cache) {
|
||||
let destination = instruction.a_field();
|
||||
let value_type = instruction.b_type();
|
||||
let jump_next = instruction.c_field() != 0;
|
||||
|
||||
match value_type {
|
||||
TypeCode::BOOLEAN => {
|
||||
let value = instruction.b_field != 0;
|
||||
let value = instruction.b_field() != 0;
|
||||
|
||||
thread
|
||||
.current_frame_mut()
|
||||
@ -326,7 +290,7 @@ fn load_encoded(ip: &mut usize, instruction: &InstructionFields, thread: &mut Th
|
||||
.set_inner(value);
|
||||
}
|
||||
TypeCode::BYTE => {
|
||||
let value = instruction.b_field as u8;
|
||||
let value = instruction.b_field() as u8;
|
||||
|
||||
thread
|
||||
.current_frame_mut()
|
||||
@ -344,11 +308,11 @@ fn load_encoded(ip: &mut usize, instruction: &InstructionFields, thread: &mut Th
|
||||
}
|
||||
}
|
||||
|
||||
fn load_constant(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let destination = instruction.a_field as usize;
|
||||
let constant_index = instruction.b_field as usize;
|
||||
let constant_type = instruction.b_type;
|
||||
let jump_next = instruction.c_field != 0;
|
||||
fn load_constant(ip: &mut usize, instruction: &Instruction, thread: &mut Thread, _: &mut Cache) {
|
||||
let destination = instruction.a_field() as usize;
|
||||
let constant_index = instruction.b_field() as usize;
|
||||
let constant_type = instruction.b_type();
|
||||
let jump_next = instruction.c_field() != 0;
|
||||
let current_frame = thread.current_frame_mut();
|
||||
|
||||
match constant_type {
|
||||
@ -396,12 +360,12 @@ fn load_constant(ip: &mut usize, instruction: &InstructionFields, thread: &mut T
|
||||
}
|
||||
}
|
||||
|
||||
fn load_list(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let destination = instruction.a_field as usize;
|
||||
let start_register = instruction.b_field as usize;
|
||||
let item_type = instruction.b_type;
|
||||
let end_register = instruction.c_field as usize;
|
||||
let jump_next = instruction.d_field;
|
||||
fn load_list(ip: &mut usize, instruction: &Instruction, thread: &mut Thread, _: &mut Cache) {
|
||||
let destination = instruction.a_field() as usize;
|
||||
let start_register = instruction.b_field() as usize;
|
||||
let item_type = instruction.b_type();
|
||||
let end_register = instruction.c_field() as usize;
|
||||
let jump_next = instruction.d_field();
|
||||
let current_frame = thread.current_frame_mut();
|
||||
|
||||
let mut item_pointers = Vec::with_capacity(end_register - start_register + 1);
|
||||
@ -489,58 +453,58 @@ fn load_list(ip: &mut usize, instruction: &InstructionFields, thread: &mut Threa
|
||||
}
|
||||
}
|
||||
|
||||
fn load_function(_: &mut usize, _: &InstructionFields, _: &mut Thread) {
|
||||
fn load_function(_: &mut usize, _: &Instruction, _: &mut Thread, _: &mut Cache) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn load_self(_: &mut usize, _: &InstructionFields, _: &mut Thread) {
|
||||
fn load_self(_: &mut usize, _: &Instruction, _: &mut Thread, _: &mut Cache) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn subtract(_: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
fn subtract(_: &mut usize, instruction: &Instruction, thread: &mut Thread, _: &mut Cache) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn multiply(_: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
fn multiply(_: &mut usize, instruction: &Instruction, thread: &mut Thread, _: &mut Cache) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn divide(_: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
fn divide(_: &mut usize, instruction: &Instruction, thread: &mut Thread, _: &mut Cache) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn modulo(_: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
fn modulo(_: &mut usize, instruction: &Instruction, thread: &mut Thread, _: &mut Cache) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn test(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
fn test(ip: &mut usize, instruction: &Instruction, thread: &mut Thread, _: &mut Cache) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn test_set(_: &mut usize, _: &InstructionFields, _: &mut Thread) {
|
||||
fn test_set(_: &mut usize, _: &Instruction, _: &mut Thread, _: &mut Cache) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn negate(_: &mut usize, _: &InstructionFields, _: &mut Thread) {
|
||||
fn negate(_: &mut usize, _: &Instruction, _: &mut Thread, _: &mut Cache) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn not(_: &mut usize, _: &InstructionFields, _: &mut Thread) {
|
||||
fn not(_: &mut usize, _: &Instruction, _: &mut Thread, _: &mut Cache) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn call(_: &mut usize, _: &InstructionFields, _: &mut Thread) {
|
||||
fn call(_: &mut usize, _: &Instruction, _: &mut Thread, _: &mut Cache) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn call_native(_: &mut usize, _: &InstructionFields, _: &mut Thread) {
|
||||
fn call_native(_: &mut usize, _: &Instruction, _: &mut Thread, _: &mut Cache) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn r#return(_: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let should_return_value = instruction.b_field != 0;
|
||||
let return_register = instruction.c_field as usize;
|
||||
let return_type = instruction.b_type;
|
||||
fn r#return(_: &mut usize, instruction: &Instruction, thread: &mut Thread, _: &mut Cache) {
|
||||
let should_return_value = instruction.b_field() != 0;
|
||||
let return_register = instruction.c_field() as usize;
|
||||
let return_type = instruction.b_type();
|
||||
let current_frame = thread.current_frame();
|
||||
|
||||
if should_return_value {
|
||||
|
@ -3,7 +3,6 @@ use std::{rc::Rc, thread::JoinHandle};
|
||||
use tracing::{info, trace};
|
||||
|
||||
use crate::{
|
||||
instruction::InstructionFields,
|
||||
vm::{action::ActionSequence, CallFrame},
|
||||
Chunk, DustString, Span, Value,
|
||||
};
|
||||
@ -39,13 +38,7 @@ impl Thread {
|
||||
.unwrap_or_else(|| DustString::from("anonymous"))
|
||||
);
|
||||
|
||||
let mut actions = ActionSequence::new(
|
||||
self.chunk
|
||||
.instructions
|
||||
.iter()
|
||||
.map(InstructionFields::from)
|
||||
.collect(),
|
||||
);
|
||||
let mut actions = ActionSequence::new(self.chunk.instructions.iter().copied());
|
||||
|
||||
trace!("Thread actions: {}", actions);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user