diff options
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/tinywasm/src/imports.rs | 3 | ||||
| -rw-r--r-- | crates/tinywasm/src/runtime/executor/mod.rs | 42 | ||||
| -rw-r--r-- | crates/tinywasm/src/runtime/stack/blocks.rs | 3 | ||||
| -rw-r--r-- | crates/tinywasm/src/runtime/stack/call_stack.rs | 7 | ||||
| -rw-r--r-- | crates/tinywasm/tests/generated/progress-mvp.svg | 6 |
5 files changed, 26 insertions, 35 deletions
diff --git a/crates/tinywasm/src/imports.rs b/crates/tinywasm/src/imports.rs index a13e488..1b3a9cf 100644 --- a/crates/tinywasm/src/imports.rs +++ b/crates/tinywasm/src/imports.rs @@ -84,7 +84,8 @@ impl Imports { Ok(self) } - pub(crate) fn link(self, store: &mut crate::Store, module: &crate::Module) -> Result<LinkedImports> { + pub(crate) fn link(self, _store: &mut crate::Store, _module: &crate::Module) -> Result<LinkedImports> { + // TODO: link to other modules (currently only direct imports are supported) let values = self.values; Ok(LinkedImports { values }) } diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs index fae095f..e3d8a93 100644 --- a/crates/tinywasm/src/runtime/executor/mod.rs +++ b/crates/tinywasm/src/runtime/executor/mod.rs @@ -35,6 +35,7 @@ impl DefaultRuntime { match exec_one(&mut cf, instr, instrs, stack, store, &module)? { // Continue execution at the new top of the call stack ExecResult::Call => { + cf = stack.call_stack.pop()?; func = store.get_func(cf.func_ptr)?.clone(); instrs = func.instructions(); continue; @@ -76,18 +77,17 @@ enum ExecResult { // Break to a block at the given index (relative to the current frame) // If there is no block at the given index, return or call the parent function +// +// This is a bit hard to see from the spec, but it's vaild to use breaks to return +// from a function, so we need to check if the label stack is empty macro_rules! break_to { ($cf:ident, $stack:ident, $break_to_relative:ident) => {{ - let res = $cf.break_to(*$break_to_relative, &mut $stack.values); - match res { - Some(()) => {} - None => match $stack.call_stack.is_empty() { - true => return Ok(ExecResult::Return), - false => { - *$cf = $stack.call_stack.pop()?; - return Ok(ExecResult::Call); - } - }, + if $cf.break_to(*$break_to_relative, &mut $stack.values).is_none() { + if $stack.call_stack.is_empty() { + return Ok(ExecResult::Return); + } else { + return Ok(ExecResult::Call); + } } }}; } @@ -143,8 +143,6 @@ fn exec_one( stack.call_stack.push(call_frame); // call the function - *cf = stack.call_stack.pop()?; - debug!("calling: {:?}", func); return Ok(ExecResult::Call); } @@ -221,6 +219,7 @@ fn exec_one( if instr.len() != *len { panic!("Expected {} BrLabel instructions, got {}", len, instr.len()); } + cf.instr_ptr += *len; todo!("br_table"); } @@ -234,27 +233,22 @@ fn exec_one( Return => match stack.call_stack.is_empty() { true => return Ok(ExecResult::Return), - false => { - *cf = stack.call_stack.pop()?; - return Ok(ExecResult::Call); - } + false => return Ok(ExecResult::Call), }, EndFunc => { - if cf.labels.len() > 0 { - panic!("endfunc: block frames not empty, this should have been validated by the parser"); - } + debug_assert!( + cf.labels.len() > 0, + "endfunc: block frames not empty, this should have been validated by the parser" + ); match stack.call_stack.is_empty() { true => return Ok(ExecResult::Return), - false => { - *cf = stack.call_stack.pop()?; - return Ok(ExecResult::Call); - } + false => return Ok(ExecResult::Call), } } - // We're essentially using else as a EndBlockFrame instruction + // We're essentially using else as a EndBlockFrame instruction for if blocks Else(end_offset) => { let Some(block) = cf.labels.pop() else { panic!("else: no label to end, this should have been validated by the parser"); diff --git a/crates/tinywasm/src/runtime/stack/blocks.rs b/crates/tinywasm/src/runtime/stack/blocks.rs index 46c341d..f5a0d8d 100644 --- a/crates/tinywasm/src/runtime/stack/blocks.rs +++ b/crates/tinywasm/src/runtime/stack/blocks.rs @@ -1,5 +1,4 @@ -use alloc::{vec, vec::Vec}; -use log::info; +use alloc::vec::Vec; use tinywasm_types::BlockArgs; use crate::{ModuleInstance, Result}; diff --git a/crates/tinywasm/src/runtime/stack/call_stack.rs b/crates/tinywasm/src/runtime/stack/call_stack.rs index c5193c3..239659c 100644 --- a/crates/tinywasm/src/runtime/stack/call_stack.rs +++ b/crates/tinywasm/src/runtime/stack/call_stack.rs @@ -89,13 +89,10 @@ impl CallFrame { } /// Break to a block at the given index (relative to the current frame) - /// Returns `None` if there is no block at the given index (e.g. if we need to return, this is validated by the parser) + /// Returns `None` if there is no block at the given index (e.g. if we need to return, this is handled by the caller) #[inline] pub(crate) fn break_to(&mut self, break_to_relative: u32, value_stack: &mut super::ValueStack) -> Option<()> { - let Some(break_to) = self.labels.get_relative_to_top(break_to_relative as usize) else { - return None; - }; - + let break_to = self.labels.get_relative_to_top(break_to_relative as usize)?; value_stack.break_to(break_to.stack_ptr, break_to.args.results); // instr_ptr points to the label instruction, but the next step diff --git a/crates/tinywasm/tests/generated/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index caad2bb..7829bdc 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -53,12 +53,12 @@ v0.1.0 (17630) </text> <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="716,345 716,350 "/> <text x="898" y="355" dy="0.76em" text-anchor="middle" font-family="Victor Mono" font-size="12.096774193548388" opacity="1" fill="#000000"> -v0.2.0-alpha.0 (18657) +v0.2.0-alpha.0 (18674) </text> <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" points="898,345 898,350 "/> -<rect x="266" y="212" width="172" height="132" opacity="0.5" fill="#0000FF" stroke="none"/> <rect x="85" y="212" width="171" height="132" opacity="0.5" fill="#0000FF" stroke="none"/> +<rect x="266" y="212" width="172" height="132" opacity="0.5" fill="#0000FF" stroke="none"/> +<rect x="812" y="77" width="172" height="267" opacity="0.5" fill="#0000FF" stroke="none"/> <rect x="630" y="92" width="172" height="252" opacity="0.5" fill="#0000FF" stroke="none"/> <rect x="448" y="185" width="172" height="159" opacity="0.5" fill="#0000FF" stroke="none"/> -<rect x="812" y="77" width="172" height="267" opacity="0.5" fill="#0000FF" stroke="none"/> </svg> |
