Use a lookup table instead of matching operation codes in the VM
This commit is contained in:
parent
20f451fe6c
commit
395f0af213
@ -17,7 +17,7 @@ use std::io::Write;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
use crate::{ConcreteValue, DustString, FunctionType, Instruction, Span, Type};
|
use crate::{ConcreteValue, DustString, FunctionType, Instruction, Span};
|
||||||
|
|
||||||
/// In-memory representation of a Dust program or function.
|
/// In-memory representation of a Dust program or function.
|
||||||
///
|
///
|
||||||
|
@ -154,7 +154,6 @@ pub struct Instruction(u32);
|
|||||||
|
|
||||||
#[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub struct InstructionData {
|
pub struct InstructionData {
|
||||||
pub operation: Operation,
|
|
||||||
pub a: u8,
|
pub a: u8,
|
||||||
pub b: u8,
|
pub b: u8,
|
||||||
pub c: u8,
|
pub c: u8,
|
||||||
@ -226,16 +225,18 @@ impl Instruction {
|
|||||||
self.0 = (self.0 & 0xFF00FFFF) | ((bits as u32) << 24);
|
self.0 = (self.0 & 0xFF00FFFF) | ((bits as u32) << 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decode(self) -> InstructionData {
|
pub fn decode(self) -> (Operation, InstructionData) {
|
||||||
InstructionData {
|
(
|
||||||
operation: self.operation(),
|
self.operation(),
|
||||||
a: self.a_field(),
|
InstructionData {
|
||||||
b: self.b_field(),
|
a: self.a_field(),
|
||||||
c: self.c_field(),
|
b: self.b_field(),
|
||||||
b_is_constant: self.b_is_constant(),
|
c: self.c_field(),
|
||||||
c_is_constant: self.c_is_constant(),
|
b_is_constant: self.b_is_constant(),
|
||||||
d: self.d_field(),
|
c_is_constant: self.c_is_constant(),
|
||||||
}
|
d: self.d_field(),
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn r#move(from: u8, to: u8) -> Instruction {
|
pub fn r#move(from: u8, to: u8) -> Instruction {
|
||||||
@ -498,7 +499,6 @@ impl Instruction {
|
|||||||
Operation::LoadBoolean
|
Operation::LoadBoolean
|
||||||
| Operation::LoadConstant
|
| Operation::LoadConstant
|
||||||
| Operation::LoadList
|
| Operation::LoadList
|
||||||
| Operation::LoadMap
|
|
||||||
| Operation::LoadSelf
|
| Operation::LoadSelf
|
||||||
| Operation::GetLocal
|
| Operation::GetLocal
|
||||||
| Operation::Add
|
| Operation::Add
|
||||||
@ -506,7 +506,6 @@ impl Instruction {
|
|||||||
| Operation::Multiply
|
| Operation::Multiply
|
||||||
| Operation::Divide
|
| Operation::Divide
|
||||||
| Operation::Modulo
|
| Operation::Modulo
|
||||||
| Operation::Power
|
|
||||||
| Operation::Negate
|
| Operation::Negate
|
||||||
| Operation::Not
|
| Operation::Not
|
||||||
| Operation::Equal
|
| Operation::Equal
|
||||||
|
@ -9,27 +9,25 @@ pub const CLOSE_BYTE: u8 = 1;
|
|||||||
pub const LOAD_BOOLEAN_BYTE: u8 = 2;
|
pub const LOAD_BOOLEAN_BYTE: u8 = 2;
|
||||||
pub const LOAD_CONSTANT_BYTE: u8 = 3;
|
pub const LOAD_CONSTANT_BYTE: u8 = 3;
|
||||||
pub const LOAD_LIST_BYTE: u8 = 4;
|
pub const LOAD_LIST_BYTE: u8 = 4;
|
||||||
pub const LOAD_MAP_BYTE: u8 = 5;
|
pub const LOAD_SELF_BYTE: u8 = 5;
|
||||||
pub const LOAD_SELF_BYTE: u8 = 6;
|
pub const GET_LOCAL_BYTE: u8 = 6;
|
||||||
pub const GET_LOCAL_BYTE: u8 = 7;
|
pub const SET_LOCAL_BYTE: u8 = 7;
|
||||||
pub const SET_LOCAL_BYTE: u8 = 8;
|
pub const ADD_BYTE: u8 = 8;
|
||||||
pub const ADD_BYTE: u8 = 9;
|
pub const SUBTRACT_BYTE: u8 = 9;
|
||||||
pub const SUBTRACT_BYTE: u8 = 10;
|
pub const MULTIPLY_BYTE: u8 = 10;
|
||||||
pub const MULTIPLY_BYTE: u8 = 11;
|
pub const DIVIDE_BYTE: u8 = 11;
|
||||||
pub const DIVIDE_BYTE: u8 = 12;
|
pub const MODULO_BYTE: u8 = 12;
|
||||||
pub const MODULO_BYTE: u8 = 13;
|
pub const TEST_BYTE: u8 = 13;
|
||||||
pub const POWER_BYTE: u8 = 14;
|
pub const TEST_SET_BYTE: u8 = 14;
|
||||||
pub const TEST_BYTE: u8 = 15;
|
pub const EQUAL_BYTE: u8 = 15;
|
||||||
pub const TEST_SET_BYTE: u8 = 16;
|
pub const LESS_BYTE: u8 = 16;
|
||||||
pub const EQUAL_BYTE: u8 = 17;
|
pub const LESS_EQUAL_BYTE: u8 = 17;
|
||||||
pub const LESS_BYTE: u8 = 18;
|
pub const NEGATE_BYTE: u8 = 18;
|
||||||
pub const LESS_EQUAL_BYTE: u8 = 19;
|
pub const NOT_BYTE: u8 = 19;
|
||||||
pub const NEGATE_BYTE: u8 = 20;
|
pub const CALL_BYTE: u8 = 20;
|
||||||
pub const NOT_BYTE: u8 = 21;
|
pub const CALL_NATIVE_BYTE: u8 = 21;
|
||||||
pub const CALL_BYTE: u8 = 22;
|
pub const JUMP_BYTE: u8 = 22;
|
||||||
pub const CALL_NATIVE_BYTE: u8 = 23;
|
pub const RETURN_BYTE: u8 = 23;
|
||||||
pub const JUMP_BYTE: u8 = 24;
|
|
||||||
pub const RETURN_BYTE: u8 = 25;
|
|
||||||
|
|
||||||
/// Part of an [Instruction][crate::Instruction] that is encoded as a single byte.
|
/// Part of an [Instruction][crate::Instruction] that is encoded as a single byte.
|
||||||
#[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
@ -40,7 +38,6 @@ pub enum Operation {
|
|||||||
LoadBoolean = LOAD_BOOLEAN_BYTE,
|
LoadBoolean = LOAD_BOOLEAN_BYTE,
|
||||||
LoadConstant = LOAD_CONSTANT_BYTE,
|
LoadConstant = LOAD_CONSTANT_BYTE,
|
||||||
LoadList = LOAD_LIST_BYTE,
|
LoadList = LOAD_LIST_BYTE,
|
||||||
LoadMap = LOAD_MAP_BYTE,
|
|
||||||
LoadSelf = LOAD_SELF_BYTE,
|
LoadSelf = LOAD_SELF_BYTE,
|
||||||
GetLocal = GET_LOCAL_BYTE,
|
GetLocal = GET_LOCAL_BYTE,
|
||||||
SetLocal = SET_LOCAL_BYTE,
|
SetLocal = SET_LOCAL_BYTE,
|
||||||
@ -49,7 +46,6 @@ pub enum Operation {
|
|||||||
Multiply = MULTIPLY_BYTE,
|
Multiply = MULTIPLY_BYTE,
|
||||||
Divide = DIVIDE_BYTE,
|
Divide = DIVIDE_BYTE,
|
||||||
Modulo = MODULO_BYTE,
|
Modulo = MODULO_BYTE,
|
||||||
Power = POWER_BYTE,
|
|
||||||
Test = TEST_BYTE,
|
Test = TEST_BYTE,
|
||||||
TestSet = TEST_SET_BYTE,
|
TestSet = TEST_SET_BYTE,
|
||||||
Equal = EQUAL_BYTE,
|
Equal = EQUAL_BYTE,
|
||||||
@ -71,7 +67,6 @@ impl From<u8> for Operation {
|
|||||||
LOAD_BOOLEAN_BYTE => Self::LoadBoolean,
|
LOAD_BOOLEAN_BYTE => Self::LoadBoolean,
|
||||||
LOAD_CONSTANT_BYTE => Self::LoadConstant,
|
LOAD_CONSTANT_BYTE => Self::LoadConstant,
|
||||||
LOAD_LIST_BYTE => Self::LoadList,
|
LOAD_LIST_BYTE => Self::LoadList,
|
||||||
LOAD_MAP_BYTE => Self::LoadMap,
|
|
||||||
LOAD_SELF_BYTE => Self::LoadSelf,
|
LOAD_SELF_BYTE => Self::LoadSelf,
|
||||||
GET_LOCAL_BYTE => Self::GetLocal,
|
GET_LOCAL_BYTE => Self::GetLocal,
|
||||||
SET_LOCAL_BYTE => Self::SetLocal,
|
SET_LOCAL_BYTE => Self::SetLocal,
|
||||||
@ -80,7 +75,6 @@ impl From<u8> for Operation {
|
|||||||
MULTIPLY_BYTE => Self::Multiply,
|
MULTIPLY_BYTE => Self::Multiply,
|
||||||
DIVIDE_BYTE => Self::Divide,
|
DIVIDE_BYTE => Self::Divide,
|
||||||
MODULO_BYTE => Self::Modulo,
|
MODULO_BYTE => Self::Modulo,
|
||||||
POWER_BYTE => Self::Power,
|
|
||||||
TEST_BYTE => Self::Test,
|
TEST_BYTE => Self::Test,
|
||||||
TEST_SET_BYTE => Self::TestSet,
|
TEST_SET_BYTE => Self::TestSet,
|
||||||
EQUAL_BYTE => Self::Equal,
|
EQUAL_BYTE => Self::Equal,
|
||||||
@ -111,7 +105,6 @@ impl Operation {
|
|||||||
Self::LoadBoolean => "LOAD_BOOLEAN",
|
Self::LoadBoolean => "LOAD_BOOLEAN",
|
||||||
Self::LoadConstant => "LOAD_CONSTANT",
|
Self::LoadConstant => "LOAD_CONSTANT",
|
||||||
Self::LoadList => "LOAD_LIST",
|
Self::LoadList => "LOAD_LIST",
|
||||||
Self::LoadMap => "LOAD_MAP",
|
|
||||||
Self::LoadSelf => "LOAD_SELF",
|
Self::LoadSelf => "LOAD_SELF",
|
||||||
Self::GetLocal => "GET_LOCAL",
|
Self::GetLocal => "GET_LOCAL",
|
||||||
Self::SetLocal => "SET_LOCAL",
|
Self::SetLocal => "SET_LOCAL",
|
||||||
@ -120,7 +113,6 @@ impl Operation {
|
|||||||
Self::Multiply => "MULTIPLY",
|
Self::Multiply => "MULTIPLY",
|
||||||
Self::Divide => "DIVIDE",
|
Self::Divide => "DIVIDE",
|
||||||
Self::Modulo => "MODULO",
|
Self::Modulo => "MODULO",
|
||||||
Self::Power => "POWER",
|
|
||||||
Self::Test => "TEST",
|
Self::Test => "TEST",
|
||||||
Self::TestSet => "TEST_SET",
|
Self::TestSet => "TEST_SET",
|
||||||
Self::Equal => "EQUAL",
|
Self::Equal => "EQUAL",
|
||||||
@ -152,13 +144,12 @@ impl Display for Operation {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
const ALL_OPERATIONS: [Operation; 26] = [
|
const ALL_OPERATIONS: [Operation; 24] = [
|
||||||
Operation::Move,
|
Operation::Move,
|
||||||
Operation::Close,
|
Operation::Close,
|
||||||
Operation::LoadBoolean,
|
Operation::LoadBoolean,
|
||||||
Operation::LoadConstant,
|
Operation::LoadConstant,
|
||||||
Operation::LoadList,
|
Operation::LoadList,
|
||||||
Operation::LoadMap,
|
|
||||||
Operation::LoadSelf,
|
Operation::LoadSelf,
|
||||||
Operation::GetLocal,
|
Operation::GetLocal,
|
||||||
Operation::SetLocal,
|
Operation::SetLocal,
|
||||||
@ -167,7 +158,6 @@ mod tests {
|
|||||||
Operation::Multiply,
|
Operation::Multiply,
|
||||||
Operation::Divide,
|
Operation::Divide,
|
||||||
Operation::Modulo,
|
Operation::Modulo,
|
||||||
Operation::Power,
|
|
||||||
Operation::Test,
|
Operation::Test,
|
||||||
Operation::TestSet,
|
Operation::TestSet,
|
||||||
Operation::Equal,
|
Operation::Equal,
|
||||||
|
@ -154,7 +154,7 @@ impl ValueRef<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn less_than(&self, other: ValueRef) -> Result<Value, ValueError> {
|
pub fn less(&self, other: ValueRef) -> Result<Value, ValueError> {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(ValueRef::Concrete(left), ValueRef::Concrete(right)) => {
|
(ValueRef::Concrete(left), ValueRef::Concrete(right)) => {
|
||||||
left.less_than(right).map(Value::Concrete)
|
left.less_than(right).map(Value::Concrete)
|
||||||
@ -163,7 +163,7 @@ impl ValueRef<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn less_than_or_equal(&self, other: ValueRef) -> Result<Value, ValueError> {
|
pub fn less_equal(&self, other: ValueRef) -> Result<Value, ValueError> {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(ValueRef::Concrete(left), ValueRef::Concrete(right)) => {
|
(ValueRef::Concrete(left), ValueRef::Concrete(right)) => {
|
||||||
left.less_than_or_equal(right).map(Value::Concrete)
|
left.less_than_or_equal(right).map(Value::Concrete)
|
||||||
|
1127
dust-lang/src/vm.rs
1127
dust-lang/src/vm.rs
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user