summaryrefslogtreecommitdiffstats
path: root/bytecode/src/encoding.rs
diff options
context:
space:
mode:
Diffstat (limited to 'bytecode/src/encoding.rs')
-rw-r--r--bytecode/src/encoding.rs23
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 })
}