summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/parser/README.md5
-rw-r--r--crates/parser/src/conversion.rs36
-rw-r--r--crates/parser/src/module.rs2
-rw-r--r--crates/tinywasm/src/func.rs57
-rw-r--r--crates/tinywasm/src/imports.rs6
-rw-r--r--crates/tinywasm/src/instance.rs16
-rw-r--r--crates/tinywasm/src/interpreter/executor.rs6
-rw-r--r--crates/tinywasm/src/interpreter/stack/value_stack.rs20
-rw-r--r--crates/tinywasm/src/interpreter/values.rs26
-rw-r--r--crates/tinywasm/src/reference.rs20
-rw-r--r--crates/tinywasm/src/store/table.rs8
-rw-r--r--crates/tinywasm/tests/host_func_signature_check.rs34
-rw-r--r--crates/tinywasm/tests/imported_table_init.rs4
-rw-r--r--crates/tinywasm/tests/module_descriptors.rs20
-rw-r--r--crates/tinywasm/tests/testsuite/run.rs18
-rw-r--r--crates/tinywasm/tests/testsuite/util.rs2
-rw-r--r--crates/types/src/instructions.rs4
-rw-r--r--crates/types/src/lib.rs53
-rw-r--r--crates/types/src/value.rs99
-rw-r--r--examples/rust/README.md2
20 files changed, 228 insertions, 210 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::<Result<Vec<_>>>()?
.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<FuncType>
}
let ty = types.next().unwrap().unwrap_func();
- let params = ty.params().iter().map(convert_valtype).collect::<Vec<ValType>>().into_boxed_slice();
- let results = ty.results().iter().map(convert_valtype).collect::<Vec<ValType>>().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(&params, &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<Box<[C
for op in ops.iter().take(ops.len() - 1) {
let instr = match op {
wasmparser::Operator::RefNull { hty } => 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<Box<[C
Ok(out.into_boxed_slice())
}
-pub(crate) fn convert_heaptype(heap: wasmparser::HeapType) -> 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<P, R>(store: &mut Store, func: impl Fn(FuncContext<'_>, P) -> Result<R> + 'static) -> Function
where
- P: FromWasmValueTuple + ValTypesFromTuple,
- R: IntoWasmValueTuple + ValTypesFromTuple,
+ P: FromWasmValueTuple + WasmTypesFromTuple,
+ R: IntoWasmValueTuple + WasmTypesFromTuple,
{
let inner_func = move |ctx: FuncContext<'_>, args: &[WasmValue]| -> Result<Vec<WasmValue>> {
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 == &param.val_type())) {
+ if !(func_ty.params().iter().zip(params).all(|(ty, param)| ty == &param.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<Vec<WasmValue>> {
- 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<P: IntoWasmValueTuple + ValTypesFromTuple, R: FromWasmValueTuple + ValTypesFromTuple>(
+ pub fn func<P: IntoWasmValueTuple + WasmTypesFromTuple, R: FromWasmValueTuple + WasmTypesFromTuple>(
&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<P: IntoWasmValueTuple + ValTypesFromTuple, R: FromWasmValueTuple + ValTypesFromTuple>(
+ 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<P: ValTypesFromTuple, R: ValTypesFromTuple>(func: &Function, func_name: &str) -> Result<()> {
- let expected = FuncType { params: P::val_types(), results: R::val_types() };
+ fn validate_typed_func<P: WasmTypesFromTuple, R: WasmTypesFromTuple>(
+ 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<HostFunction>) -> Result<()> {
- let params = self.store.stack.values.pop_types(&host_func.ty.params).collect::<Box<_>>();
+ let params = self.store.stack.values.pop_types(host_func.ty.params()).collect::<Box<_>>();
let res = host_func.call(FuncContext { store: self.store, module_addr: self.module.idx }, &params)?;
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::<i32>() 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<Item = &'a ValType>,
+ val_types: impl IntoIterator<Item = &'a WasmType>,
) -> impl core::iter::Iterator<Item = WasmValue> {
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::<Value128>().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::<Value128>().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()),
+ (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()),
- (_, 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"),
+ (_, 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<TableElement> {
+fn table_value_to_element(element_type: WasmType, value: WasmValue) -> Result<TableElement> {
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<Self> {
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<WasmValue>)> {
let mut cases = Vec::<(Module, FuncType, Vec<WasmValue>)>::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::<Vec<_>>();
+ let result_tys = results.iter().map(WasmType::from).collect::<Vec<_>>();
+ let func_ty = FuncType::new(&param_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<I: IntoIterator<Item = &'a ValType>>(iter: I) -> Self {
+ fn from_iter<I: IntoIterator<Item = &'a WasmType>>(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<T>(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<u32>,
}
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<u32>) -> Self {
+ pub fn new(element_type: WasmType, size_initial: u32, size_max: Option<u32>) -> 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<usize>,
- 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<FuncAddr>) -> 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<FuncAddr> {
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<ExternAddr>) -> 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<ExternAddr> {
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<i32> {
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<i64> {
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<f32> {
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<f64> {
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<i128> {
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<ExternRef> {
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<FuncRef> {
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<WasmValue> 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<WasmValue> for $t
impl TryFrom<WasmValue> for $t {
type Error = ();
#[inline]
fn try_from(value: WasmValue) -> Result<Self, Self::Error> {
- 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.