summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorHenry Gressmann <mail@henrygressmann.de>2024-03-09 13:51:32 +0100
committerHenry Gressmann <mail@henrygressmann.de>2024-03-09 13:51:32 +0100
commit735c7cb636edfd4704460c94a9c7d65e5bf4df48 (patch)
tree5b60de853a4bb62649d2d1ce4732bdfa49ce29fb /crates
parentc50bae752f3e788faf66b376d065374cc4085931 (diff)
chore: improve documentation, tests
Closes #6 Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
Diffstat (limited to 'crates')
-rw-r--r--crates/cli/Cargo.toml2
-rw-r--r--crates/parser/src/conversion.rs8
-rw-r--r--crates/parser/src/lib.rs18
-rw-r--r--crates/parser/src/std.rs5
-rw-r--r--crates/parser/src/visit.rs8
-rw-r--r--crates/tinywasm/Cargo.toml2
-rw-r--r--crates/tinywasm/src/runtime/interpreter/mod.rs35
-rw-r--r--crates/tinywasm/src/runtime/stack/block_stack.rs6
-rw-r--r--crates/tinywasm/src/runtime/stack/value_stack.rs10
-rw-r--r--crates/tinywasm/src/runtime/value.rs1
-rw-r--r--crates/tinywasm/src/store/global.rs29
-rw-r--r--crates/tinywasm/src/store/memory.rs7
-rw-r--r--crates/tinywasm/src/store/mod.rs8
-rw-r--r--crates/tinywasm/src/store/table.rs83
-rw-r--r--crates/tinywasm/tests/generated/2.0.csv1
-rw-r--r--crates/tinywasm/tests/generated/mvp.csv1
-rw-r--r--crates/types/src/lib.rs48
-rw-r--r--crates/types/src/value.rs2
18 files changed, 195 insertions, 79 deletions
diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml
index f6105c8..61f419a 100644
--- a/crates/cli/Cargo.toml
+++ b/crates/cli/Cargo.toml
@@ -19,7 +19,7 @@ argh="0.1"
color-eyre={version="0.6", default-features=false}
log="0.4"
pretty_env_logger="0.5"
-wast={version="200.0", optional=true}
+wast={version="201.0", optional=true}
[features]
default=["wat"]
diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs
index c13d08f..ccdc308 100644
--- a/crates/parser/src/conversion.rs
+++ b/crates/parser/src/conversion.rs
@@ -187,6 +187,7 @@ pub(crate) fn convert_module_type(ty: wasmparser::RecGroup) -> Result<FuncType>
));
}
let ty = types.next().unwrap().unwrap_func();
+
let params =
ty.params().iter().map(|p| Ok(convert_valtype(p))).collect::<Result<Vec<ValType>>>()?.into_boxed_slice();
@@ -197,11 +198,10 @@ pub(crate) fn convert_module_type(ty: wasmparser::RecGroup) -> Result<FuncType>
}
pub(crate) fn convert_blocktype(blocktype: wasmparser::BlockType) -> BlockArgs {
- use wasmparser::BlockType::*;
match blocktype {
- Empty => BlockArgs::Empty,
- Type(ty) => BlockArgs::Type(convert_valtype(&ty)),
- FuncType(ty) => BlockArgs::FuncType(ty),
+ wasmparser::BlockType::Empty => BlockArgs::Empty,
+ wasmparser::BlockType::Type(ty) => BlockArgs::Type(convert_valtype(&ty)),
+ wasmparser::BlockType::FuncType(ty) => BlockArgs::FuncType(ty),
}
}
diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs
index 7beb5f8..5fb3c48 100644
--- a/crates/parser/src/lib.rs
+++ b/crates/parser/src/lib.rs
@@ -8,9 +8,11 @@
#![cfg_attr(not(feature = "std"), feature(error_in_core))]
//! See [`tinywasm`](https://docs.rs/tinywasm) for documentation.
-mod std;
extern crate alloc;
+#[cfg(feature = "std")]
+extern crate std;
+
// log for logging (optional).
#[cfg(feature = "logging")]
#[allow(clippy::single_component_path_imports)]
@@ -32,7 +34,7 @@ mod visit;
use alloc::{string::ToString, vec::Vec};
pub use error::*;
use module::ModuleReader;
-use tinywasm_types::{TypedWasmFunction, WasmFunction};
+use tinywasm_types::WasmFunction;
use wasmparser::{Validator, WasmFeatures};
pub use tinywasm_types::TinyWasmModule;
@@ -156,13 +158,10 @@ impl TryFrom<ModuleReader> for TinyWasmModule {
.code
.into_iter()
.zip(code_type_addrs)
- .map(|((instructions, locals), ty_idx)| TypedWasmFunction {
- type_addr: ty_idx,
- wasm_function: WasmFunction {
- instructions,
- locals,
- ty: reader.func_types.get(ty_idx as usize).expect("No func type for func, this is a bug").clone(),
- },
+ .map(|((instructions, locals), ty_idx)| WasmFunction {
+ instructions,
+ locals,
+ ty: reader.func_types.get(ty_idx as usize).expect("No func type for func, this is a bug").clone(),
})
.collect::<Vec<_>>();
@@ -175,7 +174,6 @@ impl TryFrom<ModuleReader> for TinyWasmModule {
globals: globals.into_boxed_slice(),
table_types: table_types.into_boxed_slice(),
imports: reader.imports.into_boxed_slice(),
- version: reader.version,
start_func: reader.start_func,
data: reader.data.into_boxed_slice(),
exports: reader.exports.into_boxed_slice(),
diff --git a/crates/parser/src/std.rs b/crates/parser/src/std.rs
deleted file mode 100644
index 16a7058..0000000
--- a/crates/parser/src/std.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-#[cfg(feature = "std")]
-extern crate std;
-
-#[cfg(feature = "std")]
-pub(crate) use std::*;
diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs
index cc9f0e2..b438fc1 100644
--- a/crates/parser/src/visit.rs
+++ b/crates/parser/src/visit.rs
@@ -10,7 +10,6 @@ struct ValidateThenVisit<'a, T, U>(T, &'a mut U);
macro_rules! validate_then_visit {
($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident)*) => {
$(
- #[inline]
fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output {
self.0.$visit($($($arg.clone()),*)?)?;
Ok(self.1.$visit($($($arg),*)?))
@@ -103,7 +102,7 @@ pub(crate) struct FunctionBuilder {
impl FunctionBuilder {
pub(crate) fn new(instr_capacity: usize) -> Self {
- Self { instructions: Vec::with_capacity(instr_capacity), label_ptrs: Vec::with_capacity(128) }
+ Self { instructions: Vec::with_capacity(instr_capacity), label_ptrs: Vec::with_capacity(256) }
}
#[cold]
@@ -391,7 +390,6 @@ impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder {
self.visit(Instruction::Else(0))
}
- #[inline]
fn visit_end(&mut self) -> Self::Output {
let Some(label_pointer) = self.label_ptrs.pop() else {
return self.visit(Instruction::EndFunc);
@@ -422,11 +420,11 @@ impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder {
*else_offset = (label_pointer - if_label_pointer)
.try_into()
- .expect("else_instr_end_offset is too large, tinywasm does not support blocks that large");
+ .expect("else_instr_end_offset is too large, tinywasm does not support blocks that large");
*end_offset = (current_instr_ptr - if_label_pointer)
.try_into()
- .expect("else_instr_end_offset is too large, tinywasm does not support blocks that large");
+ .expect("else_instr_end_offset is too large, tinywasm does not support blocks that large");
}
Instruction::Block(_, ref mut end_offset)
| Instruction::Loop(_, ref mut end_offset)
diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml
index 406a82d..dc0f525 100644
--- a/crates/tinywasm/Cargo.toml
+++ b/crates/tinywasm/Cargo.toml
@@ -20,7 +20,7 @@ libm={version="0.2", default-features=false}
[dev-dependencies]
wasm-testsuite={path="../wasm-testsuite"}
-wast={version="200.0"}
+wast={version="201.0"}
owo-colors={version="4.0"}
eyre={version="0.6"}
serde_json={version="1.0"}
diff --git a/crates/tinywasm/src/runtime/interpreter/mod.rs b/crates/tinywasm/src/runtime/interpreter/mod.rs
index 007acaa..b014a85 100644
--- a/crates/tinywasm/src/runtime/interpreter/mod.rs
+++ b/crates/tinywasm/src/runtime/interpreter/mod.rs
@@ -94,7 +94,7 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
Unreachable => {
cold();
return Err(crate::Trap::Unreachable.into());
- } // we don't need to include the call frame here because it's already on the stack
+ }
Drop => stack.values.pop().map(|_| ())?,
Select(
@@ -295,8 +295,7 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
},
EndFunc => {
- if stack.blocks.len() != cf.block_ptr {
- cold();
+ if unlikely(stack.blocks.len() != cf.block_ptr) {
panic!("endfunc: block frames not empty, this should have been validated by the parser");
}
@@ -308,35 +307,29 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
// We're essentially using else as a EndBlockFrame instruction for if blocks
Else(end_offset) => {
- let Some(block) = stack.blocks.pop() else {
- cold();
- panic!("else: no label to end, this should have been validated by the parser");
- };
+ let block =
+ stack.blocks.pop().expect("else: no label to end, this should have been validated by the parser");
- let res_count = block.results;
- stack.values.truncate_keep(block.stack_ptr, res_count);
+ stack.values.truncate_keep(block.stack_ptr, block.results);
cf.instr_ptr += *end_offset as usize;
}
+ // remove the label from the label stack
EndBlockFrame => {
- // remove the label from the label stack
- let Some(block) = stack.blocks.pop() else {
- cold();
- panic!("end blockframe: no label to end, this should have been validated by the parser");
- };
+ let block = stack
+ .blocks
+ .pop()
+ .expect("end blockframe: no label to end, this should have been validated by the parser");
stack.values.truncate_keep(block.stack_ptr, block.results);
}
LocalGet(local_index) => stack.values.push(cf.get_local(*local_index as usize)),
LocalSet(local_index) => cf.set_local(*local_index as usize, stack.values.pop()?),
- LocalTee(local_index) => {
- let local = stack.values.last();
- cf.set_local(
- *local_index as usize,
- *local.expect("localtee: stack is empty. this should have been validated by the parser"),
- );
- }
+ LocalTee(local_index) => cf.set_local(
+ *local_index as usize,
+ *stack.values.last().expect("localtee: stack is empty. this should have been validated by the parser"),
+ ),
GlobalGet(global_index) => {
let idx = module.resolve_global_addr(*global_index);
diff --git a/crates/tinywasm/src/runtime/stack/block_stack.rs b/crates/tinywasm/src/runtime/stack/block_stack.rs
index cf7a0d4..4fe7690 100644
--- a/crates/tinywasm/src/runtime/stack/block_stack.rs
+++ b/crates/tinywasm/src/runtime/stack/block_stack.rs
@@ -1,4 +1,4 @@
-use crate::{unlikely, ModuleInstance};
+use crate::{unlikely, Error, ModuleInstance, Result};
use alloc::vec::Vec;
use tinywasm_types::BlockArgs;
@@ -30,8 +30,8 @@ impl BlockStack {
}
#[inline]
- pub(crate) fn pop(&mut self) -> Option<BlockFrame> {
- self.0.pop()
+ pub(crate) fn pop(&mut self) -> Result<BlockFrame> {
+ self.0.pop().ok_or(Error::BlockStackUnderflow)
}
/// keep the top `len` blocks and discard the rest
diff --git a/crates/tinywasm/src/runtime/stack/value_stack.rs b/crates/tinywasm/src/runtime/stack/value_stack.rs
index 5903228..fed043f 100644
--- a/crates/tinywasm/src/runtime/stack/value_stack.rs
+++ b/crates/tinywasm/src/runtime/stack/value_stack.rs
@@ -69,8 +69,14 @@ impl ValueStack {
}
#[inline]
- pub(crate) fn last(&self) -> Option<&RawWasmValue> {
- self.stack.last()
+ pub(crate) fn last(&self) -> Result<&RawWasmValue> {
+ match self.stack.last() {
+ Some(v) => Ok(v),
+ None => {
+ cold();
+ Err(Error::ValueStackUnderflow)
+ }
+ }
}
#[inline]
diff --git a/crates/tinywasm/src/runtime/value.rs b/crates/tinywasm/src/runtime/value.rs
index 4835eab..2381657 100644
--- a/crates/tinywasm/src/runtime/value.rs
+++ b/crates/tinywasm/src/runtime/value.rs
@@ -92,7 +92,6 @@ type RawValue = u64;
type RawValueRep = [u8; 8];
// This all looks like a lot of extra steps, but the compiler will optimize it all away.
-// The `u128` is used to make the conversion easier to write.
impl_from_raw_wasm_value!(i32, |x| x as RawValue, |x: RawValueRep| i32::from_ne_bytes(x[0..4].try_into().unwrap()));
impl_from_raw_wasm_value!(i64, |x| x as RawValue, |x: RawValueRep| i64::from_ne_bytes(x[0..8].try_into().unwrap()));
impl_from_raw_wasm_value!(f32, |x| f32::to_bits(x) as RawValue, |x: RawValueRep| f32::from_bits(u32::from_ne_bytes(
diff --git a/crates/tinywasm/src/store/global.rs b/crates/tinywasm/src/store/global.rs
index 1bcbad7..cbba1a2 100644
--- a/crates/tinywasm/src/store/global.rs
+++ b/crates/tinywasm/src/store/global.rs
@@ -40,3 +40,32 @@ impl GlobalInstance {
Ok(())
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_global_instance_get_set() {
+ let global_type = GlobalType { ty: ValType::I32, mutable: true };
+ let initial_value = RawWasmValue::from(10i32);
+ let owner = 0;
+
+ let mut global_instance = GlobalInstance::new(global_type, initial_value, owner);
+
+ // Test `get`
+ assert_eq!(global_instance.get(), WasmValue::I32(10), "global value should be 10");
+
+ // Test `set` with correct type
+ assert!(global_instance.set(WasmValue::I32(20)).is_ok(), "set should succeed");
+ assert_eq!(global_instance.get(), WasmValue::I32(20), "global value should be 20");
+
+ // Test `set` with incorrect type
+ assert!(matches!(global_instance.set(WasmValue::F32(1.0)), Err(Error::Other(_))), "set should fail");
+
+ // Test `set` on immutable global
+ let immutable_global_type = GlobalType { ty: ValType::I32, mutable: false };
+ let mut immutable_global_instance = GlobalInstance::new(immutable_global_type, initial_value, owner);
+ assert!(matches!(immutable_global_instance.set(WasmValue::I32(30)), Err(Error::Other(_))));
+ }
+}
diff --git a/crates/tinywasm/src/store/memory.rs b/crates/tinywasm/src/store/memory.rs
index ea820da..9866b6b 100644
--- a/crates/tinywasm/src/store/memory.rs
+++ b/crates/tinywasm/src/store/memory.rs
@@ -275,4 +275,11 @@ mod memory_instance_tests {
let mut memory = create_test_memory();
assert!(memory.grow(MAX_PAGES as i32 + 1).is_none());
}
+
+ #[test]
+ fn test_memory_grow_max_pages() {
+ let mut memory = create_test_memory();
+ assert_eq!(memory.grow(1), Some(1));
+ assert_eq!(memory.grow(1), None);
+ }
}
diff --git a/crates/tinywasm/src/store/mod.rs b/crates/tinywasm/src/store/mod.rs
index f4e0df9..1cdcff3 100644
--- a/crates/tinywasm/src/store/mod.rs
+++ b/crates/tinywasm/src/store/mod.rs
@@ -180,15 +180,11 @@ impl Store {
// Linking related functions
impl Store {
/// Add functions to the store, returning their addresses in the store
- pub(crate) fn init_funcs(
- &mut self,
- funcs: Vec<TypedWasmFunction>,
- idx: ModuleInstanceAddr,
- ) -> Result<Vec<FuncAddr>> {
+ pub(crate) fn init_funcs(&mut self, funcs: Vec<WasmFunction>, idx: ModuleInstanceAddr) -> Result<Vec<FuncAddr>> {
let func_count = self.data.funcs.len();
let mut func_addrs = Vec::with_capacity(func_count);
for (i, func) in funcs.into_iter().enumerate() {
- self.data.funcs.push(FunctionInstance::new_wasm(func.wasm_function, idx));
+ self.data.funcs.push(FunctionInstance::new_wasm(func, idx));
func_addrs.push((i + func_count) as FuncAddr);
}
Ok(func_addrs)
diff --git a/crates/tinywasm/src/store/table.rs b/crates/tinywasm/src/store/table.rs
index d9dd9ad..52c35f6 100644
--- a/crates/tinywasm/src/store/table.rs
+++ b/crates/tinywasm/src/store/table.rs
@@ -116,3 +116,86 @@ impl TableElement {
}
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ // Helper to create a dummy TableType
+ fn dummy_table_type() -> TableType {
+ TableType { element_type: ValType::RefFunc, size_initial: 10, size_max: Some(20) }
+ }
+
+ #[test]
+ fn test_table_instance_creation() {
+ let kind = dummy_table_type();
+ let table_instance = TableInstance::new(kind.clone(), 0);
+ assert_eq!(table_instance.size(), kind.size_initial as i32, "Table instance creation failed: size mismatch");
+ }
+
+ #[test]
+ fn test_get_wasm_val() {
+ let kind = dummy_table_type();
+ let mut table_instance = TableInstance::new(kind, 0);
+
+ table_instance.set(0, 0).expect("Setting table element failed");
+
+ match table_instance.get_wasm_val(0) {
+ Ok(WasmValue::RefFunc(_)) => {}
+ _ => assert!(false, "get_wasm_val failed to return the correct WasmValue"),
+ }
+
+ match table_instance.get_wasm_val(999) {
+ Err(Error::Trap(Trap::UndefinedElement { .. })) => {}
+ _ => assert!(false, "get_wasm_val failed to handle undefined element correctly"),
+ }
+ }
+
+ #[test]
+ fn test_set_and_get() {
+ let kind = dummy_table_type();
+ let mut table_instance = TableInstance::new(kind, 0);
+
+ let result = table_instance.set(0, 1);
+ assert!(result.is_ok(), "Setting table element failed");
+
+ let elem = table_instance.get(0);
+ assert!(
+ elem.is_ok() && matches!(elem.unwrap(), &TableElement::Initialized(1)),
+ "Getting table element failed or returned incorrect value"
+ );
+ }
+
+ #[test]
+ fn test_table_grow_and_fit() {
+ let kind = dummy_table_type();
+ let mut table_instance = TableInstance::new(kind, 0);
+
+ let result = table_instance.set(15, 1);
+ assert!(result.is_ok(), "Table grow on set failed");
+
+ let size = table_instance.size();
+ assert!(size >= 16, "Table did not grow to expected size");
+ }
+
+ #[test]
+ fn test_table_init() {
+ let kind = dummy_table_type();
+ let mut table_instance = TableInstance::new(kind, 0);
+
+ let init_elements = vec![TableElement::Initialized(0); 5];
+ let func_addrs = vec![0, 1, 2, 3, 4];
+ let result = table_instance.init(&func_addrs, 0, &init_elements);
+
+ assert!(result.is_ok(), "Initializing table with elements failed");
+
+ for i in 0..5 {
+ let elem = table_instance.get(i);
+ assert!(
+ elem.is_ok() && matches!(elem.unwrap(), &TableElement::Initialized(_)),
+ "Element not initialized correctly at index {}",
+ i
+ );
+ }
+ }
+}
diff --git a/crates/tinywasm/tests/generated/2.0.csv b/crates/tinywasm/tests/generated/2.0.csv
index 40ef2ae..c97b58e 100644
--- a/crates/tinywasm/tests/generated/2.0.csv
+++ b/crates/tinywasm/tests/generated/2.0.csv
@@ -1,3 +1,4 @@
0.3.0,26722,1161,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":223,"failed":0},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":118,"failed":0},{"name":"br_table.wast","passed":174,"failed":0},{"name":"bulk.wast","passed":8,"failed":109},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":170,"failed":0},{"name":"comments.wast","passed":8,"failed":0},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":619,"failed":0},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"elem.wast","passed":98,"failed":1},{"name":"endianness.wast","passed":69,"failed":0},{"name":"exports.wast","passed":96,"failed":0},{"name":"f32.wast","passed":2514,"failed":0},{"name":"f32_bitwise.wast","passed":364,"failed":0},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":2514,"failed":0},{"name":"f64_bitwise.wast","passed":364,"failed":0},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":8,"failed":0},{"name":"float_exprs.wast","passed":900,"failed":0},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":441,"failed":0},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":172,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"global.wast","passed":110,"failed":0},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":171,"failed":12},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":108,"failed":0},{"name":"int_literals.wast","passed":51,"failed":0},{"name":"labels.wast","passed":29,"failed":0},{"name":"left-to-right.wast","passed":96,"failed":0},{"name":"linking.wast","passed":132,"failed":0},{"name":"load.wast","passed":97,"failed":0},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":97,"failed":0},{"name":"loop.wast","passed":120,"failed":0},{"name":"memory.wast","passed":79,"failed":0},{"name":"memory_copy.wast","passed":3928,"failed":522},{"name":"memory_fill.wast","passed":64,"failed":36},{"name":"memory_grow.wast","passed":96,"failed":0},{"name":"memory_init.wast","passed":177,"failed":63},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":42,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"names.wast","passed":486,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"ref_func.wast","passed":9,"failed":8},{"name":"ref_is_null.wast","passed":4,"failed":12},{"name":"ref_null.wast","passed":1,"failed":2},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":148,"failed":0},{"name":"skip-stack-guard-page.wast","passed":11,"failed":0},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":20,"failed":0},{"name":"store.wast","passed":68,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"table-sub.wast","passed":2,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"table_copy.wast","passed":1613,"failed":115},{"name":"table_fill.wast","passed":23,"failed":22},{"name":"table_get.wast","passed":10,"failed":6},{"name":"table_grow.wast","passed":21,"failed":29},{"name":"table_init.wast","passed":594,"failed":186},{"name":"table_set.wast","passed":19,"failed":7},{"name":"table_size.wast","passed":8,"failed":31},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unreached-valid.wast","passed":7,"failed":0},{"name":"unwind.wast","passed":50,"failed":0},{"name":"utf8-custom-section-id.wast","passed":176,"failed":0},{"name":"utf8-import-field.wast","passed":176,"failed":0},{"name":"utf8-import-module.wast","passed":176,"failed":0},{"name":"utf8-invalid-encoding.wast","passed":176,"failed":0}]
0.4.0,27549,334,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":223,"failed":0},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":118,"failed":0},{"name":"br_table.wast","passed":174,"failed":0},{"name":"bulk.wast","passed":75,"failed":42},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":170,"failed":0},{"name":"comments.wast","passed":8,"failed":0},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":619,"failed":0},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"elem.wast","passed":99,"failed":0},{"name":"endianness.wast","passed":69,"failed":0},{"name":"exports.wast","passed":96,"failed":0},{"name":"f32.wast","passed":2514,"failed":0},{"name":"f32_bitwise.wast","passed":364,"failed":0},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":2514,"failed":0},{"name":"f64_bitwise.wast","passed":364,"failed":0},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":8,"failed":0},{"name":"float_exprs.wast","passed":900,"failed":0},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":441,"failed":0},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":172,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"global.wast","passed":110,"failed":0},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":183,"failed":0},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":108,"failed":0},{"name":"int_literals.wast","passed":51,"failed":0},{"name":"labels.wast","passed":29,"failed":0},{"name":"left-to-right.wast","passed":96,"failed":0},{"name":"linking.wast","passed":132,"failed":0},{"name":"load.wast","passed":97,"failed":0},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":97,"failed":0},{"name":"loop.wast","passed":120,"failed":0},{"name":"memory.wast","passed":79,"failed":0},{"name":"memory_copy.wast","passed":4450,"failed":0},{"name":"memory_fill.wast","passed":100,"failed":0},{"name":"memory_grow.wast","passed":96,"failed":0},{"name":"memory_init.wast","passed":240,"failed":0},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":42,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"names.wast","passed":486,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"ref_func.wast","passed":9,"failed":8},{"name":"ref_is_null.wast","passed":4,"failed":12},{"name":"ref_null.wast","passed":1,"failed":2},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":148,"failed":0},{"name":"skip-stack-guard-page.wast","passed":11,"failed":0},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":20,"failed":0},{"name":"store.wast","passed":68,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"table-sub.wast","passed":2,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"table_copy.wast","passed":1613,"failed":115},{"name":"table_fill.wast","passed":23,"failed":22},{"name":"table_get.wast","passed":10,"failed":6},{"name":"table_grow.wast","passed":21,"failed":29},{"name":"table_init.wast","passed":720,"failed":60},{"name":"table_set.wast","passed":19,"failed":7},{"name":"table_size.wast","passed":8,"failed":31},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unreached-valid.wast","passed":7,"failed":0},{"name":"unwind.wast","passed":50,"failed":0},{"name":"utf8-custom-section-id.wast","passed":176,"failed":0},{"name":"utf8-import-field.wast","passed":176,"failed":0},{"name":"utf8-import-module.wast","passed":176,"failed":0},{"name":"utf8-invalid-encoding.wast","passed":176,"failed":0}]
0.4.1,27551,335,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":223,"failed":0},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":118,"failed":0},{"name":"br_table.wast","passed":174,"failed":0},{"name":"bulk.wast","passed":75,"failed":42},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":170,"failed":0},{"name":"comments.wast","passed":8,"failed":0},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":619,"failed":0},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"elem.wast","passed":99,"failed":0},{"name":"endianness.wast","passed":69,"failed":0},{"name":"exports.wast","passed":96,"failed":0},{"name":"f32.wast","passed":2514,"failed":0},{"name":"f32_bitwise.wast","passed":364,"failed":0},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":2514,"failed":0},{"name":"f64_bitwise.wast","passed":364,"failed":0},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":8,"failed":0},{"name":"float_exprs.wast","passed":900,"failed":0},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":441,"failed":0},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":172,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"global.wast","passed":110,"failed":0},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":186,"failed":0},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":108,"failed":0},{"name":"int_literals.wast","passed":51,"failed":0},{"name":"labels.wast","passed":29,"failed":0},{"name":"left-to-right.wast","passed":96,"failed":0},{"name":"linking.wast","passed":132,"failed":0},{"name":"load.wast","passed":97,"failed":0},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":97,"failed":0},{"name":"loop.wast","passed":120,"failed":0},{"name":"memory.wast","passed":79,"failed":0},{"name":"memory_copy.wast","passed":4450,"failed":0},{"name":"memory_fill.wast","passed":100,"failed":0},{"name":"memory_grow.wast","passed":96,"failed":0},{"name":"memory_init.wast","passed":240,"failed":0},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":42,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"names.wast","passed":486,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"ref_func.wast","passed":9,"failed":8},{"name":"ref_is_null.wast","passed":4,"failed":12},{"name":"ref_null.wast","passed":1,"failed":2},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":148,"failed":0},{"name":"skip-stack-guard-page.wast","passed":11,"failed":0},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":20,"failed":0},{"name":"store.wast","passed":68,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"table-sub.wast","passed":2,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"table_copy.wast","passed":1613,"failed":115},{"name":"table_fill.wast","passed":23,"failed":22},{"name":"table_get.wast","passed":10,"failed":6},{"name":"table_grow.wast","passed":21,"failed":29},{"name":"table_init.wast","passed":719,"failed":61},{"name":"table_set.wast","passed":19,"failed":7},{"name":"table_size.wast","passed":8,"failed":31},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unreached-valid.wast","passed":7,"failed":0},{"name":"unwind.wast","passed":50,"failed":0},{"name":"utf8-custom-section-id.wast","passed":176,"failed":0},{"name":"utf8-import-field.wast","passed":176,"failed":0},{"name":"utf8-import-module.wast","passed":176,"failed":0},{"name":"utf8-invalid-encoding.wast","passed":176,"failed":0}]
+0.5.0,27551,335,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":223,"failed":0},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":118,"failed":0},{"name":"br_table.wast","passed":174,"failed":0},{"name":"bulk.wast","passed":75,"failed":42},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":170,"failed":0},{"name":"comments.wast","passed":8,"failed":0},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":619,"failed":0},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"elem.wast","passed":99,"failed":0},{"name":"endianness.wast","passed":69,"failed":0},{"name":"exports.wast","passed":96,"failed":0},{"name":"f32.wast","passed":2514,"failed":0},{"name":"f32_bitwise.wast","passed":364,"failed":0},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":2514,"failed":0},{"name":"f64_bitwise.wast","passed":364,"failed":0},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":8,"failed":0},{"name":"float_exprs.wast","passed":900,"failed":0},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":441,"failed":0},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":172,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"global.wast","passed":110,"failed":0},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":186,"failed":0},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":108,"failed":0},{"name":"int_literals.wast","passed":51,"failed":0},{"name":"labels.wast","passed":29,"failed":0},{"name":"left-to-right.wast","passed":96,"failed":0},{"name":"linking.wast","passed":132,"failed":0},{"name":"load.wast","passed":97,"failed":0},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":97,"failed":0},{"name":"loop.wast","passed":120,"failed":0},{"name":"memory.wast","passed":79,"failed":0},{"name":"memory_copy.wast","passed":4450,"failed":0},{"name":"memory_fill.wast","passed":100,"failed":0},{"name":"memory_grow.wast","passed":96,"failed":0},{"name":"memory_init.wast","passed":240,"failed":0},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":42,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"names.wast","passed":486,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"ref_func.wast","passed":9,"failed":8},{"name":"ref_is_null.wast","passed":4,"failed":12},{"name":"ref_null.wast","passed":1,"failed":2},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":148,"failed":0},{"name":"skip-stack-guard-page.wast","passed":11,"failed":0},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":20,"failed":0},{"name":"store.wast","passed":68,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"table-sub.wast","passed":2,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"table_copy.wast","passed":1613,"failed":115},{"name":"table_fill.wast","passed":23,"failed":22},{"name":"table_get.wast","passed":10,"failed":6},{"name":"table_grow.wast","passed":21,"failed":29},{"name":"table_init.wast","passed":719,"failed":61},{"name":"table_set.wast","passed":19,"failed":7},{"name":"table_size.wast","passed":8,"failed":31},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unreached-valid.wast","passed":7,"failed":0},{"name":"unwind.wast","passed":50,"failed":0},{"name":"utf8-custom-section-id.wast","passed":176,"failed":0},{"name":"utf8-import-field.wast","passed":176,"failed":0},{"name":"utf8-import-module.wast","passed":176,"failed":0},{"name":"utf8-invalid-encoding.wast","passed":176,"failed":0}]
diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv
index 2e151d5..e2b015a 100644
--- a/crates/tinywasm/tests/generated/mvp.csv
+++ b/crates/tinywasm/tests/generated/mvp.csv
@@ -5,3 +5,4 @@
0.3.0,20254,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":223,"failed":0},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":118,"failed":0},{"name":"br_table.wast","passed":174,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":170,"failed":0},{"name":"comments.wast","passed":8,"failed":0},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":619,"failed":0},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"elem.wast","passed":99,"failed":0},{"name":"endianness.wast","passed":69,"failed":0},{"name":"exports.wast","passed":96,"failed":0},{"name":"f32.wast","passed":2514,"failed":0},{"name":"f32_bitwise.wast","passed":364,"failed":0},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":2514,"failed":0},{"name":"f64_bitwise.wast","passed":364,"failed":0},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":8,"failed":0},{"name":"float_exprs.wast","passed":900,"failed":0},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":441,"failed":0},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":172,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"global.wast","passed":110,"failed":0},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":183,"failed":0},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":108,"failed":0},{"name":"int_literals.wast","passed":51,"failed":0},{"name":"labels.wast","passed":29,"failed":0},{"name":"left-to-right.wast","passed":96,"failed":0},{"name":"linking.wast","passed":132,"failed":0},{"name":"load.wast","passed":97,"failed":0},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":97,"failed":0},{"name":"loop.wast","passed":120,"failed":0},{"name":"memory.wast","passed":79,"failed":0},{"name":"memory_grow.wast","passed":96,"failed":0},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":42,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"names.wast","passed":486,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":148,"failed":0},{"name":"skip-stack-guard-page.wast","passed":11,"failed":0},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":20,"failed":0},{"name":"store.wast","passed":68,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unreached-valid.wast","passed":7,"failed":0},{"name":"unwind.wast","passed":50,"failed":0},{"name":"utf8-custom-section-id.wast","passed":176,"failed":0},{"name":"utf8-import-field.wast","passed":176,"failed":0},{"name":"utf8-import-module.wast","passed":176,"failed":0},{"name":"utf8-invalid-encoding.wast","passed":176,"failed":0}]
0.4.0,20254,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":223,"failed":0},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":118,"failed":0},{"name":"br_table.wast","passed":174,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":170,"failed":0},{"name":"comments.wast","passed":8,"failed":0},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":619,"failed":0},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"elem.wast","passed":99,"failed":0},{"name":"endianness.wast","passed":69,"failed":0},{"name":"exports.wast","passed":96,"failed":0},{"name":"f32.wast","passed":2514,"failed":0},{"name":"f32_bitwise.wast","passed":364,"failed":0},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":2514,"failed":0},{"name":"f64_bitwise.wast","passed":364,"failed":0},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":8,"failed":0},{"name":"float_exprs.wast","passed":900,"failed":0},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":441,"failed":0},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":172,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"global.wast","passed":110,"failed":0},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":183,"failed":0},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":108,"failed":0},{"name":"int_literals.wast","passed":51,"failed":0},{"name":"labels.wast","passed":29,"failed":0},{"name":"left-to-right.wast","passed":96,"failed":0},{"name":"linking.wast","passed":132,"failed":0},{"name":"load.wast","passed":97,"failed":0},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":97,"failed":0},{"name":"loop.wast","passed":120,"failed":0},{"name":"memory.wast","passed":79,"failed":0},{"name":"memory_grow.wast","passed":96,"failed":0},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":42,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"names.wast","passed":486,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":148,"failed":0},{"name":"skip-stack-guard-page.wast","passed":11,"failed":0},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":20,"failed":0},{"name":"store.wast","passed":68,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unreached-valid.wast","passed":7,"failed":0},{"name":"unwind.wast","passed":50,"failed":0},{"name":"utf8-custom-section-id.wast","passed":176,"failed":0},{"name":"utf8-import-field.wast","passed":176,"failed":0},{"name":"utf8-import-module.wast","passed":176,"failed":0},{"name":"utf8-invalid-encoding.wast","passed":176,"failed":0}]
0.4.1,20257,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":223,"failed":0},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":118,"failed":0},{"name":"br_table.wast","passed":174,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":170,"failed":0},{"name":"comments.wast","passed":8,"failed":0},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":619,"failed":0},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"elem.wast","passed":99,"failed":0},{"name":"endianness.wast","passed":69,"failed":0},{"name":"exports.wast","passed":96,"failed":0},{"name":"f32.wast","passed":2514,"failed":0},{"name":"f32_bitwise.wast","passed":364,"failed":0},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":2514,"failed":0},{"name":"f64_bitwise.wast","passed":364,"failed":0},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":8,"failed":0},{"name":"float_exprs.wast","passed":900,"failed":0},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":441,"failed":0},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":172,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"global.wast","passed":110,"failed":0},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":186,"failed":0},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":108,"failed":0},{"name":"int_literals.wast","passed":51,"failed":0},{"name":"labels.wast","passed":29,"failed":0},{"name":"left-to-right.wast","passed":96,"failed":0},{"name":"linking.wast","passed":132,"failed":0},{"name":"load.wast","passed":97,"failed":0},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":97,"failed":0},{"name":"loop.wast","passed":120,"failed":0},{"name":"memory.wast","passed":79,"failed":0},{"name":"memory_grow.wast","passed":96,"failed":0},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":42,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"names.wast","passed":486,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":148,"failed":0},{"name":"skip-stack-guard-page.wast","passed":11,"failed":0},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":20,"failed":0},{"name":"store.wast","passed":68,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unreached-valid.wast","passed":7,"failed":0},{"name":"unwind.wast","passed":50,"failed":0},{"name":"utf8-custom-section-id.wast","passed":176,"failed":0},{"name":"utf8-import-field.wast","passed":176,"failed":0},{"name":"utf8-import-module.wast","passed":176,"failed":0},{"name":"utf8-invalid-encoding.wast","passed":176,"failed":0}]
+0.5.0,20257,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":223,"failed":0},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":118,"failed":0},{"name":"br_table.wast","passed":174,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":170,"failed":0},{"name":"comments.wast","passed":8,"failed":0},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":619,"failed":0},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"elem.wast","passed":99,"failed":0},{"name":"endianness.wast","passed":69,"failed":0},{"name":"exports.wast","passed":96,"failed":0},{"name":"f32.wast","passed":2514,"failed":0},{"name":"f32_bitwise.wast","passed":364,"failed":0},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":2514,"failed":0},{"name":"f64_bitwise.wast","passed":364,"failed":0},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":8,"failed":0},{"name":"float_exprs.wast","passed":900,"failed":0},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":441,"failed":0},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":172,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"global.wast","passed":110,"failed":0},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":186,"failed":0},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":108,"failed":0},{"name":"int_literals.wast","passed":51,"failed":0},{"name":"labels.wast","passed":29,"failed":0},{"name":"left-to-right.wast","passed":96,"failed":0},{"name":"linking.wast","passed":132,"failed":0},{"name":"load.wast","passed":97,"failed":0},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":97,"failed":0},{"name":"loop.wast","passed":120,"failed":0},{"name":"memory.wast","passed":79,"failed":0},{"name":"memory_grow.wast","passed":96,"failed":0},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":42,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"names.wast","passed":486,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":148,"failed":0},{"name":"skip-stack-guard-page.wast","passed":11,"failed":0},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":20,"failed":0},{"name":"store.wast","passed":68,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unreached-valid.wast","passed":7,"failed":0},{"name":"unwind.wast","passed":50,"failed":0},{"name":"utf8-custom-section-id.wast","passed":176,"failed":0},{"name":"utf8-import-field.wast","passed":176,"failed":0},{"name":"utf8-import-module.wast","passed":176,"failed":0},{"name":"utf8-invalid-encoding.wast","passed":176,"failed":0}]
diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs
index d2da7d7..679f3bf 100644
--- a/crates/types/src/lib.rs
+++ b/crates/types/src/lib.rs
@@ -41,37 +41,54 @@ pub mod archive;
#[derive(Debug, Clone, Default, PartialEq)]
#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))]
pub struct TinyWasmModule {
- /// The version of the WebAssembly module.
- pub version: Option<u16>,
-
- /// The start function of the WebAssembly module.
+ /// Optional address of the start function
+ ///
+ /// Corresponds to the `start` section of the original WebAssembly module.
pub start_func: Option<FuncAddr>,
- /// The functions of the WebAssembly module.
- pub funcs: Box<[TypedWasmFunction]>,
+ /// Optimized and validated WebAssembly functions
+ ///
+ /// Contains data from to the `code`, `func`, and `type` sections of the original WebAssembly module.
+ pub funcs: Box<[WasmFunction]>,
- /// The types of the WebAssembly module.
+ /// A vector of type definitions, indexed by `TypeAddr`
+ ///
+ /// Corresponds to the `type` section of the original WebAssembly module.
pub func_types: Box<[FuncType]>,
- /// The exports of the WebAssembly module.
+ /// Exported items of the WebAssembly module.
+ ///
+ /// Corresponds to the `export` section of the original WebAssembly module.
pub exports: Box<[Export]>,
- /// The tables of the WebAssembly module.
+ /// Global components of the WebAssembly module.
+ ///
+ /// Corresponds to the `global` section of the original WebAssembly module.
pub globals: Box<[Global]>,
- /// The tables of the WebAssembly module.
+ /// Table components of the WebAssembly module used to initialize tables.
+ ///
+ /// Corresponds to the `table` section of the original WebAssembly module.
pub table_types: Box<[TableType]>,
- /// The memories of the WebAssembly module.
+ /// Memory components of the WebAssembly module used to initialize memories.
+ ///
+ /// Corresponds to the `memory` section of the original WebAssembly module.
pub memory_types: Box<[MemoryType]>,
- /// The imports of the WebAssembly module.
+ /// Imports of the WebAssembly module.
+ ///
+ /// Corresponds to the `import` section of the original WebAssembly module.
pub imports: Box<[Import]>,
/// Data segments of the WebAssembly module.
+ ///
+ /// Corresponds to the `data` section of the original WebAssembly module.
pub data: Box<[Data]>,
/// Element segments of the WebAssembly module.
+ ///
+ /// Corresponds to the `elem` section of the original WebAssembly module.
pub elements: Box<[Element]>,
}
@@ -164,13 +181,6 @@ pub struct WasmFunction {
pub ty: FuncType,
}
-#[derive(Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))]
-pub struct TypedWasmFunction {
- pub type_addr: u32,
- pub wasm_function: WasmFunction,
-}
-
/// A WebAssembly Module Export
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))]
diff --git a/crates/types/src/value.rs b/crates/types/src/value.rs
index bcd43e5..28ca6e2 100644
--- a/crates/types/src/value.rs
+++ b/crates/types/src/value.rs
@@ -5,7 +5,7 @@ use crate::{ConstInstruction, ExternAddr, FuncAddr};
/// A WebAssembly value.
///
/// See <https://webassembly.github.io/spec/core/syntax/types.html#value-types>
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, PartialEq)]
pub enum WasmValue {
// Num types
/// A 32-bit integer.