Skip to content

Commit 5caced7

Browse files
chore: simplify ToWasmTypes traits, general cleanup
Signed-off-by: Henry <mail@henrygressmann.de>
1 parent bec0136 commit 5caced7

29 files changed

Lines changed: 448 additions & 661 deletions

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4444
- `Parser::new` now takes `ParserOptions`. Use `Parser::default()` for default settings. `Parser::with_options` was removed.
4545
- Pluggable memory backends and `Config::with_trap_on_oom` were removed for performance reasons. Linear memory is always `Vec`-backed. Use `ResourceLimiter` to allow, reject, or trap memory allocation and growth requests.
4646
- `WasmTupleChain` was removed. Use direct tuples up to arity 20 or untyped functions for larger signatures.
47+
- `ToWasmTypes` was renamed to `WasmTypes`, and `ToWasmType` was renamed to `WasmValueType`. Conversion traits now include `WasmTypes`, and `FromWasmValues::from_wasm_values` rejects unconsumed values directly.
4748
- The `.twasm` format changed. Regenerate archives created by earlier TinyWasm versions.
4849

4950
## [0.10.0] - 2026-07-24

Cargo.lock

Lines changed: 13 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ pretty_env_logger = "0.5"
3131
serde = { version = "1.0", features = ["derive"] }
3232
serde_json = { version = "1.0" }
3333
wasm-testsuite = { version = "0.7" }
34-
wasmparser = { version = "0.257", default-features = false }
35-
wast = "257"
36-
wat = "1.257"
34+
wasmparser = { version = "0.258", default-features = false }
35+
wast = "258"
36+
wat = "1.258"
3737

3838
criterion = { version = "0.8", default-features = false, features = ["cargo_bench_support", "rayon"] }
3939

crates/cli/src/wast_runner.rs

Lines changed: 15 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ use anyhow::{Context, Result, anyhow, bail};
99
use log::{debug, error};
1010
use tinywasm::types::{MemoryType, RefType, RefValue, TableType, WasmType, WasmValue};
1111
use tinywasm::{ExecProgress, Global, HostFunction, Imports, Memory, Module, ModuleInstance, Store, Table};
12-
use wast::{QuoteWat, core::AbstractHeapType};
12+
use wast::QuoteWat;
13+
use wast::core::{AbstractHeapType, NanPattern};
1314

1415
const TEST_TIME_SLICE: Duration = Duration::from_millis(20);
1516
const TEST_MAX_SUSPENSIONS: u32 = 1000;
@@ -18,6 +19,15 @@ const ACCEPTED_MALFORMED_MESSAGES: &[&str] =
1819
&["integer representation too long", "zero byte expected", "zero flag expected"];
1920
const ACCEPTED_INVALID_MESSAGES: &[&str] = &["multiple memories"];
2021

22+
macro_rules! float_value {
23+
($pattern:expr, $float:ty, $variant:ident) => {
24+
match $pattern {
25+
NanPattern::CanonicalNan | NanPattern::ArithmeticNan => WasmValue::$variant(<$float>::NAN),
26+
NanPattern::Value(value) => WasmValue::$variant(<$float>::from_bits(value.bits)),
27+
}
28+
};
29+
}
30+
2131
#[derive(Default)]
2232
struct ModuleRegistry {
2333
definitions: HashMap<String, Module>,
@@ -845,10 +855,10 @@ fn wastarg2tinywasmvalue(store: &mut Store, arg: wast::WastArg) -> Result<WasmVa
845855
fn wast_v128_to_bytes(i: wast::core::V128Pattern) -> [u8; 16] {
846856
let res: Vec<u8> = match i {
847857
wast::core::V128Pattern::F32x4(f) => {
848-
f.iter().flat_map(|v| nanpattern2tinywasmvalue(*v).unwrap().as_f32().unwrap().to_le_bytes()).collect()
858+
f.iter().flat_map(|v| float_value!(*v, f32, F32).as_f32().unwrap().to_le_bytes()).collect()
849859
}
850860
wast::core::V128Pattern::F64x2(f) => {
851-
f.iter().flat_map(|v| nanpattern2tinywasmvalue(*v).unwrap().as_f64().unwrap().to_le_bytes()).collect()
861+
f.iter().flat_map(|v| float_value!(*v, f64, F64).as_f64().unwrap().to_le_bytes()).collect()
852862
}
853863
wast::core::V128Pattern::I16x8(f) => f.iter().flat_map(|v| v.to_le_bytes()).collect(),
854864
wast::core::V128Pattern::I32x4(f) => f.iter().flat_map(|v| v.to_le_bytes()).collect(),
@@ -920,8 +930,8 @@ fn wastretcore2tinywasmvalue(ret: wast::core::WastRetCore) -> Result<ExpectedVal
920930
RefStruct, V128,
921931
};
922932
Ok(match ret {
923-
F32(f) => ExpectedValue::Exact(nanpattern2tinywasmvalue(f)?),
924-
F64(f) => ExpectedValue::Exact(nanpattern2tinywasmvalue(f)?),
933+
F32(f) => ExpectedValue::Exact(float_value!(f, f32, F32)),
934+
F64(f) => ExpectedValue::Exact(float_value!(f, f64, F64)),
925935
I32(i) => ExpectedValue::Exact(WasmValue::I32(i)),
926936
I64(i) => ExpectedValue::Exact(WasmValue::I64(i)),
927937
V128(i) => ExpectedValue::Exact(WasmValue::V128(wast_v128_to_bytes(i))),
@@ -945,63 +955,6 @@ fn wastretcore2tinywasmvalue(ret: wast::core::WastRetCore) -> Result<ExpectedVal
945955
})
946956
}
947957

948-
enum Bits {
949-
U32(u32),
950-
U64(u64),
951-
}
952-
953-
trait FloatToken {
954-
fn bits(&self) -> Bits;
955-
fn canonical_nan() -> WasmValue;
956-
fn arithmetic_nan() -> WasmValue;
957-
fn value(&self) -> WasmValue {
958-
match self.bits() {
959-
Bits::U32(v) => WasmValue::F32(f32::from_bits(v)),
960-
Bits::U64(v) => WasmValue::F64(f64::from_bits(v)),
961-
}
962-
}
963-
}
964-
965-
impl FloatToken for wast::token::F32 {
966-
fn bits(&self) -> Bits {
967-
Bits::U32(self.bits)
968-
}
969-
970-
fn canonical_nan() -> WasmValue {
971-
WasmValue::F32(f32::NAN)
972-
}
973-
974-
fn arithmetic_nan() -> WasmValue {
975-
WasmValue::F32(f32::NAN)
976-
}
977-
}
978-
979-
impl FloatToken for wast::token::F64 {
980-
fn bits(&self) -> Bits {
981-
Bits::U64(self.bits)
982-
}
983-
984-
fn canonical_nan() -> WasmValue {
985-
WasmValue::F64(f64::NAN)
986-
}
987-
988-
fn arithmetic_nan() -> WasmValue {
989-
WasmValue::F64(f64::NAN)
990-
}
991-
}
992-
993-
fn nanpattern2tinywasmvalue<T>(arg: wast::core::NanPattern<T>) -> Result<WasmValue>
994-
where
995-
T: FloatToken,
996-
{
997-
use wast::core::NanPattern::{ArithmeticNan, CanonicalNan, Value};
998-
Ok(match arg {
999-
CanonicalNan => T::canonical_nan(),
1000-
ArithmeticNan => T::arithmetic_nan(),
1001-
Value(v) => v.value(),
1002-
})
1003-
}
1004-
1005958
#[cfg(test)]
1006959
mod tests {
1007960
use super::*;

crates/tinywasm/src/engine.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,16 @@ pub enum FuelPolicy {
5151
}
5252

5353
/// Default size for the 32-bit value stack (i32, f32, ref values).
54-
pub const DEFAULT_VALUE_STACK_32_SIZE: usize = 36 * 1024; // 36k slots
54+
const DEFAULT_VALUE_STACK_32_SIZE: usize = 36 * 1024; // 36k slots
5555

5656
/// Default size for the 64-bit value stack (i64, f64 values).
57-
pub const DEFAULT_VALUE_STACK_64_SIZE: usize = 32 * 1024; // 32k slots
57+
const DEFAULT_VALUE_STACK_64_SIZE: usize = 32 * 1024; // 32k slots
5858

5959
/// Default size for the 128-bit value stack (v128 values).
60-
pub const DEFAULT_VALUE_STACK_128_SIZE: usize = 4 * 1024; // 4k slots
60+
const DEFAULT_VALUE_STACK_128_SIZE: usize = 4 * 1024; // 4k slots
6161

6262
/// Default maximum size for the call stack (function frames).
63-
pub const DEFAULT_MAX_CALL_STACK_SIZE: usize = 1024; // 1024 frames
63+
const DEFAULT_MAX_CALL_STACK_SIZE: usize = 1024; // 1024 frames
6464

6565
/// Stack allocation policy.
6666
#[derive(Clone, Copy, PartialEq, Eq)]

crates/tinywasm/src/func/context.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,11 @@ impl FuncContext<'_> {
2121
}
2222

2323
/// Get the module instance.
24-
pub fn module(&self) -> crate::ModuleInstance {
24+
pub fn module(&self) -> &crate::ModuleInstance {
2525
unwrap_or_unreachable!(
2626
self.store.get_module_instance(self.module_id),
2727
"invalid module instance id in host function context"
2828
)
29-
.clone()
3029
}
3130

3231
/// Get a memory export.
@@ -46,7 +45,7 @@ impl FuncContext<'_> {
4645

4746
/// Get the value of a global export.
4847
pub fn global_get(&mut self, name: &str) -> Result<WasmValue> {
49-
self.module().global_get(self.store, name)
48+
self.module().clone().global_get(self.store, name)
5049
}
5150

5251
/// Get a global export.
@@ -56,7 +55,7 @@ impl FuncContext<'_> {
5655

5756
/// Set the value of a mutable global export.
5857
pub fn global_set(&mut self, name: &str, value: WasmValue) -> Result<()> {
59-
self.module().global_set(self.store, name, value)
58+
self.module().clone().global_set(self.store, name, value)
6059
}
6160

6261
/// Charge additional fuel from the currently running resumable invocation.
@@ -98,11 +97,11 @@ impl FuncContext<'_> {
9897

9998
/// Calls a Store-aware function reference in the current module context.
10099
pub fn call_ref(&mut self, func: FuncRef, args: &[WasmValue], results: &mut [WasmValue]) -> Result<()> {
101-
let addr = func.addr(self.store.store_id()).ok_or(crate::Trap::InvalidStore)?;
100+
let addr = func.addr(self.store.id()).ok_or(crate::Trap::InvalidStore)?;
102101
if self.store.state.funcs.get(addr as usize).is_none() {
103102
return Err(crate::Trap::InvalidReference.into());
104103
}
105-
let function = Function { item: crate::StoreItem::new(self.store.store_id(), addr), module_id: self.module_id };
104+
let function = Function { item: crate::StoreItem::new(self.store.id(), addr), module_id: self.module_id };
106105
self.call_untyped(&function, args, results)
107106
}
108107

@@ -132,7 +131,7 @@ impl FuncContext<'_> {
132131
let value_stack_base = store.value_stack.base();
133132
func.func.call_untyped(store, params, results, call_stack_base, value_stack_base)?;
134133
values.drain(..param_count);
135-
R::from_wasm_values_exact(&mut values.drain(..))
134+
R::from_wasm_values(&mut values.drain(..))
136135
})
137136
} else {
138137
let call_stack_base = self.store.call_stack.len();

crates/tinywasm/src/func/host.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use alloc::{boxed::Box, vec::Vec};
22
use tinywasm_types::{FuncType, ModuleInstanceId, TypeAddr, WasmType};
33

4-
use super::{FromWasmValues, FuncContext, IntoWasmValues, ToWasmTypes};
4+
use super::{FromWasmValues, FuncContext, IntoWasmValues};
55
use crate::shared::StoreShared;
66
use crate::store::FuncValueTypes;
77
use crate::{Function, FunctionInstance, Result, Store, WasmValue};
@@ -33,7 +33,7 @@ impl HostFunction {
3333
pub(crate) fn instantiate_registered(&self, store: &mut Store, type_addr: TypeAddr) -> Function {
3434
let addr = store
3535
.add_func(FunctionInstance { type_addr, inner: crate::store::FunctionInstanceInner::Host(self.clone()) });
36-
Function { item: crate::StoreItem::new(store.store_id(), addr), module_id: 0 }
36+
Function { item: crate::StoreItem::new(store.id(), addr), module_id: 0 }
3737
}
3838

3939
/// Resolves the importing module's types without allocating a function instance.
@@ -213,10 +213,10 @@ impl HostFunction {
213213
pub fn from<F, P, R>(func: F) -> Self
214214
where
215215
F: Fn(FuncContext<'_>, P) -> Result<R> + HostFunctionCallback + 'static,
216-
P: FromWasmValues + ToWasmTypes + 'static,
217-
R: IntoWasmValues + ToWasmTypes + 'static,
216+
P: FromWasmValues + 'static,
217+
R: IntoWasmValues + 'static,
218218
{
219-
let ty = FuncType::new(&P::wasm_types(), &R::wasm_types());
219+
let ty = FuncType::new(P::WASM_TYPES, R::WASM_TYPES);
220220
let func = TypedHostCallbackImpl { func, marker: core::marker::PhantomData };
221221
Self(StoreShared::new(HostFunctionInner { ty, callback: HostCallback::Typed(Box::new(func)) }))
222222
}
@@ -261,7 +261,7 @@ where
261261
{
262262
fn call(&self, ctx: FuncContext<'_>, args: &[WasmValue], results: &mut [WasmValue]) -> Result<()> {
263263
let mut values = args.iter().cloned();
264-
let params = cold_err!(P::from_wasm_values_exact(&mut values))?;
264+
let params = cold_err!(P::from_wasm_values(&mut values))?;
265265
let mut values = (self.func)(ctx, params)?.into_wasm_values();
266266
for result in results {
267267
*result = cold_err!(values.next().ok_or_else(|| crate::Error::other("not enough typed function results")))?;
@@ -279,7 +279,7 @@ where
279279
};
280280
let params = {
281281
let mut values = store.stack_value_iter(type_addr, FuncValueTypes::Params, base)?;
282-
cold_err!(P::from_wasm_values_exact(&mut values))
282+
cold_err!(P::from_wasm_values(&mut values))
283283
};
284284
store.value_stack.truncate_to_base(base);
285285
let result = cold_err!((self.func)(FuncContext { store, module_id }, params?))?;

crates/tinywasm/src/func/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub use host::HostFunction;
1616
#[doc(hidden)]
1717
pub use host::HostFunctionCallback;
1818
pub use resume::{ExecProgress, FuncExecution, FuncExecutionTyped};
19-
pub use values::{FromWasmValues, IntoWasmValues, ToWasmType, ToWasmTypes};
19+
pub use values::{FromWasmValues, IntoWasmValues, WasmTypes, WasmValueType};
2020

2121
fn write_typed_params(params: &mut [WasmValue], mut values: impl Iterator<Item = WasmValue>) -> Result<()> {
2222
for param in params {
@@ -42,7 +42,7 @@ impl Function {
4242
/// Returns this function as a Store-aware WebAssembly function reference.
4343
pub fn as_func_ref(&self, store: &Store) -> Result<FuncRef> {
4444
self.item.validate_store(store)?;
45-
Ok(FuncRef::new(store.store_id(), self.addr()))
45+
Ok(FuncRef::new(store.id(), self.addr()))
4646
}
4747

4848
#[inline]
@@ -219,7 +219,7 @@ impl<P: IntoWasmValues, R: FromWasmValues> FunctionTyped<P, R> {
219219
let (params, results) = values.split_at_mut(param_count);
220220
self.func.call(store, params, results)?;
221221
values.drain(..param_count);
222-
R::from_wasm_values_exact(&mut values.drain(..))
222+
R::from_wasm_values(&mut values.drain(..))
223223
})
224224
} else {
225225
store.enter_execution()?;

0 commit comments

Comments
 (0)