fix(bytecode): make bytecode more compact (inline atom ops; smaller opcodes)
This commit is contained in:
parent
391c478647
commit
de02eba3dc
|
@ -10,31 +10,25 @@ pub enum ValueType {
|
|||
Pointer = 0x50, /* P */
|
||||
}
|
||||
|
||||
#[repr(u16)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, IntEnum)]
|
||||
pub enum OpType {
|
||||
Label = 0x6c62, /* lb */
|
||||
CallRemote = 0x6372, /* cr */
|
||||
CallLocal = 0x636c, /* cl */
|
||||
Jump = 0x6a70, /* jp */
|
||||
JumpCond = 0x6a63, /* jc */
|
||||
Return = 0x7274, /* rt */
|
||||
|
||||
Push = 0x7073, /* ps */
|
||||
Pop = 0x7071, /* pq */
|
||||
Dup = 0x6470, /* dp */
|
||||
Swap = 0x3c3e, /* <> */
|
||||
|
||||
OnAtom = 0x613b, /* a; */
|
||||
DoMath2 = 0x6d3b, /* m; */
|
||||
}
|
||||
|
||||
// the following enum exists to save space for decoded instructions
|
||||
#[repr(u8)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, IntEnum)]
|
||||
pub enum AtomOp {
|
||||
Build = 0x2e, /* . */
|
||||
Decon = 0x2a, /* * */
|
||||
pub enum OpType {
|
||||
Label = 0x4c, /* L */
|
||||
CallRemote = 0x43, /* C */
|
||||
CallLocal = 0x49, /* I */
|
||||
Jump = 0x4a, /* J */
|
||||
JumpCond = 0x6a, /* j */
|
||||
Return = 0x52, /* R */
|
||||
// stack operations
|
||||
Push = 0x50, /* P */
|
||||
Pop = 0x51, /* Q */
|
||||
Dup = 0x44, /* D */
|
||||
Swap = 0x53, /* S */
|
||||
// atom operations
|
||||
ABuild = 0x2e, /* . */
|
||||
ADecon = 0x2a, /* * */
|
||||
// extensions
|
||||
DoMath2 = 0x4d, /* M */
|
||||
}
|
||||
|
||||
// u16 because we assume we may add many additional math operations in the future
|
||||
|
@ -48,5 +42,4 @@ pub enum MathBinOp {
|
|||
|
||||
impl Sealed for ValueType {}
|
||||
impl Sealed for OpType {}
|
||||
impl Sealed for AtomOp {}
|
||||
impl Sealed for MathBinOp {}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::consts::{AtomOp, MathBinOp, OpType};
|
||||
use crate::consts::{MathBinOp, OpType};
|
||||
use crate::{Atom, Value};
|
||||
use core::fmt;
|
||||
|
||||
|
@ -40,7 +40,8 @@ pub enum Instr<'a> {
|
|||
Swap,
|
||||
|
||||
/// basic atom operations
|
||||
OnAtom(AtomOp),
|
||||
ABuild,
|
||||
ADecon,
|
||||
|
||||
/// basic math operations (on integers and atoms)
|
||||
DoMath2(MathBinOp),
|
||||
|
@ -60,7 +61,8 @@ impl Instr<'_> {
|
|||
Instr::Pop(_) => OpType::Pop,
|
||||
Instr::Dup => OpType::Dup,
|
||||
Instr::Swap => OpType::Swap,
|
||||
Instr::OnAtom(_) => OpType::OnAtom,
|
||||
Instr::ABuild => OpType::ABuild,
|
||||
Instr::ADecon => OpType::ADecon,
|
||||
Instr::DoMath2(_) => OpType::DoMath2,
|
||||
}
|
||||
}
|
||||
|
@ -94,7 +96,7 @@ impl<'a> crate::Parse<'a> for Instr<'a> {
|
|||
type Err = ParseError;
|
||||
|
||||
fn parse(inp: &'a [u8]) -> Result<(&'a [u8], Self), ParseError> {
|
||||
if inp.len() < 2 {
|
||||
if inp.is_empty() {
|
||||
return Err(ParseError);
|
||||
}
|
||||
let (inp, otyp) = OpType::parse(inp)?;
|
||||
|
@ -109,12 +111,13 @@ impl<'a> crate::Parse<'a> for Instr<'a> {
|
|||
OpType::JumpCond => u64::parse(inp).map(|(inp, val)| (inp, Instr::JumpCond(val))),
|
||||
OpType::Push => Ok(Value::parse(inp).map(|(inp, val)| (inp, Instr::Push(val)))?),
|
||||
OpType::Pop => u32::parse(inp).map(|(inp, val)| (inp, Instr::Pop(val))),
|
||||
OpType::OnAtom => AtomOp::parse(inp).map(|(inp, val)| (inp, Instr::OnAtom(val))),
|
||||
OpType::DoMath2 => MathBinOp::parse(inp).map(|(inp, val)| (inp, Instr::DoMath2(val))),
|
||||
OpType::Label => Ok((inp, Instr::Label)),
|
||||
OpType::Return => Ok((inp, Instr::Return)),
|
||||
OpType::Dup => Ok((inp, Instr::Dup)),
|
||||
OpType::Swap => Ok((inp, Instr::Swap)),
|
||||
OpType::ABuild => Ok((inp, Instr::ABuild)),
|
||||
OpType::ADecon => Ok((inp, Instr::ADecon)),
|
||||
}
|
||||
.map_err(|()| ParseError)
|
||||
}
|
||||
|
@ -136,8 +139,12 @@ impl Instr<'_> {
|
|||
Instr::Push(val) => val.write_to(writer)?,
|
||||
Instr::Pop(val) => writer.write_all(&val.to_be_bytes())?,
|
||||
Instr::DoMath2(val) => writer.write_all(&val.int_value().to_be_bytes())?,
|
||||
Instr::OnAtom(val) => writer.write_all(&val.int_value().to_be_bytes())?,
|
||||
Instr::Label | Instr::Return | Instr::Dup | Instr::Swap => {}
|
||||
Instr::Label
|
||||
| Instr::Return
|
||||
| Instr::Dup
|
||||
| Instr::Swap
|
||||
| Instr::ABuild
|
||||
| Instr::ADecon => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ impl Process {
|
|||
|
||||
fn run(&mut self) {
|
||||
loop {
|
||||
use fogtix_bytecode::consts::{AtomOp, MathBinOp};
|
||||
use fogtix_bytecode::consts::MathBinOp;
|
||||
let previptr = self.instrp.1;
|
||||
tracing::trace!("previptr = {}", previptr);
|
||||
let nxti_arr = match self.instrp.0.h.get(previptr..) {
|
||||
|
@ -273,7 +273,7 @@ impl Process {
|
|||
let (y, z) = x.split_at_mut(1);
|
||||
core::mem::swap(&mut y[0], &mut z[0]);
|
||||
}
|
||||
Instr::OnAtom(AtomOp::Build) => {
|
||||
Instr::ABuild => {
|
||||
let a = self.stack.pop();
|
||||
let b = self.stack.pop();
|
||||
match (a, b) {
|
||||
|
@ -286,7 +286,7 @@ impl Process {
|
|||
}
|
||||
}
|
||||
}
|
||||
Instr::OnAtom(AtomOp::Decon) => match self.stack.pop() {
|
||||
Instr::ADecon => match self.stack.pop() {
|
||||
Some(StackEntValue::Atom(Atom(b, a))) => {
|
||||
self.stack.push(StackEntValue::Int(b));
|
||||
self.stack.push(StackEntValue::Int(a));
|
||||
|
|
Loading…
Reference in a new issue