diff options
| author | Henry <mail@henrygressmann.de> | 2026-05-02 15:40:47 +0200 |
|---|---|---|
| committer | Henry <mail@henrygressmann.de> | 2026-05-02 15:45:44 +0200 |
| commit | 5ed8982ad2cb4b348046aa11c527ce6a51f02e0e (patch) | |
| tree | c5427ac3ffdeedfa37b698eeb4f2dac09859b4a6 /crates | |
| parent | 361b715de9ea6a859aaafe84d4bcd3d46ed70797 (diff) | |
feat: add doom example, fix import argument order
Signed-off-by: Henry <mail@henrygressmann.de>
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/tinywasm/src/interpreter/executor.rs | 4 | ||||
| -rw-r--r-- | crates/tinywasm/src/reference.rs | 13 | ||||
| -rw-r--r-- | crates/tinywasm/tests/host_import_arg_order.rs | 31 |
3 files changed, 47 insertions, 1 deletions
diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index b1178d8..4d862d6 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -6,6 +6,7 @@ use super::no_std_floats::NoStdFloatExt; use alloc::boxed::Box; use alloc::rc::Rc; +use alloc::vec::Vec; use alloc::sync::Arc; use interpreter::stack::CallFrame; @@ -969,7 +970,8 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> { } fn exec_call_host(&mut self, host_func: Rc<HostFunction>) -> Result<(), Trap> { - let params = self.store.value_stack.pop_types(host_func.ty.params()).collect::<Box<_>>(); + let mut params = self.store.value_stack.pop_types(host_func.ty.params().iter().rev()).collect::<Vec<_>>(); + params.reverse(); let res = match host_func.call(FuncContext { store: self.store, module_addr: self.module.idx() }, ¶ms) { Ok(res) => res, Err(err) => { diff --git a/crates/tinywasm/src/reference.rs b/crates/tinywasm/src/reference.rs index 44916b4..5f8d46f 100644 --- a/crates/tinywasm/src/reference.rs +++ b/crates/tinywasm/src/reference.rs @@ -261,6 +261,19 @@ impl Memory { }) } + /// Copies a nul-terminated C string into memory. + pub fn write_cstring(&self, store: &mut Store, offset: usize, string: &CString) -> Result<()> { + self.copy_from_slice(store, offset, string.as_bytes_with_nul()) + } + + /// Copies a UTF-8 string into memory and appends a trailing nul byte. + pub fn write_cstring_bytes(&self, store: &mut Store, offset: usize, string: &str) -> Result<()> { + let mut bytes = Vec::with_capacity(string.len() + 1); + bytes.extend_from_slice(string.as_bytes()); + bytes.push(0); + self.copy_from_slice(store, offset, &bytes) + } + /// Reads a C-style string from memory. pub fn read_cstring(&self, store: &Store, offset: usize, len: usize) -> Result<CString> { CString::from_vec_with_nul(self.read_vec(store, offset, len)?) diff --git a/crates/tinywasm/tests/host_import_arg_order.rs b/crates/tinywasm/tests/host_import_arg_order.rs new file mode 100644 index 0000000..2004641 --- /dev/null +++ b/crates/tinywasm/tests/host_import_arg_order.rs @@ -0,0 +1,31 @@ +use tinywasm::{HostFunction, Imports, ModuleInstance, Store}; + +#[test] +fn multi_arg_host_imports_preserve_source_order() { + let wasm = wat::parse_str( + r#" + (module + (import "env" "pair" (func $pair (param i32 i32) (result i32))) + (func (export "call_pair") (param i32 i32) (result i32) + local.get 0 + local.get 1 + call $pair)) + "#, + ) + .unwrap(); + + let module = tinywasm::parse_bytes(&wasm).unwrap(); + let mut store = Store::default(); + + let pair = HostFunction::from(&mut store, |_ctx, (left, right): (i32, i32)| -> tinywasm::Result<i32> { + Ok(left * 1000 + right) + }); + + let mut imports = Imports::new(); + imports.define("env", "pair", pair); + + let instance = ModuleInstance::instantiate(&mut store, &module, Some(imports)).unwrap(); + let func = instance.func::<(i32, i32), i32>(&store, "call_pair").unwrap(); + + assert_eq!(func.call(&mut store, (12, 34)).unwrap(), 12034); +} |
