diff options
Diffstat (limited to 'bytecode/src/encoding.rs')
| -rw-r--r-- | bytecode/src/encoding.rs | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/bytecode/src/encoding.rs b/bytecode/src/encoding.rs index e37696d..eb6633d 100644 --- a/bytecode/src/encoding.rs +++ b/bytecode/src/encoding.rs @@ -2,37 +2,44 @@ use crate::heap; use crate::value::Value; use std::error::Error; +#[derive(Debug, Clone, Copy)] pub enum Arg { Local(u8), Const(Value), } +#[derive(Debug, Clone, Copy)] pub struct Alloc { pub out: u8, pub size: Arg, } +#[derive(Debug, Clone, Copy)] pub struct Poke { pub offset: usize, pub ptr: u8, pub val: Arg, } +#[derive(Debug, Clone, Copy)] pub struct Peek { pub out: u8, pub offset: usize, pub val: Arg, } +#[derive(Debug, Clone, Copy)] pub struct Shuf { pub out: u8, pub val: Arg, } +#[derive(Debug, Clone, Copy)] pub struct Exit { pub val: Arg, } +#[derive(Debug, Clone, Copy)] pub enum Op { Alloc(Alloc), Call, @@ -74,19 +81,19 @@ impl Reader<'_> { Ok(res) } - fn parse_u64(&mut self) -> Result<u64, Box<dyn Error>> { + fn parse_value(&mut self) -> Result<Value, Box<dyn Error>> { if self.data.len() < 8 { return Err(Box::from("value: no data")); } let mut res = [0; 8]; res.copy_from_slice(&self.data[..8]); self.advance(8); - Ok(u64::from_le_bytes(res)) + Ok(Value(u64::from_le_bytes(res))) } fn parse_arg(&mut self, is_const: bool) -> Result<Arg, Box<dyn Error>> { if is_const { - Ok(Arg::Const(Value(self.parse_u64()?))) + Ok(Arg::Const(self.parse_value()?)) } else { Ok(Arg::Local(self.parse_local()?)) } @@ -109,14 +116,20 @@ impl Op { } 2 => Op::Call, 3 => { - let offset = usize::try_from(r.parse_u64()?)?; + let Some(ioffset) = r.parse_value()?.to_int() else { + return Err(Box::from("invalid offset")); + }; + let offset = usize::try_from(ioffset)?; let ptr = r.parse_local()?; let val = r.parse_arg(arg1_const)?; Op::Poke(Poke { offset, ptr, val }) } 4 => { let out = r.parse_local()?; - let offset = usize::try_from(r.parse_u64()?)?; + let Some(ioffset) = r.parse_value()?.to_int() else { + return Err(Box::from("invalid offset")); + }; + let offset = usize::try_from(ioffset)?; let val = r.parse_arg(arg1_const)?; Op::Peek(Peek { out, offset, val }) } |
