From c2061cf63b0c131632c07191af2f9f76d13e8a3e Mon Sep 17 00:00:00 2001 From: Henry Date: Sun, 12 Apr 2026 22:39:22 +0200 Subject: chore: cleanup Signed-off-by: Henry --- crates/parser/README.md | 5 +- crates/parser/src/conversion.rs | 36 ++++---- crates/parser/src/module.rs | 2 +- crates/tinywasm/src/func.rs | 57 ++++++------- crates/tinywasm/src/imports.rs | 6 +- crates/tinywasm/src/instance.rs | 16 ++-- crates/tinywasm/src/interpreter/executor.rs | 6 +- .../tinywasm/src/interpreter/stack/value_stack.rs | 20 ++--- crates/tinywasm/src/interpreter/values.rs | 28 +++--- crates/tinywasm/src/reference.rs | 20 ++--- crates/tinywasm/src/store/table.rs | 8 +- crates/tinywasm/tests/host_func_signature_check.rs | 34 ++++---- crates/tinywasm/tests/imported_table_init.rs | 4 +- crates/tinywasm/tests/module_descriptors.rs | 20 ++--- crates/tinywasm/tests/testsuite/run.rs | 18 ++-- crates/tinywasm/tests/testsuite/util.rs | 2 +- crates/types/src/instructions.rs | 4 +- crates/types/src/lib.rs | 53 ++++++++---- crates/types/src/value.rs | 99 ++++++++++------------ examples/rust/README.md | 2 +- 20 files changed, 229 insertions(+), 211 deletions(-) diff --git a/crates/parser/README.md b/crates/parser/README.md index 104cd50..c7eef8d 100644 --- a/crates/parser/README.md +++ b/crates/parser/README.md @@ -1,7 +1,6 @@ # `tinywasm-parser` -This crate provides a parser that can parse WebAssembly modules into a TinyWasm module. -It uses [my fork](https://crates.io/crates/tinywasm-wasmparser) of the [`wasmparser`](https://crates.io/crates/wasmparser) crate that has been modified to be compatible with `no_std` environments. +This crate provides a compiler that can convert WebAssembly modules into a `tinywasm` modules. ## Features @@ -16,6 +15,6 @@ let bytes = include_bytes!("./file.wasm"); let parser = Parser::new(); let module = parser.parse_module_bytes(bytes).unwrap(); -let mudule = parser.parse_module_file("path/to/file.wasm").unwrap(); +let module = parser.parse_module_file("path/to/file.wasm").unwrap(); let module = parser.parse_module_stream(&mut stream).unwrap(); ``` diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs index 63a42b2..19ce975 100644 --- a/crates/parser/src/conversion.rs +++ b/crates/parser/src/conversion.rs @@ -28,7 +28,7 @@ pub(crate) fn convert_module_element(element: wasmparser::Element<'_>) -> Result .collect::>>()? .into_boxed_slice(); - Ok(tinywasm_types::Element { kind, items, ty: ValType::RefFunc, range: element.range }) + Ok(tinywasm_types::Element { kind, items, ty: WasmType::RefFunc, range: element.range }) } wasmparser::ElementItems::Expressions(ty, exprs) => { @@ -211,26 +211,26 @@ pub(crate) fn convert_module_type(ty: wasmparser::RecGroup) -> Result } let ty = types.next().unwrap().unwrap_func(); - let params = ty.params().iter().map(convert_valtype).collect::>().into_boxed_slice(); - let results = ty.results().iter().map(convert_valtype).collect::>().into_boxed_slice(); - Ok(FuncType { params, results }) + let params: Vec<_> = ty.params().iter().map(convert_valtype).collect(); + let results: Vec<_> = ty.results().iter().map(convert_valtype).collect(); + Ok(FuncType::new(¶ms, &results)) } -pub(crate) fn convert_reftype(reftype: wasmparser::RefType) -> ValType { +pub(crate) fn convert_reftype(reftype: wasmparser::RefType) -> WasmType { match reftype { - _ if reftype.is_func_ref() => ValType::RefFunc, - _ if reftype.is_extern_ref() => ValType::RefExtern, + _ if reftype.is_func_ref() => WasmType::RefFunc, + _ if reftype.is_extern_ref() => WasmType::RefExtern, _ => unimplemented!("Unsupported reference type: {:?}, {:?}", reftype, reftype.heap_type()), } } -pub(crate) fn convert_valtype(valtype: &wasmparser::ValType) -> ValType { +pub(crate) fn convert_valtype(valtype: &wasmparser::ValType) -> WasmType { match valtype { - wasmparser::ValType::I32 => ValType::I32, - wasmparser::ValType::I64 => ValType::I64, - wasmparser::ValType::F32 => ValType::F32, - wasmparser::ValType::F64 => ValType::F64, - wasmparser::ValType::V128 => ValType::V128, + wasmparser::ValType::I32 => WasmType::I32, + wasmparser::ValType::I64 => WasmType::I64, + wasmparser::ValType::F32 => WasmType::F32, + wasmparser::ValType::F64 => WasmType::F64, + wasmparser::ValType::V128 => WasmType::V128, wasmparser::ValType::Ref(r) => convert_reftype(*r), } } @@ -247,8 +247,8 @@ pub(crate) fn process_const_operators(ops: OperatorsReader<'_>) -> Result match convert_heaptype(*hty) { - ValType::RefFunc => ConstInstruction::RefFunc(None), - ValType::RefExtern => ConstInstruction::RefExtern(None), + WasmType::RefFunc => ConstInstruction::RefFunc(None), + WasmType::RefExtern => ConstInstruction::RefExtern(None), _ => unimplemented!("Unsupported heap type: {:?}", hty), }, wasmparser::Operator::RefFunc { function_index } => ConstInstruction::RefFunc(Some(*function_index)), @@ -276,11 +276,11 @@ pub(crate) fn process_const_operators(ops: OperatorsReader<'_>) -> Result ValType { +pub(crate) fn convert_heaptype(heap: wasmparser::HeapType) -> WasmType { match heap { - wasmparser::HeapType::Abstract { shared: false, ty: wasmparser::AbstractHeapType::Func } => ValType::RefFunc, + wasmparser::HeapType::Abstract { shared: false, ty: wasmparser::AbstractHeapType::Func } => WasmType::RefFunc, wasmparser::HeapType::Abstract { shared: false, ty: wasmparser::AbstractHeapType::Extern } => { - ValType::RefExtern + WasmType::RefExtern } _ => unimplemented!("Unsupported heap type: {:?}", heap), } diff --git a/crates/parser/src/module.rs b/crates/parser/src/module.rs index b53dfd6..081af2b 100644 --- a/crates/parser/src/module.rs +++ b/crates/parser/src/module.rs @@ -181,7 +181,7 @@ impl ModuleReader { let funcs = self.code.into_iter().zip(self.code_type_addrs).enumerate().map( |(func_idx, ((instructions, mut data, locals), ty_idx))| { let ty = self.func_types.get(ty_idx as usize).expect("No func type for func, this is a bug").clone(); - let params = ValueCounts::from_iter(&ty.params); + let params = ValueCounts::from_iter(ty.params()); let self_func = (imported_func_count + func_idx) as u32; let instructions = optimize::optimize_instructions(instructions, &mut data, self_func, options); WasmFunction { instructions: ArcSlice::from(instructions), data, locals, params, ty } diff --git a/crates/tinywasm/src/func.rs b/crates/tinywasm/src/func.rs index aa7c674..e2a187f 100644 --- a/crates/tinywasm/src/func.rs +++ b/crates/tinywasm/src/func.rs @@ -3,7 +3,7 @@ use crate::reference::StoreItem; use crate::{Error, FunctionInstance, InterpreterRuntime, Result, Store, unlikely}; use alloc::rc::Rc; use alloc::{boxed::Box, format, string::ToString, vec, vec::Vec}; -use tinywasm_types::{ExternRef, FuncRef, FuncType, ModuleInstanceAddr, ValType, WasmValue}; +use tinywasm_types::{ExternRef, FuncRef, FuncType, ModuleInstanceAddr, WasmType, WasmValue}; impl Function { /// Call a function (Invocation) @@ -132,12 +132,12 @@ impl HostFunction { let ty = ty_inner.clone(); let result = func(ctx, args)?; - if result.len() != ty.results.len() { + if result.len() != ty.results().len() { return Err(crate::Error::InvalidHostFnReturn { expected: ty.clone(), actual: result }); }; - result.iter().zip(ty.results.iter()).try_for_each(|(val, res_ty)| { - if val.val_type() != *res_ty { + result.iter().zip(ty.results().iter()).try_for_each(|(val, res_ty)| { + if WasmType::from(val) != *res_ty { return Err(crate::Error::InvalidHostFnReturn { expected: ty.clone(), actual: result.clone() }); } Ok(()) @@ -153,8 +153,8 @@ impl HostFunction { /// Create a new typed host function import. pub fn from(store: &mut Store, func: impl Fn(FuncContext<'_>, P) -> Result + 'static) -> Function where - P: FromWasmValueTuple + ValTypesFromTuple, - R: IntoWasmValueTuple + ValTypesFromTuple, + P: FromWasmValueTuple + WasmTypesFromTuple, + R: IntoWasmValueTuple + WasmTypesFromTuple, { let inner_func = move |ctx: FuncContext<'_>, args: &[WasmValue]| -> Result> { let args = P::from_wasm_value_tuple(args)?; @@ -162,8 +162,7 @@ impl HostFunction { Ok(result.into_wasm_value_tuple()) }; - let results = R::val_types(); - let ty = tinywasm_types::FuncType { params: P::val_types(), results }; + let ty = tinywasm_types::FuncType::new(&P::wasm_types(), &R::wasm_types()); let addr = store.add_func(FunctionInstance::Host(Rc::new(Self { func: Box::new(inner_func), ty: ty.clone() }))); Function { item: crate::StoreItem::new(store.id(), addr), module_addr: 0, addr, ty } } @@ -363,15 +362,15 @@ impl<'store> FuncExecution<'store> { } fn validate_call_params(func_ty: &FuncType, params: &[WasmValue]) -> Result<()> { - if unlikely(func_ty.params.len() != params.len()) { + if unlikely(func_ty.params().len() != params.len()) { return Err(Error::Other(format!( "param count mismatch: expected {}, got {}", - func_ty.params.len(), + func_ty.params().len(), params.len() ))); } - if !(func_ty.params.iter().zip(params).all(|(ty, param)| ty == ¶m.val_type())) { + if !(func_ty.params().iter().zip(params).all(|(ty, param)| ty == ¶m.into())) { return Err(Error::Other("Type mismatch".into())); } @@ -379,8 +378,8 @@ fn validate_call_params(func_ty: &FuncType, params: &[WasmValue]) -> Result<()> } fn collect_call_results(store: &mut Store, func_ty: &FuncType) -> Result> { - debug_assert!(store.stack.values.len() >= func_ty.results.len()); // m values are on the top of the stack (Ensured by validation) - let mut res: Vec<_> = store.stack.values.pop_types(func_ty.results.iter().rev()).collect(); // pop in reverse order since the stack is LIFO + debug_assert!(store.stack.values.len() >= func_ty.results().len()); // m values are on the top of the stack (Ensured by validation) + let mut res: Vec<_> = store.stack.values.pop_types(func_ty.results().iter().rev()).collect(); // pop in reverse order since the stack is LIFO res.reverse(); // reverse to get the original order Ok(res) } @@ -443,28 +442,28 @@ impl<'store, R: FromWasmValueTuple> FuncExecutionTyped<'store, R> { } } -pub trait ValTypesFromTuple { - fn val_types() -> Box<[ValType]>; +pub trait WasmTypesFromTuple { + fn wasm_types() -> Box<[WasmType]>; } -pub trait ToValType { - fn to_val_type() -> ValType; +pub trait ToWasmType { + fn to_wasm_type() -> WasmType; } macro_rules! impl_scalar_wasm_traits { ($($T:ty => $val_ty:ident),+ $(,)?) => { $( - impl ToValType for $T { + impl ToWasmType for $T { #[inline] - fn to_val_type() -> ValType { - ValType::$val_ty + fn to_wasm_type() -> WasmType { + WasmType::$val_ty } } - impl ValTypesFromTuple for $T { + impl WasmTypesFromTuple for $T { #[inline] - fn val_types() -> Box<[ValType]> { - Box::new([ValType::$val_ty]) + fn wasm_types() -> Box<[WasmType]> { + Box::new([WasmType::$val_ty]) } } @@ -495,13 +494,13 @@ macro_rules! impl_scalar_wasm_traits { macro_rules! impl_tuple_traits { ($($T:ident),+) => { - impl<$($T),+> ValTypesFromTuple for ($($T,)+) + impl<$($T),+> WasmTypesFromTuple for ($($T,)+) where - $($T: ToValType,)+ + $($T: ToWasmType,)+ { #[inline] - fn val_types() -> Box<[ValType]> { - Box::new([$($T::to_val_type(),)+]) + fn wasm_types() -> Box<[WasmType]> { + Box::new([$($T::to_wasm_type(),)+]) } } @@ -569,9 +568,9 @@ impl_scalar_wasm_traits!( ); impl_tuple!(impl_tuple_traits); -impl ValTypesFromTuple for () { +impl WasmTypesFromTuple for () { #[inline] - fn val_types() -> Box<[ValType]> { + fn wasm_types() -> Box<[WasmType]> { Box::new([]) } } diff --git a/crates/tinywasm/src/imports.rs b/crates/tinywasm/src/imports.rs index abd9b70..89578b8 100644 --- a/crates/tinywasm/src/imports.rs +++ b/crates/tinywasm/src/imports.rs @@ -67,7 +67,7 @@ impl From<&Import> for ExternName { /// # use log; /// # fn main() -> tinywasm::Result<()> { /// use tinywasm::{Global, HostFunction, Imports, Memory, Module, Store, Table}; -/// use tinywasm::types::{ValType, TableType, MemoryType, WasmValue}; +/// use tinywasm::types::{WasmType, TableType, MemoryType, WasmValue}; /// # let wasm = wat::parse_str("(module)").expect("valid wat"); /// # let module = Module::parse_bytes(&wasm)?; /// # let mut store = Store::default(); @@ -81,9 +81,9 @@ impl From<&Import> for ExternName { /// Ok(()) /// }); /// -/// let table = Table::new(&mut store, TableType::new(ValType::RefFunc, 10, Some(20)), WasmValue::default_for(ValType::RefFunc))?; +/// let table = Table::new(&mut store, TableType::new(WasmType::RefFunc, 10, Some(20)), WasmValue::default_for(WasmType::RefFunc))?; /// let memory = Memory::new(&mut store, MemoryType::default().with_page_count_initial(1).with_page_count_max(Some(2)))?; -/// let global_i32 = Global::new(&mut store, tinywasm::types::GlobalType::default().with_ty(ValType::I32), WasmValue::I32(666))?; +/// let global_i32 = Global::new(&mut store, tinywasm::types::GlobalType::default().with_ty(WasmType::I32), WasmValue::I32(666))?; /// /// imports /// .define("my_module", "print_i32", print_i32) diff --git a/crates/tinywasm/src/instance.rs b/crates/tinywasm/src/instance.rs index 2e5b4b6..d2c3b2c 100644 --- a/crates/tinywasm/src/instance.rs +++ b/crates/tinywasm/src/instance.rs @@ -2,7 +2,7 @@ use alloc::boxed::Box; use alloc::{format, rc::Rc}; use tinywasm_types::*; -use crate::func::{FromWasmValueTuple, IntoWasmValueTuple, ValTypesFromTuple}; +use crate::func::{FromWasmValueTuple, IntoWasmValueTuple, WasmTypesFromTuple}; use crate::{Error, Function, FunctionTyped, Global, Imports, Memory, Module, Result, Store, Table}; /// A typed view over an exported extern value. @@ -304,7 +304,7 @@ impl ModuleInstance { } /// Get a typed function export by name. - pub fn func( + pub fn func( &self, store: &Store, name: &str, @@ -317,7 +317,10 @@ impl ModuleInstance { /// Get a typed function by its module-local index. #[cfg_attr(docsrs, doc(cfg(feature = "guest_debug")))] #[cfg(feature = "guest_debug")] - pub fn func_typed_by_index( + pub fn func_typed_by_index< + P: IntoWasmValueTuple + WasmTypesFromTuple, + R: FromWasmValueTuple + WasmTypesFromTuple, + >( &self, store: &Store, func_index: FuncAddr, @@ -327,8 +330,11 @@ impl ModuleInstance { Ok(FunctionTyped { func, marker: core::marker::PhantomData }) } - fn validate_typed_func(func: &Function, func_name: &str) -> Result<()> { - let expected = FuncType { params: P::val_types(), results: R::val_types() }; + fn validate_typed_func( + func: &Function, + func_name: &str, + ) -> Result<()> { + let expected = FuncType::new(&P::wasm_types(), &R::wasm_types()); if func.ty != expected { #[cfg(feature = "debug")] return Err(Error::Other(format!( diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index e76220f..63ddee7 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -738,7 +738,7 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> { Ok(()) } fn exec_call_host(&mut self, host_func: Rc) -> Result<()> { - let params = self.store.stack.values.pop_types(&host_func.ty.params).collect::>(); + let params = self.store.stack.values.pop_types(host_func.ty.params()).collect::>(); let res = host_func.call(FuncContext { store: self.store, module_addr: self.module.idx }, ¶ms)?; self.store.stack.values.extend_from_wasmvalues(&res)?; self.cf.incr_instr_ptr(); @@ -780,7 +780,7 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> { let func_ref = { let table_idx: u32 = self.store.stack.values.pop::() as u32; let table = self.store.state.get_table(self.module.resolve_table_addr(table_addr)); - assert!(table.kind.element_type == ValType::RefFunc, "table is not of type funcref"); + assert!(table.kind.element_type == WasmType::RefFunc, "table is not of type funcref"); let table = table.get(table_idx).map_err(|_| Error::from(Trap::UndefinedElement { index: table_idx as usize }))?; table.addr().ok_or_else(|| Error::from(Trap::UninitializedElement { index: table_idx as usize }))? @@ -814,7 +814,7 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> { } fn exec_return(&mut self) -> bool { - let results = ValueCounts::from_iter(&self.func.ty.results); + let results = ValueCounts::from_iter(self.func.ty.results()); self.store.stack.values.truncate_keep_counts(self.cf.locals_base, results); let Some(cf) = self.store.stack.call_stack.pop() else { return true }; diff --git a/crates/tinywasm/src/interpreter/stack/value_stack.rs b/crates/tinywasm/src/interpreter/stack/value_stack.rs index 1203929..8db3c85 100644 --- a/crates/tinywasm/src/interpreter/stack/value_stack.rs +++ b/crates/tinywasm/src/interpreter/stack/value_stack.rs @@ -1,6 +1,6 @@ use alloc::boxed::Box; use alloc::vec::Vec; -use tinywasm_types::{ExternRef, FuncRef, LocalAddr, ValType, ValueCounts, WasmValue}; +use tinywasm_types::{ExternRef, FuncRef, LocalAddr, ValueCounts, WasmType, WasmValue}; use crate::{Result, Trap, engine::Config, interpreter::*, unlikely}; @@ -197,7 +197,7 @@ impl ValueStack { pub(crate) fn pop_types<'a>( &'a mut self, - val_types: impl IntoIterator, + val_types: impl IntoIterator, ) -> impl core::iter::Iterator { val_types.into_iter().map(|val_type| self.pop_wasmvalue(*val_type)) } @@ -272,15 +272,15 @@ impl ValueStack { Ok(()) } - pub(crate) fn pop_wasmvalue(&mut self, val_type: ValType) -> WasmValue { + pub(crate) fn pop_wasmvalue(&mut self, val_type: WasmType) -> WasmValue { match val_type { - ValType::I32 => WasmValue::I32(self.pop()), - ValType::I64 => WasmValue::I64(self.pop()), - ValType::F32 => WasmValue::F32(self.pop()), - ValType::F64 => WasmValue::F64(self.pop()), - ValType::RefExtern => WasmValue::RefExtern(ExternRef::new(self.pop())), - ValType::RefFunc => WasmValue::RefFunc(FuncRef::new(self.pop())), - ValType::V128 => WasmValue::V128(self.pop::().into()), + WasmType::I32 => WasmValue::I32(self.pop()), + WasmType::I64 => WasmValue::I64(self.pop()), + WasmType::F32 => WasmValue::F32(self.pop()), + WasmType::F64 => WasmValue::F64(self.pop()), + WasmType::RefExtern => WasmValue::RefExtern(ExternRef::new(self.pop())), + WasmType::RefFunc => WasmValue::RefFunc(FuncRef::new(self.pop())), + WasmType::V128 => WasmValue::V128(self.pop::().into()), } } diff --git a/crates/tinywasm/src/interpreter/values.rs b/crates/tinywasm/src/interpreter/values.rs index 54ba00f..b8e15f4 100644 --- a/crates/tinywasm/src/interpreter/values.rs +++ b/crates/tinywasm/src/interpreter/values.rs @@ -2,7 +2,7 @@ use crate::{Result, interpreter::simd::Value128}; use super::stack::{CallFrame, ValueStack}; use tinywasm_types::LocalAddr; -use tinywasm_types::{ExternRef, FuncRef, ValType, WasmValue}; +use tinywasm_types::{ExternRef, FuncRef, WasmType, WasmValue}; pub(crate) type Value32 = u32; pub(crate) type Value64 = u64; @@ -55,20 +55,20 @@ impl TinyWasmValue { } /// Attaches a type to the value (panics if the size of the value is not the same as the type) - pub fn attach_type(&self, ty: ValType) -> WasmValue { + pub fn attach_type(&self, ty: WasmType) -> WasmValue { match (self, ty) { - (Self::Value32(v), ValType::I32) => WasmValue::I32(*v as i32), - (Self::Value64(v), ValType::I64) => WasmValue::I64(*v as i64), - (Self::Value32(v), ValType::F32) => WasmValue::F32(f32::from_bits(*v)), - (Self::Value64(v), ValType::F64) => WasmValue::F64(f64::from_bits(*v)), - (Self::ValueRef(v), ValType::RefExtern) => WasmValue::RefExtern(ExternRef::new(*v)), - (Self::ValueRef(v), ValType::RefFunc) => WasmValue::RefFunc(FuncRef::new(*v)), - (Self::Value128(v), ValType::V128) => WasmValue::V128((*v).into()), - - (_, ValType::I32 | ValType::F32) => panic!("Expected Value32"), - (_, ValType::I64 | ValType::F64) => panic!("Expected Value64"), - (_, ValType::RefExtern | ValType::RefFunc) => panic!("Expected ValueRef"), - (_, ValType::V128) => panic!("Expected Value128"), + (Self::Value32(v), WasmType::I32) => WasmValue::I32(*v as i32), + (Self::Value64(v), WasmType::I64) => WasmValue::I64(*v as i64), + (Self::Value32(v), WasmType::F32) => WasmValue::F32(f32::from_bits(*v)), + (Self::Value64(v), WasmType::F64) => WasmValue::F64(f64::from_bits(*v)), + (Self::ValueRef(v), WasmType::RefExtern) => WasmValue::RefExtern(ExternRef::new(*v)), + (Self::ValueRef(v), WasmType::RefFunc) => WasmValue::RefFunc(FuncRef::new(*v)), + (Self::Value128(v), WasmType::V128) => WasmValue::V128((*v).into()), + + (_, WasmType::I32 | WasmType::F32) => panic!("Expected Value32"), + (_, WasmType::I64 | WasmType::F64) => panic!("Expected Value64"), + (_, WasmType::RefExtern | WasmType::RefFunc) => panic!("Expected ValueRef"), + (_, WasmType::V128) => panic!("Expected Value128"), } } } diff --git a/crates/tinywasm/src/reference.rs b/crates/tinywasm/src/reference.rs index ad0ff84..3808293 100644 --- a/crates/tinywasm/src/reference.rs +++ b/crates/tinywasm/src/reference.rs @@ -6,7 +6,7 @@ use alloc::{ffi::CString, format}; use crate::store::{GlobalInstance, TableElement, TableInstance}; use crate::{Error, MemoryInstance, Result, Store}; use tinywasm_types::{ - Addr, ExternRef, FuncRef, GlobalAddr, GlobalType, MemAddr, MemoryArch, MemoryType, TableAddr, TableType, ValType, + Addr, ExternRef, FuncRef, GlobalAddr, GlobalType, MemAddr, MemoryArch, MemoryType, TableAddr, TableType, WasmType, WasmValue, }; @@ -162,18 +162,18 @@ impl Memory { } } -fn table_element_to_value(element_type: ValType, element: TableElement) -> WasmValue { +fn table_element_to_value(element_type: WasmType, element: TableElement) -> WasmValue { match element_type { - ValType::RefFunc => WasmValue::RefFunc(FuncRef::new(element.addr())), - ValType::RefExtern => WasmValue::RefExtern(ExternRef::new(element.addr())), + WasmType::RefFunc => WasmValue::RefFunc(FuncRef::new(element.addr())), + WasmType::RefExtern => WasmValue::RefExtern(ExternRef::new(element.addr())), _ => unreachable!("table element type must be a reference type"), } } -fn table_value_to_element(element_type: ValType, value: WasmValue) -> Result { +fn table_value_to_element(element_type: WasmType, value: WasmValue) -> Result { match (element_type, value) { - (ValType::RefFunc, WasmValue::RefFunc(func_ref)) => Ok(TableElement::from(func_ref.addr())), - (ValType::RefExtern, WasmValue::RefExtern(extern_ref)) => Ok(TableElement::from(extern_ref.addr())), + (WasmType::RefFunc, WasmValue::RefFunc(func_ref)) => Ok(TableElement::from(func_ref.addr())), + (WasmType::RefExtern, WasmValue::RefExtern(extern_ref)) => Ok(TableElement::from(extern_ref.addr())), _ => Err(Error::Other("invalid table value type".to_string())), } } @@ -187,8 +187,8 @@ impl Table { /// Create a new table in the given store. pub fn new(store: &mut Store, ty: TableType, init: WasmValue) -> Result { let init = match (ty.element_type, init) { - (ValType::RefFunc, WasmValue::RefFunc(func_ref)) => TableElement::from(func_ref.addr()), - (ValType::RefExtern, WasmValue::RefExtern(extern_ref)) => TableElement::from(extern_ref.addr()), + (WasmType::RefFunc, WasmValue::RefFunc(func_ref)) => TableElement::from(func_ref.addr()), + (WasmType::RefExtern, WasmValue::RefExtern(extern_ref)) => TableElement::from(extern_ref.addr()), _ => return Err(Error::Other("invalid table init value".to_string())), }; let addr = store.state.tables.len() as TableAddr; @@ -300,7 +300,7 @@ impl Global { if !global.ty.mutable { return Err(Error::Other("global is immutable".to_string())); } - if value.val_type() != global.ty.ty { + if WasmType::from(value) != global.ty.ty { return Err(Error::Other("invalid global value type".to_string())); } global.value.set(value.into()); diff --git a/crates/tinywasm/src/store/table.rs b/crates/tinywasm/src/store/table.rs index 86f9f0d..df98508 100644 --- a/crates/tinywasm/src/store/table.rs +++ b/crates/tinywasm/src/store/table.rs @@ -32,8 +32,8 @@ impl TableInstance { let val = self.get(addr)?.addr(); Ok(match self.kind.element_type { - ValType::RefFunc => WasmValue::RefFunc(FuncRef::new(val)), - ValType::RefExtern => WasmValue::RefExtern(ExternRef::new(val)), + WasmType::RefFunc => WasmValue::RefFunc(FuncRef::new(val)), + WasmType::RefExtern => WasmValue::RefExtern(ExternRef::new(val)), _ => Err(Error::UnsupportedFeature("non-ref table".into()))?, }) } @@ -127,7 +127,7 @@ impl TableInstance { } fn resolve_func_ref(&self, func_addrs: &[u32], addr: Addr) -> Addr { - if self.kind.element_type != ValType::RefFunc { + if self.kind.element_type != WasmType::RefFunc { return addr; } @@ -188,7 +188,7 @@ mod tests { // Helper to create a dummy TableType fn dummy_table_type() -> TableType { - TableType { element_type: ValType::RefFunc, size_initial: 10, size_max: Some(20) } + TableType { element_type: WasmType::RefFunc, size_initial: 10, size_max: Some(20) } } #[test] diff --git a/crates/tinywasm/tests/host_func_signature_check.rs b/crates/tinywasm/tests/host_func_signature_check.rs index 6667e7a..0b09a51 100644 --- a/crates/tinywasm/tests/host_func_signature_check.rs +++ b/crates/tinywasm/tests/host_func_signature_check.rs @@ -2,7 +2,7 @@ use eyre::Result; use std::fmt::Write; use tinywasm::{ FuncContext, HostFunction, Imports, Module, Store, - types::{FuncType, ValType, WasmValue}, + types::{FuncType, WasmType, WasmValue}, }; use tinywasm_types::ExternRef; @@ -15,15 +15,13 @@ const VAL_LISTS: &[&[WasmValue]] = &[ &[WasmValue::RefExtern(ExternRef::null()), WasmValue::F64(0.0), WasmValue::I32(0)], ]; -fn value_types(values: &[WasmValue]) -> Box<[ValType]> { - values.iter().map(WasmValue::val_type).collect() -} - fn module_cases() -> Vec<(Module, FuncType, Vec)> { let mut cases = Vec::<(Module, FuncType, Vec)>::new(); for results in VAL_LISTS { for params in VAL_LISTS { - let func_ty = FuncType { results: value_types(results), params: value_types(params) }; + let param_tys = params.iter().map(WasmType::from).collect::>(); + let result_tys = results.iter().map(WasmType::from).collect::>(); + let func_ty = FuncType::new(¶m_tys, &result_tys); cases.push((proxy_module(&func_ty), func_ty, params.to_vec())); } } @@ -44,7 +42,7 @@ fn test_return_invalid_type() -> Result<()> { let instance = module.clone().instantiate(&mut store, Some(imports)).unwrap(); let caller = instance.func_untyped(&store, "call_hfn").unwrap(); // Return-type mismatch is only observable at call time. - let should_succeed = returned_values.iter().map(WasmValue::val_type).eq(ty.results.iter().copied()); + let should_succeed = returned_values.iter().map(WasmType::from).eq(ty.results().iter().copied()); let call_res = caller.call(&mut store, &args); assert_eq!(call_res.is_ok(), should_succeed); } @@ -118,22 +116,22 @@ fn test_linking_invalid_typed_func() -> Result<()> { Ok(()) } -fn to_name(ty: &ValType) -> &str { +fn to_name(ty: &WasmType) -> &str { match ty { - ValType::I32 => "i32", - ValType::I64 => "i64", - ValType::F32 => "f32", - ValType::F64 => "f64", - ValType::V128 => "v128", - ValType::RefFunc => "funcref", - ValType::RefExtern => "externref", + WasmType::I32 => "i32", + WasmType::I64 => "i64", + WasmType::F32 => "f32", + WasmType::F64 => "f64", + WasmType::V128 => "v128", + WasmType::RefFunc => "funcref", + WasmType::RefExtern => "externref", } } fn proxy_module(func_ty: &FuncType) -> Module { - let results = func_ty.results.as_ref(); - let params = func_ty.params.as_ref(); - let join_surround = |list: &[ValType], keyword| { + let results = func_ty.results(); + let params = func_ty.params(); + let join_surround = |list: &[WasmType], keyword| { if list.is_empty() { return "".to_string(); } diff --git a/crates/tinywasm/tests/imported_table_init.rs b/crates/tinywasm/tests/imported_table_init.rs index 8b07000..b92401d 100644 --- a/crates/tinywasm/tests/imported_table_init.rs +++ b/crates/tinywasm/tests/imported_table_init.rs @@ -1,5 +1,5 @@ use eyre::Result; -use tinywasm::types::{FuncRef, TableType, ValType, WasmValue}; +use tinywasm::types::{FuncRef, TableType, WasmType, WasmValue}; use tinywasm::{Imports, Module, Store, Table}; #[test] @@ -20,7 +20,7 @@ fn imported_table_uses_provided_init_value() -> Result<()> { let mut store = Store::default(); let mut imports = Imports::new(); let table = - Table::new(&mut store, TableType::new(ValType::RefFunc, 3, None), WasmValue::RefFunc(FuncRef::new(Some(0))))?; + Table::new(&mut store, TableType::new(WasmType::RefFunc, 3, None), WasmValue::RefFunc(FuncRef::new(Some(0))))?; imports.define("host", "table", table); let instance = module.instantiate(&mut store, Some(imports))?; diff --git a/crates/tinywasm/tests/module_descriptors.rs b/crates/tinywasm/tests/module_descriptors.rs index 9993599..6c8c1ad 100644 --- a/crates/tinywasm/tests/module_descriptors.rs +++ b/crates/tinywasm/tests/module_descriptors.rs @@ -1,5 +1,5 @@ use eyre::Result; -use tinywasm::types::ValType; +use tinywasm::types::WasmType; use tinywasm::{ExportType, ImportType, Module}; #[test] @@ -31,8 +31,8 @@ fn module_descriptors_resolve_imported_and_local_export_types() -> Result<()> { let ifunc_import = imports.iter().find(|import| import.name == "ifunc").expect("ifunc import not found"); match ifunc_import.ty { ImportType::Func(ty) => { - assert_eq!(ty.params.as_ref(), &[ValType::I32]); - assert_eq!(ty.results.as_ref(), &[ValType::I32]); + assert_eq!(ty.params(), &[WasmType::I32]); + assert_eq!(ty.results(), &[WasmType::I32]); } _ => panic!("ifunc import should be a function type"), } @@ -41,7 +41,7 @@ fn module_descriptors_resolve_imported_and_local_export_types() -> Result<()> { match iglobal_import.ty { ImportType::Global(ty) => { assert!(ty.mutable); - assert_eq!(ty.ty, ValType::I32); + assert_eq!(ty.ty, WasmType::I32); } _ => panic!("iglobal import should be a global type"), } @@ -52,8 +52,8 @@ fn module_descriptors_resolve_imported_and_local_export_types() -> Result<()> { let ifunc_export = exports.iter().find(|export| export.name == "ifunc_export").expect("ifunc export not found"); match ifunc_export.ty { ExportType::Func(ty) => { - assert_eq!(ty.params.as_ref(), &[ValType::I32]); - assert_eq!(ty.results.as_ref(), &[ValType::I32]); + assert_eq!(ty.params(), &[WasmType::I32]); + assert_eq!(ty.results(), &[WasmType::I32]); } _ => panic!("ifunc export should resolve to imported function type"), } @@ -63,7 +63,7 @@ fn module_descriptors_resolve_imported_and_local_export_types() -> Result<()> { match iglobal_export.ty { ExportType::Global(ty) => { assert!(ty.mutable); - assert_eq!(ty.ty, ValType::I32); + assert_eq!(ty.ty, WasmType::I32); } _ => panic!("iglobal export should resolve to imported global type"), } @@ -71,8 +71,8 @@ fn module_descriptors_resolve_imported_and_local_export_types() -> Result<()> { let lfunc_export = exports.iter().find(|export| export.name == "lfunc_export").expect("lfunc export not found"); match lfunc_export.ty { ExportType::Func(ty) => { - assert_eq!(ty.params.as_ref(), &[ValType::I64]); - assert_eq!(ty.results.as_ref(), &[ValType::I64]); + assert_eq!(ty.params(), &[WasmType::I64]); + assert_eq!(ty.results(), &[WasmType::I64]); } _ => panic!("lfunc export should resolve to local function type"), } @@ -82,7 +82,7 @@ fn module_descriptors_resolve_imported_and_local_export_types() -> Result<()> { match lglobal_export.ty { ExportType::Global(ty) => { assert!(!ty.mutable); - assert_eq!(ty.ty, ValType::I64); + assert_eq!(ty.ty, WasmType::I64); } _ => panic!("lglobal export should resolve to local global type"), } diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index b45baa4..a39ffa7 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -6,7 +6,7 @@ use eyre::{Result, eyre}; use indexmap::IndexMap; use log::{debug, error, info}; use tinywasm::{Global, HostFunction, Imports, Memory, ModuleInstance, Table}; -use tinywasm_types::{ExternVal, MemoryType, ModuleInstanceAddr, TableType, ValType, WasmValue}; +use tinywasm_types::{ExternVal, MemoryType, ModuleInstanceAddr, TableType, WasmType, WasmValue}; use wasm_testsuite::data::TestFile; use wasm_testsuite::wast; use wasm_testsuite::wast::{Wast, lexer::Lexer, parser::ParseBuffer}; @@ -92,8 +92,8 @@ impl TestSuite { let table = Table::new( store, - TableType::new(ValType::RefFunc, 10, Some(20)), - WasmValue::default_for(ValType::RefFunc), + TableType::new(WasmType::RefFunc, 10, Some(20)), + WasmValue::default_for(WasmType::RefFunc), )?; let print = HostFunction::from(store, |_ctx: tinywasm::FuncContext, (): ()| { @@ -132,12 +132,14 @@ impl TestSuite { }); let memory = Memory::new(store, MemoryType::default().with_page_count_initial(1).with_page_count_max(Some(2)))?; - let global_i32 = Global::new(store, tinywasm_types::GlobalType::new(ValType::I32, false), WasmValue::I32(666))?; - let global_i64 = Global::new(store, tinywasm_types::GlobalType::new(ValType::I64, false), WasmValue::I64(666))?; + let global_i32 = + Global::new(store, tinywasm_types::GlobalType::new(WasmType::I32, false), WasmValue::I32(666))?; + let global_i64 = + Global::new(store, tinywasm_types::GlobalType::new(WasmType::I64, false), WasmValue::I64(666))?; let global_f32 = - Global::new(store, tinywasm_types::GlobalType::new(ValType::F32, false), WasmValue::F32(666.6))?; + Global::new(store, tinywasm_types::GlobalType::new(WasmType::F32, false), WasmValue::F32(666.6))?; let global_f64 = - Global::new(store, tinywasm_types::GlobalType::new(ValType::F64, false), WasmValue::F64(666.6))?; + Global::new(store, tinywasm_types::GlobalType::new(WasmType::F64, false), WasmValue::F64(666.6))?; imports .define("spectest", "memory", memory) @@ -468,7 +470,7 @@ impl TestSuite { let expected = expected_alternatives .iter() .filter_map(|alts| alts.first()) - .find(|exp| module_global.attach_type(exp.val_type()).eq_loose(exp)); + .find(|exp| module_global.attach_type(WasmType::from(*exp)).eq_loose(exp)); if expected.is_none() { test_group.add_result( diff --git a/crates/tinywasm/tests/testsuite/util.rs b/crates/tinywasm/tests/testsuite/util.rs index 4b3e001..e03f08b 100644 --- a/crates/tinywasm/tests/testsuite/util.rs +++ b/crates/tinywasm/tests/testsuite/util.rs @@ -1,7 +1,7 @@ use std::panic::{self, AssertUnwindSafe}; use eyre::{Result, bail, eyre}; -use tinywasm_types::{ExternRef, FuncRef, ModuleInstanceAddr, TinyWasmModule, ValType, WasmValue}; +use tinywasm_types::{ExternRef, FuncRef, ModuleInstanceAddr, TinyWasmModule, WasmType, WasmValue}; use wasm_testsuite::wast; use wasm_testsuite::wast::{QuoteWat, core::AbstractHeapType}; diff --git a/crates/types/src/instructions.rs b/crates/types/src/instructions.rs index 8c0680e..01398b5 100644 --- a/crates/types/src/instructions.rs +++ b/crates/types/src/instructions.rs @@ -1,4 +1,4 @@ -use super::{FuncAddr, GlobalAddr, LocalAddr, TableAddr, TypeAddr, ValType, ValueCounts}; +use super::{FuncAddr, GlobalAddr, LocalAddr, TableAddr, TypeAddr, ValueCounts, WasmType}; use crate::{ConstIdx, DataAddr, ElemAddr, ExternAddr, MemAddr}; /// Represents a memory immediate in a WebAssembly memory instruction. @@ -142,7 +142,7 @@ pub enum Instruction { F64Const(f64), // > Reference Types - RefNull(ValType), + RefNull(WasmType), RefFunc(FuncAddr), RefIsNull, diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index f74336c..ece6086 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -200,8 +200,27 @@ impl ExternVal { #[cfg_attr(feature = "debug", derive(Debug))] #[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct FuncType { - pub params: Box<[ValType]>, - pub results: Box<[ValType]>, + data: Box<[WasmType]>, + param_count: u16, +} + +impl FuncType { + /// Create a new function type. + pub fn new(params: &[WasmType], results: &[WasmType]) -> Self { + let param_count = params.len() as u16; + let data: Box<[WasmType]> = params.iter().cloned().chain(results.iter().cloned()).collect(); + Self { data, param_count } + } + + /// Get the parameter types of this function type. + pub fn params(&self) -> &[WasmType] { + &self.data[..self.param_count as usize] + } + + /// Get the result types of this function type. + pub fn results(&self) -> &[WasmType] { + &self.data[self.param_count as usize..] + } } #[derive(Default, Clone, Copy, PartialEq, Eq)] @@ -221,15 +240,15 @@ impl ValueCounts { } } -impl<'a> FromIterator<&'a ValType> for ValueCounts { +impl<'a> FromIterator<&'a WasmType> for ValueCounts { #[inline] - fn from_iter>(iter: I) -> Self { + fn from_iter>(iter: I) -> Self { iter.into_iter().fold(Self::default(), |mut counts, ty| { match ty { - ValType::I32 | ValType::F32 => counts.c32 += 1, - ValType::I64 | ValType::F64 => counts.c64 += 1, - ValType::V128 => counts.c128 += 1, - ValType::RefExtern | ValType::RefFunc => counts.cref += 1, + WasmType::I32 | WasmType::F32 => counts.c32 += 1, + WasmType::I64 | WasmType::F64 => counts.c64 += 1, + WasmType::V128 => counts.c128 += 1, + WasmType::RefExtern | WasmType::RefFunc => counts.cref += 1, } counts }) @@ -247,8 +266,8 @@ pub struct WasmFunction { pub ty: FuncType, } -#[derive(Clone, PartialEq)] #[doc(hidden)] +#[derive(Clone, PartialEq)] // wrapper around Arc<[T]> to support serde serialization and deserialization pub struct ArcSlice(pub Arc<[T]>); @@ -333,17 +352,17 @@ pub struct Global { #[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct GlobalType { pub mutable: bool, - pub ty: ValType, + pub ty: WasmType, } impl GlobalType { /// Create a new global type. - pub const fn new(ty: ValType, mutable: bool) -> Self { + pub const fn new(ty: WasmType, mutable: bool) -> Self { Self { mutable, ty } } /// Set a different value type. - pub const fn with_ty(mut self, ty: ValType) -> Self { + pub const fn with_ty(mut self, ty: WasmType) -> Self { self.ty = ty; self } @@ -357,7 +376,7 @@ impl GlobalType { impl Default for GlobalType { fn default() -> Self { - Self::new(ValType::I32, false) + Self::new(WasmType::I32, false) } } @@ -365,17 +384,17 @@ impl Default for GlobalType { #[cfg_attr(feature = "debug", derive(Debug))] #[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct TableType { - pub element_type: ValType, + pub element_type: WasmType, pub size_initial: u32, pub size_max: Option, } impl TableType { pub fn empty() -> Self { - Self { element_type: ValType::RefFunc, size_initial: 0, size_max: None } + Self { element_type: WasmType::RefFunc, size_initial: 0, size_max: None } } - pub fn new(element_type: ValType, size_initial: u32, size_max: Option) -> Self { + pub fn new(element_type: WasmType, size_initial: u32, size_max: Option) -> Self { Self { element_type, size_initial, size_max } } } @@ -525,7 +544,7 @@ pub struct Element { pub kind: ElementKind, pub items: Box<[ElementItem]>, pub range: Range, - pub ty: ValType, + pub ty: WasmType, } #[derive(Clone, PartialEq)] diff --git a/crates/types/src/value.rs b/crates/types/src/value.rs index f468be5..462749b 100644 --- a/crates/types/src/value.rs +++ b/crates/types/src/value.rs @@ -18,7 +18,6 @@ pub enum WasmValue { F64(f64), // /// A 128-bit vector V128(i128), - RefExtern(ExternRef), RefFunc(FuncRef), } @@ -70,55 +69,52 @@ impl Debug for FuncRef { } impl FuncRef { - /// Create a new `FuncRef` from a `FuncAddr`. - /// Should only be used by the runtime. - #[doc(hidden)] #[inline] + /// Create a new [`FuncRef`] from a [`FuncAddr`]. pub const fn new(addr: Option) -> Self { Self(addr) } - /// Create a null `FuncRef`. #[inline] + /// Create a null [`FuncRef`]. pub const fn null() -> Self { Self(None) } - /// Check if the `FuncRef` is null. #[inline] + /// Check if the [`FuncRef`] is null. pub const fn is_null(&self) -> bool { self.0.is_none() } - /// Get the `FuncAddr` from the `FuncRef`. #[inline] + /// Get the [`FuncAddr`] from the [`FuncRef`]. pub const fn addr(&self) -> Option { self.0 } } impl ExternRef { - /// Create a new `ExternRef` from an `ExternAddr`. - /// Should only be used by the runtime. - #[doc(hidden)] #[inline] + /// Create a new [`ExternRef`] from an [`ExternAddr`]. + /// Should only be used by the runtime. pub const fn new(addr: Option) -> Self { Self(addr) } - /// Create a null `ExternRef`. + /// Create a null [`ExternRef`]. #[inline] pub const fn null() -> Self { Self(None) } - /// Check if the `ExternRef` is null. + /// Check if the [`ExternRef`] is null. #[inline] pub const fn is_null(&self) -> bool { self.0.is_none() } - /// Get the `ExternAddr` from the `ExternRef`. + /// Get the [`ExternAddr`] from the [`ExternRef`]. #[inline] pub const fn addr(&self) -> Option { self.0 @@ -126,8 +122,8 @@ impl ExternRef { } impl WasmValue { - #[doc(hidden)] #[inline] + /// Get the matching [`ConstInstruction`] for this value. pub fn const_instr(&self) -> alloc::boxed::Box<[ConstInstruction]> { alloc::boxed::Box::new([match self { Self::I32(i) => ConstInstruction::I32Const(*i), @@ -140,22 +136,22 @@ impl WasmValue { }]) } - /// Get the default value for a given type. #[inline] - pub const fn default_for(ty: ValType) -> Self { + /// Get the default value for a given type. + pub const fn default_for(ty: WasmType) -> Self { match ty { - ValType::I32 => Self::I32(0), - ValType::I64 => Self::I64(0), - ValType::F32 => Self::F32(0.0), - ValType::F64 => Self::F64(0.0), - ValType::V128 => Self::V128(0), - ValType::RefFunc => Self::RefFunc(FuncRef::null()), - ValType::RefExtern => Self::RefExtern(ExternRef::null()), + WasmType::I32 => Self::I32(0), + WasmType::I64 => Self::I64(0), + WasmType::F32 => Self::F32(0.0), + WasmType::F64 => Self::F64(0.0), + WasmType::V128 => Self::V128(0), + WasmType::RefFunc => Self::RefFunc(FuncRef::null()), + WasmType::RefExtern => Self::RefExtern(ExternRef::null()), } } - /// Check if two values are equal, ignoring differences in NaN values. #[inline] + /// Check if two values are equal, ignoring differences in NaN values. pub fn eq_loose(&self, other: &Self) -> bool { match (self, other) { (Self::I32(a), Self::I32(b)) => a == b, @@ -233,7 +229,7 @@ impl WasmValue { }) && a_f64x2.iter().any(|x| x.is_nan()) } - #[doc(hidden)] + /// Return the `i32` from a `WasmValue`, if it is an `I32`. pub const fn as_i32(&self) -> Option { match self { Self::I32(i) => Some(*i), @@ -241,7 +237,7 @@ impl WasmValue { } } - #[doc(hidden)] + /// Return the `i64` from a `WasmValue`, if it is an `I64`. pub const fn as_i64(&self) -> Option { match self { Self::I64(i) => Some(*i), @@ -249,7 +245,7 @@ impl WasmValue { } } - #[doc(hidden)] + /// Return the `f32` from a `WasmValue`, if it is a `F32`. pub const fn as_f32(&self) -> Option { match self { Self::F32(i) => Some(*i), @@ -257,7 +253,7 @@ impl WasmValue { } } - #[doc(hidden)] + /// Return the `f64` from a `WasmValue`, if it is a `F64`. pub const fn as_f64(&self) -> Option { match self { Self::F64(i) => Some(*i), @@ -265,7 +261,7 @@ impl WasmValue { } } - #[doc(hidden)] + /// Return the `i128` from a `WasmValue`, if it is a `V128`. pub const fn as_v128(&self) -> Option { match self { Self::V128(i) => Some(*i), @@ -273,7 +269,7 @@ impl WasmValue { } } - #[doc(hidden)] + /// Return the [[`ExternRef`]] from a `WasmValue`, if it is one pub const fn as_ref_extern(&self) -> Option { match self { Self::RefExtern(ref_extern) => Some(*ref_extern), @@ -281,7 +277,7 @@ impl WasmValue { } } - #[doc(hidden)] + /// Return the [`FuncRef`] from a `WasmValue`, if it is one pub const fn as_ref_func(&self) -> Option { match self { Self::RefFunc(ref_func) => Some(*ref_func), @@ -290,27 +286,33 @@ impl WasmValue { } } -impl WasmValue { - /// Get the type of a [`WasmValue`] +impl From<&WasmValue> for WasmType { #[inline] - pub const fn val_type(&self) -> ValType { - match self { - Self::I32(_) => ValType::I32, - Self::I64(_) => ValType::I64, - Self::F32(_) => ValType::F32, - Self::F64(_) => ValType::F64, - Self::V128(_) => ValType::V128, - Self::RefExtern(_) => ValType::RefExtern, - Self::RefFunc(_) => ValType::RefFunc, + fn from(value: &WasmValue) -> Self { + match value { + WasmValue::I32(_) => WasmType::I32, + WasmValue::I64(_) => WasmType::I64, + WasmValue::F32(_) => WasmType::F32, + WasmValue::F64(_) => WasmType::F64, + WasmValue::V128(_) => WasmType::V128, + WasmValue::RefExtern(_) => WasmType::RefExtern, + WasmValue::RefFunc(_) => WasmType::RefFunc, } } } +impl From for WasmType { + #[inline] + fn from(value: WasmValue) -> Self { + Self::from(&value) + } +} + /// Type of a WebAssembly value. #[derive(Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "debug", derive(Debug))] #[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] -pub enum ValType { +pub enum WasmType { /// A 32-bit integer. I32, /// A 64-bit integer. @@ -327,13 +329,12 @@ pub enum ValType { RefExtern, } -impl ValType { +impl WasmType { #[inline] pub const fn default_value(&self) -> WasmValue { WasmValue::default_for(*self) } - #[doc(hidden)] #[inline] pub const fn is_simd(&self) -> bool { matches!(self, Self::V128) @@ -343,7 +344,6 @@ impl ValType { macro_rules! impl_conversion_for_wasmvalue { ($($t:ty => $variant:ident),*) => { $( - // Implementing From<$t> for WasmValue impl From<$t> for WasmValue { #[inline] fn from(i: $t) -> Self { @@ -351,17 +351,12 @@ macro_rules! impl_conversion_for_wasmvalue { } } - // Implementing TryFrom for $t impl TryFrom for $t { type Error = (); #[inline] fn try_from(value: WasmValue) -> Result { - if let WasmValue::$variant(i) = value { - Ok(i) - } else { - Err(()) - } + if let WasmValue::$variant(i) = value { Ok(i) } else { Err(()) } } } )* diff --git a/examples/rust/README.md b/examples/rust/README.md index c24054c..6742ca4 100644 --- a/examples/rust/README.md +++ b/examples/rust/README.md @@ -1,6 +1,6 @@ # WebAssembly Rust Examples -This is a seperate crate that generates WebAssembly from Rust code. +This is a separate crate that generates WebAssembly from Rust code. It is used by the `wasm-rust` example. Requires the `wasm32-unknown-unknown` target to be installed. -- cgit v1.3.1