Skip to content
This repository was archived by the owner on Oct 3, 2025. It is now read-only.

Commit 5a193cf

Browse files
feat: add support for more instructions
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
1 parent 33ad024 commit 5a193cf

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

crates/tinywasm/src/runtime/executor/mod.rs

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@ impl DefaultRuntime {
3535
ExecResult::Ok => {
3636
cf.instr_ptr += 1;
3737
}
38+
39+
// trap the program
40+
ExecResult::Trap(trap) => {
41+
cf.instr_ptr += 1;
42+
// push the call frame back onto the stack so that it can be resumed
43+
// if the trap can be handled
44+
stack.call_stack.push(cf);
45+
return Err(Error::Trap(trap));
46+
}
3847
}
3948
}
4049

@@ -50,6 +59,7 @@ enum ExecResult {
5059
Ok,
5160
Return,
5261
Call,
62+
Trap(crate::Trap),
5363
}
5464

5565
#[inline]
@@ -63,9 +73,21 @@ fn exec_one(
6373
) -> Result<ExecResult> {
6474
use tinywasm_types::Instruction::*;
6575
match instr {
66-
Nop => {} // do nothing
67-
Unreachable => return Err(Error::Trap(crate::Trap::Unreachable)),
68-
76+
Nop => { /* do nothing */ }
77+
Unreachable => return Ok(ExecResult::Trap(crate::Trap::Unreachable)), // we don't need to include the call frame here because it's already on the stack
78+
Drop => {
79+
stack.values.pop().ok_or(Error::StackUnderflow)?;
80+
}
81+
Select => {
82+
let cond: i32 = stack.values.pop().ok_or(Error::StackUnderflow)?.into();
83+
let val2 = stack.values.pop().ok_or(Error::StackUnderflow)?;
84+
85+
// if cond != 0, we already have the right value on the stack
86+
if cond == 0 {
87+
let _ = stack.values.pop().ok_or(Error::StackUnderflow)?;
88+
stack.values.push(val2);
89+
}
90+
}
6991
Return => {
7092
debug!("return");
7193
}
@@ -117,7 +139,6 @@ fn exec_one(
117139

118140
todo!()
119141
}
120-
121142
Br(v) => cf.break_to(*v, &mut stack.values)?,
122143
BrIf(v) => {
123144
let val: i32 = stack.values.pop().ok_or(Error::StackUnderflow)?.into();
@@ -164,19 +185,16 @@ fn exec_one(
164185
LocalGet(local_index) => {
165186
debug!("local.get: {:?}", local_index);
166187
let val = cf.get_local(*local_index as usize);
167-
debug!("local: {:#?}", val);
168188
stack.values.push(val);
169189
}
170190
LocalSet(local_index) => {
171-
debug!("local.set: {:?}", local_index);
172191
let val = stack.values.pop().ok_or(Error::StackUnderflow)?;
173192
cf.set_local(*local_index as usize, val);
174193
}
194+
// Equivalent to local.set, local.get
175195
LocalTee(local_index) => {
176-
debug!("local.tee: {:?}", local_index);
177-
let val = stack.values.pop().ok_or(Error::StackUnderflow)?;
178-
cf.set_local(*local_index as usize, val);
179-
stack.values.push(val);
196+
let val = stack.values.last().ok_or(Error::StackUnderflow)?;
197+
cf.set_local(*local_index as usize, *val);
180198
}
181199
I32Const(val) => stack.values.push((*val).into()),
182200
I64Const(val) => stack.values.push((*val).into()),

crates/tinywasm/src/runtime/stack/value_stack.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ impl ValueStack {
5757
self.stack.push(value);
5858
}
5959

60+
#[inline]
61+
pub(crate) fn last(&self) -> Option<&RawWasmValue> {
62+
self.stack.last()
63+
}
64+
6065
#[inline]
6166
pub(crate) fn pop(&mut self) -> Option<RawWasmValue> {
6267
self.top -= 1;

0 commit comments

Comments
 (0)