summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/cli/src/cmd/run.rs16
-rw-r--r--crates/tinywasm/src/instance.rs23
-rw-r--r--crates/tinywasm/src/interpreter/executor.rs9
-rw-r--r--crates/tinywasm/tests/internal_refs.rs5
-rw-r--r--crates/tinywasm/tests/start_function.rs23
5 files changed, 44 insertions, 32 deletions
diff --git a/crates/cli/src/cmd/run.rs b/crates/cli/src/cmd/run.rs
index b2f5e03..06f29f1 100644
--- a/crates/cli/src/cmd/run.rs
+++ b/crates/cli/src/cmd/run.rs
@@ -1,4 +1,4 @@
-use eyre::{Result, bail};
+use eyre::Result;
use tinywasm::types::ExportType;
use tinywasm::{ModuleInstance, Store};
@@ -34,13 +34,17 @@ pub fn run(args: RunArgs) -> Result<()> {
Ok(())
}
None => {
- if instance.start_func(&store)?.is_none() {
- bail!(
- "module has no start function or `_start` export; use `tinywasm inspect {module_path}` or `tinywasm run --invoke <export> {module_path}`"
- )
+ if instance.start_func(&store)?.is_some() {
+ let _ = instance.start(&mut store)?;
+ return Ok(());
}
- let _ = instance.start(&mut store)?;
+ let start = instance.func_untyped(&store, "_start").map_err(|_| {
+ eyre::eyre!(
+ "module has no start function or `_start` export. Use `tinywasm inspect {module_path}` or `tinywasm run --invoke <export> {module_path}`"
+ )
+ })?;
+ start.call(&mut store, &[])?;
Ok(())
}
}
diff --git a/crates/tinywasm/src/instance.rs b/crates/tinywasm/src/instance.rs
index b75127f..f1003ab 100644
--- a/crates/tinywasm/src/instance.rs
+++ b/crates/tinywasm/src/instance.rs
@@ -604,7 +604,8 @@ impl ModuleInstance {
/// # use tinywasm::{ModuleInstance, Store};
/// # let wasm = wat::parse_str(r#"
/// # (module
- /// # (func (export "_start"))
+ /// # (func $start)
+ /// # (start $start)
/// # )
/// # "#).expect("valid wat");
/// # let module = tinywasm::parse_bytes(&wasm)?;
@@ -619,21 +620,8 @@ impl ModuleInstance {
pub fn start_func(&self, store: &Store) -> Result<Option<Function>> {
self.validate_store(store)?;
- let func_addr = match self.0.func_start {
- Some(func_index) => func_index,
- None => {
- // Alternatively, check for a _start function in the exports.
- let Some(ExternVal::Func(func_addr)) = self.export_addr("_start") else {
- return Ok(None);
- };
-
- return Ok(Some(Function {
- item: crate::StoreItem::new(self.0.store_id, func_addr),
- module_addr: self.id(),
- addr: func_addr,
- ty: store.state.get_func(func_addr).ty().clone(),
- }));
- }
+ let Some(func_addr) = self.0.func_start else {
+ return Ok(None);
};
let func_addr = self.resolve_func_addr(func_addr);
@@ -656,9 +644,10 @@ impl ModuleInstance {
/// # let wasm = wat::parse_str(r#"
/// # (module
/// # (global $g (mut i32) (i32.const 0))
- /// # (func (export "_start")
+ /// # (func $start
/// # i32.const 7
/// # global.set $g)
+ /// # (start $start)
/// # (export "g" (global $g)))
/// # "#).expect("valid wat");
/// # let module = tinywasm::parse_bytes(&wasm)?;
diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs
index 37b2f43..e54b5e5 100644
--- a/crates/tinywasm/src/interpreter/executor.rs
+++ b/crates/tinywasm/src/interpreter/executor.rs
@@ -49,6 +49,7 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> {
}
}
+ #[allow(clippy::redundant_closure_call)] // we wrap these in closures to get better perf traces
#[inline(always)]
fn exec(&mut self) -> Result<Option<()>, Trap> {
macro_rules! stack_op {
@@ -264,7 +265,7 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> {
}};
}
- let next = match self.func.instructions.get(self.cf.instr_ptr as usize) {
+ let next = match self.func.instructions.get(self.cf.instr_ptr) {
Some(instr) => instr,
None => {
cold_path();
@@ -1654,12 +1655,6 @@ impl<'store> Executor<'store, true> {
}
}
-#[cold]
-#[inline(never)]
-fn instruction_pointer_out_of_bounds(instr_ptr: usize, instruction_count: usize) -> ! {
- panic!("Instruction pointer out of bounds: {instr_ptr} ({instruction_count} instructions)")
-}
-
#[inline(always)]
fn cmp_i32(lhs: i32, rhs: i32, op: CmpOp) -> bool {
match op {
diff --git a/crates/tinywasm/tests/internal_refs.rs b/crates/tinywasm/tests/internal_refs.rs
index 2382597..18033a7 100644
--- a/crates/tinywasm/tests/internal_refs.rs
+++ b/crates/tinywasm/tests/internal_refs.rs
@@ -169,14 +169,15 @@ fn export_func_type_index_mismatch_fixture_would_break_old_lookup() -> Result<()
}
#[test]
-fn start_prefers_exported_start_without_re_resolving_store_addr() -> Result<()> {
+fn start_resolves_module_func_index_to_store_addr() -> Result<()> {
let wasm = wat::parse_str(
r#"
(module
(global (export "g") (mut i32) (i32.const 0))
- (func (export "_start")
+ (func $start
i32.const 1
global.set 0)
+ (start $start)
)
"#,
)?;
diff --git a/crates/tinywasm/tests/start_function.rs b/crates/tinywasm/tests/start_function.rs
new file mode 100644
index 0000000..077c0fc
--- /dev/null
+++ b/crates/tinywasm/tests/start_function.rs
@@ -0,0 +1,23 @@
+use eyre::Result;
+use tinywasm::{ModuleInstance, Store};
+
+#[test]
+fn exported_wasi_start_is_not_run_during_instantiation() -> Result<()> {
+ let wasm = wat::parse_str(
+ r#"
+ (module
+ (table 1 funcref)
+ (func $_start (export "_start")
+ unreachable)
+ (elem (i32.const 0) func $_start))
+ "#,
+ )?;
+ let module = tinywasm::parse_bytes(&wasm)?;
+ let mut store = Store::default();
+
+ let instance = ModuleInstance::instantiate(&mut store, &module, None)?;
+
+ assert!(instance.start_func(&store)?.is_none());
+ assert!(instance.func::<(), ()>(&store, "_start")?.call(&mut store, ()).is_err());
+ Ok(())
+}