feat(bytecode): pop and dup should take 16bit values

This commit is contained in:
Alain Zscheile 2022-09-25 01:58:51 +02:00
parent de02eba3dc
commit b1ea85cf3e
2 changed files with 18 additions and 25 deletions

View file

@ -31,10 +31,10 @@ pub enum Instr<'a> {
Push(Value<'a>),
/// pops the top $0+1 values from the stack
Pop(u32),
Pop(u16),
/// duplicates the top stack value
Dup,
/// duplicates the top-$0 stack value, pushing it to the top of the stack
Dup(u16),
/// swaps the 2 top-most stack values
Swap,
@ -59,7 +59,7 @@ impl Instr<'_> {
Instr::Return => OpType::Return,
Instr::Push(_) => OpType::Push,
Instr::Pop(_) => OpType::Pop,
Instr::Dup => OpType::Dup,
Instr::Dup(_) => OpType::Dup,
Instr::Swap => OpType::Swap,
Instr::ABuild => OpType::ABuild,
Instr::ADecon => OpType::ADecon,
@ -110,11 +110,11 @@ impl<'a> crate::Parse<'a> for Instr<'a> {
OpType::Jump => u64::parse(inp).map(|(inp, val)| (inp, Instr::Jump(val))),
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::Pop => u16::parse(inp).map(|(inp, val)| (inp, Instr::Pop(val))),
OpType::Dup => u16::parse(inp).map(|(inp, val)| (inp, Instr::Dup(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)),
@ -138,13 +138,9 @@ impl Instr<'_> {
Instr::JumpCond(val) => writer.write_all(&val.to_be_bytes())?,
Instr::Push(val) => val.write_to(writer)?,
Instr::Pop(val) => writer.write_all(&val.to_be_bytes())?,
Instr::Dup(val) => writer.write_all(&val.to_be_bytes())?,
Instr::DoMath2(val) => writer.write_all(&val.int_value().to_be_bytes())?,
Instr::Label
| Instr::Return
| Instr::Dup
| Instr::Swap
| Instr::ABuild
| Instr::ADecon => {}
Instr::Label | Instr::Return | Instr::Swap | Instr::ABuild | Instr::ADecon => {}
}
Ok(())
}

View file

@ -242,24 +242,21 @@ impl Process {
}
Instr::Pop(cnt) => {
let ssl = self.stack.len() - 1;
match usize::try_from(cnt) {
Ok(cnt) => {
if cnt >= ssl {
self.stack = Vec::new();
} else {
self.stack.truncate(ssl - cnt - 1);
}
}
Err(_) => self.stack = Vec::new(),
let cnt = usize::from(cnt);
if cnt >= ssl {
self.stack = Vec::new();
} else {
self.stack.truncate(ssl - cnt - 1);
}
}
Instr::Dup => {
let x = match self.stack.last() {
Instr::Dup(delta) => {
let x = match self.stack.len().checked_sub(usize::from(delta) + 1) {
None => {
tracing::error!("dup on empty stack @ {}", previptr);
tracing::error!("dup on too small stack @ {}", previptr);
break;
}
Some(x) => x.clone(),
// SAFETY: the value x is always smaller than the stack height
Some(x) => self.stack[x].clone(),
};
self.stack.push(x);
}