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

Commit 6853862

Browse files
chore: simplify interpreter
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
1 parent e2ae76c commit 6853862

File tree

4 files changed

+31
-49
lines changed

4 files changed

+31
-49
lines changed

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

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ use no_std_floats::NoStdFloatExt;
2323

2424
impl InterpreterRuntime {
2525
pub(crate) fn exec(&self, store: &mut Store, stack: &mut Stack) -> Result<()> {
26-
let mut executor = Executor::new(store, stack)?;
27-
executor.run_to_completion()
26+
Executor::new(store, stack)?.run_to_completion()
2827
}
2928
}
3029

@@ -36,24 +35,36 @@ struct Executor<'store, 'stack> {
3635
module: ModuleInstance,
3736
}
3837

38+
impl Iterator for Executor<'_, '_> {
39+
type Item = Result<()>;
40+
41+
fn next(&mut self) -> Option<Self::Item> {
42+
match self.exec_next() {
43+
Ok(ControlFlow::Continue(())) => Some(Ok(())),
44+
Ok(ControlFlow::Break(())) => None,
45+
Err(e) => Some(Err(e)),
46+
}
47+
}
48+
}
49+
3950
impl<'store, 'stack> Executor<'store, 'stack> {
4051
pub(crate) fn new(store: &'store mut Store, stack: &'stack mut Stack) -> Result<Self> {
41-
let current_frame = stack.call_stack.pop()?;
52+
let current_frame = stack.call_stack.pop().ok_or_else(|| Error::CallStackUnderflow)?;
4253
let current_module = store.get_module_instance_raw(current_frame.module_addr);
4354
Ok(Self { cf: current_frame, module: current_module, stack, store })
4455
}
4556

4657
pub(crate) fn run_to_completion(&mut self) -> Result<()> {
4758
loop {
48-
match self.next()? {
59+
match self.exec_next()? {
4960
ControlFlow::Break(..) => return Ok(()),
5061
ControlFlow::Continue(..) => continue,
5162
};
5263
}
5364
}
5465

5566
#[inline(always)]
56-
pub(crate) fn next(&mut self) -> Result<ControlFlow<()>> {
67+
pub(crate) fn exec_next(&mut self) -> Result<ControlFlow<()>> {
5768
use tinywasm_types::Instruction::*;
5869
match self.cf.fetch_instr() {
5970
Nop => cold(),
@@ -360,22 +371,17 @@ impl<'store, 'stack> Executor<'store, 'stack> {
360371

361372
#[inline(always)]
362373
fn exec_return(&mut self) -> Result<ControlFlow<()>> {
363-
// returning from the main function is a break
364-
if self.stack.call_stack.is_empty() {
365-
return Ok(ControlFlow::Break(()));
366-
}
367-
368374
let old = self.cf.block_ptr;
369-
self.cf = self.stack.call_stack.pop()?;
375+
match self.stack.call_stack.pop() {
376+
None => return Ok(ControlFlow::Break(())),
377+
Some(cf) => self.cf = cf,
378+
}
370379

371380
if old > self.cf.block_ptr {
372381
self.stack.blocks.truncate(old);
373382
}
374383

375-
if self.cf.module_addr != self.module.id() {
376-
self.module.swap_with(self.cf.module_addr, self.store);
377-
}
378-
384+
self.module.swap_with(self.cf.module_addr, self.store);
379385
Ok(ControlFlow::Continue(()))
380386
}
381387

@@ -390,7 +396,6 @@ impl<'store, 'stack> Executor<'store, 'stack> {
390396
self.stack.values.push(val.into());
391397
}
392398

393-
#[allow(clippy::too_many_arguments)]
394399
#[inline(always)]
395400
fn exec_i32_store_local(&mut self, local: u32, const_i32: i32, offset: u32, mem_addr: u8) -> Result<()> {
396401
let mem = self.store.get_mem(self.module.resolve_mem_addr(mem_addr as u32))?;
@@ -660,7 +665,7 @@ impl<'store, 'stack> Executor<'store, 'stack> {
660665
return Ok(ControlFlow::Continue(()));
661666
}
662667
};
663-
return self.exec_call(wasm_func.clone(), func_inst.owner);
668+
self.exec_call(wasm_func.clone(), func_inst.owner)
664669
}
665670

666671
#[inline(always)]
@@ -680,11 +685,10 @@ impl<'store, 'stack> Executor<'store, 'stack> {
680685
crate::Function::Wasm(f) => f,
681686
crate::Function::Host(host_func) => {
682687
if unlikely(host_func.ty != *call_ty) {
683-
return Err(Trap::IndirectCallTypeMismatch {
688+
return Err(Error::Trap(Trap::IndirectCallTypeMismatch {
684689
actual: host_func.ty.clone(),
685690
expected: call_ty.clone(),
686-
}
687-
.into());
691+
}));
688692
}
689693

690694
let host_func = host_func.clone();
@@ -701,7 +705,7 @@ impl<'store, 'stack> Executor<'store, 'stack> {
701705
}
702706

703707
cold();
704-
return Err(Trap::IndirectCallTypeMismatch { actual: wasm_func.ty.clone(), expected: call_ty.clone() }.into());
708+
Err(Trap::IndirectCallTypeMismatch { actual: wasm_func.ty.clone(), expected: call_ty.clone() }.into())
705709
}
706710

707711
#[inline(always)]

crates/tinywasm/src/runtime/mod.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,10 @@ compile_error!("`simd` feature requires nightly");
99
#[cfg(feature = "simd")]
1010
mod raw_simd;
1111

12-
use crate::Result;
13-
1412
pub use raw::RawWasmValue;
1513
pub(crate) use stack::CallFrame;
1614
pub(crate) use stack::Stack;
1715

18-
#[allow(rustdoc::private_intra_doc_links)]
19-
/// A WebAssembly runtime.
20-
///
21-
/// See <https://webassembly.github.io/spec/core/exec/runtime.html>
22-
pub trait Runtime {
23-
/// Execute all call-frames on the stack until the stack is empty.
24-
fn exec(&self, store: &mut crate::Store, stack: &mut Stack) -> Result<()>;
25-
}
26-
2716
/// The main TinyWasm runtime.
2817
///
2918
/// This is the default runtime used by TinyWasm.

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

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::runtime::RawWasmValue;
2-
use crate::{cold, unlikely};
3-
use crate::{Error, Result, Trap};
2+
use crate::unlikely;
3+
use crate::{Result, Trap};
44
use alloc::{boxed::Box, rc::Rc, vec::Vec};
55
use tinywasm_types::{Instruction, LocalAddr, ModuleInstanceAddr, WasmFunction};
66

@@ -22,25 +22,14 @@ impl CallStack {
2222
Self { stack }
2323
}
2424

25-
#[inline]
26-
pub(crate) fn is_empty(&self) -> bool {
27-
self.stack.is_empty()
28-
}
29-
3025
#[inline(always)]
31-
pub(crate) fn pop(&mut self) -> Result<CallFrame> {
32-
match self.stack.pop() {
33-
Some(frame) => Ok(frame),
34-
None => {
35-
cold();
36-
Err(Error::CallStackUnderflow)
37-
}
38-
}
26+
pub(crate) fn pop(&mut self) -> Option<CallFrame> {
27+
self.stack.pop()
3928
}
4029

4130
#[inline(always)]
4231
pub(crate) fn push(&mut self, call_frame: CallFrame) -> Result<()> {
43-
if unlikely(self.stack.len() >= self.stack.capacity()) {
32+
if unlikely((self.stack.len() + 1) >= CALL_STACK_SIZE) {
4433
return Err(Trap::CallStackOverflow.into());
4534
}
4635
self.stack.push(call_frame);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pub(crate) use value_stack::ValueStack;
88

99
/// A WebAssembly Stack
1010
#[derive(Debug)]
11-
pub struct Stack {
11+
pub(crate) struct Stack {
1212
pub(crate) values: ValueStack,
1313
pub(crate) blocks: BlockStack,
1414
pub(crate) call_stack: CallStack,

0 commit comments

Comments
 (0)