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

Commit 4da23c0

Browse files
feat: implicit function lable
Signed-off-by: Henry Gressmann <[email protected]>
1 parent 29018ba commit 4da23c0

File tree

7 files changed

+42
-20
lines changed

7 files changed

+42
-20
lines changed

crates/tinywasm/src/error.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ pub enum Error {
5454
/// The label stack is empty
5555
LabelStackUnderflow,
5656

57+
/// An invalid label type was encountered
58+
InvalidLabelType,
59+
5760
/// The call stack is empty
5861
CallStackEmpty,
5962

@@ -72,6 +75,7 @@ impl Display for Error {
7275

7376
Self::Trap(trap) => write!(f, "trap: {:?}", trap),
7477

78+
Self::InvalidLabelType => write!(f, "invalid label type"),
7579
Self::Other(message) => write!(f, "unknown error: {}", message),
7680
Self::UnsupportedFeature(feature) => write!(f, "unsupported feature: {}", feature),
7781
Self::FuncDidNotReturn => write!(f, "function did not return"),

crates/tinywasm/src/func.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,9 @@ impl FuncHandle {
5757
let call_frame = CallFrame::new(self.addr as usize, params, func_inst.locals().to_vec());
5858

5959
// 7. Push the frame f to the call stack
60+
// & 8. Push the values to the stack (Not needed since the call frame owns the values)
6061
stack.call_stack.push(call_frame);
6162

62-
// 8. Push the values to the stack (Not needed since the call frame owns the values)
63-
6463
// 9. Invoke the function instance
6564
let runtime = store.runtime();
6665
runtime.exec(store, &mut stack, self.module.clone())?;

crates/tinywasm/src/imports.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ use tinywasm_types::{Global, GlobalType, ModuleInstanceAddr, WasmValue};
1111
pub enum Extern {
1212
/// A global value
1313
Global(Global),
14-
/// A registered module
15-
Module(String),
1614
// Func(HostFunc),
1715
// Table(Table),
1816
}

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

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,24 @@ enum ExecResult {
7474
Trap(crate::Trap),
7575
}
7676

77+
// Break to a block at the given index (relative to the current frame)
78+
// If there is no block at the given index, return or call the parent function
79+
macro_rules! break_to {
80+
($cf:ident, $stack:ident, $break_to_relative:ident) => {{
81+
let res = $cf.break_to(*$break_to_relative, &mut $stack.values);
82+
match res {
83+
Some(()) => {}
84+
None => match $stack.call_stack.is_empty() {
85+
true => return Ok(ExecResult::Return),
86+
false => {
87+
*$cf = $stack.call_stack.pop()?;
88+
return Ok(ExecResult::Call);
89+
}
90+
},
91+
}
92+
}};
93+
}
94+
7795
/// Run a single step of the interpreter
7896
/// A seperate function is used so later, we can more easily implement
7997
/// a step-by-step debugger (using generators once they're stable?)
@@ -207,10 +225,10 @@ fn exec_one(
207225
todo!("br_table");
208226
}
209227

210-
Br(v) => cf.break_to(*v, &mut stack.values)?,
228+
Br(v) => break_to!(cf, stack, v),
211229
BrIf(v) => {
212230
if stack.values.pop_t::<i32>()? > 0 {
213-
cf.break_to(*v, &mut stack.values)?
231+
break_to!(cf, stack, v);
214232
}
215233
}
216234

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

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
use alloc::vec::Vec;
1+
use alloc::{vec, vec::Vec};
22
use log::info;
33
use tinywasm_types::BlockArgs;
44

55
use crate::{ModuleInstance, Result};
66

7-
#[derive(Debug, Default, Clone)]
7+
#[derive(Debug, Clone, Default)]
88
pub(crate) struct Labels(Vec<LabelFrame>);
99

1010
impl Labels {
@@ -13,15 +13,18 @@ impl Labels {
1313
}
1414

1515
#[inline]
16-
pub(crate) fn push(&mut self, block: LabelFrame) {
17-
self.0.push(block);
16+
pub(crate) fn push(&mut self, label: LabelFrame) {
17+
self.0.push(label);
1818
}
1919

2020
#[inline]
21-
/// get the block at the given index, where 0 is the top of the stack
21+
/// get the label at the given index, where 0 is the top of the stack
2222
pub(crate) fn get_relative_to_top(&self, index: usize) -> Option<&LabelFrame> {
23-
info!("get block: {}", index);
24-
info!("blocks: {:?}", self.0);
23+
let len = self.0.len();
24+
if index >= len {
25+
return None;
26+
}
27+
2528
self.0.get(self.0.len() - index - 1)
2629
}
2730

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,12 @@ impl CallFrame {
8989
}
9090

9191
/// Break to a block at the given index (relative to the current frame)
92+
/// Returns `None` if there is no block at the given index (e.g. if we need to return, this is validated by the parser)
9293
#[inline]
93-
pub(crate) fn break_to(&mut self, break_to_relative: u32, value_stack: &mut super::ValueStack) -> Result<()> {
94-
let break_to = self
95-
.labels
96-
.get_relative_to_top(break_to_relative as usize)
97-
.ok_or(Error::LabelStackUnderflow)?;
94+
pub(crate) fn break_to(&mut self, break_to_relative: u32, value_stack: &mut super::ValueStack) -> Option<()> {
95+
let Some(break_to) = self.labels.get_relative_to_top(break_to_relative as usize) else {
96+
return None;
97+
};
9898

9999
value_stack.break_to(break_to.stack_ptr, break_to.args.results);
100100

@@ -131,7 +131,7 @@ impl CallFrame {
131131
// // };
132132

133133
// self.block_frames.trim(block_index as usize);
134-
Ok(())
134+
Some(())
135135
}
136136

137137
pub(crate) fn new_raw(func_ptr: usize, params: &[RawWasmValue], local_types: Vec<ValType>) -> Self {

crates/tinywasm/tests/generated/mvp.csv

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)