fix(bytecode): make bytecode more compact (inline atom ops; smaller opcodes)

This commit is contained in:
Alain Zscheile 2022-09-25 01:39:47 +02:00
parent 391c478647
commit de02eba3dc
3 changed files with 34 additions and 34 deletions

View file

@ -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 {}

View file

@ -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(())
}

View file

@ -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));