From 991397eca74fae71c84e1ea5159c5773cd9bc005 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Thu, 29 Aug 2024 15:27:10 +0200 Subject: [PATCH 01/54] docs: fix image on crates.io Signed-off-by: Henry Gressmann --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0cf8b66..2d897ee 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@
- +

TinyWasm

A tiny WebAssembly Runtime written in safe Rust From 07804aa2291c2e09bf80e0826b5a693646a6a67a Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Thu, 29 Aug 2024 19:47:35 +0200 Subject: [PATCH 02/54] test: fix testsuite on stable Signed-off-by: Henry Gressmann --- crates/tinywasm/tests/generated/wasm-1.csv | 2 +- crates/tinywasm/tests/generated/wasm-2.csv | 2 +- crates/tinywasm/tests/generated/wasm-extended-const.csv | 2 +- crates/tinywasm/tests/generated/wasm-multi-memory.csv | 2 +- crates/tinywasm/tests/testsuite/util.rs | 3 ++- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/crates/tinywasm/tests/generated/wasm-1.csv b/crates/tinywasm/tests/generated/wasm-1.csv index 158943a..64f92d1 100644 --- a/crates/tinywasm/tests/generated/wasm-1.csv +++ b/crates/tinywasm/tests/generated/wasm-1.csv @@ -4,4 +4,4 @@ 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}] 0.6.1,27572,335,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.7.0,27572,335,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.8.0-alpha.0,20358,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":126,"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":98,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_grow.wast","passed":104,"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.8.0,20358,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":126,"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":98,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_grow.wast","passed":104,"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/tinywasm/tests/generated/wasm-2.csv b/crates/tinywasm/tests/generated/wasm-2.csv index b5ba154..0e43692 100644 --- a/crates/tinywasm/tests/generated/wasm-2.csv +++ b/crates/tinywasm/tests/generated/wasm-2.csv @@ -9,4 +9,4 @@ 0.6.0,20278,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.6.1,20278,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.7.0,20278,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.8.0-alpha.0,28006,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":126,"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":117,"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":98,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_copy.wast","passed":4450,"failed":0},{"name":"memory_fill.wast","passed":100,"failed":0},{"name":"memory_grow.wast","passed":104,"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":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":16,"failed":0},{"name":"ref_null.wast","passed":3,"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-sub.wast","passed":2,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"table_copy.wast","passed":1728,"failed":0},{"name":"table_fill.wast","passed":45,"failed":0},{"name":"table_get.wast","passed":16,"failed":0},{"name":"table_grow.wast","passed":58,"failed":0},{"name":"table_init.wast","passed":780,"failed":0},{"name":"table_set.wast","passed":26,"failed":0},{"name":"table_size.wast","passed":39,"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.8.0,28006,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":126,"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":117,"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":98,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_copy.wast","passed":4450,"failed":0},{"name":"memory_fill.wast","passed":100,"failed":0},{"name":"memory_grow.wast","passed":104,"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":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":16,"failed":0},{"name":"ref_null.wast","passed":3,"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-sub.wast","passed":2,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"table_copy.wast","passed":1728,"failed":0},{"name":"table_fill.wast","passed":45,"failed":0},{"name":"table_get.wast","passed":16,"failed":0},{"name":"table_grow.wast","passed":58,"failed":0},{"name":"table_init.wast","passed":780,"failed":0},{"name":"table_set.wast","passed":26,"failed":0},{"name":"table_size.wast","passed":39,"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/tinywasm/tests/generated/wasm-extended-const.csv b/crates/tinywasm/tests/generated/wasm-extended-const.csv index 8cd9132..1c80050 100644 --- a/crates/tinywasm/tests/generated/wasm-extended-const.csv +++ b/crates/tinywasm/tests/generated/wasm-extended-const.csv @@ -1 +1 @@ -0.8.0-alpha.0,211,79,[{"name":"data.wast","passed":61,"failed":4},{"name":"elem.wast","passed":99,"failed":12},{"name":"global.wast","passed":51,"failed":63}] +0.8.0,211,79,[{"name":"data.wast","passed":61,"failed":4},{"name":"elem.wast","passed":99,"failed":12},{"name":"global.wast","passed":51,"failed":63}] diff --git a/crates/tinywasm/tests/generated/wasm-multi-memory.csv b/crates/tinywasm/tests/generated/wasm-multi-memory.csv index f0f8400..acfe7f3 100644 --- a/crates/tinywasm/tests/generated/wasm-multi-memory.csv +++ b/crates/tinywasm/tests/generated/wasm-multi-memory.csv @@ -1 +1 @@ -0.8.0-alpha.0,1710,1,[{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"binary.wast","passed":124,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"imports.wast","passed":183,"failed":0},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":149,"failed":0},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"simd_memory-multi.wast","passed":0,"failed":1},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"traps0.wast","passed":15,"failed":0}] +0.8.0,1710,1,[{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"binary.wast","passed":124,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"imports.wast","passed":183,"failed":0},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":149,"failed":0},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"simd_memory-multi.wast","passed":0,"failed":1},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"traps0.wast","passed":15,"failed":0}] diff --git a/crates/tinywasm/tests/testsuite/util.rs b/crates/tinywasm/tests/testsuite/util.rs index e238f72..29f028b 100644 --- a/crates/tinywasm/tests/testsuite/util.rs +++ b/crates/tinywasm/tests/testsuite/util.rs @@ -5,7 +5,8 @@ use tinywasm_types::{ModuleInstanceAddr, TinyWasmModule, ValType, WasmValue}; use wast::{core::AbstractHeapType, QuoteWat}; pub fn try_downcast_panic(panic: Box) -> String { - let info = panic.downcast_ref::().or(None).map(ToString::to_string).clone(); + #[allow(deprecated)] // new name is not available on stable + let info = panic.downcast_ref::().or(None).map(ToString::to_string).clone(); let info_string = panic.downcast_ref::().cloned(); let info_str = panic.downcast::<&str>().ok().map(|s| *s); From 86bcc87de2163f4b83e1e3f4bfa3dd7ec6482284 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Mon, 2 Sep 2024 22:49:51 +0200 Subject: [PATCH 03/54] wip: simd support Signed-off-by: Henry Gressmann --- crates/parser/src/lib.rs | 4 +- .../tests/generated/wasm-annotations.csv | 1 + .../tests/generated/wasm-memory64.csv | 1 + crates/tinywasm/tests/generated/wasm-simd.csv | 1 + crates/tinywasm/tests/test-wasm-memory64.rs | 10 +++ crates/tinywasm/tests/testsuite/mod.rs | 4 ++ crates/tinywasm/tests/testsuite/util.rs | 23 ++++++- crates/types/src/value.rs | 64 +++++++++++++++++++ 8 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 crates/tinywasm/tests/generated/wasm-annotations.csv create mode 100644 crates/tinywasm/tests/generated/wasm-memory64.csv create mode 100644 crates/tinywasm/tests/generated/wasm-simd.csv diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index dfe6b0c..5e8f9e0 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -61,6 +61,8 @@ impl Parser { function_references: true, tail_call: true, multi_memory: true, + memory64: false, + simd: true, gc_types: true, component_model: false, @@ -70,10 +72,8 @@ impl Parser { exceptions: false, extended_const: false, gc: false, - memory64: false, memory_control: false, relaxed_simd: false, - simd: false, threads: false, custom_page_sizes: false, shared_everything_threads: false, diff --git a/crates/tinywasm/tests/generated/wasm-annotations.csv b/crates/tinywasm/tests/generated/wasm-annotations.csv new file mode 100644 index 0000000..582bc1b --- /dev/null +++ b/crates/tinywasm/tests/generated/wasm-annotations.csv @@ -0,0 +1 @@ +0.8.0,331,286,[{"name":"annotations.wast","passed":74,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"simd_lane.wast","passed":189,"failed":286},{"name":"token.wast","passed":61,"failed":0}] diff --git a/crates/tinywasm/tests/generated/wasm-memory64.csv b/crates/tinywasm/tests/generated/wasm-memory64.csv new file mode 100644 index 0000000..5c9f985 --- /dev/null +++ b/crates/tinywasm/tests/generated/wasm-memory64.csv @@ -0,0 +1 @@ +0.8.0,15074,3213,[{"name":"address.wast","passed":260,"failed":0},{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"address64.wast","passed":0,"failed":242},{"name":"align.wast","passed":162,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"align64.wast","passed":83,"failed":73},{"name":"annotations.wast","passed":74,"failed":0},{"name":"array_copy.wast","passed":4,"failed":31},{"name":"array_fill.wast","passed":3,"failed":14},{"name":"array_init_data.wast","passed":2,"failed":31},{"name":"array_init_elem.wast","passed":3,"failed":20},{"name":"binary-gc.wast","passed":1,"failed":0},{"name":"binary-leb128.wast","passed":92,"failed":1},{"name":"binary.wast","passed":124,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"br_if.wast","passed":119,"failed":0},{"name":"br_on_cast.wast","passed":6,"failed":31},{"name":"br_on_cast_fail.wast","passed":6,"failed":31},{"name":"br_on_non_null.wast","passed":1,"failed":9},{"name":"br_on_null.wast","passed":1,"failed":9},{"name":"br_table.wast","passed":24,"failed":162},{"name":"call_indirect.wast","passed":47,"failed":124},{"name":"call_ref.wast","passed":4,"failed":31},{"name":"data.wast","passed":59,"failed":6},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"elem.wast","passed":137,"failed":14},{"name":"endianness64.wast","passed":0,"failed":69},{"name":"exports.wast","passed":97,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"float_memory64.wast","passed":0,"failed":90},{"name":"func.wast","passed":175,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":107,"failed":82},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking.wast","passed":122,"failed":41},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"load64.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_init.wast","passed":10,"failed":0},{"name":"local_tee.wast","passed":98,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory64.wast","passed":10,"failed":53},{"name":"memory64/array.wast (skipped)","passed":0,"failed":0},{"name":"memory64/extern.wast (skipped)","passed":0,"failed":0},{"name":"memory64/global.wast (skipped)","passed":0,"failed":0},{"name":"memory64/i31.wast (skipped)","passed":0,"failed":0},{"name":"memory64/ref_null.wast (skipped)","passed":0,"failed":0},{"name":"memory64/select.wast (skipped)","passed":0,"failed":0},{"name":"memory64/simd_address.wast (skipped)","passed":0,"failed":0},{"name":"memory64/simd_lane.wast (skipped)","passed":0,"failed":0},{"name":"memory64/struct.wast (skipped)","passed":0,"failed":0},{"name":"memory64/table.wast (skipped)","passed":0,"failed":0},{"name":"memory_copy.wast","passed":8385,"failed":515},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill.wast","passed":164,"failed":36},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":149,"failed":0},{"name":"memory_grow64.wast","passed":0,"failed":49},{"name":"memory_init.wast","passed":307,"failed":173},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_redundancy64.wast","passed":0,"failed":8},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"memory_trap64.wast","passed":0,"failed":172},{"name":"ref.wast","passed":12,"failed":1},{"name":"ref_as_non_null.wast","passed":1,"failed":6},{"name":"ref_cast.wast","passed":0,"failed":45},{"name":"ref_eq.wast","passed":6,"failed":83},{"name":"ref_is_null.wast","passed":2,"failed":20},{"name":"ref_test.wast","passed":0,"failed":71},{"name":"return_call.wast","passed":18,"failed":27},{"name":"return_call_indirect.wast","passed":31,"failed":45},{"name":"return_call_ref.wast","passed":11,"failed":40},{"name":"simd_memory-multi.wast","passed":0,"failed":1},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"table-sub.wast","passed":2,"failed":1},{"name":"table_copy.wast","passed":1742,"failed":30},{"name":"table_copy_mixed.wast","passed":3,"failed":1},{"name":"table_fill.wast","passed":9,"failed":71},{"name":"table_get.wast","passed":5,"failed":12},{"name":"table_grow.wast","passed":28,"failed":43},{"name":"table_init.wast","passed":588,"failed":288},{"name":"table_set.wast","passed":7,"failed":21},{"name":"table_size.wast","passed":2,"failed":38},{"name":"tag.wast","passed":1,"failed":8},{"name":"throw.wast","passed":3,"failed":10},{"name":"throw_ref.wast","passed":2,"failed":13},{"name":"token.wast","passed":61,"failed":0},{"name":"traps0.wast","passed":15,"failed":0},{"name":"try_table.wast","passed":11,"failed":50},{"name":"type-canon.wast","passed":0,"failed":2},{"name":"type-equivalence.wast","passed":12,"failed":20},{"name":"type-rec.wast","passed":6,"failed":14},{"name":"type-subtyping.wast","passed":16,"failed":86},{"name":"unreached-invalid.wast","passed":121,"failed":0},{"name":"unreached-valid.wast","passed":2,"failed":11}] diff --git a/crates/tinywasm/tests/generated/wasm-simd.csv b/crates/tinywasm/tests/generated/wasm-simd.csv new file mode 100644 index 0000000..e9bc8ae --- /dev/null +++ b/crates/tinywasm/tests/generated/wasm-simd.csv @@ -0,0 +1 @@ +0.8.0,1300,24679,[{"name":"simd_address.wast","passed":4,"failed":45},{"name":"simd_align.wast","passed":46,"failed":54},{"name":"simd_bit_shift.wast","passed":39,"failed":213},{"name":"simd_bitwise.wast","passed":28,"failed":141},{"name":"simd_boolean.wast","passed":16,"failed":261},{"name":"simd_const.wast","passed":301,"failed":456},{"name":"simd_conversions.wast","passed":48,"failed":234},{"name":"simd_f32x4.wast","passed":16,"failed":774},{"name":"simd_f32x4_arith.wast","passed":16,"failed":1806},{"name":"simd_f32x4_cmp.wast","passed":24,"failed":2583},{"name":"simd_f32x4_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f32x4_rounding.wast","passed":24,"failed":177},{"name":"simd_f64x2.wast","passed":8,"failed":795},{"name":"simd_f64x2_arith.wast","passed":16,"failed":1809},{"name":"simd_f64x2_cmp.wast","passed":24,"failed":2661},{"name":"simd_f64x2_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f64x2_rounding.wast","passed":24,"failed":177},{"name":"simd_i16x8_arith.wast","passed":11,"failed":183},{"name":"simd_i16x8_arith2.wast","passed":19,"failed":153},{"name":"simd_i16x8_cmp.wast","passed":30,"failed":435},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":4,"failed":17},{"name":"simd_i16x8_extmul_i8x16.wast","passed":12,"failed":105},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":3,"failed":27},{"name":"simd_i16x8_sat_arith.wast","passed":16,"failed":206},{"name":"simd_i32x4_arith.wast","passed":11,"failed":183},{"name":"simd_i32x4_arith2.wast","passed":26,"failed":123},{"name":"simd_i32x4_cmp.wast","passed":40,"failed":435},{"name":"simd_i32x4_dot_i16x8.wast","passed":3,"failed":27},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":4,"failed":17},{"name":"simd_i32x4_extmul_i16x8.wast","passed":12,"failed":105},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":4,"failed":103},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":4,"failed":103},{"name":"simd_i64x2_arith.wast","passed":11,"failed":189},{"name":"simd_i64x2_arith2.wast","passed":2,"failed":23},{"name":"simd_i64x2_cmp.wast","passed":10,"failed":103},{"name":"simd_i64x2_extmul_i32x4.wast","passed":12,"failed":105},{"name":"simd_i8x16_arith.wast","passed":8,"failed":123},{"name":"simd_i8x16_arith2.wast","passed":25,"failed":186},{"name":"simd_i8x16_cmp.wast","passed":30,"failed":415},{"name":"simd_i8x16_sat_arith.wast","passed":24,"failed":190},{"name":"simd_int_to_int_extend.wast","passed":24,"failed":229},{"name":"simd_lane.wast","passed":189,"failed":286},{"name":"simd_linking.wast","passed":0,"failed":3},{"name":"simd_load.wast","passed":8,"failed":31},{"name":"simd_load16_lane.wast","passed":3,"failed":33},{"name":"simd_load32_lane.wast","passed":3,"failed":21},{"name":"simd_load64_lane.wast","passed":3,"failed":13},{"name":"simd_load8_lane.wast","passed":3,"failed":49},{"name":"simd_load_extend.wast","passed":18,"failed":86},{"name":"simd_load_splat.wast","passed":12,"failed":114},{"name":"simd_load_zero.wast","passed":10,"failed":29},{"name":"simd_splat.wast","passed":23,"failed":162},{"name":"simd_store.wast","passed":9,"failed":19},{"name":"simd_store16_lane.wast","passed":3,"failed":33},{"name":"simd_store32_lane.wast","passed":3,"failed":21},{"name":"simd_store64_lane.wast","passed":3,"failed":13},{"name":"simd_store8_lane.wast","passed":3,"failed":49}] diff --git a/crates/tinywasm/tests/test-wasm-memory64.rs b/crates/tinywasm/tests/test-wasm-memory64.rs index ab23762..0dfe2b8 100644 --- a/crates/tinywasm/tests/test-wasm-memory64.rs +++ b/crates/tinywasm/tests/test-wasm-memory64.rs @@ -5,6 +5,16 @@ use testsuite::TestSuite; fn main() -> Result<()> { let mut test_suite = TestSuite::new(); + test_suite.skip("memory64/array.wast"); + test_suite.skip("memory64/extern.wast"); + test_suite.skip("memory64/global.wast"); + test_suite.skip("memory64/i31.wast"); + test_suite.skip("memory64/ref_null.wast"); + test_suite.skip("memory64/select.wast"); + test_suite.skip("memory64/simd_address.wast"); + test_suite.skip("memory64/simd_lane.wast"); + test_suite.skip("memory64/struct.wast"); + test_suite.skip("memory64/table.wast"); TestSuite::set_log_level(log::LevelFilter::Off); test_suite.run_spec_group(wasm_testsuite::get_proposal_tests("memory64"))?; diff --git a/crates/tinywasm/tests/testsuite/mod.rs b/crates/tinywasm/tests/testsuite/mod.rs index ca62d4e..3c23e00 100644 --- a/crates/tinywasm/tests/testsuite/mod.rs +++ b/crates/tinywasm/tests/testsuite/mod.rs @@ -50,6 +50,10 @@ impl TestSuite { Self(BTreeMap::new(), Vec::new()) } + pub fn skip(&mut self, name: &str) { + self.1.push(name.to_string()); + } + pub fn failed(&self) -> bool { self.0.values().any(|group| group.stats().1 > 0) } diff --git a/crates/tinywasm/tests/testsuite/util.rs b/crates/tinywasm/tests/testsuite/util.rs index 29f028b..16fc01c 100644 --- a/crates/tinywasm/tests/testsuite/util.rs +++ b/crates/tinywasm/tests/testsuite/util.rs @@ -97,12 +97,13 @@ fn wastarg2tinywasmvalue(arg: wast::WastArg) -> Result WasmValue::F32(f32::from_bits(f.bits)), F64(f) => WasmValue::F64(f64::from_bits(f.bits)), I32(i) => WasmValue::I32(i), I64(i) => WasmValue::I64(i), + V128(i) => WasmValue::V128(i128::from_le_bytes(i.to_le_bytes()).try_into().unwrap()), RefExtern(v) => WasmValue::RefExtern(v), RefNull(t) => match t { wast::core::HeapType::Abstract { shared: false, ty: AbstractHeapType::Func } => { @@ -117,17 +118,33 @@ fn wastarg2tinywasmvalue(arg: wast::WastArg) -> Result u128 { + match i { + wast::core::V128Pattern::F32x4(f) => { + f.iter().fold(0, |acc, &f| acc << 32 | nanpattern2tinywasmvalue(f).unwrap().as_f32().unwrap() as u128) + } + wast::core::V128Pattern::F64x2(f) => { + f.iter().fold(0, |acc, &f| acc << 64 | nanpattern2tinywasmvalue(f).unwrap().as_f64().unwrap() as u128) + } + wast::core::V128Pattern::I16x8(f) => f.iter().fold(0, |acc, &f| acc << 16 | f as u128), + wast::core::V128Pattern::I32x4(f) => f.iter().fold(0, |acc, &f| acc << 32 | f as u128), + wast::core::V128Pattern::I64x2(f) => f.iter().fold(0, |acc, &f| acc << 64 | f as u128), + wast::core::V128Pattern::I8x16(f) => f.iter().fold(0, |acc, &f| acc << 8 | f as u128), + } +} + fn wastret2tinywasmvalue(ret: wast::WastRet) -> Result { let wast::WastRet::Core(ret) = ret else { return Err(eyre!("unsupported arg type")); }; - use wast::core::WastRetCore::{RefExtern, RefFunc, RefNull, F32, F64, I32, I64}; + use wast::core::WastRetCore::{RefExtern, RefFunc, RefNull, F32, F64, I32, I64, V128}; Ok(match ret { F32(f) => nanpattern2tinywasmvalue(f)?, F64(f) => nanpattern2tinywasmvalue(f)?, I32(i) => WasmValue::I32(i), I64(i) => WasmValue::I64(i), + V128(i) => WasmValue::V128(wast_i128_to_i128(i)), RefNull(t) => match t { Some(wast::core::HeapType::Abstract { shared: false, ty: AbstractHeapType::Func }) => { WasmValue::RefNull(ValType::RefFunc) @@ -139,10 +156,12 @@ fn wastret2tinywasmvalue(ret: wast::WastRet) -> Result match v { Some(v) => WasmValue::RefExtern(v), + None => WasmValue::RefNull(ValType::RefExtern), _ => return Err(eyre!("unsupported arg type: refextern: {:?}", v)), }, RefFunc(v) => match v { Some(wast::token::Index::Num(n, _)) => WasmValue::RefFunc(n), + None => WasmValue::RefNull(ValType::RefFunc), _ => return Err(eyre!("unsupported arg type: reffunc: {:?}", v)), }, a => return Err(eyre!("unsupported arg type {:?}", a)), diff --git a/crates/types/src/value.rs b/crates/types/src/value.rs index 416f678..825fa1f 100644 --- a/crates/types/src/value.rs +++ b/crates/types/src/value.rs @@ -79,6 +79,70 @@ impl WasmValue { _ => false, } } + + #[doc(hidden)] + pub fn as_i32(&self) -> Option { + match self { + Self::I32(i) => Some(*i), + _ => None, + } + } + + #[doc(hidden)] + pub fn as_i64(&self) -> Option { + match self { + Self::I64(i) => Some(*i), + _ => None, + } + } + + #[doc(hidden)] + pub fn as_f32(&self) -> Option { + match self { + Self::F32(i) => Some(*i), + _ => None, + } + } + + #[doc(hidden)] + pub fn as_f64(&self) -> Option { + match self { + Self::F64(i) => Some(*i), + _ => None, + } + } + + #[doc(hidden)] + pub fn as_v128(&self) -> Option { + match self { + Self::V128(i) => Some(*i), + _ => None, + } + } + + #[doc(hidden)] + pub fn as_ref_extern(&self) -> Option { + match self { + Self::RefExtern(addr) => Some(*addr), + _ => None, + } + } + + #[doc(hidden)] + pub fn as_ref_func(&self) -> Option { + match self { + Self::RefFunc(addr) => Some(*addr), + _ => None, + } + } + + #[doc(hidden)] + pub fn as_ref_null(&self) -> Option { + match self { + Self::RefNull(ty) => Some(*ty), + _ => None, + } + } } #[cold] From ba6a03d6038f8c1e3973879bd23490a86539d2b1 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Thu, 5 Sep 2024 22:47:38 +0200 Subject: [PATCH 04/54] chore: update to rust 1.81, update wasm testsuite Signed-off-by: Henry Gressmann --- Cargo.lock | 28 +++++++++---------- Cargo.toml | 2 +- crates/parser/src/error.rs | 3 +- crates/tinywasm/src/error.rs | 3 +- crates/tinywasm/src/std.rs | 6 ---- .../tests/generated/wasm-memory64.csv | 2 +- .../tests/generated/wasm-multi-memory.csv | 2 +- crates/tinywasm/tests/testsuite/util.rs | 3 +- crates/types/src/archive.rs | 3 +- crates/wasm-testsuite/data | 2 +- 10 files changed, 22 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eb1ab92..e429505 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,7 +65,7 @@ dependencies = [ "argh_shared", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -217,18 +217,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.16" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" +checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.15" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" dependencies = [ "anstyle", "clap_lex", @@ -458,9 +458,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -710,7 +710,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.76", + "syn 2.0.77", "walkdir", ] @@ -769,14 +769,14 @@ checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] name = "serde_json" -version = "1.0.127" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", "memchr", @@ -814,9 +814,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.76" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -1135,5 +1135,5 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] diff --git a/Cargo.toml b/Cargo.toml index 81d9533..7196533 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ criterion={version="0.5", default-features=false, features=["cargo_bench_support [workspace.package] version="0.8.0" -rust-version="1.80" +rust-version="1.81" edition="2021" license="MIT OR Apache-2.0" authors=["Henry Gressmann "] diff --git a/crates/parser/src/error.rs b/crates/parser/src/error.rs index 7bd484f..9ff2f79 100644 --- a/crates/parser/src/error.rs +++ b/crates/parser/src/error.rs @@ -59,8 +59,7 @@ impl Display for ParseError { } } -#[cfg(any(feature = "std", all(not(feature = "std"), feature = "nightly")))] -impl crate::std::error::Error for ParseError {} +impl core::error::Error for ParseError {} impl From for ParseError { fn from(value: wasmparser::BinaryReaderError) -> Self { diff --git a/crates/tinywasm/src/error.rs b/crates/tinywasm/src/error.rs index 73df9a2..ebc71af 100644 --- a/crates/tinywasm/src/error.rs +++ b/crates/tinywasm/src/error.rs @@ -225,8 +225,7 @@ impl Display for Trap { } } -#[cfg(any(feature = "std", all(not(feature = "std"), feature = "nightly")))] -impl crate::std::error::Error for Error {} +impl core::error::Error for Error {} #[cfg(feature = "parser")] impl From for Error { diff --git a/crates/tinywasm/src/std.rs b/crates/tinywasm/src/std.rs index f1e97a4..90368e1 100644 --- a/crates/tinywasm/src/std.rs +++ b/crates/tinywasm/src/std.rs @@ -9,10 +9,4 @@ pub(crate) use std::*; pub(crate) mod error { #[cfg(feature = "std")] extern crate std; - - #[cfg(feature = "std")] - pub(crate) use std::error::Error; - - #[cfg(all(not(feature = "std"), feature = "nightly"))] - pub(crate) use core::error::Error; } diff --git a/crates/tinywasm/tests/generated/wasm-memory64.csv b/crates/tinywasm/tests/generated/wasm-memory64.csv index 5c9f985..774d1e1 100644 --- a/crates/tinywasm/tests/generated/wasm-memory64.csv +++ b/crates/tinywasm/tests/generated/wasm-memory64.csv @@ -1 +1 @@ -0.8.0,15074,3213,[{"name":"address.wast","passed":260,"failed":0},{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"address64.wast","passed":0,"failed":242},{"name":"align.wast","passed":162,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"align64.wast","passed":83,"failed":73},{"name":"annotations.wast","passed":74,"failed":0},{"name":"array_copy.wast","passed":4,"failed":31},{"name":"array_fill.wast","passed":3,"failed":14},{"name":"array_init_data.wast","passed":2,"failed":31},{"name":"array_init_elem.wast","passed":3,"failed":20},{"name":"binary-gc.wast","passed":1,"failed":0},{"name":"binary-leb128.wast","passed":92,"failed":1},{"name":"binary.wast","passed":124,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"br_if.wast","passed":119,"failed":0},{"name":"br_on_cast.wast","passed":6,"failed":31},{"name":"br_on_cast_fail.wast","passed":6,"failed":31},{"name":"br_on_non_null.wast","passed":1,"failed":9},{"name":"br_on_null.wast","passed":1,"failed":9},{"name":"br_table.wast","passed":24,"failed":162},{"name":"call_indirect.wast","passed":47,"failed":124},{"name":"call_ref.wast","passed":4,"failed":31},{"name":"data.wast","passed":59,"failed":6},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"elem.wast","passed":137,"failed":14},{"name":"endianness64.wast","passed":0,"failed":69},{"name":"exports.wast","passed":97,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"float_memory64.wast","passed":0,"failed":90},{"name":"func.wast","passed":175,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":107,"failed":82},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking.wast","passed":122,"failed":41},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"load64.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_init.wast","passed":10,"failed":0},{"name":"local_tee.wast","passed":98,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory64.wast","passed":10,"failed":53},{"name":"memory64/array.wast (skipped)","passed":0,"failed":0},{"name":"memory64/extern.wast (skipped)","passed":0,"failed":0},{"name":"memory64/global.wast (skipped)","passed":0,"failed":0},{"name":"memory64/i31.wast (skipped)","passed":0,"failed":0},{"name":"memory64/ref_null.wast (skipped)","passed":0,"failed":0},{"name":"memory64/select.wast (skipped)","passed":0,"failed":0},{"name":"memory64/simd_address.wast (skipped)","passed":0,"failed":0},{"name":"memory64/simd_lane.wast (skipped)","passed":0,"failed":0},{"name":"memory64/struct.wast (skipped)","passed":0,"failed":0},{"name":"memory64/table.wast (skipped)","passed":0,"failed":0},{"name":"memory_copy.wast","passed":8385,"failed":515},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill.wast","passed":164,"failed":36},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":149,"failed":0},{"name":"memory_grow64.wast","passed":0,"failed":49},{"name":"memory_init.wast","passed":307,"failed":173},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_redundancy64.wast","passed":0,"failed":8},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"memory_trap64.wast","passed":0,"failed":172},{"name":"ref.wast","passed":12,"failed":1},{"name":"ref_as_non_null.wast","passed":1,"failed":6},{"name":"ref_cast.wast","passed":0,"failed":45},{"name":"ref_eq.wast","passed":6,"failed":83},{"name":"ref_is_null.wast","passed":2,"failed":20},{"name":"ref_test.wast","passed":0,"failed":71},{"name":"return_call.wast","passed":18,"failed":27},{"name":"return_call_indirect.wast","passed":31,"failed":45},{"name":"return_call_ref.wast","passed":11,"failed":40},{"name":"simd_memory-multi.wast","passed":0,"failed":1},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"table-sub.wast","passed":2,"failed":1},{"name":"table_copy.wast","passed":1742,"failed":30},{"name":"table_copy_mixed.wast","passed":3,"failed":1},{"name":"table_fill.wast","passed":9,"failed":71},{"name":"table_get.wast","passed":5,"failed":12},{"name":"table_grow.wast","passed":28,"failed":43},{"name":"table_init.wast","passed":588,"failed":288},{"name":"table_set.wast","passed":7,"failed":21},{"name":"table_size.wast","passed":2,"failed":38},{"name":"tag.wast","passed":1,"failed":8},{"name":"throw.wast","passed":3,"failed":10},{"name":"throw_ref.wast","passed":2,"failed":13},{"name":"token.wast","passed":61,"failed":0},{"name":"traps0.wast","passed":15,"failed":0},{"name":"try_table.wast","passed":11,"failed":50},{"name":"type-canon.wast","passed":0,"failed":2},{"name":"type-equivalence.wast","passed":12,"failed":20},{"name":"type-rec.wast","passed":6,"failed":14},{"name":"type-subtyping.wast","passed":16,"failed":86},{"name":"unreached-invalid.wast","passed":121,"failed":0},{"name":"unreached-valid.wast","passed":2,"failed":11}] +0.8.0,15081,3214,[{"name":"address.wast","passed":260,"failed":0},{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"address64.wast","passed":0,"failed":242},{"name":"align.wast","passed":161,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"align64.wast","passed":83,"failed":73},{"name":"annotations.wast","passed":74,"failed":0},{"name":"array_copy.wast","passed":4,"failed":31},{"name":"array_fill.wast","passed":3,"failed":14},{"name":"array_init_data.wast","passed":2,"failed":31},{"name":"array_init_elem.wast","passed":3,"failed":20},{"name":"binary-gc.wast","passed":1,"failed":0},{"name":"binary-leb128.wast","passed":92,"failed":1},{"name":"binary.wast","passed":124,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"br_if.wast","passed":119,"failed":0},{"name":"br_on_cast.wast","passed":6,"failed":31},{"name":"br_on_cast_fail.wast","passed":6,"failed":31},{"name":"br_on_non_null.wast","passed":1,"failed":9},{"name":"br_on_null.wast","passed":1,"failed":9},{"name":"br_table.wast","passed":24,"failed":162},{"name":"call_indirect.wast","passed":47,"failed":124},{"name":"call_ref.wast","passed":4,"failed":31},{"name":"data.wast","passed":59,"failed":6},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"elem.wast","passed":137,"failed":14},{"name":"endianness64.wast","passed":0,"failed":69},{"name":"exports.wast","passed":97,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"float_memory64.wast","passed":0,"failed":90},{"name":"func.wast","passed":175,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":99,"failed":82},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking.wast","passed":122,"failed":41},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"load64.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_init.wast","passed":10,"failed":0},{"name":"local_tee.wast","passed":98,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory64.wast","passed":10,"failed":53},{"name":"memory64/array.wast (skipped)","passed":0,"failed":0},{"name":"memory64/extern.wast (skipped)","passed":0,"failed":0},{"name":"memory64/global.wast (skipped)","passed":0,"failed":0},{"name":"memory64/i31.wast (skipped)","passed":0,"failed":0},{"name":"memory64/ref_null.wast (skipped)","passed":0,"failed":0},{"name":"memory64/select.wast (skipped)","passed":0,"failed":0},{"name":"memory64/simd_address.wast (skipped)","passed":0,"failed":0},{"name":"memory64/simd_lane.wast (skipped)","passed":0,"failed":0},{"name":"memory64/struct.wast (skipped)","passed":0,"failed":0},{"name":"memory64/table.wast (skipped)","passed":0,"failed":0},{"name":"memory_copy.wast","passed":8385,"failed":515},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill.wast","passed":164,"failed":36},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_grow64.wast","passed":0,"failed":49},{"name":"memory_init.wast","passed":307,"failed":173},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_redundancy64.wast","passed":0,"failed":8},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"memory_trap64.wast","passed":0,"failed":172},{"name":"ref.wast","passed":12,"failed":1},{"name":"ref_as_non_null.wast","passed":1,"failed":6},{"name":"ref_cast.wast","passed":0,"failed":45},{"name":"ref_eq.wast","passed":6,"failed":83},{"name":"ref_is_null.wast","passed":2,"failed":20},{"name":"ref_test.wast","passed":0,"failed":71},{"name":"return_call.wast","passed":18,"failed":27},{"name":"return_call_indirect.wast","passed":31,"failed":45},{"name":"return_call_ref.wast","passed":11,"failed":40},{"name":"simd_memory-multi.wast","passed":0,"failed":1},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"table-sub.wast","passed":2,"failed":1},{"name":"table_copy.wast","passed":1742,"failed":30},{"name":"table_copy_mixed.wast","passed":3,"failed":1},{"name":"table_fill.wast","passed":9,"failed":71},{"name":"table_get.wast","passed":5,"failed":12},{"name":"table_grow.wast","passed":36,"failed":43},{"name":"table_init.wast","passed":588,"failed":288},{"name":"table_set.wast","passed":7,"failed":21},{"name":"table_size.wast","passed":2,"failed":38},{"name":"tag.wast","passed":1,"failed":8},{"name":"throw.wast","passed":3,"failed":10},{"name":"throw_ref.wast","passed":2,"failed":13},{"name":"token.wast","passed":61,"failed":0},{"name":"traps0.wast","passed":15,"failed":0},{"name":"try_table.wast","passed":11,"failed":51},{"name":"type-canon.wast","passed":0,"failed":2},{"name":"type-equivalence.wast","passed":12,"failed":20},{"name":"type-rec.wast","passed":6,"failed":14},{"name":"type-subtyping.wast","passed":16,"failed":86},{"name":"unreached-invalid.wast","passed":121,"failed":0},{"name":"unreached-valid.wast","passed":2,"failed":11}] diff --git a/crates/tinywasm/tests/generated/wasm-multi-memory.csv b/crates/tinywasm/tests/generated/wasm-multi-memory.csv index acfe7f3..e4c4533 100644 --- a/crates/tinywasm/tests/generated/wasm-multi-memory.csv +++ b/crates/tinywasm/tests/generated/wasm-multi-memory.csv @@ -1 +1 @@ -0.8.0,1710,1,[{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"binary.wast","passed":124,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"imports.wast","passed":183,"failed":0},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":149,"failed":0},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"simd_memory-multi.wast","passed":0,"failed":1},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"traps0.wast","passed":15,"failed":0}] +0.8.0,1870,1,[{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"align.wast","passed":160,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"binary.wast","passed":124,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"imports.wast","passed":175,"failed":0},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"simd_memory-multi.wast","passed":0,"failed":1},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"traps0.wast","passed":15,"failed":0}] diff --git a/crates/tinywasm/tests/testsuite/util.rs b/crates/tinywasm/tests/testsuite/util.rs index 16fc01c..53eb5ff 100644 --- a/crates/tinywasm/tests/testsuite/util.rs +++ b/crates/tinywasm/tests/testsuite/util.rs @@ -5,8 +5,7 @@ use tinywasm_types::{ModuleInstanceAddr, TinyWasmModule, ValType, WasmValue}; use wast::{core::AbstractHeapType, QuoteWat}; pub fn try_downcast_panic(panic: Box) -> String { - #[allow(deprecated)] // new name is not available on stable - let info = panic.downcast_ref::().or(None).map(ToString::to_string).clone(); + let info = panic.downcast_ref::().or(None).map(ToString::to_string).clone(); let info_string = panic.downcast_ref::().cloned(); let info_str = panic.downcast::<&str>().ok().map(|s| *s); diff --git a/crates/types/src/archive.rs b/crates/types/src/archive.rs index 398b616..cce0501 100644 --- a/crates/types/src/archive.rs +++ b/crates/types/src/archive.rs @@ -50,8 +50,7 @@ impl Display for TwasmError { #[cfg(feature = "std")] extern crate std; -#[cfg(feature = "std")] -impl std::error::Error for TwasmError {} +impl core::error::Error for TwasmError {} impl TinyWasmModule { /// Creates a `TinyWasmModule` from a slice of bytes. diff --git a/crates/wasm-testsuite/data b/crates/wasm-testsuite/data index ae5a669..7c3ec23 160000 --- a/crates/wasm-testsuite/data +++ b/crates/wasm-testsuite/data @@ -1 +1 @@ -Subproject commit ae5a66933070b705dde56c2a71bf3fbc33282864 +Subproject commit 7c3ec23ab19b37c68976b555f9491752cbda6d5f From 3c16adc4e12873802b15d77a8357f56893a9c84f Mon Sep 17 00:00:00 2001 From: Daniel Stuart Date: Mon, 9 Sep 2024 19:19:25 -0300 Subject: [PATCH 05/54] feat: Custom memory page size (#22) --- Cargo.lock | 12 +- README.md | 23 ++-- crates/parser/src/conversion.rs | 11 +- crates/parser/src/lib.rs | 2 +- crates/tinywasm/Cargo.toml | 6 + crates/tinywasm/benches/argon2id.rs | 2 +- crates/tinywasm/benches/fibonacci.rs | 2 +- crates/tinywasm/benches/tinywasm.rs | 2 +- crates/tinywasm/src/imports.rs | 16 ++- crates/tinywasm/src/store/memory.rs | 49 +++++--- crates/tinywasm/src/store/mod.rs | 4 +- .../generated/wasm-custom-page-sizes.csv | 1 + .../tests/test-wasm-custom-page-sizes.rs | 20 ++++ crates/tinywasm/tests/testsuite/run.rs | 7 +- crates/types/src/lib.rs | 43 ++++++- crates/wasm-testsuite/lib.rs | 19 ++- .../custom-page-sizes-invalid.wast | 112 ++++++++++++++++++ .../custom-page-sizes/custom-page-sizes.wast | 110 +++++++++++++++++ 18 files changed, 378 insertions(+), 63 deletions(-) create mode 100644 crates/tinywasm/tests/generated/wasm-custom-page-sizes.csv create mode 100644 crates/tinywasm/tests/test-wasm-custom-page-sizes.rs create mode 100644 crates/wasm-testsuite/tests/proposals/custom-page-sizes/custom-page-sizes-invalid.wast create mode 100644 crates/wasm-testsuite/tests/proposals/custom-page-sizes/custom-page-sizes.wast diff --git a/Cargo.lock b/Cargo.lock index e429505..c8bc86c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -242,9 +242,9 @@ checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "cpufeatures" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -754,18 +754,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", diff --git a/README.md b/README.md index 2d897ee..a963ea7 100644 --- a/README.md +++ b/README.md @@ -27,17 +27,18 @@ TinyWasm passes all WebAssembly MVP tests from the [WebAssembly core testsuite]( 🚧 -- in development / partialy supported\ 🟢 -- fully supported -| Proposal | Status | TinyWasm Version | -| -------------------------------------------------------------------------------------------------------------------------- | ------ | ---------------- | -| [**Mutable Globals**](https://github.com/WebAssembly/mutable-global/blob/master/proposals/mutable-global/Overview.md) | 🟢 | 0.2.0 | -| [**Non-trapping float-to-int Conversion**](https://github.com/WebAssembly/nontrapping-float-to-int-conversions) | 🟢 | 0.2.0 | -| [**Sign-extension operators**](https://github.com/WebAssembly/sign-extension-ops) | 🟢 | 0.2.0 | -| [**Multi-value**](https://github.com/WebAssembly/spec/blob/master/proposals/multi-value/Overview.md) | 🟢 | 0.2.0 | -| [**Bulk Memory Operations**](https://github.com/WebAssembly/spec/blob/master/proposals/bulk-memory-operations/Overview.md) | 🟢 | 0.4.0 | -| [**Reference Types**](https://github.com/WebAssembly/reference-types/blob/master/proposals/reference-types/Overview.md) | 🟢 | 0.7.0 | -| [**Multiple Memories**](https://github.com/WebAssembly/multi-memory/blob/master/proposals/multi-memory/Overview.md) | 🟢 | 0.8.0 | -| [**Memory64**](https://github.com/WebAssembly/memory64/blob/master/proposals/memory64/Overview.md) | 🚧 | N/A | -| [**Fixed-Width SIMD**](https://github.com/webassembly/simd) | 🌑 | N/A | +| Proposal | Status | TinyWasm Version | +| --------------------------------------------------------------------------------------------------------------------------- | ------ | ---------------- | +| [**Mutable Globals**](https://github.com/WebAssembly/mutable-global/blob/master/proposals/mutable-global/Overview.md) | 🟢 | 0.2.0 | +| [**Non-trapping float-to-int Conversion**](https://github.com/WebAssembly/nontrapping-float-to-int-conversions) | 🟢 | 0.2.0 | +| [**Sign-extension operators**](https://github.com/WebAssembly/sign-extension-ops) | 🟢 | 0.2.0 | +| [**Multi-value**](https://github.com/WebAssembly/spec/blob/master/proposals/multi-value/Overview.md) | 🟢 | 0.2.0 | +| [**Bulk Memory Operations**](https://github.com/WebAssembly/spec/blob/master/proposals/bulk-memory-operations/Overview.md) | 🟢 | 0.4.0 | +| [**Reference Types**](https://github.com/WebAssembly/reference-types/blob/master/proposals/reference-types/Overview.md) | 🟢 | 0.7.0 | +| [**Multiple Memories**](https://github.com/WebAssembly/multi-memory/blob/master/proposals/multi-memory/Overview.md) | 🟢 | 0.8.0 | +| [**Custom Page Sizes**](https://github.com/WebAssembly/custom-page-sizes/blob/main/proposals/custom-page-sizes/Overview.md) | 🟢 | `next` | +| [**Memory64**](https://github.com/WebAssembly/memory64/blob/master/proposals/memory64/Overview.md) | 🚧 | N/A | +| [**Fixed-Width SIMD**](https://github.com/webassembly/simd) | 🌑 | N/A | ## Usage diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs index 10607a1..76099ca 100644 --- a/crates/parser/src/conversion.rs +++ b/crates/parser/src/conversion.rs @@ -105,11 +105,12 @@ pub(crate) fn convert_module_memories MemoryType { - MemoryType { - arch: if memory.memory64 { MemoryArch::I64 } else { MemoryArch::I32 }, - page_count_initial: memory.initial, - page_count_max: memory.maximum, - } + MemoryType::new( + if memory.memory64 { MemoryArch::I64 } else { MemoryArch::I32 }, + memory.initial, + memory.maximum, + memory.page_size_log2.map(|x| 1 << x), + ) } pub(crate) fn convert_module_tables<'a, T: IntoIterator>>>( diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index 5e8f9e0..8c68c64 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -63,6 +63,7 @@ impl Parser { multi_memory: true, memory64: false, simd: true, + custom_page_sizes: true, gc_types: true, component_model: false, @@ -75,7 +76,6 @@ impl Parser { memory_control: false, relaxed_simd: false, threads: false, - custom_page_sizes: false, shared_everything_threads: false, component_model_multiple_returns: false, legacy_exceptions: false, diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index 98f88f1..ebe7ffd 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -73,6 +73,12 @@ name="test-wasm-simd" harness=false test=false + +[[test]] +name="test-wasm-custom-page-sizes" +harness=false +test=false + [[test]] name="test-wast" harness=false diff --git a/crates/tinywasm/benches/argon2id.rs b/crates/tinywasm/benches/argon2id.rs index 0a8f033..6dd5ae4 100644 --- a/crates/tinywasm/benches/argon2id.rs +++ b/crates/tinywasm/benches/argon2id.rs @@ -1,6 +1,6 @@ use criterion::{criterion_group, criterion_main, Criterion}; use eyre::Result; -use tinywasm::{ModuleInstance, Store, types}; +use tinywasm::{types, ModuleInstance, Store}; use types::{archive::AlignedVec, TinyWasmModule}; const WASM: &[u8] = include_bytes!("../../../examples/rust/out/argon2id.opt.wasm"); diff --git a/crates/tinywasm/benches/fibonacci.rs b/crates/tinywasm/benches/fibonacci.rs index 557d787..9c994ca 100644 --- a/crates/tinywasm/benches/fibonacci.rs +++ b/crates/tinywasm/benches/fibonacci.rs @@ -1,6 +1,6 @@ use criterion::{criterion_group, criterion_main, Criterion}; use eyre::Result; -use tinywasm::{ModuleInstance, Store, types}; +use tinywasm::{types, ModuleInstance, Store}; use types::{archive::AlignedVec, TinyWasmModule}; const WASM: &[u8] = include_bytes!("../../../examples/rust/out/fibonacci.opt.wasm"); diff --git a/crates/tinywasm/benches/tinywasm.rs b/crates/tinywasm/benches/tinywasm.rs index cfc9cb8..da16eb8 100644 --- a/crates/tinywasm/benches/tinywasm.rs +++ b/crates/tinywasm/benches/tinywasm.rs @@ -1,6 +1,6 @@ use criterion::{criterion_group, criterion_main, Criterion}; use eyre::Result; -use tinywasm::{Extern, FuncContext, Imports, ModuleInstance, Store, types}; +use tinywasm::{types, Extern, FuncContext, Imports, ModuleInstance, Store}; use types::{archive::AlignedVec, TinyWasmModule}; const WASM: &[u8] = include_bytes!("../../../examples/rust/out/tinywasm.opt.wasm"); diff --git a/crates/tinywasm/src/imports.rs b/crates/tinywasm/src/imports.rs index 3a226f4..36ca4e3 100644 --- a/crates/tinywasm/src/imports.rs +++ b/crates/tinywasm/src/imports.rs @@ -208,7 +208,7 @@ impl From<&Import> for ExternName { /// imports /// .define("my_module", "print_i32", print_i32)? /// .define("my_module", "table", Extern::table(table_type, table_init))? -/// .define("my_module", "memory", Extern::memory(MemoryType::new_32(1, Some(2))))? +/// .define("my_module", "memory", Extern::memory(MemoryType::new_32(1, Some(2), None)))? /// .define("my_module", "global_i32", Extern::global(WasmValue::I32(666), false))? /// .link_module("my_other_module", 0)?; /// # Ok(()) @@ -317,22 +317,20 @@ impl Imports { actual: &MemoryType, real_size: Option, ) -> Result<()> { - Self::compare_types(import, &expected.arch, &actual.arch)?; + Self::compare_types(import, &expected.arch(), &actual.arch())?; - if actual.page_count_initial > expected.page_count_initial - && real_size.map_or(true, |size| actual.page_count_initial > size as u64) + if actual.page_count_initial() > expected.page_count_initial() + && real_size.map_or(true, |size| actual.page_count_initial() > size as u64) { return Err(LinkingError::incompatible_import_type(import).into()); } - if expected.page_count_max.is_none() && actual.page_count_max.is_some() { + if expected.page_size() != actual.page_size() { return Err(LinkingError::incompatible_import_type(import).into()); } - if let (Some(expected_max), Some(actual_max)) = (expected.page_count_max, actual.page_count_max) { - if actual_max < expected_max { - return Err(LinkingError::incompatible_import_type(import).into()); - } + if expected.page_count_max() > actual.page_count_max() { + return Err(LinkingError::incompatible_import_type(import).into()); } Ok(()) diff --git a/crates/tinywasm/src/store/memory.rs b/crates/tinywasm/src/store/memory.rs index b86435d..1e5ff7c 100644 --- a/crates/tinywasm/src/store/memory.rs +++ b/crates/tinywasm/src/store/memory.rs @@ -4,10 +4,6 @@ use tinywasm_types::{MemoryType, ModuleInstanceAddr}; use crate::{cold, log, Error, Result}; -const PAGE_SIZE: usize = 65536; -const MAX_PAGES: usize = 65536; -const MAX_SIZE: u64 = PAGE_SIZE as u64 * MAX_PAGES as u64; - /// A WebAssembly Memory Instance /// /// See @@ -21,13 +17,13 @@ pub(crate) struct MemoryInstance { impl MemoryInstance { pub(crate) fn new(kind: MemoryType, owner: ModuleInstanceAddr) -> Self { - assert!(kind.page_count_initial <= kind.page_count_max.unwrap_or(MAX_PAGES as u64)); - log::debug!("initializing memory with {} pages", kind.page_count_initial); + assert!(kind.page_count_initial() <= kind.page_count_max()); + log::debug!("initializing memory with {} pages of {} bytes", kind.page_count_initial(), kind.page_size()); Self { kind, - data: vec![0; PAGE_SIZE * kind.page_count_initial as usize], - page_count: kind.page_count_initial as usize, + data: vec![0; kind.initial_size() as usize], + page_count: kind.page_count_initial() as usize, _owner: owner, } } @@ -58,7 +54,7 @@ impl MemoryInstance { } pub(crate) fn max_pages(&self) -> usize { - self.kind.page_count_max.unwrap_or(MAX_PAGES as u64) as usize + self.kind.page_count_max() as usize } pub(crate) fn load(&self, addr: usize, len: usize) -> Result<&[u8]> { @@ -133,12 +129,12 @@ impl MemoryInstance { let new_pages = current_pages as i64 + pages_delta as i64; debug_assert!(new_pages <= i32::MAX as i64, "page count should never be greater than i32::MAX"); - if new_pages < 0 || new_pages > MAX_PAGES as i64 || new_pages as usize > self.max_pages() { + if new_pages < 0 || new_pages as usize > self.max_pages() { return None; } - let new_size = new_pages as usize * PAGE_SIZE; - if new_size as u64 > MAX_SIZE { + let new_size = (new_pages as u64 * self.kind.page_size()) as usize; + if new_size as u64 > self.kind.max_size() { return None; } @@ -190,7 +186,7 @@ mod memory_instance_tests { use tinywasm_types::MemoryArch; fn create_test_memory() -> MemoryInstance { - let kind = MemoryType { arch: MemoryArch::I32, page_count_initial: 1, page_count_max: Some(2) }; + let kind = MemoryType::new(MemoryArch::I32, 1, Some(2), None); let owner = ModuleInstanceAddr::default(); MemoryInstance::new(kind, owner) } @@ -249,7 +245,7 @@ mod memory_instance_tests { #[test] fn test_memory_grow_out_of_bounds() { let mut memory = create_test_memory(); - assert!(memory.grow(MAX_PAGES as i32 + 1).is_none()); + assert!(memory.grow(memory.kind.max_size() as i32 + 1).is_none()); } #[test] @@ -258,4 +254,29 @@ mod memory_instance_tests { assert_eq!(memory.grow(1), Some(1)); assert_eq!(memory.grow(1), None); } + + #[test] + fn test_memory_custom_page_size_out_of_bounds() { + let kind = MemoryType::new(MemoryArch::I32, 1, Some(2), Some(1)); + let owner = ModuleInstanceAddr::default(); + let mut memory = MemoryInstance::new(kind, owner); + + let data_to_store = [1, 2]; + assert!(memory.store(0, data_to_store.len(), &data_to_store).is_err()); + } + + #[test] + fn test_memory_custom_page_size_grow() { + let kind = MemoryType::new(MemoryArch::I32, 1, Some(2), Some(1)); + let owner = ModuleInstanceAddr::default(); + let mut memory = MemoryInstance::new(kind, owner); + + assert_eq!(memory.grow(1), Some(1)); + + let data_to_store = [1, 2]; + assert!(memory.store(0, data_to_store.len(), &data_to_store).is_ok()); + + let loaded_data = memory.load(0, data_to_store.len()).unwrap(); + assert_eq!(loaded_data, &data_to_store); + } } diff --git a/crates/tinywasm/src/store/mod.rs b/crates/tinywasm/src/store/mod.rs index 124b7dc..d4bbf33 100644 --- a/crates/tinywasm/src/store/mod.rs +++ b/crates/tinywasm/src/store/mod.rs @@ -243,7 +243,7 @@ impl Store { let mem_count = self.data.memories.len(); let mut mem_addrs = Vec::with_capacity(mem_count); for (i, mem) in memories.into_iter().enumerate() { - if let MemoryArch::I64 = mem.arch { + if let MemoryArch::I64 = mem.arch() { return Err(Error::UnsupportedFeature("64-bit memories".to_string())); } self.data.memories.push(MemoryInstance::new(mem, idx)); @@ -405,7 +405,7 @@ impl Store { } pub(crate) fn add_mem(&mut self, mem: MemoryType, idx: ModuleInstanceAddr) -> Result { - if let MemoryArch::I64 = mem.arch { + if let MemoryArch::I64 = mem.arch() { return Err(Error::UnsupportedFeature("64-bit memories".to_string())); } self.data.memories.push(MemoryInstance::new(mem, idx)); diff --git a/crates/tinywasm/tests/generated/wasm-custom-page-sizes.csv b/crates/tinywasm/tests/generated/wasm-custom-page-sizes.csv new file mode 100644 index 0000000..f9a7914 --- /dev/null +++ b/crates/tinywasm/tests/generated/wasm-custom-page-sizes.csv @@ -0,0 +1 @@ +0.8.0,57,0,[{"name":"custom-page-sizes-invalid.wast","passed":22,"failed":0},{"name":"custom-page-sizes.wast","passed":35,"failed":0}] diff --git a/crates/tinywasm/tests/test-wasm-custom-page-sizes.rs b/crates/tinywasm/tests/test-wasm-custom-page-sizes.rs new file mode 100644 index 0000000..ab8d36e --- /dev/null +++ b/crates/tinywasm/tests/test-wasm-custom-page-sizes.rs @@ -0,0 +1,20 @@ +mod testsuite; +use eyre::{eyre, Result}; +use owo_colors::OwoColorize; +use testsuite::TestSuite; + +fn main() -> Result<()> { + let mut test_suite = TestSuite::new(); + + TestSuite::set_log_level(log::LevelFilter::Off); + test_suite.run_spec_group(wasm_testsuite::get_proposal_tests("custom-page-sizes"))?; + test_suite.save_csv("./tests/generated/wasm-custom-page-sizes.csv", env!("CARGO_PKG_VERSION"))?; + + if test_suite.failed() { + println!(); + Err(eyre!(format!("{}:\n{:#?}", "failed one or more tests".red().bold(), test_suite,))) + } else { + println!("\n\npassed all tests:\n{test_suite:#?}"); + Ok(()) + } +} diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index ca788fb..a179956 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -121,7 +121,11 @@ impl TestSuite { }); imports - .define("spectest", "memory", Extern::memory(MemoryType::new_32(1, Some(2))))? + .define( + "spectest", + "memory", + Extern::memory(MemoryType::new(tinywasm_types::MemoryArch::I32, 1, Some(2), None)), + )? .define("spectest", "table", table)? .define("spectest", "global_i32", Extern::global(WasmValue::I32(666), false))? .define("spectest", "global_i64", Extern::global(WasmValue::I64(666), false))? @@ -145,6 +149,7 @@ impl TestSuite { pub fn run_spec_group>(&mut self, tests: impl IntoIterator) -> Result<()> { tests.into_iter().for_each(|group| { + println!("running group: {}", group.as_ref()); let group = group.as_ref(); let group_wast = wasm_testsuite::get_test_wast(group).expect("failed to get test wast"); if self.1.contains(&(*group).to_string()) { diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index 94dc94d..ce0d4ac 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -12,6 +12,14 @@ extern crate alloc; use alloc::boxed::Box; use core::{fmt::Debug, ops::Range}; +// Memory defaults +const MEM_PAGE_SIZE: u64 = 65536; +const MAX_MEMORY_SIZE: u64 = 4294967296; + +const fn max_page_count(page_size: u64) -> u64 { + MAX_MEMORY_SIZE / page_size +} + // log for logging (optional). #[cfg(feature = "logging")] #[allow(clippy::single_component_path_imports, unused_imports)] @@ -252,14 +260,39 @@ impl TableType { #[derive(Debug, Copy, Clone, PartialEq)] #[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] pub struct MemoryType { - pub arch: MemoryArch, - pub page_count_initial: u64, - pub page_count_max: Option, + arch: MemoryArch, + page_count_initial: u64, + page_count_max: Option, + page_size: Option, } impl MemoryType { - pub fn new_32(page_count_initial: u64, page_count_max: Option) -> Self { - Self { arch: MemoryArch::I32, page_count_initial, page_count_max } + pub fn new(arch: MemoryArch, page_count_initial: u64, page_count_max: Option, page_size: Option) -> Self { + Self { arch, page_count_initial, page_count_max, page_size } + } + + pub fn arch(&self) -> MemoryArch { + self.arch + } + + pub fn page_count_initial(&self) -> u64 { + self.page_count_initial + } + + pub fn page_count_max(&self) -> u64 { + self.page_count_max.unwrap_or_else(|| max_page_count(self.page_size())) + } + + pub fn page_size(&self) -> u64 { + self.page_size.unwrap_or(MEM_PAGE_SIZE) + } + + pub fn initial_size(&self) -> u64 { + self.page_count_initial * self.page_size() + } + + pub fn max_size(&self) -> u64 { + self.page_count_max() * self.page_size() } } diff --git a/crates/wasm-testsuite/lib.rs b/crates/wasm-testsuite/lib.rs index 1f42664..12bf459 100644 --- a/crates/wasm-testsuite/lib.rs +++ b/crates/wasm-testsuite/lib.rs @@ -12,13 +12,18 @@ use std::borrow::Cow; #[derive(RustEmbed)] #[folder = "data/"] #[include = "*.wast"] -struct Asset; +struct OfficialTests; + +#[derive(RustEmbed)] +#[folder = "tests/"] +#[include = "*.wast"] +struct CustomTests; /// List of all supported proposals. Can be used to filter tests. /// /// Includes all proposals from #[rustfmt::skip] -pub const PROPOSALS: &[&str] = &["annotations", "exception-handling", "extended-const", "function-references", "gc", "memory64", "multi-memory", "relaxed-simd", "tail-call", "threads"]; +pub const PROPOSALS: &[&str] = &["annotations", "exception-handling", "extended-const", "function-references", "gc", "memory64", "multi-memory", "relaxed-simd", "tail-call", "threads", "custom-page-sizes"]; /// List of all tests that apply to the MVP (V1) spec /// Note that the tests are still for the latest spec, so the latest version of Wast is used. @@ -35,7 +40,7 @@ pub const SIMD_TESTS: &[&str] = &["simd_address.wast", "simd_align.wast", "simd_ /// List of all tests that apply to a specific proposal. pub fn get_proposal_tests(proposal: &str) -> impl Iterator + '_ { - Asset::iter().filter_map(move |x| { + OfficialTests::iter().chain(CustomTests::iter()).filter_map(move |x| { let mut parts = x.split('/'); if parts.next() == Some("proposals") && parts.next() == Some(proposal) { Some(format!("{}/{}", proposal, parts.next().unwrap_or_default())) @@ -50,8 +55,10 @@ pub fn get_test_wast(name: &str) -> Option> { assert!(name.ends_with(".wast"), "Expected .wast file. Got: {name}"); match name.contains('/') { - true => Asset::get(&format!("proposals/{name}")).map(|x| x.data), - false => Asset::get(name).map(|x| x.data), + true => OfficialTests::get(&format!("proposals/{name}")) + .or_else(|| CustomTests::get(&format!("proposals/{name}"))) + .map(|x| x.data), + false => OfficialTests::get(name).or_else(|| CustomTests::get(name)).map(|x| x.data), } } @@ -66,7 +73,7 @@ mod tests { let mut unique_proposals = HashSet::new(); // check that all proposals are present - for proposal in Asset::iter() { + for proposal in OfficialTests::iter() { if !proposal.starts_with("proposals/") { continue; } diff --git a/crates/wasm-testsuite/tests/proposals/custom-page-sizes/custom-page-sizes-invalid.wast b/crates/wasm-testsuite/tests/proposals/custom-page-sizes/custom-page-sizes-invalid.wast new file mode 100644 index 0000000..150f58b --- /dev/null +++ b/crates/wasm-testsuite/tests/proposals/custom-page-sizes/custom-page-sizes-invalid.wast @@ -0,0 +1,112 @@ +;; from https://github.com/WebAssembly/custom-page-sizes/blob/main/test/core/custom-page-sizes/custom-page-sizes-invalid.wast + +;; Page size that is not a power of two. +(assert_malformed + (module quote "(memory 0 (pagesize 3))") + "invalid custom page size" +) + +;; Power-of-two page sizes that are not 1 or 64KiB. +(assert_invalid + (module (memory 0 (pagesize 2))) + "invalid custom page size" +) +(assert_invalid + (module (memory 0 (pagesize 4))) + "invalid custom page size" +) +(assert_invalid + (module (memory 0 (pagesize 8))) + "invalid custom page size" +) +(assert_invalid + (module (memory 0 (pagesize 16))) + "invalid custom page size" +) +(assert_invalid + (module (memory 0 (pagesize 32))) + "invalid custom page size" +) +(assert_invalid + (module (memory 0 (pagesize 64))) + "invalid custom page size" +) +(assert_invalid + (module (memory 0 (pagesize 128))) + "invalid custom page size" +) +(assert_invalid + (module (memory 0 (pagesize 256))) + "invalid custom page size" +) +(assert_invalid + (module (memory 0 (pagesize 512))) + "invalid custom page size" +) +(assert_invalid + (module (memory 0 (pagesize 1024))) + "invalid custom page size" +) +(assert_invalid + (module (memory 0 (pagesize 2048))) + "invalid custom page size" +) +(assert_invalid + (module (memory 0 (pagesize 4096))) + "invalid custom page size" +) +(assert_invalid + (module (memory 0 (pagesize 8192))) + "invalid custom page size" +) +(assert_invalid + (module (memory 0 (pagesize 16384))) + "invalid custom page size" +) +(assert_invalid + (module (memory 0 (pagesize 32768))) + "invalid custom page size" +) + +;; Power-of-two page size that is larger than 64KiB. +(assert_invalid + (module (memory 0 (pagesize 0x20000))) + "invalid custom page size" +) + +;; Power of two page size that cannot fit in a u64 to exercise checks against +;; shift overflow. +(assert_malformed + (module binary + "\00asm" "\01\00\00\00" + "\05\04\01" ;; Memory section + + ;; memory 0 + "\08" ;; flags w/ custom page size + "\00" ;; minimum = 0 + "\41" ;; pagesize = 2**65 + ) + "invalid custom page size" +) + +;; Importing a memory with the wrong page size. + +(module $m + (memory (export "small-pages-memory") 0 (pagesize 1)) + (memory (export "large-pages-memory") 0 (pagesize 65536)) +) +(register "m" $m) + +(assert_unlinkable + (module + (memory (import "m" "small-pages-memory") 0 (pagesize 65536)) + ) + "incompatible import type" +) + +(assert_unlinkable + (module + (memory (import "m" "large-pages-memory") 0 (pagesize 1)) + ) + "incompatible import type" +) diff --git a/crates/wasm-testsuite/tests/proposals/custom-page-sizes/custom-page-sizes.wast b/crates/wasm-testsuite/tests/proposals/custom-page-sizes/custom-page-sizes.wast new file mode 100644 index 0000000..f59d52b --- /dev/null +++ b/crates/wasm-testsuite/tests/proposals/custom-page-sizes/custom-page-sizes.wast @@ -0,0 +1,110 @@ +;; from https://github.com/WebAssembly/custom-page-sizes/blob/main/test/core/custom-page-sizes/custom-page-sizes.wast + +;; Check all the valid custom page sizes. +(module (memory 1 (pagesize 1))) +(module (memory 1 (pagesize 65536))) + +;; Check them all again with maximums specified. +(module (memory 1 2 (pagesize 1))) +(module (memory 1 2 (pagesize 65536))) + +;; Check the behavior of memories with page size 1. +(module + (memory 0 (pagesize 1)) + (func (export "size") (result i32) + memory.size + ) + (func (export "grow") (param i32) (result i32) + (memory.grow (local.get 0)) + ) + (func (export "load") (param i32) (result i32) + (i32.load8_u (local.get 0)) + ) + (func (export "store") (param i32 i32) + (i32.store8 (local.get 0) (local.get 1)) + ) +) + +(assert_return (invoke "size") (i32.const 0)) +(assert_trap (invoke "load" (i32.const 0)) "out of bounds memory access") + +(assert_return (invoke "grow" (i32.const 65536)) (i32.const 0)) +(assert_return (invoke "size") (i32.const 65536)) +(assert_return (invoke "load" (i32.const 65535)) (i32.const 0)) +(assert_return (invoke "store" (i32.const 65535) (i32.const 1))) +(assert_return (invoke "load" (i32.const 65535)) (i32.const 1)) +(assert_trap (invoke "load" (i32.const 65536)) "out of bounds memory access") + +(assert_return (invoke "grow" (i32.const 65536)) (i32.const 65536)) +(assert_return (invoke "size") (i32.const 131072)) +(assert_return (invoke "load" (i32.const 131071)) (i32.const 0)) +(assert_return (invoke "store" (i32.const 131071) (i32.const 1))) +(assert_return (invoke "load" (i32.const 131071)) (i32.const 1)) +(assert_trap (invoke "load" (i32.const 131072)) "out of bounds memory access") + +;; Although smaller page sizes let us get to memories larger than 2**16 pages, +;; we can't do that with the default page size, even if we explicitly state it +;; as a custom page size. +(module + (memory 0 (pagesize 65536)) + (func (export "size") (result i32) + memory.size + ) + (func (export "grow") (param i32) (result i32) + (memory.grow (local.get 0)) + ) +) +(assert_return (invoke "size") (i32.const 0)) +(assert_return (invoke "grow" (i32.const 65537)) (i32.const -1)) +(assert_return (invoke "size") (i32.const 0)) + +;; Can copy between memories of different page sizes. +(module + (memory $small 10 (pagesize 1)) + (memory $large 1 (pagesize 65536)) + + (data (memory $small) (i32.const 0) "\11\22\33\44") + (data (memory $large) (i32.const 0) "\55\66\77\88") + + (func (export "copy-small-to-large") (param i32 i32 i32) + (memory.copy $large $small (local.get 0) (local.get 1) (local.get 2)) + ) + + (func (export "copy-large-to-small") (param i32 i32 i32) + (memory.copy $small $large (local.get 0) (local.get 1) (local.get 2)) + ) + + (func (export "load8-small") (param i32) (result i32) + (i32.load8_u $small (local.get 0)) + ) + + (func (export "load8-large") (param i32) (result i32) + (i32.load8_u $large (local.get 0)) + ) +) + +(assert_return (invoke "copy-small-to-large" (i32.const 6) (i32.const 0) (i32.const 2))) +(assert_return (invoke "load8-large" (i32.const 6)) (i32.const 0x11)) +(assert_return (invoke "load8-large" (i32.const 7)) (i32.const 0x22)) + +(assert_return (invoke "copy-large-to-small" (i32.const 4) (i32.const 1) (i32.const 3))) +(assert_return (invoke "load8-small" (i32.const 4)) (i32.const 0x66)) +(assert_return (invoke "load8-small" (i32.const 5)) (i32.const 0x77)) +(assert_return (invoke "load8-small" (i32.const 6)) (i32.const 0x88)) + +;; Can link together modules that export and import memories with custom page +;; sizes. + +(module $m + (memory (export "small-pages-memory") 0 (pagesize 1)) + (memory (export "large-pages-memory") 0 (pagesize 65536)) +) +(register "m" $m) + +(module + (memory (import "m" "small-pages-memory") 0 (pagesize 1)) +) + +(module + (memory (import "m" "large-pages-memory") 0 (pagesize 65536)) +) From 34ea51ad9ccedbec3c3371104ff4240de84abdc5 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Tue, 10 Sep 2024 00:21:16 +0200 Subject: [PATCH 06/54] ci: fix github action Signed-off-by: Henry Gressmann --- .github/workflows/test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index f93c5a4..c1640e0 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -2,9 +2,9 @@ name: Rust CI on: push: - branches: [main] + branches: ["**"] pull_request: - branches: [main] + branches: ["next", "main"] jobs: build-wasm: From 58fe7ce65d7a43bc05e0f3036fcfb15a33c50cbc Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Tue, 10 Sep 2024 00:26:55 +0200 Subject: [PATCH 07/54] docs: update changelog/contributing Signed-off-by: Henry Gressmann --- .cargo/config.toml | 2 -- CHANGELOG.md | 13 ++++++++++--- CONTRIBUTING.md | 24 +++--------------------- 3 files changed, 13 insertions(+), 26 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index e25dc35..fc2d7f9 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,7 +1,5 @@ [alias] version-dev="workspaces version --no-git-commit --force tinywasm*" -dev="run -- -l debug run" - test-wasm-1="test --package tinywasm --test test-wasm-1 --release" test-wasm-2="test --package tinywasm --test test-wasm-2 --release" test-wast="test --package tinywasm --test test-wast" diff --git a/CHANGELOG.md b/CHANGELOG.md index b9b18b9..16b7533 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,18 +5,25 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - +## [Unreleased] + +### Added + +- Support for the custom memory page sizes proposal ([#22](https://github.com/explodingcamera/tinywasm/pull/22) by [@danielstuart14](https://github.com/danielstuart14)) ## [0.8.0] - 2024-08-29 **All Commits**: https://github.com/explodingcamera/tinywasm/compare/v0.7.0...v0.8.0 -### Changed +### Added - Full support for Multi-Memory proposal +- Improved support for WebAssembly 2.0 features + +### Changed + - Extern tables now correctly update their type after growing - Increased MSRV to 1.80.0 -- Improved support for WebAssembly 2.0 features - Simplify and optimize the interpreter loop - Use a seperate stack and locals for 32, 64 and 128 bit values and references (#21) - Updated to latest `wasmparser` version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e1ca837..933b19f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,29 +2,11 @@ > To improve the development experience, a number of custom commands and aliases have been added to the `.cargo/config.toml` file. These can be run using `cargo `. -- **`cargo dev [args]`**\ - e.g. `cargo dev -f check ./examples/wasm/call.wat -a i32:0`\ - Run the development version of the tinywasm-cli. This is the main command used for developing new features.\ - See [tinywasm-cli](./crates/cli) for more information. - -- **`cargo test-mvp`**\ +- **`cargo test-wasm-1`**\ Run the WebAssembly MVP (1.0) test suite. Be sure to cloned this repo with `--recursive` or initialize the submodules with `git submodule update --init --recursive` -- **`cargo test-2`**\ +- **`cargo test-wasm-2`**\ Run the full WebAssembly test suite (2.0) - **`cargo test-wast `**\ - Run a single WAST test file. e.g. `cargo test-wast ./examples/wast/i32.wast` - -- **`cargo version-dev`**\ - Bump the version to the next dev version. This should be used after a release so test results are not overwritten. Does not create a new github release. - -## Workspace Commands - -> These commands require the [cargo-workspaces](https://crates.io/crates/cargo-workspaces) crate to be installed. - -- **`cargo workspaces version`**\ - Bump the version of all crates in the workspace and push changes to git. This is used for releasing new versions on github. - -- **`cargo workspaces publish --publish-as-is`**\ - Publish all crates in the workspace to crates.io. This should be used a new version has been released on github. After publishing, the version should be bumped to the next dev version. + Run a single WAST test file. e.g. `cargo test-wast ./examples/wast/i32.wast`. Useful for debugging failing test-cases. From 4238c920b22136e35eff3c91e3a940dbbc553702 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Tue, 10 Sep 2024 00:28:46 +0200 Subject: [PATCH 08/54] fix: doc tests Signed-off-by: Henry Gressmann --- crates/tinywasm/src/imports.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/tinywasm/src/imports.rs b/crates/tinywasm/src/imports.rs index 36ca4e3..7cc5bbb 100644 --- a/crates/tinywasm/src/imports.rs +++ b/crates/tinywasm/src/imports.rs @@ -192,7 +192,7 @@ impl From<&Import> for ExternName { /// # use log; /// # fn main() -> tinywasm::Result<()> { /// use tinywasm::{Imports, Extern}; -/// use tinywasm::types::{ValType, TableType, MemoryType, WasmValue}; +/// use tinywasm::types::{ValType, TableType, MemoryType, MemoryArch, WasmValue}; /// let mut imports = Imports::new(); /// /// // function args can be either a single @@ -208,7 +208,7 @@ impl From<&Import> for ExternName { /// imports /// .define("my_module", "print_i32", print_i32)? /// .define("my_module", "table", Extern::table(table_type, table_init))? -/// .define("my_module", "memory", Extern::memory(MemoryType::new_32(1, Some(2), None)))? +/// .define("my_module", "memory", Extern::memory(MemoryType::new(MemoryArch::I32, 1, Some(2), None)))? /// .define("my_module", "global_i32", Extern::global(WasmValue::I32(666), false))? /// .link_module("my_other_module", 0)?; /// # Ok(()) From fee68d05ba85be2a358c48697bdeba2bc360b9c6 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Wed, 11 Sep 2024 21:56:15 +0200 Subject: [PATCH 09/54] chore: update deps, improve contributing guidelines, improve ci Signed-off-by: Henry Gressmann --- .github/workflows/test.yaml | 159 ++++-------- CONTRIBUTING.md | 73 +++++- Cargo.lock | 231 ++++++------------ Cargo.toml | 8 +- crates/parser/Cargo.toml | 3 +- crates/tinywasm/Cargo.toml | 21 +- .../tests/generated/wasm-annotations.csv | 2 +- .../tests/generated/wasm-multi-memory.csv | 2 +- .../tinywasm/tests/test-wasm-annotations.rs | 1 + .../tinywasm/tests/test-wasm-multi-memory.rs | 1 + crates/tinywasm/tests/testsuite/run.rs | 2 +- crates/types/Cargo.toml | 5 +- crates/types/src/archive.rs | 49 ++-- crates/types/src/instructions.rs | 6 +- crates/types/src/lib.rs | 38 +-- crates/types/src/value.rs | 2 +- examples/rust/Cargo.toml | 2 +- examples/rust/build.sh | 7 +- 18 files changed, 271 insertions(+), 341 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index c1640e0..47708fb 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -24,132 +24,73 @@ jobs: name: wasm path: examples/rust/out - test-std: + run-tests: needs: build-wasm - name: Test with default features on stable Rust - runs-on: ubuntu-latest - + strategy: + matrix: + include: + - os: ubuntu-latest + rust: stable + name: "Linux (stable)" + - os: ubuntu-latest + rust: nightly + name: "Linux (nightly)" + - os: ubuntu-latest + rust: stable + name: "Linux (stable, no default features)" + args: "--no-default-features" + - os: ubuntu-latest + rust: nightly + name: "Linux (nightly, no default features)" + args: "--no-default-features" + - os: macos-14 + rust: stable + name: "macOS arm64 (Apple M1)" + - os: ubuntu-latest + rust: stable + name: "armv7 (32-Bit Raspberry Pi)" + target: armv7-unknown-linux-gnueabihf + + runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: submodules: true - - name: Install latest stable Rust toolchain - run: rustup update stable - - - name: Load wasm - uses: actions/download-artifact@v4 - with: - name: wasm - path: examples/rust/out - - - name: Build (stable) - run: cargo +stable build --workspace - - - name: Run tests (stable) - run: cargo +stable test --workspace && cargo +stable run --example wasm-rust all - - - name: Run MVP testsuite - run: cargo +stable test-wasm-1 - - - name: Run 2.0 testsuite - run: cargo +stable test-wasm-2 - - test-no-std: - needs: build-wasm - name: Test without default features on nightly Rust - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 + - name: Install Rust toolchain + uses: actions-rust-lang/setup-rust-toolchain@v1 with: - submodules: true - - - name: Install latest nightly Rust toolchain - run: rustup update nightly + toolchain: ${{ matrix.rust }} + rustflags: "" + components: rustfmt, clippy + if: matrix.target == '' - name: Load wasm uses: actions/download-artifact@v4 with: name: wasm - path: examples/rust/out - - - name: Build (nightly, no default features) - run: cargo +nightly build --workspace --no-default-features - - name: Run tests (nightly, no default features) - run: cargo +nightly test --workspace --no-default-features && cargo +nightly run --example wasm-rust all + - name: Run tests + run: cargo test --workspace ${{ matrix.args }} && cargo run --example wasm-rust all + if: matrix.target == '' - - name: Run MVP testsuite - run: cargo +nightly test-wasm-1 - - - name: Run 2.0 testsuite - run: cargo +nightly test-wasm-2 - - test-m1: - needs: build-wasm - name: Test on arm64 (Apple M1) - runs-on: macos-14 - steps: - - uses: actions/checkout@v4 - with: - submodules: true - - name: Install stable Rust toolchain - run: rustup update stable + - name: Run clippy + run: cargo clippy --workspace --all-targets --all-features + if: matrix.target == '' - - name: Load wasm - uses: actions/download-artifact@v4 - with: - name: wasm - path: examples/rust/out - - - name: Build (stable) - run: cargo +stable build - - - name: Run tests (stable) - run: cargo +stable test - - - name: Run MVP testsuite - run: cargo +stable test-wasm-1 - - - name: Run 2.0 testsuite - run: cargo +stable test-wasm-2 - - test-armv7: - needs: build-wasm - name: Test on armv7 (32-Bit Raspberry Pi) - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - with: - submodules: true - - - name: Load wasm - uses: actions/download-artifact@v4 - with: - name: wasm - path: examples/rust/out - - - name: Run all tests (for the default workspace members) + - name: Run tests (${{ matrix.target }}) uses: houseabsolute/actions-rust-cross@v0.0.13 with: command: test - target: armv7-unknown-linux-gnueabihf - toolchain: nightly + target: ${{ matrix.target }} + toolchain: ${{ matrix.rust }} + if: matrix.target != '' - - name: Run MVP testsuite + - name: Run clippy (${{ matrix.target }}) uses: houseabsolute/actions-rust-cross@v0.0.13 with: - command: test - args: "-p tinywasm --test test-wasm-1 --release" - target: armv7-unknown-linux-gnueabihf - toolchain: nightly - - - name: Run 2.0 testsuite - uses: houseabsolute/actions-rust-cross@v0.0.13 - with: - command: test - args: "-p tinywasm --test test-wasm-2 --release" - target: armv7-unknown-linux-gnueabihf - toolchain: nightly + command: clippy + target: ${{ matrix.target }} + toolchain: ${{ matrix.rust }} + if: matrix.target != '' diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 933b19f..a0eb744 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,12 +1,69 @@ -# Scripts and Commands +# Contributing -> To improve the development experience, a number of custom commands and aliases have been added to the `.cargo/config.toml` file. These can be run using `cargo `. +Thank you for considering contributing to this project! This document outlines the process for contributing to this project. For small changes or bug fixes, feel free to open a pull request directly. For larger changes, please open an issue first to discuss the proposed changes. Also, please ensure that you open up your pull request against the `next` branch and [allow maintainers of the project to edit your code](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork). -- **`cargo test-wasm-1`**\ - Run the WebAssembly MVP (1.0) test suite. Be sure to cloned this repo with `--recursive` or initialize the submodules with `git submodule update --init --recursive` +## 1. Clone the Repository -- **`cargo test-wasm-2`**\ - Run the full WebAssembly test suite (2.0) +Ensure you clone this repository with the `--recursive` flag to include the submodules: -- **`cargo test-wast `**\ - Run a single WAST test file. e.g. `cargo test-wast ./examples/wast/i32.wast`. Useful for debugging failing test-cases. +```bash +git clone --recursive https://github.com/explodingcamera/tinywasm.git +``` + +If you have already cloned the repository, you can initialize the submodules with: + +```bash +git submodule update --init --recursive +``` + +This is required to run the WebAssembly test suite. + +## 2. Set up the Development Environment + +This project mostly uses a pretty standard Rust setup. Some common tasks: + +```bash +# Run a specific benchmark (run without arguments to see available benchmarks) +$ cargo bench --bench {bench_name} + +# Run all tests +$ cargo test + +# Run only the WebAssembly MVP (1.0) test suite +$ cargo test-wasm-1 + +# Run only the full WebAssembly test suite (2.0) +$ cargo test-wasm-2 + +# Run a specific test (run without arguments to see available tests) +$ cargo test --test {test_name} + +# Run a single WAST test file +$ cargo test-wast {path} + +# Run a specific example (run without arguments to see available examples) +# The wasm test files required to run the `wasm-rust` examples are not +# included in the main repository. +# To build these, you will need to run `./examples/rust/build.sh`. +$ cargo run --example {example_name} +``` + +### Profiling + +Either [samply](https://github.com/mstange/samply/) or [cargo-flamegraph](https://github.com/flamegraph-rs/flamegraph) are recommended for profiling. + +Example usage: + +```bash +cargo install --locked samply +cargo samply --example wasm-rust -- selfhosted +``` + +# Commits + +This project uses [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) for commit messages. For pull requests, the commit messages will be squashed so you don't need to worry about this too much. However, it is still recommended to follow this convention for consistency. + +# Branches + +- `main`: The main branch. This branch is used for the latest stable release. +- `next`: The next branch. Development happens here. diff --git a/Cargo.lock b/Cargo.lock index c8bc86c..695bde4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,17 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - [[package]] name = "ahash" version = "0.8.11" @@ -65,7 +54,7 @@ dependencies = [ "argh_shared", "proc-macro2", "quote", - "syn 2.0.77", + "syn", ] [[package]] @@ -89,18 +78,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - [[package]] name = "block-buffer" version = "0.10.4" @@ -128,46 +105,25 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytecheck" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" -dependencies = [ - "bytecheck_derive 0.6.12", - "ptr_meta", - "simdutf8", -] - -[[package]] -name = "bytecheck" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41502630fe304ce54cbb2f8389e017784dee2b0328147779fcbe43b9db06d35d" +checksum = "50c8f430744b23b54ad15161fcbc22d82a29b73eacbe425fea23ec822600bc6f" dependencies = [ - "bytecheck_derive 0.7.0", + "bytecheck_derive", "ptr_meta", + "rancor", "simdutf8", ] [[package]] name = "bytecheck_derive" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "bytecheck_derive" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eda88c587085bc07dc201ab9df871bd9baa5e07f7754b745e4d7194b43ac1eda" +checksum = "523363cbe1df49b68215efdf500b103ac3b0fb4836aed6d15689a076eadb8fff" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -370,12 +326,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - [[package]] name = "generic-array" version = "0.14.7" @@ -386,22 +336,11 @@ dependencies = [ "version_check", ] -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - [[package]] name = "globset" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" dependencies = [ "aho-corasick", "bstr", @@ -420,22 +359,13 @@ dependencies = [ "crunchy", ] -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash 0.7.8", -] - [[package]] name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "ahash 0.8.11", + "ahash", ] [[package]] @@ -463,7 +393,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown", ] [[package]] @@ -522,6 +452,26 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "munge" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64142d38c84badf60abf06ff9bd80ad2174306a5b11bd4706535090a30a419df" +dependencies = [ + "munge_macro", +] + +[[package]] +name = "munge_macro" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bb5c1d8184f13f7d0ccbeeca0def2f9a181bce2624302793005f5ca8aa62e5e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -545,9 +495,9 @@ checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "owo-colors" -version = "4.0.0" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caff54706df99d2a78a5a4e3455ff45448d81ef1bb63c22cd14052ca0e993a3f" +checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" [[package]] name = "pretty_env_logger" @@ -570,22 +520,22 @@ dependencies = [ [[package]] name = "ptr_meta" -version = "0.1.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +checksum = "fe9e76f66d3f9606f44e45598d155cb13ecf09f4a28199e48daf8c8fc937ea90" dependencies = [ "ptr_meta_derive", ] [[package]] name = "ptr_meta_derive" -version = "0.1.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +checksum = "ca414edb151b4c8d125c12566ab0d74dc9cdba36fb80eb7b848c15f495fd32d1" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -598,10 +548,13 @@ dependencies = [ ] [[package]] -name = "radium" -version = "0.7.0" +name = "rancor" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +checksum = "caf5f7161924b9d1cea0e4cabc97c372cea92b5f927fc13c6bca67157a0ad947" +dependencies = [ + "ptr_meta", +] [[package]] name = "rayon" @@ -654,40 +607,41 @@ checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "rend" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" +checksum = "bc8d57aa48e8477046d7d6296d920a1f50bbbaf45047ec46c52f6d6cccea7ef7" dependencies = [ - "bytecheck 0.6.12", + "bytecheck", ] [[package]] name = "rkyv" -version = "0.7.45" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" +checksum = "6d7fa2297190bd08087add407c3dedf28eb3be1d75955ffbd3bc312834325760" dependencies = [ - "bitvec", - "bytecheck 0.6.12", + "bytecheck", "bytes", - "hashbrown 0.12.3", + "hashbrown", + "indexmap", + "munge", "ptr_meta", + "rancor", "rend", "rkyv_derive", - "seahash", "tinyvec", "uuid", ] [[package]] name = "rkyv_derive" -version = "0.7.45" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" +checksum = "4aad510db4f88722adf0e4586ff0dedfca4af57b17c075b2420bac1db446d22c" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -710,7 +664,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.77", + "syn", "walkdir", ] @@ -740,12 +694,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "seahash" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" - [[package]] name = "semver" version = "1.0.23" @@ -769,7 +717,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn", ] [[package]] @@ -801,17 +749,6 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.77" @@ -823,12 +760,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - [[package]] name = "termcolor" version = "1.4.1" @@ -916,7 +847,6 @@ dependencies = [ name = "tinywasm-types" version = "0.8.0" dependencies = [ - "bytecheck 0.7.0", "log", "rkyv", ] @@ -929,9 +859,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-width" @@ -961,17 +891,11 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - [[package]] name = "wasm-encoder" -version = "0.216.0" +version = "0.217.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04c23aebea22c8a75833ae08ed31ccc020835b12a41999e58c31464271b94a88" +checksum = "7b88b0814c9a2b323a9b46c687e726996c255ac8b64aa237dd11c81ed4854760" dependencies = [ "leb128", ] @@ -985,22 +909,22 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.216.0" +version = "0.217.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcdee6bea3619d311fb4b299721e89a986c3470f804b6d534340e412589028e3" +checksum = "ca917a21307d3adf2b9857b94dd05ebf8496bdcff4437a9b9fb3899d3e6c74e7" dependencies = [ - "ahash 0.8.11", + "ahash", "bitflags", - "hashbrown 0.14.5", + "hashbrown", "indexmap", "semver", ] [[package]] name = "wast" -version = "216.0.0" +version = "217.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7eb1f2eecd913fdde0dc6c3439d0f24530a98ac6db6cb3d14d92a5328554a08" +checksum = "79004ecebded92d3c710d4841383368c7f04b63d0992ddd6b0c7d5029b7629b7" dependencies = [ "bumpalo", "leb128", @@ -1011,9 +935,9 @@ dependencies = [ [[package]] name = "wat" -version = "1.216.0" +version = "1.217.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac0409090fb5154f95fb5ba3235675fd9e579e731524d63b6a2f653e1280c82a" +checksum = "c126271c3d92ca0f7c63e4e462e40c69cca52fd4245fcda730d1cf558fb55088" dependencies = [ "wast", ] @@ -1109,15 +1033,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - [[package]] name = "zerocopy" version = "0.7.35" @@ -1135,5 +1050,5 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn", ] diff --git a/Cargo.toml b/Cargo.toml index 7196533..ae231c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,8 +4,8 @@ default-members=[".", "crates/tinywasm", "crates/types", "crates/parser"] resolver="2" [workspace.dependencies] -wast="216" -wat="1.216" +wast="217" +wat="1.217" eyre="0.6" log="0.4" pretty_env_logger="0.5" @@ -51,3 +51,7 @@ lto="thin" codegen-units=1 panic="abort" inherits="release" + +[profile.samply] +inherits = "release" +debug = true diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index efb0817..fa16664 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -9,7 +9,7 @@ repository.workspace=true rust-version.workspace=true [dependencies] -wasmparser={version="0.216", default-features=false, features=["validate"]} +wasmparser={version="0.217", default-features=false, features=["validate", "features"]} log={workspace=true, optional=true} tinywasm-types={version="0.8.0-alpha.0", path="../types", default-features=false} @@ -17,4 +17,3 @@ tinywasm-types={version="0.8.0-alpha.0", path="../types", default-features=false default=["std", "logging"] logging=["log"] std=["tinywasm-types/std", "wasmparser/std"] -nightly=[] diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index ebe7ffd..264d4b9 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -33,49 +33,42 @@ serde={version="1.0", features=["derive"]} default=["std", "parser", "logging", "archive"] logging=["log", "tinywasm-parser?/logging", "tinywasm-types/logging"] std=["tinywasm-parser?/std", "tinywasm-types/std"] -parser=["tinywasm-parser"] +parser=["dep:tinywasm-parser"] archive=["tinywasm-types/archive"] -simd=[] -nightly=["tinywasm-parser?/nightly"] +nightly=[] [[test]] name="test-wasm-1" harness=false -test=false [[test]] name="test-wasm-2" harness=false -test=false [[test]] name="test-wasm-multi-memory" harness=false -test=false [[test]] -name="test-wasm-memory64" +name="test-wasm-annotations" harness=false -test=false [[test]] -name="test-wasm-annotations" +name="test-wasm-custom-page-sizes" harness=false -test=false [[test]] -name="test-wasm-extended-const" +name="test-wasm-memory64" harness=false test=false [[test]] -name="test-wasm-simd" +name="test-wasm-extended-const" harness=false test=false - [[test]] -name="test-wasm-custom-page-sizes" +name="test-wasm-simd" harness=false test=false diff --git a/crates/tinywasm/tests/generated/wasm-annotations.csv b/crates/tinywasm/tests/generated/wasm-annotations.csv index 582bc1b..1e66217 100644 --- a/crates/tinywasm/tests/generated/wasm-annotations.csv +++ b/crates/tinywasm/tests/generated/wasm-annotations.csv @@ -1 +1 @@ -0.8.0,331,286,[{"name":"annotations.wast","passed":74,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"simd_lane.wast","passed":189,"failed":286},{"name":"token.wast","passed":61,"failed":0}] +0.8.0,142,0,[{"name":"annotations.wast","passed":74,"failed":0},{"name":"annotations/simd_lane.wast (skipped)","passed":0,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"token.wast","passed":61,"failed":0}] diff --git a/crates/tinywasm/tests/generated/wasm-multi-memory.csv b/crates/tinywasm/tests/generated/wasm-multi-memory.csv index e4c4533..b730f97 100644 --- a/crates/tinywasm/tests/generated/wasm-multi-memory.csv +++ b/crates/tinywasm/tests/generated/wasm-multi-memory.csv @@ -1 +1 @@ -0.8.0,1870,1,[{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"align.wast","passed":160,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"binary.wast","passed":124,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"imports.wast","passed":175,"failed":0},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"simd_memory-multi.wast","passed":0,"failed":1},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"traps0.wast","passed":15,"failed":0}] +0.8.0,1870,0,[{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"align.wast","passed":160,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"binary.wast","passed":124,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"imports.wast","passed":175,"failed":0},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"multi-memory/simd_memory-multi.wast (skipped)","passed":0,"failed":0},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"traps0.wast","passed":15,"failed":0}] diff --git a/crates/tinywasm/tests/test-wasm-annotations.rs b/crates/tinywasm/tests/test-wasm-annotations.rs index fa40467..c521156 100644 --- a/crates/tinywasm/tests/test-wasm-annotations.rs +++ b/crates/tinywasm/tests/test-wasm-annotations.rs @@ -7,6 +7,7 @@ fn main() -> Result<()> { let mut test_suite = TestSuite::new(); TestSuite::set_log_level(log::LevelFilter::Off); + test_suite.skip("annotations/simd_lane.wast"); test_suite.run_spec_group(wasm_testsuite::get_proposal_tests("annotations"))?; test_suite.save_csv("./tests/generated/wasm-annotations.csv", env!("CARGO_PKG_VERSION"))?; diff --git a/crates/tinywasm/tests/test-wasm-multi-memory.rs b/crates/tinywasm/tests/test-wasm-multi-memory.rs index 2cee13d..9b1f8b7 100644 --- a/crates/tinywasm/tests/test-wasm-multi-memory.rs +++ b/crates/tinywasm/tests/test-wasm-multi-memory.rs @@ -7,6 +7,7 @@ fn main() -> Result<()> { let mut test_suite = TestSuite::new(); TestSuite::set_log_level(log::LevelFilter::Off); + test_suite.skip("multi-memory/simd_memory-multi.wast"); test_suite.run_spec_group(wasm_testsuite::get_proposal_tests("multi-memory"))?; test_suite.save_csv("./tests/generated/wasm-multi-memory.csv", env!("CARGO_PKG_VERSION"))?; diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index a179956..ac11eda 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -184,7 +184,7 @@ impl TestSuite { let span = directive.span(); use wast::WastDirective::{ AssertExhaustion, AssertInvalid, AssertMalformed, AssertReturn, AssertTrap, AssertUnlinkable, Invoke, - Register, Wat, + Module as Wat, Register, }; match directive { diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index b643964..7531ab4 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -10,11 +10,10 @@ rust-version.workspace=true [dependencies] log={workspace=true, optional=true} -rkyv={version="0.7", optional=true, default-features=false, features=["size_32", "validation"]} -bytecheck={version="0.7", optional=true} +rkyv={version="0.8.0-rc.2", optional=true, default-features=false, features=["alloc", "bytecheck"]} [features] default=["std", "logging", "archive"] std=["rkyv?/std"] -archive=["dep:rkyv", "dep:bytecheck"] +archive=["dep:rkyv"] logging=["dep:log"] diff --git a/crates/types/src/archive.rs b/crates/types/src/archive.rs index cce0501..cc60314 100644 --- a/crates/types/src/archive.rs +++ b/crates/types/src/archive.rs @@ -2,17 +2,19 @@ use core::fmt::{Display, Formatter}; use crate::TinyWasmModule; use rkyv::{ - check_archived_root, - ser::{serializers::AllocSerializer, Serializer}, - Deserialize, + access, + api::high::to_bytes_in_with_alloc, + deserialize, + ser::{allocator::Arena, WriterExt}, + Archived, }; const TWASM_MAGIC_PREFIX: &[u8; 4] = b"TWAS"; -const TWASM_VERSION: &[u8; 2] = b"01"; +const TWASM_VERSION: &[u8; 2] = b"02"; #[rustfmt::skip] const TWASM_MAGIC: [u8; 16] = [ TWASM_MAGIC_PREFIX[0], TWASM_MAGIC_PREFIX[1], TWASM_MAGIC_PREFIX[2], TWASM_MAGIC_PREFIX[3], TWASM_VERSION[0], TWASM_VERSION[1], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; -pub use rkyv::AlignedVec; +pub use rkyv::util::AlignedVec; fn validate_magic(wasm: &[u8]) -> Result { if wasm.len() < TWASM_MAGIC.len() || &wasm[..TWASM_MAGIC_PREFIX.len()] != TWASM_MAGIC_PREFIX { @@ -28,7 +30,7 @@ fn validate_magic(wasm: &[u8]) -> Result { Ok(TWASM_MAGIC.len()) } -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum TwasmError { InvalidMagic, InvalidVersion, @@ -56,20 +58,21 @@ impl TinyWasmModule { /// Creates a `TinyWasmModule` from a slice of bytes. pub fn from_twasm(wasm: &[u8]) -> Result { let len = validate_magic(wasm)?; - let root = check_archived_root::(&wasm[len..]).map_err(|_e| TwasmError::InvalidArchive)?; - Ok(root.deserialize(&mut rkyv::Infallible).unwrap()) + let root = + access::, rkyv::rancor::Error>(&wasm[len..]).map_err(|_| TwasmError::InvalidArchive)?; + deserialize::(root).map_err(|_e| TwasmError::InvalidArchive) } /// Serializes the `TinyWasmModule` into a vector of bytes. /// `AlignedVec` can be deferenced as a slice of bytes and /// implements `io::Write` when the `std` feature is enabled. - pub fn serialize_twasm(&self) -> rkyv::AlignedVec { - let mut serializer = AllocSerializer::<0>::default(); - serializer.pad(TWASM_MAGIC.len()).unwrap(); - serializer.serialize_value(self).unwrap(); - let mut out = serializer.into_serializer().into_inner(); - out[..TWASM_MAGIC.len()].copy_from_slice(&TWASM_MAGIC); - out + pub fn serialize_twasm(&self) -> AlignedVec { + let mut arena = Arena::new(); + let mut bytes = AlignedVec::new(); + >::pad(&mut bytes, TWASM_MAGIC.len()).unwrap(); + let mut bytes = to_bytes_in_with_alloc::<_, _, rkyv::rancor::Error>(self, bytes, arena.acquire()).unwrap(); + bytes[..TWASM_MAGIC.len()].copy_from_slice(&TWASM_MAGIC); + bytes } } @@ -84,4 +87,20 @@ mod tests { let wasm2 = TinyWasmModule::from_twasm(&twasm).unwrap(); assert_eq!(wasm, wasm2); } + + #[test] + fn test_invalid_magic() { + let wasm = TinyWasmModule::default(); + let mut twasm = wasm.serialize_twasm(); + twasm[0] = 0; + assert_eq!(TinyWasmModule::from_twasm(&twasm), Err(TwasmError::InvalidMagic)); + } + + #[test] + fn test_invalid_version() { + let wasm = TinyWasmModule::default(); + let mut twasm = wasm.serialize_twasm(); + twasm[4] = 0; + assert_eq!(TinyWasmModule::from_twasm(&twasm), Err(TwasmError::InvalidVersion)); + } } diff --git a/crates/types/src/instructions.rs b/crates/types/src/instructions.rs index d77d66d..2030942 100644 --- a/crates/types/src/instructions.rs +++ b/crates/types/src/instructions.rs @@ -3,7 +3,7 @@ use crate::{DataAddr, ElemAddr, MemAddr}; /// Represents a memory immediate in a WebAssembly memory instruction. #[derive(Debug, Copy, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub struct MemoryArg { pub offset: u64, pub mem_addr: MemAddr, @@ -15,7 +15,7 @@ type EndOffset = u32; type ElseOffset = u32; #[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub enum ConstInstruction { I32Const(i32), I64Const(i64), @@ -38,7 +38,7 @@ pub enum ConstInstruction { /// /// See #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] // should be kept as small as possible (16 bytes max) #[rustfmt::skip] pub enum Instruction { diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index ce0d4ac..8ee044f 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -51,7 +51,7 @@ pub mod archive; /// `TinyWasmModules` are validated before being created, so they are guaranteed to be valid (as long as they were created by `TinyWasm`). /// This means you should not trust a `TinyWasmModule` created by a third party to be valid. #[derive(Debug, Clone, Default, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub struct TinyWasmModule { /// Optional address of the start function /// @@ -108,7 +108,7 @@ pub struct TinyWasmModule { /// /// See #[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub enum ExternalKind { /// A WebAssembly Function. Func, @@ -179,14 +179,14 @@ impl ExternVal { /// /// See #[derive(Debug, Clone, PartialEq, Default)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub struct FuncType { pub params: Box<[ValType]>, pub results: Box<[ValType]>, } #[derive(Debug, Default, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub struct ValueCounts { pub c32: u32, pub c64: u32, @@ -195,7 +195,7 @@ pub struct ValueCounts { } #[derive(Debug, Default, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub struct ValueCountsSmall { pub c32: u16, pub c64: u16, @@ -204,7 +204,7 @@ pub struct ValueCountsSmall { } #[derive(Debug, Clone, PartialEq, Default)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub struct WasmFunction { pub instructions: Box<[Instruction]>, pub locals: ValueCounts, @@ -214,7 +214,7 @@ pub struct WasmFunction { /// A WebAssembly Module Export #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub struct Export { /// The name of the export. pub name: Box, @@ -225,21 +225,21 @@ pub struct Export { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub struct Global { pub ty: GlobalType, pub init: ConstInstruction, } #[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub struct GlobalType { pub mutable: bool, pub ty: ValType, } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub struct TableType { pub element_type: ValType, pub size_initial: u32, @@ -258,7 +258,7 @@ impl TableType { /// Represents a memory's type. #[derive(Debug, Copy, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub struct MemoryType { arch: MemoryArch, page_count_initial: u64, @@ -297,14 +297,14 @@ impl MemoryType { } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub enum MemoryArch { I32, I64, } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub struct Import { pub module: Box, pub name: Box, @@ -312,7 +312,7 @@ pub struct Import { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub enum ImportKind { Function(TypeAddr), Table(TableType), @@ -333,7 +333,7 @@ impl From<&ImportKind> for ExternalKind { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub struct Data { pub data: Box<[u8]>, pub range: Range, @@ -341,14 +341,14 @@ pub struct Data { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub enum DataKind { Active { mem: MemAddr, offset: ConstInstruction }, Passive, } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub struct Element { pub kind: ElementKind, pub items: Box<[ElementItem]>, @@ -357,7 +357,7 @@ pub struct Element { } #[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub enum ElementKind { Passive, Active { table: TableAddr, offset: ConstInstruction }, @@ -365,7 +365,7 @@ pub enum ElementKind { } #[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub enum ElementItem { Func(FuncAddr), Expr(ConstInstruction), diff --git a/crates/types/src/value.rs b/crates/types/src/value.rs index 825fa1f..8bbcaf2 100644 --- a/crates/types/src/value.rs +++ b/crates/types/src/value.rs @@ -182,7 +182,7 @@ impl WasmValue { /// Type of a WebAssembly value. #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub enum ValType { /// A 32-bit integer. I32, diff --git a/examples/rust/Cargo.toml b/examples/rust/Cargo.toml index f88fde4..af2391a 100644 --- a/examples/rust/Cargo.toml +++ b/examples/rust/Cargo.toml @@ -16,7 +16,7 @@ argon2={version="0.5"} [[bin]] name="hello" path="src/hello.rs" - + [[bin]] name="print" path="src/print.rs" diff --git a/examples/rust/build.sh b/examples/rust/build.sh index fcfd01c..ceb1de6 100755 --- a/examples/rust/build.sh +++ b/examples/rust/build.sh @@ -6,16 +6,17 @@ exclude_wat=("tinywasm") out_dir="./target/wasm32-unknown-unknown/wasm" dest_dir="out" -features="+reference-types,+bulk-memory,+mutable-globals" +rust_features="+reference-types,+bulk-memory,+mutable-globals,+multivalue,+sign-ext,+nontrapping-fptoint" +wasmopt_features="--enable-reference-types --enable-bulk-memory --enable-mutable-globals --enable-multivalue --enable-sign-ext --enable-nontrapping-float-to-int" # ensure out dir exists mkdir -p "$dest_dir" for bin in "${bins[@]}"; do - RUSTFLAGS="-C target-feature=$features -C panic=abort" cargo build --target wasm32-unknown-unknown --package rust-wasm-examples --profile=wasm --bin "$bin" + RUSTFLAGS="-C target-feature=$rust_features -C panic=abort" cargo build --target wasm32-unknown-unknown --package rust-wasm-examples --profile=wasm --bin "$bin" cp "$out_dir/$bin.wasm" "$dest_dir/" - wasm-opt "$dest_dir/$bin.wasm" -o "$dest_dir/$bin.opt.wasm" -O3 --enable-bulk-memory --enable-reference-types --enable-mutable-globals + wasm-opt "$dest_dir/$bin.wasm" -o "$dest_dir/$bin.opt.wasm" -O3 $wasmopt_features if [[ ! " ${exclude_wat[@]} " =~ " $bin " ]]; then wasm2wat "$dest_dir/$bin.wasm" -o "$dest_dir/$bin.wat" From b0ce7fb5fe1eda408ef40340ac86118f338ececd Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Wed, 11 Sep 2024 22:03:21 +0200 Subject: [PATCH 10/54] ci: fix github action Signed-off-by: Henry Gressmann --- .github/workflows/test.yaml | 2 ++ CONTRIBUTING.md | 3 ++- Cargo.toml | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 47708fb..586e75b 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -51,6 +51,7 @@ jobs: name: "armv7 (32-Bit Raspberry Pi)" target: armv7-unknown-linux-gnueabihf + name: Run tests on ${{ matrix.os }}, ${{ matrix.name }}) runs-on: ${{ matrix.os }} steps: - name: Checkout code @@ -70,6 +71,7 @@ jobs: uses: actions/download-artifact@v4 with: name: wasm + path: examples/rust/out - name: Run tests run: cargo test --workspace ${{ matrix.args }} && cargo run --example wasm-rust all diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a0eb744..2302bef 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -44,7 +44,8 @@ $ cargo test-wast {path} # Run a specific example (run without arguments to see available examples) # The wasm test files required to run the `wasm-rust` examples are not # included in the main repository. -# To build these, you will need to run `./examples/rust/build.sh`. +# To build these, you will need to install binaryen and wabt +# and run `./examples/rust/build.sh`. $ cargo run --example {example_name} ``` diff --git a/Cargo.toml b/Cargo.toml index ae231c3..f5141ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,5 +53,5 @@ panic="abort" inherits="release" [profile.samply] -inherits = "release" -debug = true +inherits="release" +debug=true From 0ed6acf459ff941f3b20b3e7462e4ba1cf7fdbe5 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Wed, 11 Sep 2024 22:08:27 +0200 Subject: [PATCH 11/54] chore: remove nightly features for now Signed-off-by: Henry Gressmann --- crates/tinywasm/Cargo.toml | 2 +- crates/tinywasm/src/lib.rs | 3 +-- examples/rust/Cargo.toml | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index 264d4b9..4dc82bb 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -35,7 +35,7 @@ logging=["log", "tinywasm-parser?/logging", "tinywasm-types/logging"] std=["tinywasm-parser?/std", "tinywasm-types/std"] parser=["dep:tinywasm-parser"] archive=["tinywasm-types/archive"] -nightly=[] +# nightly=[] [[test]] name="test-wasm-1" diff --git a/crates/tinywasm/src/lib.rs b/crates/tinywasm/src/lib.rs index 7038dd6..d3431e2 100644 --- a/crates/tinywasm/src/lib.rs +++ b/crates/tinywasm/src/lib.rs @@ -4,8 +4,8 @@ attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_assignments, unused_variables)) ))] #![warn(missing_docs, missing_debug_implementations, rust_2018_idioms, unreachable_pub)] -#![cfg_attr(feature = "nightly", feature(portable_simd))] #![forbid(unsafe_code)] +// #![cfg_attr(feature = "nightly", feature(portable_simd))] //! A tiny WebAssembly Runtime written in Rust //! @@ -26,7 +26,6 @@ //! With all these features disabled, `TinyWasm` only depends on `core`, `alloc` and `libm`. //! By disabling `std`, you can use `TinyWasm` in `no_std` environments. This requires //! a custom allocator and removes support for parsing from files and streams, but otherwise the API is the same. -//! Additionally, to have proper error types in `no_std`, you currently need a `nightly` compiler to use the unstable error trait in `core`. //! //! ## Getting Started //! The easiest way to get started is to use the [`Module::parse_bytes`] function to load a diff --git a/examples/rust/Cargo.toml b/examples/rust/Cargo.toml index af2391a..f691a1b 100644 --- a/examples/rust/Cargo.toml +++ b/examples/rust/Cargo.toml @@ -10,13 +10,13 @@ forced-target="wasm32-unknown-unknown" edition="2021" [dependencies] -tinywasm={path="../../crates/tinywasm", features=["parser", "std", "nightly"]} +tinywasm={path="../../crates/tinywasm", features=["parser", "std"]} argon2={version="0.5"} [[bin]] name="hello" path="src/hello.rs" - + [[bin]] name="print" path="src/print.rs" From c5f45ff56f7538944d92d5d318a01d10da04535c Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Wed, 11 Sep 2024 22:48:12 +0200 Subject: [PATCH 12/54] ci: improve no_std testing, add linux arm64 Signed-off-by: Henry Gressmann --- .github/workflows/test.yaml | 31 ++++++++++----- crates/parser/src/module.rs | 4 +- crates/tinywasm/src/func.rs | 4 +- examples/rust/Cargo.toml | 11 +++++- examples/rust/build.sh | 3 ++ examples/rust/src/tinywasm.rs | 2 +- examples/rust/src/tinywasm_no_std.rs | 17 +++++++- examples/wasm-rust.rs | 59 ++++++++++++++++++++++++++-- 8 files changed, 111 insertions(+), 20 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 586e75b..427f7e6 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -5,6 +5,8 @@ on: branches: ["**"] pull_request: branches: ["next", "main"] + schedule: + - cron: "0 0 * * 0" jobs: build-wasm: @@ -14,8 +16,13 @@ jobs: - uses: actions/checkout@v4 with: submodules: true - - name: Install Rust toolchain & Binaryen - run: rustup update && rustup target add wasm32-unknown-unknown && sudo apt-get install -y binaryen wabt + - name: Install Rust toolchain + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + target: wasm32-unknown-unknown + - name: Install Binaryen and WABT + run: sudo apt-get install -y binaryen wabt - name: Build wasm run: ./examples/rust/build.sh - name: Save artifacts @@ -31,27 +38,31 @@ jobs: include: - os: ubuntu-latest rust: stable - name: "Linux (stable)" + name: "Linux x86 (stable)" - os: ubuntu-latest rust: nightly - name: "Linux (nightly)" + name: "Linux x86 (nightly)" - os: ubuntu-latest rust: stable - name: "Linux (stable, no default features)" + name: "Linux x86 (stable, no default features)" args: "--no-default-features" - os: ubuntu-latest rust: nightly - name: "Linux (nightly, no default features)" + name: "Linux x86 (nightly, no default features)" args: "--no-default-features" - os: macos-14 rust: stable name: "macOS arm64 (Apple M1)" - os: ubuntu-latest rust: stable - name: "armv7 (32-Bit Raspberry Pi)" + name: "Linux arm64" + target: aarch64-unknown-linux-gnu + - os: ubuntu-latest + rust: stable + name: "Linux armv7" target: armv7-unknown-linux-gnueabihf - name: Run tests on ${{ matrix.os }}, ${{ matrix.name }}) + name: Run tests on ${{ matrix.name }}) runs-on: ${{ matrix.os }} steps: - name: Checkout code @@ -74,11 +85,11 @@ jobs: path: examples/rust/out - name: Run tests - run: cargo test --workspace ${{ matrix.args }} && cargo run --example wasm-rust all + run: cargo test --workspace ${{ matrix.args }} && cargo test --workspace ${{ matrix.args }} --examples if: matrix.target == '' - name: Run clippy - run: cargo clippy --workspace --all-targets --all-features + run: cargo clippy --workspace ${{ matrix.args }} if: matrix.target == '' - name: Run tests (${{ matrix.target }}) diff --git a/crates/parser/src/module.rs b/crates/parser/src/module.rs index 20ed00d..ff7d109 100644 --- a/crates/parser/src/module.rs +++ b/crates/parser/src/module.rs @@ -168,9 +168,9 @@ impl ModuleReader { validator.end(offset)?; self.end_reached = true; } - CustomSection(reader) => { + CustomSection(_reader) => { debug!("Found custom section"); - debug!("Skipping custom section: {:?}", reader.name()); + debug!("Skipping custom section: {:?}", _reader.name()); } UnknownSection { .. } => return Err(ParseError::UnsupportedSection("Unknown section".into())), section => return Err(ParseError::UnsupportedSection(format!("Unsupported section: {section:?}"))), diff --git a/crates/tinywasm/src/func.rs b/crates/tinywasm/src/func.rs index 466dd86..7035109 100644 --- a/crates/tinywasm/src/func.rs +++ b/crates/tinywasm/src/func.rs @@ -37,9 +37,9 @@ impl FuncHandle { } // 5. For each value type and the corresponding value, check if types match - if !(func_ty.params.iter().zip(params).enumerate().all(|(i, (ty, param))| { + if !(func_ty.params.iter().zip(params).enumerate().all(|(_i, (ty, param))| { if ty != ¶m.val_type() { - log::error!("param type mismatch at index {}: expected {:?}, got {:?}", i, ty, param); + log::error!("param type mismatch at index {}: expected {:?}, got {:?}", _i, ty, param); false } else { true diff --git a/examples/rust/Cargo.toml b/examples/rust/Cargo.toml index f691a1b..5c6b710 100644 --- a/examples/rust/Cargo.toml +++ b/examples/rust/Cargo.toml @@ -10,8 +10,13 @@ forced-target="wasm32-unknown-unknown" edition="2021" [dependencies] -tinywasm={path="../../crates/tinywasm", features=["parser", "std"]} +tinywasm={path="../../crates/tinywasm", default-features=false, features=["parser", "archive"]} argon2={version="0.5"} +lol_alloc="0.4.1" + +[features] +default=["std"] +std=["tinywasm/std"] [[bin]] name="hello" @@ -25,6 +30,10 @@ path="src/print.rs" name="tinywasm" path="src/tinywasm.rs" +[[bin]] +name="tinywasm_no_std" +path="src/tinywasm_no_std.rs" + [[bin]] name="fibonacci" path="src/fibonacci.rs" diff --git a/examples/rust/build.sh b/examples/rust/build.sh index ceb1de6..d1e6285 100755 --- a/examples/rust/build.sh +++ b/examples/rust/build.sh @@ -12,6 +12,9 @@ wasmopt_features="--enable-reference-types --enable-bulk-memory --enable-mutable # ensure out dir exists mkdir -p "$dest_dir" +# build no_std +cargo build --target wasm32-unknown-unknown --package rust-wasm-examples --profile=wasm --bin tinywasm_no_std --no-default-features + for bin in "${bins[@]}"; do RUSTFLAGS="-C target-feature=$rust_features -C panic=abort" cargo build --target wasm32-unknown-unknown --package rust-wasm-examples --profile=wasm --bin "$bin" diff --git a/examples/rust/src/tinywasm.rs b/examples/rust/src/tinywasm.rs index 08c8135..68e6375 100644 --- a/examples/rust/src/tinywasm.rs +++ b/examples/rust/src/tinywasm.rs @@ -12,7 +12,7 @@ pub extern "C" fn hello() { } fn run() -> tinywasm::Result<()> { - let module = tinywasm::Module::parse_bytes(include_bytes!("../out/print.wasm"))?; + let module = tinywasm::Module::parse_stream(&include_bytes!("../out/print.wasm")[..])?; let mut store = tinywasm::Store::default(); let mut imports = tinywasm::Imports::new(); diff --git a/examples/rust/src/tinywasm_no_std.rs b/examples/rust/src/tinywasm_no_std.rs index 9f2b28c..c20e243 100644 --- a/examples/rust/src/tinywasm_no_std.rs +++ b/examples/rust/src/tinywasm_no_std.rs @@ -1,7 +1,19 @@ #![no_main] #![no_std] +use lol_alloc::{AssumeSingleThreaded, FreeListAllocator}; use tinywasm::{Extern, FuncContext}; +extern crate alloc; + +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + loop {} +} + +#[global_allocator] +static ALLOCATOR: AssumeSingleThreaded = + unsafe { AssumeSingleThreaded::new(FreeListAllocator::new()) }; + #[link(wasm_import_module = "env")] extern "C" { fn printi32(x: i32); @@ -13,10 +25,13 @@ pub extern "C" fn hello() { } fn run() -> tinywasm::Result<()> { - let module = tinywasm::Module::parse_bytes(include_bytes!("../out/print.wasm"))?; let mut store = tinywasm::Store::default(); let mut imports = tinywasm::Imports::new(); + let res = tinywasm::parser::Parser::new().parse_module_bytes(include_bytes!("../out/print.wasm"))?; + let twasm = res.serialize_twasm(); + let module = tinywasm::Module::parse_bytes(&twasm)?; + imports.define( "env", "printi32", diff --git a/examples/wasm-rust.rs b/examples/wasm-rust.rs index 169fed5..a9c7572 100644 --- a/examples/wasm-rust.rs +++ b/examples/wasm-rust.rs @@ -43,6 +43,7 @@ fn main() -> Result<()> { "printi32" => printi32()?, "fibonacci" => fibonacci()?, "tinywasm" => tinywasm()?, + "tinywasm_no_std" => tinywasm_no_std()?, "argon2id" => argon2id()?, "all" => { println!("Running all examples"); @@ -54,6 +55,8 @@ fn main() -> Result<()> { fibonacci()?; println!("\ntinywasm.wasm:"); tinywasm()?; + println!("\ntinywasm_no_std.wasm:"); + tinywasm_no_std()?; println!("argon2id.wasm:"); argon2id()?; } @@ -64,7 +67,22 @@ fn main() -> Result<()> { } fn tinywasm() -> Result<()> { - let module = Module::parse_file("./examples/rust/out/tinywasm.wasm")?; + let module = Module::parse_file("./examples/rust/out/tinywasm.opt.wasm")?; + let mut store = Store::default(); + + let mut imports = Imports::new(); + imports.define("env", "printi32", Extern::typed_func(|_: FuncContext<'_>, _x: i32| Ok(())))?; + let instance = module.instantiate(&mut store, Some(black_box(imports)))?; + + let hello = instance.exported_func::<(), ()>(&store, "hello")?; + hello.call(&mut store, black_box(()))?; + hello.call(&mut store, black_box(()))?; + hello.call(&mut store, black_box(()))?; + Ok(()) +} + +fn tinywasm_no_std() -> Result<()> { + let module = Module::parse_file("./examples/rust/out/tinywasm_no_std.opt.wasm")?; let mut store = Store::default(); let mut imports = Imports::new(); @@ -79,7 +97,7 @@ fn tinywasm() -> Result<()> { } fn hello() -> Result<()> { - let module = Module::parse_file("./examples/rust/out/hello.wasm")?; + let module = Module::parse_file("./examples/rust/out/hello.opt.wasm")?; let mut store = Store::default(); let mut imports = Imports::new(); @@ -108,7 +126,7 @@ fn hello() -> Result<()> { } fn printi32() -> Result<()> { - let module = Module::parse_file("./examples/rust/out/print.wasm")?; + let module = Module::parse_file("./examples/rust/out/print.opt.wasm")?; let mut store = Store::default(); let mut imports = Imports::new(); @@ -151,3 +169,38 @@ fn argon2id() -> Result<()> { Ok(()) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_hello() { + hello().unwrap(); + } + + #[test] + fn test_printi32() { + printi32().unwrap(); + } + + #[test] + fn test_fibonacci() { + fibonacci().unwrap(); + } + + #[test] + fn test_tinywasm() { + tinywasm().unwrap(); + } + + #[test] + fn test_tinywasm_no_std() { + tinywasm_no_std().unwrap(); + } + + #[test] + fn test_argon2id() { + argon2id().unwrap(); + } +} From c34f696794d42b194e44ec0d32f20f457b36e320 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Wed, 11 Sep 2024 22:51:30 +0200 Subject: [PATCH 13/54] ci: fix build Signed-off-by: Henry Gressmann --- examples/rust/src/print.wasm | Bin 0 -> 330 bytes examples/rust/src/tinywasm.rs | 2 +- examples/rust/src/tinywasm_no_std.rs | 2 +- examples/wasm-rust.rs | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 examples/rust/src/print.wasm diff --git a/examples/rust/src/print.wasm b/examples/rust/src/print.wasm new file mode 100644 index 0000000000000000000000000000000000000000..e4aa125948a6a70c4bf879d0c3ba74d885b90ab8 GIT binary patch literal 330 zcmXw!%}&BV6ov1!fIu~1e1UFEG|i9#5_Rb-n7AHp+sjayPABt2?5aGPk7lEBb&_-P zo#X>_4Fdo+kM^vGebo05Em=(ZJTN(ooad zE`l4ZDuKEZzvyr(M1>v&=_-aqh$Ep91v-k^JYh3PA!VOSNZ?~;Y+Hqrtc#`!wG1eU zjoyRva6L>VIY$*QIySaLSKhBzFWXhlbuEuxb?HM+^jsD@+NPU)^ThL4zRn-vwD4#p zd2t~0!IGO~izaw16mhBA0+q||bgR8ZV`?q=!T5HN&XOXi6aUl7rmmKn)0fW{mJVb| Sm&AQ%$Yt{;C|{pZ1^NMzn_#N| literal 0 HcmV?d00001 diff --git a/examples/rust/src/tinywasm.rs b/examples/rust/src/tinywasm.rs index 68e6375..c3bf2d2 100644 --- a/examples/rust/src/tinywasm.rs +++ b/examples/rust/src/tinywasm.rs @@ -12,7 +12,7 @@ pub extern "C" fn hello() { } fn run() -> tinywasm::Result<()> { - let module = tinywasm::Module::parse_stream(&include_bytes!("../out/print.wasm")[..])?; + let module = tinywasm::Module::parse_stream(&include_bytes!("./print.wasm")[..])?; let mut store = tinywasm::Store::default(); let mut imports = tinywasm::Imports::new(); diff --git a/examples/rust/src/tinywasm_no_std.rs b/examples/rust/src/tinywasm_no_std.rs index c20e243..07a6a8d 100644 --- a/examples/rust/src/tinywasm_no_std.rs +++ b/examples/rust/src/tinywasm_no_std.rs @@ -28,7 +28,7 @@ fn run() -> tinywasm::Result<()> { let mut store = tinywasm::Store::default(); let mut imports = tinywasm::Imports::new(); - let res = tinywasm::parser::Parser::new().parse_module_bytes(include_bytes!("../out/print.wasm"))?; + let res = tinywasm::parser::Parser::new().parse_module_bytes(include_bytes!("./print.wasm"))?; let twasm = res.serialize_twasm(); let module = tinywasm::Module::parse_bytes(&twasm)?; diff --git a/examples/wasm-rust.rs b/examples/wasm-rust.rs index a9c7572..89203c1 100644 --- a/examples/wasm-rust.rs +++ b/examples/wasm-rust.rs @@ -82,7 +82,7 @@ fn tinywasm() -> Result<()> { } fn tinywasm_no_std() -> Result<()> { - let module = Module::parse_file("./examples/rust/out/tinywasm_no_std.opt.wasm")?; + let module = Module::parse_file("./examples/rust/out/tinywasm_no_std.wasm")?; let mut store = Store::default(); let mut imports = Imports::new(); From eb97adc740cfbaafd0c55bee6004bb3a94c85a4e Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Wed, 11 Sep 2024 22:59:06 +0200 Subject: [PATCH 14/54] ci: fix build, update changelog Signed-off-by: Henry Gressmann --- .github/workflows/test.yaml | 2 +- CHANGELOG.md | 9 +++++++++ examples/rust/build.sh | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 427f7e6..f6de2d1 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -62,7 +62,7 @@ jobs: name: "Linux armv7" target: armv7-unknown-linux-gnueabihf - name: Run tests on ${{ matrix.name }}) + name: Run tests on ${{ matrix.name }} runs-on: ${{ matrix.os }} steps: - name: Checkout code diff --git a/CHANGELOG.md b/CHANGELOG.md index 16b7533..b84e6ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for the custom memory page sizes proposal ([#22](https://github.com/explodingcamera/tinywasm/pull/22) by [@danielstuart14](https://github.com/danielstuart14)) +### Changed + +- **Breaking:**: New backwards-incompatible version of the twasm format (upgraded `rkyv` to 0.8.0) +- Increased MSRV to 1.81.0 + +### Fixed + +- Fixed archive **no_std** support which was broken in the previous release, and added more tests to ensure it stays working + ## [0.8.0] - 2024-08-29 **All Commits**: https://github.com/explodingcamera/tinywasm/compare/v0.7.0...v0.8.0 diff --git a/examples/rust/build.sh b/examples/rust/build.sh index d1e6285..d0415ac 100755 --- a/examples/rust/build.sh +++ b/examples/rust/build.sh @@ -14,6 +14,7 @@ mkdir -p "$dest_dir" # build no_std cargo build --target wasm32-unknown-unknown --package rust-wasm-examples --profile=wasm --bin tinywasm_no_std --no-default-features +cp "$out_dir/tinywasm_no_std.wasm" "$dest_dir/" for bin in "${bins[@]}"; do RUSTFLAGS="-C target-feature=$rust_features -C panic=abort" cargo build --target wasm32-unknown-unknown --package rust-wasm-examples --profile=wasm --bin "$bin" From 15ab54b24241434718b35e8d9bbdc4f1b275d277 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Wed, 11 Sep 2024 23:17:05 +0200 Subject: [PATCH 15/54] fix: custom page size memory.grow on 32-bit Signed-off-by: Henry Gressmann --- crates/tinywasm/src/store/memory.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/tinywasm/src/store/memory.rs b/crates/tinywasm/src/store/memory.rs index 1e5ff7c..4826b65 100644 --- a/crates/tinywasm/src/store/memory.rs +++ b/crates/tinywasm/src/store/memory.rs @@ -54,7 +54,7 @@ impl MemoryInstance { } pub(crate) fn max_pages(&self) -> usize { - self.kind.page_count_max() as usize + self.kind.page_count_max().try_into().unwrap_or(usize::MAX) } pub(crate) fn load(&self, addr: usize, len: usize) -> Result<&[u8]> { @@ -130,6 +130,9 @@ impl MemoryInstance { debug_assert!(new_pages <= i32::MAX as i64, "page count should never be greater than i32::MAX"); if new_pages < 0 || new_pages as usize > self.max_pages() { + log::debug!("memory.grow failed: new_pages={}, max_pages={}", new_pages, self.max_pages()); + log::debug!("{} {}", self.kind.page_count_max(), self.kind.page_size()); + return None; } From a3ca2af26f066900e2db550bbd608aceadf1ac7c Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Thu, 12 Sep 2024 21:03:44 +0200 Subject: [PATCH 16/54] chore: refactor compiler macros Signed-off-by: Henry Gressmann --- .github/workflows/test.yaml | 8 - Cargo.lock | 8 +- crates/parser/src/visit.rs | 253 ++++-------------------- crates/tinywasm/src/interpreter/simd.rs | 130 ++++++++++++ crates/tinywasm/tests/test-wasm-2.rs | 2 +- crates/types/Cargo.toml | 2 +- crates/types/src/instructions.rs | 22 +-- crates/wasm-testsuite/lib.rs | 2 +- 8 files changed, 176 insertions(+), 251 deletions(-) create mode 100644 crates/tinywasm/src/interpreter/simd.rs diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index f6de2d1..ebf0487 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -99,11 +99,3 @@ jobs: target: ${{ matrix.target }} toolchain: ${{ matrix.rust }} if: matrix.target != '' - - - name: Run clippy (${{ matrix.target }}) - uses: houseabsolute/actions-rust-cross@v0.0.13 - with: - command: clippy - target: ${{ matrix.target }} - toolchain: ${{ matrix.rust }} - if: matrix.target != '' diff --git a/Cargo.lock b/Cargo.lock index 695bde4..670a20e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -616,9 +616,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7fa2297190bd08087add407c3dedf28eb3be1d75955ffbd3bc312834325760" +checksum = "1a1dfb7c03271e31aad881e521cfe25bda0206ee94b1af152957f4f49e25ee23" dependencies = [ "bytecheck", "bytes", @@ -635,9 +635,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4aad510db4f88722adf0e4586ff0dedfca4af57b17c075b2420bac1db446d22c" +checksum = "aa3ca4a30c576aeb76aea84370da286f74d12d32029da8caec3d53b5a36a7539" dependencies = [ "proc-macro2", "quote", diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs index 73cf9b4..4e39a5a 100644 --- a/crates/parser/src/visit.rs +++ b/crates/parser/src/visit.rs @@ -43,29 +43,34 @@ pub(crate) fn process_operators_and_validate( Ok((builder.instructions.into_boxed_slice(), builder.validator.into_allocations())) } -macro_rules! define_operands { - ($($name:ident, $instr:expr),*) => {$( - fn $name(&mut self) -> Self::Output { - self.instructions.push($instr); - } - )*}; -} - -macro_rules! define_primitive_operands { - ($($name:ident, $instr:expr, $ty:ty),*) => {$( +macro_rules! define_operand { + ($name:ident($instr:ident, $ty:ty)) => { fn $name(&mut self, arg: $ty) -> Self::Output { - self.instructions.push($instr(arg)); + self.instructions.push(Instruction::$instr(arg)); } - )*}; - ($($name:ident, $instr:expr, $ty:ty, $ty2:ty),*) => {$( + }; + + ($name:ident($instr:ident, $ty:ty, $ty2:ty)) => { fn $name(&mut self, arg: $ty, arg2: $ty2) -> Self::Output { - self.instructions.push($instr(arg, arg2)); + self.instructions.push(Instruction::$instr(arg, arg2)); + } + }; + + ($name:ident($instr:ident)) => { + fn $name(&mut self) -> Self::Output { + self.instructions.push(Instruction::$instr); } + }; +} + +macro_rules! define_operands { + ($($name:ident($instr:ident $(,$ty:ty)*)),*) => {$( + define_operand!($name($instr $(,$ty)*)); )*}; } macro_rules! define_mem_operands { - ($($name:ident, $instr:ident),*) => {$( + ($($name:ident($instr:ident)),*) => {$( fn $name(&mut self, memarg: wasmparser::MemArg) -> Self::Output { self.instructions.push(Instruction::$instr { offset: memarg.offset, @@ -123,6 +128,7 @@ macro_rules! impl_visit_operator { (@@saturating_float_to_int $($rest:tt)* ) => {}; (@@bulk_memory $($rest:tt)* ) => {}; (@@tail_call $($rest:tt)* ) => {}; + // (@@simd $($rest:tt)* ) => {}; (@@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident) => { #[cold] fn $visit(&mut self $($(,$arg: $argty)*)?) { @@ -135,187 +141,28 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild type Output = (); wasmparser::for_each_operator!(impl_visit_operator); - define_primitive_operands! { - visit_br, Instruction::Br, u32, - visit_br_if, Instruction::BrIf, u32, - visit_global_get, Instruction::GlobalGet, u32, - visit_i32_const, Instruction::I32Const, i32, - visit_i64_const, Instruction::I64Const, i64, - visit_call, Instruction::Call, u32, - visit_memory_size, Instruction::MemorySize, u32, - visit_memory_grow, Instruction::MemoryGrow, u32 - } - define_mem_operands! { - visit_i32_load, I32Load, - visit_i64_load, I64Load, - visit_f32_load, F32Load, - visit_f64_load, F64Load, - visit_i32_load8_s, I32Load8S, - visit_i32_load8_u, I32Load8U, - visit_i32_load16_s, I32Load16S, - visit_i32_load16_u, I32Load16U, - visit_i64_load8_s, I64Load8S, - visit_i64_load8_u, I64Load8U, - visit_i64_load16_s, I64Load16S, - visit_i64_load16_u, I64Load16U, - visit_i64_load32_s, I64Load32S, - visit_i64_load32_u, I64Load32U, - // visit_i32_store, I32Store, custom implementation - visit_i64_store, I64Store, - visit_f32_store, F32Store, - visit_f64_store, F64Store, - visit_i32_store8, I32Store8, - visit_i32_store16, I32Store16, - visit_i64_store8, I64Store8, - visit_i64_store16, I64Store16, - visit_i64_store32, I64Store32 + visit_i32_load(I32Load), visit_i64_load(I64Load), visit_f32_load(F32Load), visit_f64_load(F64Load), visit_i32_load8_s(I32Load8S), visit_i32_load8_u(I32Load8U), visit_i32_load16_s(I32Load16S), visit_i32_load16_u(I32Load16U), visit_i64_load8_s(I64Load8S), visit_i64_load8_u(I64Load8U), visit_i64_load16_s(I64Load16S), visit_i64_load16_u(I64Load16U), visit_i64_load32_s(I64Load32S), visit_i64_load32_u(I64Load32U), /* visit_i32_store( I32Store), custom implementation */ visit_i64_store(I64Store), visit_f32_store(F32Store), visit_f64_store(F64Store), visit_i32_store8(I32Store8), visit_i32_store16(I32Store16), visit_i64_store8(I64Store8), visit_i64_store16(I64Store16), visit_i64_store32(I64Store32) } define_operands! { - visit_unreachable, Instruction::Unreachable, - visit_nop, Instruction::Nop, - visit_return, Instruction::Return, - visit_i32_eqz, Instruction::I32Eqz, - visit_i32_eq, Instruction::I32Eq, - visit_i32_ne, Instruction::I32Ne, - visit_i32_lt_s, Instruction::I32LtS, - visit_i32_lt_u, Instruction::I32LtU, - visit_i32_gt_s, Instruction::I32GtS, - visit_i32_gt_u, Instruction::I32GtU, - visit_i32_le_s, Instruction::I32LeS, - visit_i32_le_u, Instruction::I32LeU, - visit_i32_ge_s, Instruction::I32GeS, - visit_i32_ge_u, Instruction::I32GeU, - visit_i64_eqz, Instruction::I64Eqz, - visit_i64_eq, Instruction::I64Eq, - visit_i64_ne, Instruction::I64Ne, - visit_i64_lt_s, Instruction::I64LtS, - visit_i64_lt_u, Instruction::I64LtU, - visit_i64_gt_s, Instruction::I64GtS, - visit_i64_gt_u, Instruction::I64GtU, - visit_i64_le_s, Instruction::I64LeS, - visit_i64_le_u, Instruction::I64LeU, - visit_i64_ge_s, Instruction::I64GeS, - visit_i64_ge_u, Instruction::I64GeU, - visit_f32_eq, Instruction::F32Eq, - visit_f32_ne, Instruction::F32Ne, - visit_f32_lt, Instruction::F32Lt, - visit_f32_gt, Instruction::F32Gt, - visit_f32_le, Instruction::F32Le, - visit_f32_ge, Instruction::F32Ge, - visit_f64_eq, Instruction::F64Eq, - visit_f64_ne, Instruction::F64Ne, - visit_f64_lt, Instruction::F64Lt, - visit_f64_gt, Instruction::F64Gt, - visit_f64_le, Instruction::F64Le, - visit_f64_ge, Instruction::F64Ge, - visit_i32_clz, Instruction::I32Clz, - visit_i32_ctz, Instruction::I32Ctz, - visit_i32_popcnt, Instruction::I32Popcnt, - // visit_i32_add, Instruction::I32Add, custom implementation - visit_i32_sub, Instruction::I32Sub, - visit_i32_mul, Instruction::I32Mul, - visit_i32_div_s, Instruction::I32DivS, - visit_i32_div_u, Instruction::I32DivU, - visit_i32_rem_s, Instruction::I32RemS, - visit_i32_rem_u, Instruction::I32RemU, - visit_i32_and, Instruction::I32And, - visit_i32_or, Instruction::I32Or, - visit_i32_xor, Instruction::I32Xor, - visit_i32_shl, Instruction::I32Shl, - visit_i32_shr_s, Instruction::I32ShrS, - visit_i32_shr_u, Instruction::I32ShrU, - visit_i32_rotl, Instruction::I32Rotl, - visit_i32_rotr, Instruction::I32Rotr, - visit_i64_clz, Instruction::I64Clz, - visit_i64_ctz, Instruction::I64Ctz, - visit_i64_popcnt, Instruction::I64Popcnt, - visit_i64_add, Instruction::I64Add, - visit_i64_sub, Instruction::I64Sub, - visit_i64_mul, Instruction::I64Mul, - visit_i64_div_s, Instruction::I64DivS, - visit_i64_div_u, Instruction::I64DivU, - visit_i64_rem_s, Instruction::I64RemS, - visit_i64_rem_u, Instruction::I64RemU, - visit_i64_and, Instruction::I64And, - visit_i64_or, Instruction::I64Or, - visit_i64_xor, Instruction::I64Xor, - visit_i64_shl, Instruction::I64Shl, - visit_i64_shr_s, Instruction::I64ShrS, - visit_i64_shr_u, Instruction::I64ShrU, - // visit_i64_rotl, Instruction::I64Rotl, custom implementation - visit_i64_rotr, Instruction::I64Rotr, - visit_f32_abs, Instruction::F32Abs, - visit_f32_neg, Instruction::F32Neg, - visit_f32_ceil, Instruction::F32Ceil, - visit_f32_floor, Instruction::F32Floor, - visit_f32_trunc, Instruction::F32Trunc, - visit_f32_nearest, Instruction::F32Nearest, - visit_f32_sqrt, Instruction::F32Sqrt, - visit_f32_add, Instruction::F32Add, - visit_f32_sub, Instruction::F32Sub, - visit_f32_mul, Instruction::F32Mul, - visit_f32_div, Instruction::F32Div, - visit_f32_min, Instruction::F32Min, - visit_f32_max, Instruction::F32Max, - visit_f32_copysign, Instruction::F32Copysign, - visit_f64_abs, Instruction::F64Abs, - visit_f64_neg, Instruction::F64Neg, - visit_f64_ceil, Instruction::F64Ceil, - visit_f64_floor, Instruction::F64Floor, - visit_f64_trunc, Instruction::F64Trunc, - visit_f64_nearest, Instruction::F64Nearest, - visit_f64_sqrt, Instruction::F64Sqrt, - visit_f64_add, Instruction::F64Add, - visit_f64_sub, Instruction::F64Sub, - visit_f64_mul, Instruction::F64Mul, - visit_f64_div, Instruction::F64Div, - visit_f64_min, Instruction::F64Min, - visit_f64_max, Instruction::F64Max, - visit_f64_copysign, Instruction::F64Copysign, - visit_i32_wrap_i64, Instruction::I32WrapI64, - visit_i32_trunc_f32_s, Instruction::I32TruncF32S, - visit_i32_trunc_f32_u, Instruction::I32TruncF32U, - visit_i32_trunc_f64_s, Instruction::I32TruncF64S, - visit_i32_trunc_f64_u, Instruction::I32TruncF64U, - visit_i64_extend_i32_s, Instruction::I64ExtendI32S, - visit_i64_extend_i32_u, Instruction::I64ExtendI32U, - visit_i64_trunc_f32_s, Instruction::I64TruncF32S, - visit_i64_trunc_f32_u, Instruction::I64TruncF32U, - visit_i64_trunc_f64_s, Instruction::I64TruncF64S, - visit_i64_trunc_f64_u, Instruction::I64TruncF64U, - visit_f32_convert_i32_s, Instruction::F32ConvertI32S, - visit_f32_convert_i32_u, Instruction::F32ConvertI32U, - visit_f32_convert_i64_s, Instruction::F32ConvertI64S, - visit_f32_convert_i64_u, Instruction::F32ConvertI64U, - visit_f32_demote_f64, Instruction::F32DemoteF64, - visit_f64_convert_i32_s, Instruction::F64ConvertI32S, - visit_f64_convert_i32_u, Instruction::F64ConvertI32U, - visit_f64_convert_i64_s, Instruction::F64ConvertI64S, - visit_f64_convert_i64_u, Instruction::F64ConvertI64U, - visit_f64_promote_f32, Instruction::F64PromoteF32, - visit_i32_reinterpret_f32, Instruction::I32ReinterpretF32, - visit_i64_reinterpret_f64, Instruction::I64ReinterpretF64, - visit_f32_reinterpret_i32, Instruction::F32ReinterpretI32, - visit_f64_reinterpret_i64, Instruction::F64ReinterpretI64, + // basic instructions + visit_br(Br, u32), visit_br_if(BrIf, u32), visit_global_get(GlobalGet, u32), visit_i32_const(I32Const, i32), visit_i64_const(I64Const, i64), visit_call(Call, u32), visit_memory_size(MemorySize, u32), visit_memory_grow(MemoryGrow, u32), visit_unreachable(Unreachable), visit_nop(Nop), visit_return(Return), visit_i32_eqz(I32Eqz), visit_i32_eq(I32Eq), visit_i32_ne(I32Ne), visit_i32_lt_s(I32LtS), visit_i32_lt_u(I32LtU), visit_i32_gt_s(I32GtS), visit_i32_gt_u(I32GtU), visit_i32_le_s(I32LeS), visit_i32_le_u(I32LeU), visit_i32_ge_s(I32GeS), visit_i32_ge_u(I32GeU), visit_i64_eqz(I64Eqz), visit_i64_eq(I64Eq), visit_i64_ne(I64Ne), visit_i64_lt_s(I64LtS), visit_i64_lt_u(I64LtU), visit_i64_gt_s(I64GtS), visit_i64_gt_u(I64GtU), visit_i64_le_s(I64LeS), visit_i64_le_u(I64LeU), visit_i64_ge_s(I64GeS), visit_i64_ge_u(I64GeU), visit_f32_eq(F32Eq), visit_f32_ne(F32Ne), visit_f32_lt(F32Lt), visit_f32_gt(F32Gt), visit_f32_le(F32Le), visit_f32_ge(F32Ge), visit_f64_eq(F64Eq), visit_f64_ne(F64Ne), visit_f64_lt(F64Lt), visit_f64_gt(F64Gt), visit_f64_le(F64Le), visit_f64_ge(F64Ge), visit_i32_clz(I32Clz), visit_i32_ctz(I32Ctz), visit_i32_popcnt(I32Popcnt), visit_i32_add(I32Add), visit_i32_sub(I32Sub), visit_i32_mul(I32Mul), visit_i32_div_s(I32DivS), visit_i32_div_u(I32DivU), visit_i32_rem_s(I32RemS), visit_i32_rem_u(I32RemU), visit_i32_and(I32And), visit_i32_or(I32Or), visit_i32_xor(I32Xor), visit_i32_shl(I32Shl), visit_i32_shr_s(I32ShrS), visit_i32_shr_u(I32ShrU), visit_i32_rotl(I32Rotl), visit_i32_rotr(I32Rotr), visit_i64_clz(I64Clz), visit_i64_ctz(I64Ctz), visit_i64_popcnt(I64Popcnt), visit_i64_add(I64Add), visit_i64_sub(I64Sub), visit_i64_mul(I64Mul), visit_i64_div_s(I64DivS), visit_i64_div_u(I64DivU), visit_i64_rem_s(I64RemS), visit_i64_rem_u(I64RemU), visit_i64_and(I64And), visit_i64_or(I64Or), visit_i64_xor(I64Xor), visit_i64_shl(I64Shl), visit_i64_shr_s(I64ShrS), visit_i64_shr_u(I64ShrU), visit_i64_rotl(I64Rotl), visit_i64_rotr(I64Rotr), visit_f32_abs(F32Abs), visit_f32_neg(F32Neg), visit_f32_ceil(F32Ceil), visit_f32_floor(F32Floor), visit_f32_trunc(F32Trunc), visit_f32_nearest(F32Nearest), visit_f32_sqrt(F32Sqrt), visit_f32_add(F32Add), visit_f32_sub(F32Sub), visit_f32_mul(F32Mul), visit_f32_div(F32Div), visit_f32_min(F32Min), visit_f32_max(F32Max), visit_f32_copysign(F32Copysign), visit_f64_abs(F64Abs), visit_f64_neg(F64Neg), visit_f64_ceil(F64Ceil), visit_f64_floor(F64Floor), visit_f64_trunc(F64Trunc), visit_f64_nearest(F64Nearest), visit_f64_sqrt(F64Sqrt), visit_f64_add(F64Add), visit_f64_sub(F64Sub), visit_f64_mul(F64Mul), visit_f64_div(F64Div), visit_f64_min(F64Min), visit_f64_max(F64Max), visit_f64_copysign(F64Copysign), visit_i32_wrap_i64(I32WrapI64), visit_i32_trunc_f32_s(I32TruncF32S), visit_i32_trunc_f32_u(I32TruncF32U), visit_i32_trunc_f64_s(I32TruncF64S), visit_i32_trunc_f64_u(I32TruncF64U), visit_i64_extend_i32_s(I64ExtendI32S), visit_i64_extend_i32_u(I64ExtendI32U), visit_i64_trunc_f32_s(I64TruncF32S), visit_i64_trunc_f32_u(I64TruncF32U), visit_i64_trunc_f64_s(I64TruncF64S), visit_i64_trunc_f64_u(I64TruncF64U), visit_f32_convert_i32_s(F32ConvertI32S), visit_f32_convert_i32_u(F32ConvertI32U), visit_f32_convert_i64_s(F32ConvertI64S), visit_f32_convert_i64_u(F32ConvertI64U), visit_f32_demote_f64(F32DemoteF64), visit_f64_convert_i32_s(F64ConvertI32S), visit_f64_convert_i32_u(F64ConvertI32U), visit_f64_convert_i64_s(F64ConvertI64S), visit_f64_convert_i64_u(F64ConvertI64U), visit_f64_promote_f32(F64PromoteF32), visit_i32_reinterpret_f32(I32ReinterpretF32), visit_i64_reinterpret_f64(I64ReinterpretF64), visit_f32_reinterpret_i32(F32ReinterpretI32), visit_f64_reinterpret_i64(F64ReinterpretI64), // sign_extension - visit_i32_extend8_s, Instruction::I32Extend8S, - visit_i32_extend16_s, Instruction::I32Extend16S, - visit_i64_extend8_s, Instruction::I64Extend8S, - visit_i64_extend16_s, Instruction::I64Extend16S, - visit_i64_extend32_s, Instruction::I64Extend32S, + visit_i32_extend8_s(I32Extend8S), visit_i32_extend16_s(I32Extend16S), visit_i64_extend8_s(I64Extend8S), visit_i64_extend16_s(I64Extend16S), visit_i64_extend32_s(I64Extend32S), // Non-trapping Float-to-int Conversions - visit_i32_trunc_sat_f32_s, Instruction::I32TruncSatF32S, - visit_i32_trunc_sat_f32_u, Instruction::I32TruncSatF32U, - visit_i32_trunc_sat_f64_s, Instruction::I32TruncSatF64S, - visit_i32_trunc_sat_f64_u, Instruction::I32TruncSatF64U, - visit_i64_trunc_sat_f32_s, Instruction::I64TruncSatF32S, - visit_i64_trunc_sat_f32_u, Instruction::I64TruncSatF32U, - visit_i64_trunc_sat_f64_s, Instruction::I64TruncSatF64S, - visit_i64_trunc_sat_f64_u, Instruction::I64TruncSatF64U + visit_i32_trunc_sat_f32_s(I32TruncSatF32S), visit_i32_trunc_sat_f32_u(I32TruncSatF32U), visit_i32_trunc_sat_f64_s(I32TruncSatF64S), visit_i32_trunc_sat_f64_u(I32TruncSatF64U), visit_i64_trunc_sat_f32_s(I64TruncSatF32S), visit_i64_trunc_sat_f32_u(I64TruncSatF32U), visit_i64_trunc_sat_f64_s(I64TruncSatF64S), visit_i64_trunc_sat_f64_u(I64TruncSatF64U), + + // Reference Types + visit_ref_func(RefFunc, u32), visit_table_fill(TableFill, u32), visit_table_get(TableGet, u32), visit_table_set(TableSet, u32), visit_table_grow(TableGrow, u32), visit_table_size(TableSize, u32), + + // Bulk Memory + visit_memory_init(MemoryInit, u32, u32), visit_memory_copy(MemoryCopy, u32, u32), visit_table_init(TableInit, u32, u32), visit_memory_fill(MemoryFill, u32), visit_data_drop(DataDrop, u32), visit_elem_drop(ElemDrop, u32) + + // simd + // visit_v128_load(V128Load), visit_v128_store(V128Store), visit_v128_const(V128Const), visit_v128_not(V128Not), visit_v128_and(V128And), visit_v128_or(V128Or), visit_v128_xor(V128Xor), visit_v128_bitselect(V128Bitselect), visit_v128_any_true(V128AnyTrue), visit_v128_all_true(V128AllTrue), visit_v128_shl(V128Shl), visit_v128_shr_s(V128ShrS), visit_v128_shr_u(V128ShrU), visit_v128_add(V128Add), visit_v128_sub(V128Sub), visit_v128_mul(V128Mul), visit_v128_div_s(V128DivS), visit_v128_div_u(V128DivU), visit_v128_min_s(V128MinS), visit_v128_min_u(V128MinU), visit_v128_max_s(V128MaxS), visit_v128_max_u(V128MaxU), visit_v128_eq(V128Eq), visit_v128_ne(V128Ne), visit_v128_lt_s(V128LtS), visit_v128_lt_u(V128LtU), visit_v128_le_s(V128LeS), visit_v128_le_u(V128LeU), visit_v128_gt_s(V128GtS), visit_v128_gt_u(V128GtU), visit_v128_ge_s(V128GeS), visit_v128_ge_u(V128GeU), visit_v128_narrow_i32x4_s(V128NarrowI32x4S), visit_v128_narrow_i32x4_u(V128NarrowI32x4U), visit_v128_widen_low_i8x16_s(V128WidenLowI8x16S), visit_v128_widen_high_i8x16_s(V128WidenHighI8x16S), visit_v128_widen_low_i8x16_u(V128WidenLowI8x16U), visit_v128_widen_high_i8x16_u(V128WidenHighI8x16U), visit_v128_widen_low_i16x8_s(V128WidenLowI16x8S), visit_v128_widen_high_i16x8_s(V128WidenHighI16x8S), visit_v128_widen_low_i16x8_u(V128WidenLowI16x8U) } fn visit_return_call(&mut self, function_index: u32) -> Self::Output { @@ -452,14 +299,6 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild } } - fn visit_i64_rotl(&mut self) -> Self::Output { - self.instructions.push(Instruction::I64Rotl); - } - - fn visit_i32_add(&mut self) -> Self::Output { - self.instructions.push(Instruction::I32Add); - } - fn visit_block(&mut self, blockty: wasmparser::BlockType) -> Self::Output { self.label_ptrs.push(self.instructions.len()); self.instructions.push(match blockty { @@ -582,19 +421,6 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild self.instructions.push(Instruction::F64Const(f64::from_bits(val.bits()))); } - // Bulk Memory Operations - - define_primitive_operands! { - visit_memory_init, Instruction::MemoryInit, u32, u32, - visit_memory_copy, Instruction::MemoryCopy, u32, u32, - visit_table_init, Instruction::TableInit, u32, u32 - } - define_primitive_operands! { - visit_memory_fill, Instruction::MemoryFill, u32, - visit_data_drop, Instruction::DataDrop, u32, - visit_elem_drop, Instruction::ElemDrop, u32 - } - fn visit_table_copy(&mut self, dst_table: u32, src_table: u32) -> Self::Output { self.instructions.push(Instruction::TableCopy { from: src_table, to: dst_table }); } @@ -618,13 +444,4 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild wasmparser::ValType::Ref(_) => Instruction::SelectRef, }); } - - define_primitive_operands! { - visit_ref_func, Instruction::RefFunc, u32, - visit_table_fill, Instruction::TableFill, u32, - visit_table_get, Instruction::TableGet, u32, - visit_table_set, Instruction::TableSet, u32, - visit_table_grow, Instruction::TableGrow, u32, - visit_table_size, Instruction::TableSize, u32 - } } diff --git a/crates/tinywasm/src/interpreter/simd.rs b/crates/tinywasm/src/interpreter/simd.rs new file mode 100644 index 0000000..bc2f402 --- /dev/null +++ b/crates/tinywasm/src/interpreter/simd.rs @@ -0,0 +1,130 @@ +// WIP + +struct V128([u8; 16]); + +impl V128 { + fn f32x4(&self) -> [f32; 4] { + let mut res = [0.0; 4]; + for i in 0..4 { + let mut f = [0; 4]; + for j in 0..4 { + f[j] = self.0[i * 4 + j]; + } + res[i] = f32::from_le_bytes(f); + } + res + } + + fn i32x4(&self) -> [i32; 4] { + let mut res = [0; 4]; + for i in 0..4 { + let mut f = [0; 4]; + for j in 0..4 { + f[j] = self.0[i * 4 + j]; + } + res[i] = i32::from_le_bytes(f); + } + res + } + + fn i64x2(&self) -> [i64; 2] { + let mut res = [0; 2]; + for i in 0..2 { + let mut f = [0; 8]; + for j in 0..8 { + f[j] = self.0[i * 8 + j]; + } + res[i] = i64::from_le_bytes(f); + } + res + } + + fn f64x2(&self) -> [f64; 2] { + let mut res = [0.0; 2]; + for i in 0..2 { + let mut f = [0; 8]; + for j in 0..8 { + f[j] = self.0[i * 8 + j]; + } + res[i] = f64::from_le_bytes(f); + } + res + } + + fn i16x8(&self) -> [i16; 8] { + let mut res = [0; 8]; + for i in 0..8 { + let mut f = [0; 2]; + for j in 0..2 { + f[j] = self.0[i * 2 + j]; + } + res[i] = i16::from_le_bytes(f); + } + res + } + + fn i8x16(&self) -> [i8; 16] { + let mut res = [0; 16]; + for i in 0..16 { + res[i] = i8::from_le_bytes([self.0[i]]); + } + res + } +} + +fn vvunop(c1: V128) -> V128 { + let mut res = [0; 16]; + for i in 0..16 { + res[i] = !c1.0[i]; + } + V128(res) +} + +fn vvbinop(c1: V128, c2: V128) -> V128 { + let mut res = [0; 16]; + for i in 0..16 { + res[i] = c1.0[i] & c2.0[i]; + } + V128(res) +} + +fn vvternop(c1: V128, c2: V128, c3: V128) -> V128 { + let mut res = [0; 16]; + for i in 0..16 { + res[i] = c1.0[i] & c2.0[i] | !c1.0[i] & c3.0[i]; + } + V128(res) +} + +fn any_true(val: V128) -> bool { + val.0.iter().any(|&x| x != 0) +} + +fn i8x16_swizzle(c1: V128, c2: V128) -> V128 { + let mut res = [0; 16]; + for i in 0..16 { + res[i] = c1.0[c2.0[i] as usize]; + } + V128(res) +} + +fn i18x16_shuffle(c1: V128, c2: V128) -> V128 { + let mut res = [0; 16]; + for i in 0..16 { + res[i] = c1.0[(c2.0[i] & 0xf) as usize]; + } + V128(res) +} + +fn f32x4_abs(val: V128) -> V128 { + let mut res = [0; 16]; + for i in 0..4 { + let f = val.f32x4(); + let f = f32::abs(f[i]); + let f = f.to_le_bytes(); + for j in 0..4 { + res[i * 4 + j] = f[j]; + } + } + V128(res) +} diff --git a/crates/tinywasm/tests/test-wasm-2.rs b/crates/tinywasm/tests/test-wasm-2.rs index bd1afe6..336632f 100644 --- a/crates/tinywasm/tests/test-wasm-2.rs +++ b/crates/tinywasm/tests/test-wasm-2.rs @@ -7,7 +7,7 @@ fn main() -> Result<()> { let mut test_suite = TestSuite::new(); TestSuite::set_log_level(log::LevelFilter::Off); - test_suite.run_spec_group(wasm_testsuite::V2_DRAFT_1_TESTS)?; + test_suite.run_spec_group(wasm_testsuite::V2_TESTS)?; test_suite.save_csv("./tests/generated/wasm-2.csv", env!("CARGO_PKG_VERSION"))?; if test_suite.failed() { diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index 7531ab4..9d9f9af 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -10,7 +10,7 @@ rust-version.workspace=true [dependencies] log={workspace=true, optional=true} -rkyv={version="0.8.0-rc.2", optional=true, default-features=false, features=["alloc", "bytecheck"]} +rkyv={version="0.8.1", optional=true, default-features=false, features=["alloc", "bytecheck"]} [features] default=["std", "logging", "archive"] diff --git a/crates/types/src/instructions.rs b/crates/types/src/instructions.rs index 2030942..a3c2fee 100644 --- a/crates/types/src/instructions.rs +++ b/crates/types/src/instructions.rs @@ -42,24 +42,6 @@ pub enum ConstInstruction { // should be kept as small as possible (16 bytes max) #[rustfmt::skip] pub enum Instruction { - // > Custom Instructions - // // LocalGet + I32Const + I32Add - // I32LocalGetConstAdd(LocalAddr, i32), - // // LocalGet + I32Const + I32Store - // I32ConstStoreLocal { local: LocalAddr, const_i32: i32, offset: u32, mem_addr: u8 }, - // // LocalGet + LocalGet + I32Store - // I32StoreLocal { local_a: LocalAddr, local_b: LocalAddr, offset: u32, mem_addr: u8 }, - // // I64Xor + I64Const + I64RotL - // // Commonly used by a few crypto libraries - // I64XorConstRotl(i64), - // // LocalTee + LocalGet - // LocalTeeGet(LocalAddr, LocalAddr), - // LocalGet2(LocalAddr, LocalAddr), - // LocalGet3(LocalAddr, LocalAddr, LocalAddr), - // LocalGetSet(LocalAddr, LocalAddr), - - // LocalGetGet32(LocalAddr, LocalAddr), LocalGetGet64(LocalAddr, LocalAddr), LocalGetGet128(LocalAddr, LocalAddr), - // LocalTeeGet32(LocalAddr, LocalAddr), LocalTeeGet64(LocalAddr, LocalAddr), LocalTeeGet128(LocalAddr, LocalAddr), LocalCopy32(LocalAddr, LocalAddr), LocalCopy64(LocalAddr, LocalAddr), LocalCopy128(LocalAddr, LocalAddr), LocalCopy128Ref(LocalAddr, LocalAddr), LocalCopyRef(LocalAddr, LocalAddr), LocalsStore32(LocalAddr, LocalAddr, u32, MemAddr), LocalsStore64(LocalAddr, LocalAddr, u32, MemAddr), LocalsStore128(LocalAddr, LocalAddr, u32, MemAddr), LocalsStoreRef(LocalAddr, LocalAddr, u32, MemAddr), @@ -205,4 +187,8 @@ pub enum Instruction { MemoryFill(MemAddr), DataDrop(DataAddr), ElemDrop(ElemAddr), + + // // > SIMD Instructions + // V128Load(MemoryArg), V128Load8x8S { offset: u64, mem_addr: MemAddr }, V128Load8x8U { offset: u64, mem_addr: MemAddr }, V128Load16x4S { offset: u64, mem_addr: MemAddr }, V128Load16x4U { offset: u64, mem_addr: MemAddr }, V128Load32x2S { offset: u64, mem_addr: MemAddr }, V128Load32x2U { offset: u64, mem_addr: MemAddr }, V128Load8Splat { offset: u64, mem_addr: MemAddr }, V128Load16Splat { offset: u64, mem_addr: MemAddr }, V128Load32Splat { offset: u64, mem_addr: MemAddr }, V128Load64Splat { offset: u64, mem_addr: MemAddr }, V128Load32Zero { offset: u64, mem_addr: MemAddr }, V128Load64Zero { offset: u64, mem_addr: MemAddr }, + // V128Store { offset: u64, mem_addr: MemAddr }, V128Store8x8 { offset: u64, mem_addr: MemAddr }, V128Store16x4 { offset: u64, mem_addr: MemAddr }, V128Store32x2 { offset: u64, mem_addr: MemAddr }, } diff --git a/crates/wasm-testsuite/lib.rs b/crates/wasm-testsuite/lib.rs index 12bf459..2a2892c 100644 --- a/crates/wasm-testsuite/lib.rs +++ b/crates/wasm-testsuite/lib.rs @@ -32,7 +32,7 @@ pub const MVP_TESTS: &[&str] = &["address.wast", "align.wast", "binary-leb128.wa /// List of all tests that apply to the V2 draft 1 spec. #[rustfmt::skip] -pub const V2_DRAFT_1_TESTS: &[&str] = &["address.wast", "align.wast", "binary-leb128.wast", "binary.wast", "block.wast", "br.wast", "br_if.wast", "br_table.wast", "bulk.wast", "call.wast", "call_indirect.wast", "comments.wast", "const.wast", "conversions.wast", "custom.wast", "data.wast", "elem.wast", "endianness.wast", "exports.wast", "f32.wast", "f32_bitwise.wast", "f32_cmp.wast", "f64.wast", "f64_bitwise.wast", "f64_cmp.wast", "fac.wast", "float_exprs.wast", "float_literals.wast", "float_memory.wast", "float_misc.wast", "forward.wast", "func.wast", "func_ptrs.wast", "global.wast", "i32.wast", "i64.wast", "if.wast", "imports.wast", "inline-module.wast", "int_exprs.wast", "int_literals.wast", "labels.wast", "left-to-right.wast", "linking.wast", "load.wast", "local_get.wast", "local_set.wast", "local_tee.wast", "loop.wast", "memory.wast", "memory_copy.wast", "memory_fill.wast", "memory_grow.wast", "memory_init.wast", "memory_redundancy.wast", "memory_size.wast", "memory_trap.wast", "names.wast", "nop.wast", "obsolete-keywords.wast", "ref_func.wast", "ref_is_null.wast", "ref_null.wast", "return.wast", "select.wast", "skip-stack-guard-page.wast", "stack.wast", "start.wast", "store.wast", "switch.wast", "table-sub.wast", "table.wast", "table_copy.wast", "table_fill.wast", "table_get.wast", "table_grow.wast", "table_init.wast", "table_set.wast", "table_size.wast", "token.wast", "traps.wast", "type.wast", "unreachable.wast", "unreached-invalid.wast", "unreached-valid.wast", "unwind.wast", "utf8-custom-section-id.wast", "utf8-import-field.wast", "utf8-import-module.wast", "utf8-invalid-encoding.wast"]; +pub const V2_TESTS: &[&str] = &["address.wast", "align.wast", "binary-leb128.wast", "binary.wast", "block.wast", "br.wast", "br_if.wast", "br_table.wast", "bulk.wast", "call.wast", "call_indirect.wast", "comments.wast", "const.wast", "conversions.wast", "custom.wast", "data.wast", "elem.wast", "endianness.wast", "exports.wast", "f32.wast", "f32_bitwise.wast", "f32_cmp.wast", "f64.wast", "f64_bitwise.wast", "f64_cmp.wast", "fac.wast", "float_exprs.wast", "float_literals.wast", "float_memory.wast", "float_misc.wast", "forward.wast", "func.wast", "func_ptrs.wast", "global.wast", "i32.wast", "i64.wast", "if.wast", "imports.wast", "inline-module.wast", "int_exprs.wast", "int_literals.wast", "labels.wast", "left-to-right.wast", "linking.wast", "load.wast", "local_get.wast", "local_set.wast", "local_tee.wast", "loop.wast", "memory.wast", "memory_copy.wast", "memory_fill.wast", "memory_grow.wast", "memory_init.wast", "memory_redundancy.wast", "memory_size.wast", "memory_trap.wast", "names.wast", "nop.wast", "obsolete-keywords.wast", "ref_func.wast", "ref_is_null.wast", "ref_null.wast", "return.wast", "select.wast", "skip-stack-guard-page.wast", "stack.wast", "start.wast", "store.wast", "switch.wast", "table-sub.wast", "table.wast", "table_copy.wast", "table_fill.wast", "table_get.wast", "table_grow.wast", "table_init.wast", "table_set.wast", "table_size.wast", "token.wast", "traps.wast", "type.wast", "unreachable.wast", "unreached-invalid.wast", "unreached-valid.wast", "unwind.wast", "utf8-custom-section-id.wast", "utf8-import-field.wast", "utf8-import-module.wast", "utf8-invalid-encoding.wast"]; /// List of all tests that apply to the simd proposal #[rustfmt::skip] From c00031a82782393eb32a9143aedb61e902a7c5d0 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sat, 5 Oct 2024 23:05:42 +0200 Subject: [PATCH 17/54] chore: update deps Signed-off-by: Henry Gressmann --- Cargo.lock | 92 ++++++++++--------- Cargo.toml | 4 +- crates/parser/Cargo.toml | 2 +- crates/parser/src/lib.rs | 1 + crates/parser/src/visit.rs | 10 +- crates/tinywasm/src/interpreter/mod.rs | 1 + crates/tinywasm/src/reference.rs | 4 +- crates/tinywasm/src/store/table.rs | 4 +- crates/tinywasm/tests/generated/wasm-1.csv | 2 +- crates/tinywasm/tests/generated/wasm-2.csv | 2 +- .../tests/generated/wasm-multi-memory.csv | 2 +- crates/wasm-testsuite/data | 2 +- 12 files changed, 67 insertions(+), 59 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 670a20e..eaea884 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -68,9 +68,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bitflags" @@ -128,9 +128,9 @@ dependencies = [ [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "cast" @@ -173,18 +173,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.17" +version = "4.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" +checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.17" +version = "4.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" +checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" dependencies = [ "anstyle", "clap_lex", @@ -368,6 +368,12 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" + [[package]] name = "hermit-abi" version = "0.4.0" @@ -388,12 +394,12 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.0", ] [[package]] @@ -430,9 +436,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.158" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libm" @@ -483,9 +489,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "oorandom" @@ -578,9 +584,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.6" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", @@ -590,9 +596,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", @@ -601,28 +607,28 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rend" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc8d57aa48e8477046d7d6296d920a1f50bbbaf45047ec46c52f6d6cccea7ef7" +checksum = "a31c1f1959e4db12c985c0283656be0925f1539549db1e47c4bd0b8b599e1ef7" dependencies = [ "bytecheck", ] [[package]] name = "rkyv" -version = "0.8.1" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a1dfb7c03271e31aad881e521cfe25bda0206ee94b1af152957f4f49e25ee23" +checksum = "395027076c569819ea6035ee62e664f5e03d74e281744f55261dd1afd939212b" dependencies = [ "bytecheck", "bytes", - "hashbrown", + "hashbrown 0.14.5", "indexmap", "munge", "ptr_meta", @@ -635,9 +641,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.8.1" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa3ca4a30c576aeb76aea84370da286f74d12d32029da8caec3d53b5a36a7539" +checksum = "09cb82b74b4810f07e460852c32f522e979787691b0b7b7439fe473e49d49b2f" dependencies = [ "proc-macro2", "quote", @@ -745,15 +751,15 @@ dependencies = [ [[package]] name = "simdutf8" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "syn" -version = "2.0.77" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -865,9 +871,9 @@ checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "uuid" @@ -893,9 +899,9 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.217.0" +version = "0.218.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b88b0814c9a2b323a9b46c687e726996c255ac8b64aa237dd11c81ed4854760" +checksum = "22b896fa8ceb71091ace9bcb81e853f54043183a1c9667cf93422c40252ffa0a" dependencies = [ "leb128", ] @@ -909,22 +915,22 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.217.0" +version = "0.218.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca917a21307d3adf2b9857b94dd05ebf8496bdcff4437a9b9fb3899d3e6c74e7" +checksum = "b09e46c7fceceaa72b2dd1a8a137ea7fd8f93dfaa69806010a709918e496c5dc" dependencies = [ "ahash", "bitflags", - "hashbrown", + "hashbrown 0.14.5", "indexmap", "semver", ] [[package]] name = "wast" -version = "217.0.0" +version = "218.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79004ecebded92d3c710d4841383368c7f04b63d0992ddd6b0c7d5029b7629b7" +checksum = "8a53cd1f0fa505df97557e36a58bddb8296e2fcdcd089529545ebfdb18a1b9d7" dependencies = [ "bumpalo", "leb128", @@ -935,9 +941,9 @@ dependencies = [ [[package]] name = "wat" -version = "1.217.0" +version = "1.218.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c126271c3d92ca0f7c63e4e462e40c69cca52fd4245fcda730d1cf558fb55088" +checksum = "4f87f8e14e776762e07927c27c2054d2cf678aab9aae2d431a79b3e31e4dd391" dependencies = [ "wast", ] diff --git a/Cargo.toml b/Cargo.toml index f5141ec..33c354c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,8 +4,8 @@ default-members=[".", "crates/tinywasm", "crates/types", "crates/parser"] resolver="2" [workspace.dependencies] -wast="217" -wat="1.217" +wast="218" +wat="1.218" eyre="0.6" log="0.4" pretty_env_logger="0.5" diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index fa16664..aa2f589 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -9,7 +9,7 @@ repository.workspace=true rust-version.workspace=true [dependencies] -wasmparser={version="0.217", default-features=false, features=["validate", "features"]} +wasmparser={version="0.218", default-features=false, features=["validate", "features"]} log={workspace=true, optional=true} tinywasm-types={version="0.8.0-alpha.0", path="../types", default-features=false} diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index 8c68c64..e736576 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -66,6 +66,7 @@ impl Parser { custom_page_sizes: true, gc_types: true, + stack_switching: false, component_model: false, component_model_nested_names: false, component_model_values: false, diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs index 4e39a5a..c9e5eac 100644 --- a/crates/parser/src/visit.rs +++ b/crates/parser/src/visit.rs @@ -8,7 +8,7 @@ use wasmparser::{FuncValidator, FuncValidatorAllocations, FunctionBody, VisitOpe struct ValidateThenVisit<'a, R: WasmModuleResources>(usize, &'a mut FunctionBuilder); macro_rules! validate_then_visit { - ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident)*) => {$( + ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {$( fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output { self.1.$visit($($($arg.clone()),*)?); self.1.validator_visitor(self.0).$visit($($($arg),*)?)?; @@ -118,8 +118,8 @@ impl FunctionBuilder { } macro_rules! impl_visit_operator { - ($(@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident)*) => { - $(impl_visit_operator!(@@$proposal $op $({ $($arg: $argty),* })? => $visit);)* + ($(@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => { + $(impl_visit_operator!(@@$proposal $op $({ $($arg: $argty),* })? => $visit ($($ann:tt)*));)* }; (@@mvp $($rest:tt)* ) => {}; @@ -129,7 +129,7 @@ macro_rules! impl_visit_operator { (@@bulk_memory $($rest:tt)* ) => {}; (@@tail_call $($rest:tt)* ) => {}; // (@@simd $($rest:tt)* ) => {}; - (@@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident) => { + (@@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*)) => { #[cold] fn $visit(&mut self $($(,$arg: $argty)*)?) { self.unsupported(stringify!($visit)) @@ -137,7 +137,7 @@ macro_rules! impl_visit_operator { }; } -impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuilder { +impl wasmparser::VisitOperator<'_> for FunctionBuilder { type Output = (); wasmparser::for_each_operator!(impl_visit_operator); diff --git a/crates/tinywasm/src/interpreter/mod.rs b/crates/tinywasm/src/interpreter/mod.rs index 0b7df2f..c97708e 100644 --- a/crates/tinywasm/src/interpreter/mod.rs +++ b/crates/tinywasm/src/interpreter/mod.rs @@ -1,5 +1,6 @@ pub(crate) mod executor; pub(crate) mod num_helpers; +// pub(crate) mod simd; pub(crate) mod stack; mod values; diff --git a/crates/tinywasm/src/reference.rs b/crates/tinywasm/src/reference.rs index 3765098..e151c87 100644 --- a/crates/tinywasm/src/reference.rs +++ b/crates/tinywasm/src/reference.rs @@ -16,14 +16,14 @@ pub struct MemoryRef<'a>(pub(crate) &'a MemoryInstance); #[derive(Debug)] pub struct MemoryRefMut<'a>(pub(crate) &'a mut MemoryInstance); -impl<'a> MemoryRefLoad for MemoryRef<'a> { +impl MemoryRefLoad for MemoryRef<'_> { /// Load a slice of memory fn load(&self, offset: usize, len: usize) -> Result<&[u8]> { self.0.load(offset, len) } } -impl<'a> MemoryRefLoad for MemoryRefMut<'a> { +impl MemoryRefLoad for MemoryRefMut<'_> { /// Load a slice of memory fn load(&self, offset: usize, len: usize) -> Result<&[u8]> { self.0.load(offset, len) diff --git a/crates/tinywasm/src/store/table.rs b/crates/tinywasm/src/store/table.rs index 0e08582..200d331 100644 --- a/crates/tinywasm/src/store/table.rs +++ b/crates/tinywasm/src/store/table.rs @@ -49,7 +49,7 @@ impl TableInstance { pub(crate) fn get(&self, addr: TableAddr) -> Result<&TableElement> { // self.elements.get(addr as usize).ok_or_else(|| Error::Trap(Trap::UndefinedElement { index: addr as usize })) - self.elements.get(addr as usize).ok_or_else(|| { + self.elements.get(addr as usize).ok_or({ Error::Trap(Trap::TableOutOfBounds { offset: addr as usize, len: 1, max: self.elements.len() }) }) } @@ -135,7 +135,7 @@ impl TableInstance { pub(crate) fn init(&mut self, offset: i32, init: &[TableElement]) -> Result<()> { let offset = offset as usize; - let end = offset.checked_add(init.len()).ok_or_else(|| { + let end = offset.checked_add(init.len()).ok_or({ Error::Trap(crate::Trap::TableOutOfBounds { offset, len: init.len(), max: self.elements.len() }) })?; diff --git a/crates/tinywasm/tests/generated/wasm-1.csv b/crates/tinywasm/tests/generated/wasm-1.csv index 64f92d1..1447fdf 100644 --- a/crates/tinywasm/tests/generated/wasm-1.csv +++ b/crates/tinywasm/tests/generated/wasm-1.csv @@ -4,4 +4,4 @@ 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}] 0.6.1,27572,335,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.7.0,27572,335,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.8.0,20358,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":126,"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":98,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_grow.wast","passed":104,"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.8.0,20360,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":128,"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":98,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_grow.wast","passed":104,"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/tinywasm/tests/generated/wasm-2.csv b/crates/tinywasm/tests/generated/wasm-2.csv index 0e43692..548da5b 100644 --- a/crates/tinywasm/tests/generated/wasm-2.csv +++ b/crates/tinywasm/tests/generated/wasm-2.csv @@ -9,4 +9,4 @@ 0.6.0,20278,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.6.1,20278,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.7.0,20278,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.8.0,28006,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":126,"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":117,"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":98,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_copy.wast","passed":4450,"failed":0},{"name":"memory_fill.wast","passed":100,"failed":0},{"name":"memory_grow.wast","passed":104,"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":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":16,"failed":0},{"name":"ref_null.wast","passed":3,"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-sub.wast","passed":2,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"table_copy.wast","passed":1728,"failed":0},{"name":"table_fill.wast","passed":45,"failed":0},{"name":"table_get.wast","passed":16,"failed":0},{"name":"table_grow.wast","passed":58,"failed":0},{"name":"table_init.wast","passed":780,"failed":0},{"name":"table_set.wast","passed":26,"failed":0},{"name":"table_size.wast","passed":39,"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.8.0,28008,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":128,"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":117,"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":98,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_copy.wast","passed":4450,"failed":0},{"name":"memory_fill.wast","passed":100,"failed":0},{"name":"memory_grow.wast","passed":104,"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":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":16,"failed":0},{"name":"ref_null.wast","passed":3,"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-sub.wast","passed":2,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"table_copy.wast","passed":1728,"failed":0},{"name":"table_fill.wast","passed":45,"failed":0},{"name":"table_get.wast","passed":16,"failed":0},{"name":"table_grow.wast","passed":58,"failed":0},{"name":"table_init.wast","passed":780,"failed":0},{"name":"table_set.wast","passed":26,"failed":0},{"name":"table_size.wast","passed":39,"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/tinywasm/tests/generated/wasm-multi-memory.csv b/crates/tinywasm/tests/generated/wasm-multi-memory.csv index b730f97..088ba86 100644 --- a/crates/tinywasm/tests/generated/wasm-multi-memory.csv +++ b/crates/tinywasm/tests/generated/wasm-multi-memory.csv @@ -1 +1 @@ -0.8.0,1870,0,[{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"align.wast","passed":160,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"binary.wast","passed":124,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"imports.wast","passed":175,"failed":0},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"multi-memory/simd_memory-multi.wast (skipped)","passed":0,"failed":0},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"traps0.wast","passed":15,"failed":0}] +0.8.0,1872,0,[{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"align.wast","passed":160,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"binary.wast","passed":126,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"imports.wast","passed":175,"failed":0},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"multi-memory/simd_memory-multi.wast (skipped)","passed":0,"failed":0},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"traps0.wast","passed":15,"failed":0}] diff --git a/crates/wasm-testsuite/data b/crates/wasm-testsuite/data index 7c3ec23..cbde6d5 160000 --- a/crates/wasm-testsuite/data +++ b/crates/wasm-testsuite/data @@ -1 +1 @@ -Subproject commit 7c3ec23ab19b37c68976b555f9491752cbda6d5f +Subproject commit cbde6d5f26ba12d4f455b65bd0648cdba4d95f15 From 4c1f44a79d0e04fb33042c2eabc27040d260dfa5 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Fri, 11 Oct 2024 22:44:29 +0200 Subject: [PATCH 18/54] feat: add simd support to the parser --- Cargo.lock | 43 ++-- Cargo.toml | 6 +- crates/cli/Cargo.toml | 2 +- crates/parser/Cargo.toml | 4 +- crates/parser/src/conversion.rs | 4 +- crates/parser/src/lib.rs | 3 +- crates/parser/src/module.rs | 21 +- crates/parser/src/visit.rs | 130 ++++++++--- crates/tinywasm/Cargo.toml | 4 +- crates/tinywasm/src/interpreter/executor.rs | 58 ++--- .../src/interpreter/stack/call_stack.rs | 27 ++- .../src/interpreter/stack/value_stack.rs | 4 +- crates/tinywasm/src/interpreter/values.rs | 46 ++-- crates/tinywasm/tests/generated/wasm-simd.csv | 1 + crates/types/src/instructions.rs | 211 ++++++++++++------ crates/types/src/lib.rs | 38 ++++ crates/wasm-testsuite/Cargo.toml | 2 +- 17 files changed, 408 insertions(+), 196 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eaea884..03584d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -173,18 +173,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.19" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.19" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstyle", "clap_lex", @@ -517,9 +517,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" dependencies = [ "unicode-ident", ] @@ -613,9 +613,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rend" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31c1f1959e4db12c985c0283656be0925f1539549db1e47c4bd0b8b599e1ef7" +checksum = "a35e8a6bf28cd121053a66aa2e6a2e3eaffad4a60012179f0e864aa5ffeff215" dependencies = [ "bytecheck", ] @@ -802,7 +802,7 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tinywasm" -version = "0.8.0" +version = "0.9.0-alpha.0" dependencies = [ "criterion", "eyre", @@ -820,7 +820,7 @@ dependencies = [ [[package]] name = "tinywasm-cli" -version = "0.8.0" +version = "0.9.0-alpha.0" dependencies = [ "argh", "eyre", @@ -832,7 +832,7 @@ dependencies = [ [[package]] name = "tinywasm-parser" -version = "0.8.0" +version = "0.9.0-alpha.0" dependencies = [ "log", "tinywasm-types", @@ -851,7 +851,7 @@ dependencies = [ [[package]] name = "tinywasm-types" -version = "0.8.0" +version = "0.9.0-alpha.0" dependencies = [ "log", "rkyv", @@ -899,25 +899,26 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.218.0" +version = "0.219.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22b896fa8ceb71091ace9bcb81e853f54043183a1c9667cf93422c40252ffa0a" +checksum = "29cbbd772edcb8e7d524a82ee8cef8dd046fc14033796a754c3ad246d019fa54" dependencies = [ "leb128", + "wasmparser", ] [[package]] name = "wasm-testsuite" -version = "0.5.0" +version = "0.6.0-alpha.0" dependencies = [ "rust-embed", ] [[package]] name = "wasmparser" -version = "0.218.0" +version = "0.219.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09e46c7fceceaa72b2dd1a8a137ea7fd8f93dfaa69806010a709918e496c5dc" +checksum = "5c771866898879073c53b565a6c7b49953795159836714ac56a5befb581227c5" dependencies = [ "ahash", "bitflags", @@ -928,9 +929,9 @@ dependencies = [ [[package]] name = "wast" -version = "218.0.0" +version = "219.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a53cd1f0fa505df97557e36a58bddb8296e2fcdcd089529545ebfdb18a1b9d7" +checksum = "4f79a9d9df79986a68689a6b40bcc8d5d40d807487b235bebc2ac69a242b54a1" dependencies = [ "bumpalo", "leb128", @@ -941,9 +942,9 @@ dependencies = [ [[package]] name = "wat" -version = "1.218.0" +version = "1.219.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f87f8e14e776762e07927c27c2054d2cf678aab9aae2d431a79b3e31e4dd391" +checksum = "8bc3cf014fb336883a411cd662f987abf6a1d2a27f2f0008616a0070bbf6bd0d" dependencies = [ "wast", ] diff --git a/Cargo.toml b/Cargo.toml index 33c354c..0125c7b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,15 +4,15 @@ default-members=[".", "crates/tinywasm", "crates/types", "crates/parser"] resolver="2" [workspace.dependencies] -wast="218" -wat="1.218" +wast="219" +wat="1.219" eyre="0.6" log="0.4" pretty_env_logger="0.5" criterion={version="0.5", default-features=false, features=["cargo_bench_support", "rayon"]} [workspace.package] -version="0.8.0" +version="0.9.0-alpha.0" rust-version="1.81" edition="2021" license="MIT OR Apache-2.0" diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 51a669d..d5e64a8 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -15,7 +15,7 @@ path="src/bin.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tinywasm={version="0.8.0-alpha.0", path="../tinywasm", features=["std", "parser"]} +tinywasm={version="0.9.0-alpha.0", path="../tinywasm", features=["std", "parser"]} argh="0.1" eyre={workspace=true} log={workspace=true} diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index aa2f589..83bb32b 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -9,9 +9,9 @@ repository.workspace=true rust-version.workspace=true [dependencies] -wasmparser={version="0.218", default-features=false, features=["validate", "features"]} +wasmparser={version="0.219", default-features=false, features=["validate", "features"]} log={workspace=true, optional=true} -tinywasm-types={version="0.8.0-alpha.0", path="../types", default-features=false} +tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false} [features] default=["std", "logging"] diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs index 76099ca..1ebe392 100644 --- a/crates/parser/src/conversion.rs +++ b/crates/parser/src/conversion.rs @@ -203,8 +203,8 @@ pub(crate) fn convert_module_code( } } - let (body, allocations) = process_operators_and_validate(validator, func, local_addr_map)?; - Ok(((body, local_counts), allocations)) + let (body, data, allocations) = process_operators_and_validate(validator, func, local_addr_map)?; + Ok(((body, data, local_counts), allocations)) } pub(crate) fn convert_module_type(ty: wasmparser::RecGroup) -> Result { diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index e736576..2222ffa 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -61,10 +61,11 @@ impl Parser { function_references: true, tail_call: true, multi_memory: true, - memory64: false, simd: true, + memory64: true, custom_page_sizes: true, + wide_arithmetic: false, gc_types: true, stack_switching: false, component_model: false, diff --git a/crates/parser/src/module.rs b/crates/parser/src/module.rs index ff7d109..9b31f9e 100644 --- a/crates/parser/src/module.rs +++ b/crates/parser/src/module.rs @@ -3,12 +3,12 @@ use crate::{conversion, ParseError, Result}; use alloc::string::ToString; use alloc::{boxed::Box, format, vec::Vec}; use tinywasm_types::{ - Data, Element, Export, FuncType, Global, Import, Instruction, MemoryType, TableType, TinyWasmModule, ValType, - ValueCounts, ValueCountsSmall, WasmFunction, + Data, Element, Export, FuncType, Global, Import, Instruction, MemoryType, TableType, TinyWasmModule, ValueCounts, + ValueCountsSmall, WasmFunction, WasmFunctionData, }; use wasmparser::{FuncValidatorAllocations, Payload, Validator}; -pub(crate) type Code = (Box<[Instruction]>, ValueCounts); +pub(crate) type Code = (Box<[Instruction]>, WasmFunctionData, ValueCounts); #[derive(Default)] pub(crate) struct ModuleReader { @@ -179,7 +179,6 @@ impl ModuleReader { Ok(()) } - #[inline] pub(crate) fn into_module(self) -> Result { if !self.end_reached { return Err(ParseError::EndNotReached); @@ -193,18 +192,10 @@ impl ModuleReader { .code .into_iter() .zip(self.code_type_addrs) - .map(|((instructions, locals), ty_idx)| { - let mut params = ValueCountsSmall::default(); + .map(|((instructions, 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(); - for param in &ty.params { - match param { - ValType::I32 | ValType::F32 => params.c32 += 1, - ValType::I64 | ValType::F64 => params.c64 += 1, - ValType::V128 => params.c128 += 1, - ValType::RefExtern | ValType::RefFunc => params.cref += 1, - } - } - WasmFunction { instructions, locals, params, ty } + let params = ValueCountsSmall::from(&ty.params); + WasmFunction { instructions, data, locals, params, ty } }) .collect::>() .into_boxed_slice(); diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs index c9e5eac..2e80d20 100644 --- a/crates/parser/src/visit.rs +++ b/crates/parser/src/visit.rs @@ -3,7 +3,7 @@ use crate::Result; use crate::conversion::{convert_heaptype, convert_valtype}; use alloc::string::ToString; use alloc::{boxed::Box, vec::Vec}; -use tinywasm_types::{Instruction, MemoryArg}; +use tinywasm_types::{Instruction, MemoryArg, SimdInstruction, WasmFunctionData}; use wasmparser::{FuncValidator, FuncValidatorAllocations, FunctionBody, VisitOperator, WasmModuleResources}; struct ValidateThenVisit<'a, R: WasmModuleResources>(usize, &'a mut FunctionBuilder); @@ -26,7 +26,7 @@ pub(crate) fn process_operators_and_validate( validator: FuncValidator, body: FunctionBody<'_>, local_addr_map: Vec, -) -> Result<(Box<[Instruction]>, FuncValidatorAllocations)> { +) -> Result<(Box<[Instruction]>, WasmFunctionData, FuncValidatorAllocations)> { let mut reader = body.get_operators_reader()?; let remaining = reader.get_binary_reader().bytes_remaining(); let mut builder = FunctionBuilder::new(remaining, validator, local_addr_map); @@ -40,42 +40,65 @@ pub(crate) fn process_operators_and_validate( return Err(builder.errors.remove(0)); } - Ok((builder.instructions.into_boxed_slice(), builder.validator.into_allocations())) + Ok(( + builder.instructions.into_boxed_slice(), + WasmFunctionData { v128_constants: builder.v128_constants.into_boxed_slice() }, + builder.validator.into_allocations(), + )) } macro_rules! define_operand { - ($name:ident($instr:ident, $ty:ty)) => { + ($name:ident($instr:expr, $ty:ty)) => { fn $name(&mut self, arg: $ty) -> Self::Output { - self.instructions.push(Instruction::$instr(arg)); + self.instructions.push($instr(arg).into()); } }; - ($name:ident($instr:ident, $ty:ty, $ty2:ty)) => { + ($name:ident($instr:expr, $ty:ty, $ty2:ty)) => { fn $name(&mut self, arg: $ty, arg2: $ty2) -> Self::Output { - self.instructions.push(Instruction::$instr(arg, arg2)); + self.instructions.push($instr(arg, arg2).into()); } }; - ($name:ident($instr:ident)) => { + ($name:ident($instr:expr)) => { fn $name(&mut self) -> Self::Output { - self.instructions.push(Instruction::$instr); + self.instructions.push($instr.into()); } }; } macro_rules! define_operands { ($($name:ident($instr:ident $(,$ty:ty)*)),*) => {$( - define_operand!($name($instr $(,$ty)*)); + define_operand!($name(Instruction::$instr $(,$ty)*)); + )*}; +} + +macro_rules! define_operands_simd { + ($($name:ident($instr:ident $(,$ty:ty)*)),*) => {$( + define_operand!($name(SimdInstruction::$instr $(,$ty)*)); )*}; } macro_rules! define_mem_operands { ($($name:ident($instr:ident)),*) => {$( fn $name(&mut self, memarg: wasmparser::MemArg) -> Self::Output { - self.instructions.push(Instruction::$instr { - offset: memarg.offset, - mem_addr: memarg.memory, - }); + self.instructions.push(Instruction::$instr(MemoryArg::new(memarg.offset, memarg.memory))); + } + )*}; +} + +macro_rules! define_mem_operands_simd { + ($($name:ident($instr:ident)),*) => {$( + fn $name(&mut self, memarg: wasmparser::MemArg) -> Self::Output { + self.instructions.push(SimdInstruction::$instr(MemoryArg::new(memarg.offset, memarg.memory)).into()); + } + )*}; +} + +macro_rules! define_mem_operands_simd_lane { + ($($name:ident($instr:ident)),*) => {$( + fn $name(&mut self, memarg: wasmparser::MemArg, lane: u8) -> Self::Output { + self.instructions.push(SimdInstruction::$instr(MemoryArg::new(memarg.offset, memarg.memory), lane).into()); } )*}; } @@ -83,6 +106,7 @@ macro_rules! define_mem_operands { pub(crate) struct FunctionBuilder { validator: FuncValidator, instructions: Vec, + v128_constants: Vec, label_ptrs: Vec, local_addr_map: Vec, errors: Vec, @@ -107,6 +131,7 @@ impl FunctionBuilder { validator, local_addr_map, instructions: Vec::with_capacity(instr_capacity), + v128_constants: Vec::new(), label_ptrs: Vec::with_capacity(256), errors: Vec::new(), } @@ -127,8 +152,8 @@ macro_rules! impl_visit_operator { (@@sign_extension $($rest:tt)* ) => {}; (@@saturating_float_to_int $($rest:tt)* ) => {}; (@@bulk_memory $($rest:tt)* ) => {}; - (@@tail_call $($rest:tt)* ) => {}; - // (@@simd $($rest:tt)* ) => {}; + // (@@tail_call $($rest:tt)* ) => {}; + (@@simd $($rest:tt)* ) => {}; (@@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*)) => { #[cold] fn $visit(&mut self $($(,$arg: $argty)*)?) { @@ -142,7 +167,7 @@ impl wasmparser::VisitOperator<'_> for FunctionBuilder wasmparser::VisitOperator<'_> for FunctionBuilder Self::Output { - self.instructions.push(Instruction::ReturnCall(function_index)); + fn visit_i8x16_shuffle(&mut self, lanes: [u8; 16]) -> Self::Output { + self.v128_constants.push(u128::from_le_bytes(lanes)); + self.instructions.push(SimdInstruction::I8x16Shuffle(self.v128_constants.len() as u32 - 1).into()); } - fn visit_return_call_indirect(&mut self, type_index: u32, table_index: u32) -> Self::Output { - self.instructions.push(Instruction::ReturnCallIndirect(type_index, table_index)); + fn visit_v128_const(&mut self, value: wasmparser::V128) -> Self::Output { + self.v128_constants.push(value.i128() as u128); + self.instructions.push(SimdInstruction::V128Const(self.v128_constants.len() as u32 - 1).into()); } + // fn visit_return_call(&mut self, function_index: u32) -> Self::Output { + // self.instructions.push(Instruction::ReturnCall(function_index)); + // } + + // fn visit_return_call_indirect(&mut self, type_index: u32, table_index: u32) -> Self::Output { + // self.instructions.push(Instruction::ReturnCallIndirect(type_index, table_index)); + // } + fn visit_global_set(&mut self, global_index: u32) -> Self::Output { match self.validator.get_operand_type(0) { Some(Some(t)) => self.instructions.push(match t { @@ -206,11 +285,6 @@ impl wasmparser::VisitOperator<'_> for FunctionBuilder self.visit_unreachable(), } } - fn visit_i32_store(&mut self, memarg: wasmparser::MemArg) -> Self::Output { - let arg = MemoryArg { offset: memarg.offset, mem_addr: memarg.memory }; - let i32store = Instruction::I32Store { offset: arg.offset, mem_addr: arg.mem_addr }; - self.instructions.push(i32store); - } fn visit_local_get(&mut self, idx: u32) -> Self::Output { let Ok(resolved_idx) = self.local_addr_map[idx as usize].try_into() else { diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index 4dc82bb..401e3de 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -15,8 +15,8 @@ path="src/lib.rs" [dependencies] log={workspace=true, optional=true} -tinywasm-parser={version="0.8.0-alpha.0", path="../parser", default-features=false, optional=true} -tinywasm-types={version="0.8.0-alpha.0", path="../types", default-features=false} +tinywasm-parser={version="0.9.0-alpha.0", path="../parser", default-features=false, optional=true} +tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false} libm={version="0.2", default-features=false} [dev-dependencies] diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index c2df82c..2326227 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -26,7 +26,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { Ok(Self { cf: current_frame, module: current_module, stack, store }) } - #[inline] + #[inline(always)] pub(crate) fn run_to_completion(&mut self) -> Result<()> { loop { if let ControlFlow::Break(res) = self.exec_next() { @@ -114,30 +114,30 @@ impl<'store, 'stack> Executor<'store, 'stack> { ElemDrop(elem_index) => self.exec_elem_drop(*elem_index), TableCopy { from, to } => self.exec_table_copy(*from, *to).to_cf()?, - I32Store { mem_addr, offset } => self.exec_mem_store::(*mem_addr, *offset, |v| v)?, - I64Store { mem_addr, offset } => self.exec_mem_store::(*mem_addr, *offset, |v| v)?, - F32Store { mem_addr, offset } => self.exec_mem_store::(*mem_addr, *offset, |v| v)?, - F64Store { mem_addr, offset } => self.exec_mem_store::(*mem_addr, *offset, |v| v)?, - I32Store8 { mem_addr, offset } => self.exec_mem_store::(*mem_addr, *offset, |v| v as i8)?, - I32Store16 { mem_addr, offset } => self.exec_mem_store::(*mem_addr, *offset, |v| v as i16)?, - I64Store8 { mem_addr, offset } => self.exec_mem_store::(*mem_addr, *offset, |v| v as i8)?, - I64Store16 { mem_addr, offset } => self.exec_mem_store::(*mem_addr, *offset, |v| v as i16)?, - I64Store32 { mem_addr, offset } => self.exec_mem_store::(*mem_addr, *offset, |v| v as i32)?, - - I32Load { mem_addr, offset } => self.exec_mem_load::(*mem_addr, *offset, |v| v)?, - I64Load { mem_addr, offset } => self.exec_mem_load::(*mem_addr, *offset, |v| v)?, - F32Load { mem_addr, offset } => self.exec_mem_load::(*mem_addr, *offset, |v| v)?, - F64Load { mem_addr, offset } => self.exec_mem_load::(*mem_addr, *offset, |v| v)?, - I32Load8S { mem_addr, offset } => self.exec_mem_load::(*mem_addr, *offset, |v| v as i32)?, - I32Load8U { mem_addr, offset } => self.exec_mem_load::(*mem_addr, *offset, |v| v as i32)?, - I32Load16S { mem_addr, offset } => self.exec_mem_load::(*mem_addr, *offset, |v| v as i32)?, - I32Load16U { mem_addr, offset } => self.exec_mem_load::(*mem_addr, *offset, |v| v as i32)?, - I64Load8S { mem_addr, offset } => self.exec_mem_load::(*mem_addr, *offset, |v| v as i64)?, - I64Load8U { mem_addr, offset } => self.exec_mem_load::(*mem_addr, *offset, |v| v as i64)?, - I64Load16S { mem_addr, offset } => self.exec_mem_load::(*mem_addr, *offset, |v| v as i64)?, - I64Load16U { mem_addr, offset } => self.exec_mem_load::(*mem_addr, *offset, |v| v as i64)?, - I64Load32S { mem_addr, offset } => self.exec_mem_load::(*mem_addr, *offset, |v| v as i64)?, - I64Load32U { mem_addr, offset } => self.exec_mem_load::(*mem_addr, *offset, |v| v as i64)?, + I32Store(m) => self.exec_mem_store::(m.mem_addr(), m.offset(), |v| v)?, + I64Store(m) => self.exec_mem_store::(m.mem_addr(), m.offset(), |v| v)?, + F32Store(m) => self.exec_mem_store::(m.mem_addr(), m.offset(), |v| v)?, + F64Store(m) => self.exec_mem_store::(m.mem_addr(), m.offset(), |v| v)?, + I32Store8(m) => self.exec_mem_store::(m.mem_addr(), m.offset(), |v| v as i8)?, + I32Store16(m) => self.exec_mem_store::(m.mem_addr(), m.offset(), |v| v as i16)?, + I64Store8(m) => self.exec_mem_store::(m.mem_addr(), m.offset(), |v| v as i8)?, + I64Store16(m) => self.exec_mem_store::(m.mem_addr(), m.offset(), |v| v as i16)?, + I64Store32(m) => self.exec_mem_store::(m.mem_addr(), m.offset(), |v| v as i32)?, + + I32Load(m) => self.exec_mem_load::(m.mem_addr(), m.offset(), |v| v)?, + I64Load(m) => self.exec_mem_load::(m.mem_addr(), m.offset(), |v| v)?, + F32Load(m) => self.exec_mem_load::(m.mem_addr(), m.offset(), |v| v)?, + F64Load(m) => self.exec_mem_load::(m.mem_addr(), m.offset(), |v| v)?, + I32Load8S(m) => self.exec_mem_load::(m.mem_addr(), m.offset(), |v| v as i32)?, + I32Load8U(m) => self.exec_mem_load::(m.mem_addr(), m.offset(), |v| v as i32)?, + I32Load16S(m) => self.exec_mem_load::(m.mem_addr(), m.offset(), |v| v as i32)?, + I32Load16U(m) => self.exec_mem_load::(m.mem_addr(), m.offset(), |v| v as i32)?, + I64Load8S(m) => self.exec_mem_load::(m.mem_addr(), m.offset(), |v| v as i64)?, + I64Load8U(m) => self.exec_mem_load::(m.mem_addr(), m.offset(), |v| v as i64)?, + I64Load16S(m) => self.exec_mem_load::(m.mem_addr(), m.offset(), |v| v as i64)?, + I64Load16U(m) => self.exec_mem_load::(m.mem_addr(), m.offset(), |v| v as i64)?, + I64Load32S(m) => self.exec_mem_load::(m.mem_addr(), m.offset(), |v| v as i64)?, + I64Load32U(m) => self.exec_mem_load::(m.mem_addr(), m.offset(), |v| v as i64)?, I64Eqz => self.stack.values.replace_top::(|v| Ok(i32::from(v == 0))).to_cf()?, I32Eqz => self.stack.values.replace_top_same::(|v| Ok(i32::from(v == 0))).to_cf()?, @@ -302,6 +302,10 @@ impl<'store, 'stack> Executor<'store, 'stack> { LocalCopy128(from, to) => self.exec_local_copy::(*from, *to), LocalCopyRef(from, to) => self.exec_local_copy::(*from, *to), + Simd(_) => { + unreachable!("unimplemented sidm instruction"); + } + instr => { unreachable!("unimplemented instruction: {:?}", instr); } @@ -585,10 +589,10 @@ impl<'store, 'stack> Executor<'store, 'stack> { mem.store(dst as usize, size as usize, &data[offset as usize..((offset + size) as usize)]) } fn exec_data_drop(&mut self, data_index: u32) { - self.store.get_data_mut(self.module.resolve_data_addr(data_index)).drop() + self.store.get_data_mut(self.module.resolve_data_addr(data_index)).drop(); } fn exec_elem_drop(&mut self, elem_index: u32) { - self.store.get_elem_mut(self.module.resolve_elem_addr(elem_index)).drop() + self.store.get_elem_mut(self.module.resolve_elem_addr(elem_index)).drop(); } fn exec_table_copy(&mut self, from: u32, to: u32) -> Result<()> { let size: i32 = self.stack.values.pop(); diff --git a/crates/tinywasm/src/interpreter/stack/call_stack.rs b/crates/tinywasm/src/interpreter/stack/call_stack.rs index 7c2be9c..f0e8d18 100644 --- a/crates/tinywasm/src/interpreter/stack/call_stack.rs +++ b/crates/tinywasm/src/interpreter/stack/call_stack.rs @@ -22,12 +22,12 @@ impl CallStack { Self { stack: vec![initial_frame] } } - #[inline(always)] + #[inline] pub(crate) fn pop(&mut self) -> Option { self.stack.pop() } - #[inline(always)] + #[inline] pub(crate) fn push(&mut self, call_frame: CallFrame) -> ControlFlow> { if unlikely((self.stack.len() + 1) >= MAX_CALL_STACK_SIZE) { return ControlFlow::Break(Some(Trap::CallStackOverflow.into())); @@ -60,44 +60,47 @@ impl Locals { } pub(crate) fn set(&mut self, local_index: LocalAddr, value: T) { - T::local_set(self, local_index, value) + T::local_set(self, local_index, value); } } impl CallFrame { - #[inline(always)] + #[inline] pub(crate) fn instr_ptr(&self) -> usize { self.instr_ptr } - #[inline(always)] + #[inline] pub(crate) fn incr_instr_ptr(&mut self) { self.instr_ptr += 1; } - #[inline(always)] + #[inline] pub(crate) fn jump(&mut self, offset: usize) { self.instr_ptr += offset; } - #[inline(always)] + #[inline] pub(crate) fn module_addr(&self) -> ModuleInstanceAddr { self.module_addr } - #[inline(always)] + #[inline] pub(crate) fn block_ptr(&self) -> u32 { self.block_ptr } #[inline(always)] pub(crate) fn fetch_instr(&self) -> &Instruction { - &self.func_instance.instructions[self.instr_ptr] + match self.func_instance.instructions.get(self.instr_ptr) { + Some(instr) => instr, + None => unreachable!("Instruction out of bounds, this is a bug"), + } } /// Break to a block at the given index (relative to the current frame) /// Returns `None` if there is no block at the given index (e.g. if we need to return, this is handled by the caller) - #[inline(always)] + #[inline] pub(crate) fn break_to( &mut self, break_to_relative: u32, @@ -140,7 +143,7 @@ impl CallFrame { Some(()) } - #[inline(always)] + #[inline] pub(crate) fn new( wasm_func_inst: Rc, owner: ModuleInstanceAddr, @@ -192,7 +195,7 @@ impl CallFrame { Self { instr_ptr: 0, func_instance: wasm_func_inst, module_addr: owner, block_ptr, locals } } - #[inline(always)] + #[inline] pub(crate) fn instructions(&self) -> &[Instruction] { &self.func_instance.instructions } diff --git a/crates/tinywasm/src/interpreter/stack/value_stack.rs b/crates/tinywasm/src/interpreter/stack/value_stack.rs index 03c676e..7cbf612 100644 --- a/crates/tinywasm/src/interpreter/stack/value_stack.rs +++ b/crates/tinywasm/src/interpreter/stack/value_stack.rs @@ -48,7 +48,7 @@ impl ValueStack { #[inline] pub(crate) fn push(&mut self, value: T) { - T::stack_push(self, value) + T::stack_push(self, value); } #[inline] @@ -180,7 +180,7 @@ impl ValueStack { pub(crate) fn extend_from_wasmvalues(&mut self, values: &[WasmValue]) { for value in values { - self.push_dyn(value.into()) + self.push_dyn(value.into()); } } } diff --git a/crates/tinywasm/src/interpreter/values.rs b/crates/tinywasm/src/interpreter/values.rs index 7b363a8..99cf443 100644 --- a/crates/tinywasm/src/interpreter/values.rs +++ b/crates/tinywasm/src/interpreter/values.rs @@ -169,7 +169,6 @@ macro_rules! impl_internalvalue { impl sealed::Sealed for $outer {} impl From<$outer> for TinyWasmValue { - #[inline(always)] fn from(value: $outer) -> Self { TinyWasmValue::$variant($to_internal(value)) } @@ -180,44 +179,59 @@ macro_rules! impl_internalvalue { fn stack_push(stack: &mut ValueStack, value: Self) { stack.$stack.push($to_internal(value)); } + #[inline(always)] fn stack_pop(stack: &mut ValueStack) -> Self { - ($to_outer)(stack.$stack.pop().expect("ValueStack underflow, this is a bug")) + match stack.$stack.pop() { + Some(v) => $to_outer(v), + None => unreachable!("ValueStack underflow, this is a bug"), + } } + #[inline(always)] fn stack_peek(stack: &ValueStack) -> Self { - ($to_outer)(*stack.$stack.last().expect("ValueStack underflow, this is a bug")) + match stack.$stack.last() { + Some(v) => $to_outer(*v), + None => unreachable!("ValueStack underflow, this is a bug"), + } } #[inline(always)] fn stack_calculate(stack: &mut ValueStack, func: fn(Self, Self) -> Result) -> Result<()> { let v2 = stack.$stack.pop(); let v1 = stack.$stack.last_mut(); - if let (Some(v1), Some(v2)) = (v1, v2) { - *v1 = $to_internal(func($to_outer(*v1), $to_outer(v2))?); - } else { - unreachable!("ValueStack underflow, this is a bug"); - } - Ok(()) + let (Some(v1), Some(v2)) = (v1, v2) else { + unreachable!("ValueStack underflow, this is a bug"); + }; + + *v1 = $to_internal(func($to_outer(*v1), $to_outer(v2))?); + return Ok(()) } #[inline(always)] fn replace_top(stack: &mut ValueStack, func: fn(Self) -> Result) -> Result<()> { - if let Some(v) = stack.$stack.last_mut() { - *v = $to_internal(func($to_outer(*v))?); - Ok(()) - } else { + let Some(v) = stack.$stack.last_mut() else { unreachable!("ValueStack underflow, this is a bug"); - } + }; + + *v = $to_internal(func($to_outer(*v))?); + Ok(()) } #[inline(always)] fn local_get(locals: &Locals, index: LocalAddr) -> Self { - $to_outer(locals.$locals[index as usize]) + match locals.$locals.get(index as usize) { + Some(v) => $to_outer(*v), + None => unreachable!("Local variable out of bounds, this is a bug"), + } } + #[inline(always)] fn local_set(locals: &mut Locals, index: LocalAddr, value: Self) { - locals.$locals[index as usize] = $to_internal(value); + match locals.$locals.get_mut(index as usize) { + Some(v) => *v = $to_internal(value), + None => unreachable!("Local variable out of bounds, this is a bug"), + } } } )* diff --git a/crates/tinywasm/tests/generated/wasm-simd.csv b/crates/tinywasm/tests/generated/wasm-simd.csv index e9bc8ae..a7fc7ef 100644 --- a/crates/tinywasm/tests/generated/wasm-simd.csv +++ b/crates/tinywasm/tests/generated/wasm-simd.csv @@ -1 +1,2 @@ 0.8.0,1300,24679,[{"name":"simd_address.wast","passed":4,"failed":45},{"name":"simd_align.wast","passed":46,"failed":54},{"name":"simd_bit_shift.wast","passed":39,"failed":213},{"name":"simd_bitwise.wast","passed":28,"failed":141},{"name":"simd_boolean.wast","passed":16,"failed":261},{"name":"simd_const.wast","passed":301,"failed":456},{"name":"simd_conversions.wast","passed":48,"failed":234},{"name":"simd_f32x4.wast","passed":16,"failed":774},{"name":"simd_f32x4_arith.wast","passed":16,"failed":1806},{"name":"simd_f32x4_cmp.wast","passed":24,"failed":2583},{"name":"simd_f32x4_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f32x4_rounding.wast","passed":24,"failed":177},{"name":"simd_f64x2.wast","passed":8,"failed":795},{"name":"simd_f64x2_arith.wast","passed":16,"failed":1809},{"name":"simd_f64x2_cmp.wast","passed":24,"failed":2661},{"name":"simd_f64x2_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f64x2_rounding.wast","passed":24,"failed":177},{"name":"simd_i16x8_arith.wast","passed":11,"failed":183},{"name":"simd_i16x8_arith2.wast","passed":19,"failed":153},{"name":"simd_i16x8_cmp.wast","passed":30,"failed":435},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":4,"failed":17},{"name":"simd_i16x8_extmul_i8x16.wast","passed":12,"failed":105},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":3,"failed":27},{"name":"simd_i16x8_sat_arith.wast","passed":16,"failed":206},{"name":"simd_i32x4_arith.wast","passed":11,"failed":183},{"name":"simd_i32x4_arith2.wast","passed":26,"failed":123},{"name":"simd_i32x4_cmp.wast","passed":40,"failed":435},{"name":"simd_i32x4_dot_i16x8.wast","passed":3,"failed":27},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":4,"failed":17},{"name":"simd_i32x4_extmul_i16x8.wast","passed":12,"failed":105},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":4,"failed":103},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":4,"failed":103},{"name":"simd_i64x2_arith.wast","passed":11,"failed":189},{"name":"simd_i64x2_arith2.wast","passed":2,"failed":23},{"name":"simd_i64x2_cmp.wast","passed":10,"failed":103},{"name":"simd_i64x2_extmul_i32x4.wast","passed":12,"failed":105},{"name":"simd_i8x16_arith.wast","passed":8,"failed":123},{"name":"simd_i8x16_arith2.wast","passed":25,"failed":186},{"name":"simd_i8x16_cmp.wast","passed":30,"failed":415},{"name":"simd_i8x16_sat_arith.wast","passed":24,"failed":190},{"name":"simd_int_to_int_extend.wast","passed":24,"failed":229},{"name":"simd_lane.wast","passed":189,"failed":286},{"name":"simd_linking.wast","passed":0,"failed":3},{"name":"simd_load.wast","passed":8,"failed":31},{"name":"simd_load16_lane.wast","passed":3,"failed":33},{"name":"simd_load32_lane.wast","passed":3,"failed":21},{"name":"simd_load64_lane.wast","passed":3,"failed":13},{"name":"simd_load8_lane.wast","passed":3,"failed":49},{"name":"simd_load_extend.wast","passed":18,"failed":86},{"name":"simd_load_splat.wast","passed":12,"failed":114},{"name":"simd_load_zero.wast","passed":10,"failed":29},{"name":"simd_splat.wast","passed":23,"failed":162},{"name":"simd_store.wast","passed":9,"failed":19},{"name":"simd_store16_lane.wast","passed":3,"failed":33},{"name":"simd_store32_lane.wast","passed":3,"failed":21},{"name":"simd_store64_lane.wast","passed":3,"failed":13},{"name":"simd_store8_lane.wast","passed":3,"failed":49}] +0.9.0-alpha.0,1702,24277,[{"name":"simd_address.wast","passed":7,"failed":42},{"name":"simd_align.wast","passed":92,"failed":8},{"name":"simd_bit_shift.wast","passed":41,"failed":211},{"name":"simd_bitwise.wast","passed":30,"failed":139},{"name":"simd_boolean.wast","passed":18,"failed":259},{"name":"simd_const.wast","passed":551,"failed":206},{"name":"simd_conversions.wast","passed":50,"failed":232},{"name":"simd_f32x4.wast","passed":18,"failed":772},{"name":"simd_f32x4_arith.wast","passed":19,"failed":1803},{"name":"simd_f32x4_cmp.wast","passed":26,"failed":2581},{"name":"simd_f32x4_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f32x4_rounding.wast","passed":25,"failed":176},{"name":"simd_f64x2.wast","passed":10,"failed":793},{"name":"simd_f64x2_arith.wast","passed":19,"failed":1806},{"name":"simd_f64x2_cmp.wast","passed":26,"failed":2659},{"name":"simd_f64x2_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f64x2_rounding.wast","passed":25,"failed":176},{"name":"simd_i16x8_arith.wast","passed":13,"failed":181},{"name":"simd_i16x8_arith2.wast","passed":21,"failed":151},{"name":"simd_i16x8_cmp.wast","passed":32,"failed":433},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":5,"failed":16},{"name":"simd_i16x8_extmul_i8x16.wast","passed":13,"failed":104},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":4,"failed":26},{"name":"simd_i16x8_sat_arith.wast","passed":18,"failed":204},{"name":"simd_i32x4_arith.wast","passed":13,"failed":181},{"name":"simd_i32x4_arith2.wast","passed":28,"failed":121},{"name":"simd_i32x4_cmp.wast","passed":42,"failed":433},{"name":"simd_i32x4_dot_i16x8.wast","passed":4,"failed":26},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":5,"failed":16},{"name":"simd_i32x4_extmul_i16x8.wast","passed":13,"failed":104},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":5,"failed":102},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":5,"failed":102},{"name":"simd_i64x2_arith.wast","passed":13,"failed":187},{"name":"simd_i64x2_arith2.wast","passed":4,"failed":21},{"name":"simd_i64x2_cmp.wast","passed":11,"failed":102},{"name":"simd_i64x2_extmul_i32x4.wast","passed":13,"failed":104},{"name":"simd_i8x16_arith.wast","passed":10,"failed":121},{"name":"simd_i8x16_arith2.wast","passed":27,"failed":184},{"name":"simd_i8x16_cmp.wast","passed":32,"failed":413},{"name":"simd_i8x16_sat_arith.wast","passed":26,"failed":188},{"name":"simd_int_to_int_extend.wast","passed":25,"failed":228},{"name":"simd_lane.wast","passed":200,"failed":275},{"name":"simd_linking.wast","passed":0,"failed":3},{"name":"simd_load.wast","passed":22,"failed":17},{"name":"simd_load16_lane.wast","passed":4,"failed":32},{"name":"simd_load32_lane.wast","passed":4,"failed":20},{"name":"simd_load64_lane.wast","passed":4,"failed":12},{"name":"simd_load8_lane.wast","passed":4,"failed":48},{"name":"simd_load_extend.wast","passed":20,"failed":84},{"name":"simd_load_splat.wast","passed":14,"failed":112},{"name":"simd_load_zero.wast","passed":12,"failed":27},{"name":"simd_splat.wast","passed":26,"failed":159},{"name":"simd_store.wast","passed":11,"failed":17},{"name":"simd_store16_lane.wast","passed":3,"failed":33},{"name":"simd_store32_lane.wast","passed":3,"failed":21},{"name":"simd_store64_lane.wast","passed":3,"failed":13},{"name":"simd_store8_lane.wast","passed":3,"failed":49}] diff --git a/crates/types/src/instructions.rs b/crates/types/src/instructions.rs index a3c2fee..1edfef7 100644 --- a/crates/types/src/instructions.rs +++ b/crates/types/src/instructions.rs @@ -1,12 +1,27 @@ use super::{FuncAddr, GlobalAddr, LabelAddr, LocalAddr, TableAddr, TypeAddr, ValType}; -use crate::{DataAddr, ElemAddr, MemAddr}; +use crate::{ConstIdx, DataAddr, ElemAddr, MemAddr}; /// Represents a memory immediate in a WebAssembly memory instruction. #[derive(Debug, Copy, Clone, PartialEq)] #[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] -pub struct MemoryArg { - pub offset: u64, - pub mem_addr: MemAddr, + +pub struct MemoryArg([u8; 12]); + +impl MemoryArg { + pub fn new(offset: u64, mem_addr: MemAddr) -> Self { + let mut bytes = [0; 12]; + bytes[0..8].copy_from_slice(&offset.to_le_bytes()); + bytes[8..12].copy_from_slice(&mem_addr.to_le_bytes()); + Self(bytes) + } + + pub fn offset(&self) -> u64 { + u64::from_le_bytes(self.0[0..8].try_into().expect("invalid offset")) + } + + pub fn mem_addr(&self) -> MemAddr { + MemAddr::from_le_bytes(self.0[8..12].try_into().expect("invalid mem_addr")) + } } type BrTableDefault = u32; @@ -42,8 +57,8 @@ pub enum ConstInstruction { // should be kept as small as possible (16 bytes max) #[rustfmt::skip] pub enum Instruction { - LocalCopy32(LocalAddr, LocalAddr), LocalCopy64(LocalAddr, LocalAddr), LocalCopy128(LocalAddr, LocalAddr), LocalCopy128Ref(LocalAddr, LocalAddr), LocalCopyRef(LocalAddr, LocalAddr), - LocalsStore32(LocalAddr, LocalAddr, u32, MemAddr), LocalsStore64(LocalAddr, LocalAddr, u32, MemAddr), LocalsStore128(LocalAddr, LocalAddr, u32, MemAddr), LocalsStoreRef(LocalAddr, LocalAddr, u32, MemAddr), + LocalCopy32(LocalAddr, LocalAddr), LocalCopy64(LocalAddr, LocalAddr), LocalCopy128(LocalAddr, LocalAddr), LocalCopyRef(LocalAddr, LocalAddr), + // LocalsStore32(LocalAddr, LocalAddr, u32, MemAddr), LocalsStore64(LocalAddr, LocalAddr, u32, MemAddr), LocalsStore128(LocalAddr, LocalAddr, u32, MemAddr), LocalsStoreRef(LocalAddr, LocalAddr, u32, MemAddr), // > Control Instructions // See @@ -71,68 +86,48 @@ pub enum Instruction { Return, Call(FuncAddr), CallIndirect(TypeAddr, TableAddr), - ReturnCall(FuncAddr), - ReturnCallIndirect(TypeAddr, TableAddr), + // ReturnCall(FuncAddr), + // ReturnCallIndirect(TypeAddr, TableAddr), // > Parametric Instructions // See - Drop32, - Drop64, - Drop128, - DropRef, - - Select32, - Select64, - Select128, - SelectRef, + Drop32, Select32, + Drop64, Select64, + Drop128, Select128, + DropRef, SelectRef, // > Variable Instructions // See - LocalGet32(LocalAddr), - LocalGet64(LocalAddr), - LocalGet128(LocalAddr), - LocalGetRef(LocalAddr), - - LocalSet32(LocalAddr), - LocalSet64(LocalAddr), - LocalSet128(LocalAddr), - LocalSetRef(LocalAddr), - - LocalTee32(LocalAddr), - LocalTee64(LocalAddr), - LocalTee128(LocalAddr), - LocalTeeRef(LocalAddr), - GlobalGet(GlobalAddr), - GlobalSet32(GlobalAddr), - GlobalSet64(GlobalAddr), - GlobalSet128(GlobalAddr), - GlobalSetRef(GlobalAddr), + LocalGet32(LocalAddr), LocalSet32(LocalAddr), LocalTee32(LocalAddr), GlobalSet32(GlobalAddr), + LocalGet64(LocalAddr), LocalSet64(LocalAddr), LocalTee64(LocalAddr), GlobalSet64(GlobalAddr), + LocalGet128(LocalAddr), LocalSet128(LocalAddr), LocalTee128(LocalAddr), GlobalSet128(GlobalAddr), + LocalGetRef(LocalAddr), LocalSetRef(LocalAddr), LocalTeeRef(LocalAddr), GlobalSetRef(GlobalAddr), // > Memory Instructions - I32Load { offset: u64, mem_addr: MemAddr }, - I64Load { offset: u64, mem_addr: MemAddr }, - F32Load { offset: u64, mem_addr: MemAddr }, - F64Load { offset: u64, mem_addr: MemAddr }, - I32Load8S { offset: u64, mem_addr: MemAddr }, - I32Load8U { offset: u64, mem_addr: MemAddr }, - I32Load16S { offset: u64, mem_addr: MemAddr }, - I32Load16U { offset: u64, mem_addr: MemAddr }, - I64Load8S { offset: u64, mem_addr: MemAddr }, - I64Load8U { offset: u64, mem_addr: MemAddr }, - I64Load16S { offset: u64, mem_addr: MemAddr }, - I64Load16U { offset: u64, mem_addr: MemAddr }, - I64Load32S { offset: u64, mem_addr: MemAddr }, - I64Load32U { offset: u64, mem_addr: MemAddr }, - I32Store { offset: u64, mem_addr: MemAddr }, - I64Store { offset: u64, mem_addr: MemAddr }, - F32Store { offset: u64, mem_addr: MemAddr }, - F64Store { offset: u64, mem_addr: MemAddr }, - I32Store8 { offset: u64, mem_addr: MemAddr }, - I32Store16 { offset: u64, mem_addr: MemAddr }, - I64Store8 { offset: u64, mem_addr: MemAddr }, - I64Store16 { offset: u64, mem_addr: MemAddr }, - I64Store32 { offset: u64, mem_addr: MemAddr }, + I32Load(MemoryArg), + I64Load(MemoryArg), + F32Load(MemoryArg), + F64Load(MemoryArg), + I32Load8S(MemoryArg), + I32Load8U(MemoryArg), + I32Load16S(MemoryArg), + I32Load16U(MemoryArg), + I64Load8S(MemoryArg), + I64Load8U(MemoryArg), + I64Load16S(MemoryArg), + I64Load16U(MemoryArg), + I64Load32S(MemoryArg), + I64Load32U(MemoryArg), + I32Store(MemoryArg), + I64Store(MemoryArg), + F32Store(MemoryArg), + F64Store(MemoryArg), + I32Store8(MemoryArg), + I32Store16(MemoryArg), + I64Store8(MemoryArg), + I64Store16(MemoryArg), + I64Store32(MemoryArg), MemorySize(MemAddr), MemoryGrow(MemAddr), @@ -146,7 +141,7 @@ pub enum Instruction { RefNull(ValType), RefFunc(FuncAddr), RefIsNull, - + // > Numeric Instructions // See I32Eqz, I32Eq, I32Ne, I32LtS, I32LtU, I32GtS, I32GtU, I32LeS, I32LeU, I32GeS, I32GeU, @@ -188,7 +183,97 @@ pub enum Instruction { DataDrop(DataAddr), ElemDrop(ElemAddr), - // // > SIMD Instructions - // V128Load(MemoryArg), V128Load8x8S { offset: u64, mem_addr: MemAddr }, V128Load8x8U { offset: u64, mem_addr: MemAddr }, V128Load16x4S { offset: u64, mem_addr: MemAddr }, V128Load16x4U { offset: u64, mem_addr: MemAddr }, V128Load32x2S { offset: u64, mem_addr: MemAddr }, V128Load32x2U { offset: u64, mem_addr: MemAddr }, V128Load8Splat { offset: u64, mem_addr: MemAddr }, V128Load16Splat { offset: u64, mem_addr: MemAddr }, V128Load32Splat { offset: u64, mem_addr: MemAddr }, V128Load64Splat { offset: u64, mem_addr: MemAddr }, V128Load32Zero { offset: u64, mem_addr: MemAddr }, V128Load64Zero { offset: u64, mem_addr: MemAddr }, - // V128Store { offset: u64, mem_addr: MemAddr }, V128Store8x8 { offset: u64, mem_addr: MemAddr }, V128Store16x4 { offset: u64, mem_addr: MemAddr }, V128Store32x2 { offset: u64, mem_addr: MemAddr }, + // > SIMD Instructions + Simd(SimdInstruction), +} + +impl From for Instruction { + fn from(instr: SimdInstruction) -> Self { + Instruction::Simd(instr) + } +} + +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[rustfmt::skip] +pub enum SimdInstruction { + V128Load(MemoryArg), + V128Load8x8S(MemoryArg), V128Load8x8U(MemoryArg), + V128Load16x4S(MemoryArg), V128Load16x4U(MemoryArg), + V128Load32x2S(MemoryArg), V128Load32x2U(MemoryArg), + + V128Load8Splat(MemoryArg), V128Load16Splat(MemoryArg), V128Load32Splat(MemoryArg), V128Load64Splat(MemoryArg), + V128Load8Lane(MemoryArg, u8), V128Load16Lane(MemoryArg, u8), V128Load32Lane(MemoryArg, u8), V128Load64Lane(MemoryArg, u8), + + V128Load32Zero(MemoryArg), V128Load64Zero(MemoryArg), + + V128Store(MemoryArg), V128Store8Lane(MemoryArg, u8), V128Store16Lane(MemoryArg, u8), V128Store32Lane(MemoryArg, u8), V128Store64Lane(MemoryArg, u8), + + I8x16Shuffle(ConstIdx), + V128Const(ConstIdx), + + I8x16ExtractLaneS(u8), I8x16ExtractLaneU(u8), I8x16ReplaceLane(u8), + I16x8ExtractLaneS(u8), I16x8ExtractLaneU(u8), I16x8ReplaceLane(u8), + I32x4ExtractLane(u8), I32x4ReplaceLane(u8), + I64x2ExtractLane(u8), I64x2ReplaceLane(u8), + F32x4ExtractLane(u8), F32x4ReplaceLane(u8), + F64x2ExtractLane(u8), F64x2ReplaceLane(u8), + + V128Not, V128And, V128AndNot, V128Or, V128Xor, V128Bitselect, V128AnyTrue, + + I8x16Splat, I8x16Swizzle, I8x16Eq, I8x16Ne, I8x16LtS, I8x16LtU, I8x16GtS, I8x16GtU, I8x16LeS, I8x16LeU, I8x16GeS, I8x16GeU, + I16x8Splat, I16x8Eq, I16x8Ne, I16x8LtS, I16x8LtU, I16x8GtS, I16x8GtU, I16x8LeS, I16x8LeU, I16x8GeS, I16x8GeU, + I32x4Splat, I32x4Eq, I32x4Ne, I32x4LtS, I32x4LtU, I32x4GtS, I32x4GtU, I32x4LeS, I32x4LeU, I32x4GeS, I32x4GeU, + I64x2Splat, I64x2Eq, I64x2Ne, I64x2LtS, I64x2GtS, I64x2LeS, I64x2GeS, + F32x4Splat, F32x4Eq, F32x4Ne, F32x4Lt, F32x4Gt, F32x4Le, F32x4Ge, + F64x2Splat, F64x2Eq, F64x2Ne, F64x2Lt, F64x2Gt, F64x2Le, F64x2Ge, + + I8x16Abs, I8x16Neg, I8x16AllTrue, I8x16Bitmask, I8x16Shl, I8x16ShrS, I8x16ShrU, I8x16Add, I8x16Sub, I8x16MinS, I8x16MinU, I8x16MaxS, I8x16MaxU, + I16x8Abs, I16x8Neg, I16x8AllTrue, I16x8Bitmask, I16x8Shl, I16x8ShrS, I16x8ShrU, I16x8Add, I16x8Sub, I16x8MinS, I16x8MinU, I16x8MaxS, I16x8MaxU, + I32x4Abs, I32x4Neg, I32x4AllTrue, I32x4Bitmask, I32x4Shl, I32x4ShrS, I32x4ShrU, I32x4Add, I32x4Sub, I32x4MinS, I32x4MinU, I32x4MaxS, I32x4MaxU, + I64x2Abs, I64x2Neg, I64x2AllTrue, I64x2Bitmask, I64x2Shl, I64x2ShrS, I64x2ShrU, I64x2Add, I64x2Sub, I64x2Mul, + + I8x16NarrowI16x8S, I8x16NarrowI16x8U, I8x16AddSatS, I8x16AddSatU, I8x16SubSatS, I8x16SubSatU, I8x16AvgrU, + I16x8NarrowI32x4S, I16x8NarrowI32x4U, I16x8AddSatS, I16x8AddSatU, I16x8SubSatS, I16x8SubSatU, I16x8AvgrU, + + I16x8ExtAddPairwiseI8x16S, I16x8ExtAddPairwiseI8x16U, I16x8Mul, + I32x4ExtAddPairwiseI16x8S, I32x4ExtAddPairwiseI16x8U, I32x4Mul, + + I16x8ExtMulLowI8x16S, I16x8ExtMulLowI8x16U, I16x8ExtMulHighI8x16S, I16x8ExtMulHighI8x16U, + I32x4ExtMulLowI16x8S, I32x4ExtMulLowI16x8U, I32x4ExtMulHighI16x8S, I32x4ExtMulHighI16x8U, + I64x2ExtMulLowI32x4S, I64x2ExtMulLowI32x4U, I64x2ExtMulHighI32x4S, I64x2ExtMulHighI32x4U, + + I16x8ExtendLowI8x16S, I16x8ExtendLowI8x16U, I16x8ExtendHighI8x16S, I16x8ExtendHighI8x16U, + I32x4ExtendLowI16x8S, I32x4ExtendLowI16x8U, I32x4ExtendHighI16x8S, I32x4ExtendHighI16x8U, + I64x2ExtendLowI32x4S, I64x2ExtendLowI32x4U, I64x2ExtendHighI32x4S, I64x2ExtendHighI32x4U, + + I8x16Popcnt, I16x8Q15MulrSatS, I32x4DotI16x8S, + + F32x4Ceil, F32x4Floor, F32x4Trunc, F32x4Nearest, F32x4Abs, F32x4Neg, F32x4Sqrt, F32x4Add, F32x4Sub, F32x4Mul, F32x4Div, F32x4Min, F32x4Max, F32x4PMin, F32x4PMax, + F64x2Ceil, F64x2Floor, F64x2Trunc, F64x2Nearest, F64x2Abs, F64x2Neg, F64x2Sqrt, F64x2Add, F64x2Sub, F64x2Mul, F64x2Div, F64x2Min, F64x2Max, F64x2PMin, F64x2PMax, + I32x4TruncSatF32x4S, I32x4TruncSatF32x4U, + F32x4ConvertI32x4S, F32x4ConvertI32x4U, + I32x4TruncSatF64x2SZero, I32x4TruncSatF64x2UZero, + F64x2ConvertLowI32x4S, F64x2ConvertLowI32x4U, + F32x4DemoteF64x2Zero, F64x2PromoteLowF32x4, +} + +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[rustfmt::skip] +pub enum RelaxedSimd { + I8x16RelaxedSwizzle, + I32x4RelaxedTruncF32x4S, I32x4RelaxedTruncF32x4U, + I32x4RelaxedTruncF64x2SZero, I32x4RelaxedTruncF64x2UZero, + F32x4RelaxedMadd, F32x4RelaxedNmadd, + F64x2RelaxedMadd, F64x2RelaxedNmadd, + I8x16RelaxedLaneselect, + I16x8RelaxedLaneselect, + I32x4RelaxedLaneselect, + I64x2RelaxedLaneselect, + F32x4RelaxedMin, F32x4RelaxedMax, + F64x2RelaxedMin, F64x2RelaxedMax, + I16x8RelaxedQ15mulrS, + I16x8RelaxedDotI8x16I7x16S, + I32x4RelaxedDotI8x16I7x16AddS } diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index 8ee044f..58120fe 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -135,6 +135,7 @@ pub type GlobalAddr = Addr; pub type ElemAddr = Addr; pub type DataAddr = Addr; pub type ExternAddr = Addr; +pub type ConstIdx = Addr; // additional internal addresses pub type TypeAddr = Addr; @@ -203,15 +204,52 @@ pub struct ValueCountsSmall { pub cref: u16, } +impl<'a, T: IntoIterator> From for ValueCounts { + fn from(types: T) -> Self { + let mut counts = ValueCounts::default(); + for ty in types { + 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, + } + } + counts + } +} + +impl<'a, T: IntoIterator> From for ValueCountsSmall { + fn from(types: T) -> Self { + let mut counts = ValueCountsSmall::default(); + for ty in types { + 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, + } + } + counts + } +} + #[derive(Debug, Clone, PartialEq, Default)] #[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub struct WasmFunction { pub instructions: Box<[Instruction]>, + pub data: WasmFunctionData, pub locals: ValueCounts, pub params: ValueCountsSmall, pub ty: FuncType, } +#[derive(Debug, Clone, PartialEq, Default)] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +pub struct WasmFunctionData { + pub v128_constants: Box<[u128]>, +} + /// A WebAssembly Module Export #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] diff --git a/crates/wasm-testsuite/Cargo.toml b/crates/wasm-testsuite/Cargo.toml index 8edcb8a..46df77f 100644 --- a/crates/wasm-testsuite/Cargo.toml +++ b/crates/wasm-testsuite/Cargo.toml @@ -1,6 +1,6 @@ [package] name="wasm-testsuite" -version="0.5.0" +version="0.6.0-alpha.0" description="Mirror of the WebAssembly core testsuite for use in testing WebAssembly implementations" license="Apache-2.0" readme="README.md" From ab7890764023a751ae33b095e206102d3774249f Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sun, 13 Oct 2024 15:10:05 +0200 Subject: [PATCH 19/54] ci: fix build Signed-off-by: Henry Gressmann --- crates/tinywasm/src/interpreter/executor.rs | 4 ---- crates/tinywasm/tests/generated/wasm-1.csv | 1 + crates/tinywasm/tests/generated/wasm-2.csv | 1 + crates/tinywasm/tests/generated/wasm-annotations.csv | 1 + crates/tinywasm/tests/generated/wasm-custom-page-sizes.csv | 1 + crates/tinywasm/tests/generated/wasm-multi-memory.csv | 1 + examples/rust/src/tinywasm_no_std.rs | 1 + 7 files changed, 6 insertions(+), 4 deletions(-) diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index 2326227..f8e17f3 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -305,10 +305,6 @@ impl<'store, 'stack> Executor<'store, 'stack> { Simd(_) => { unreachable!("unimplemented sidm instruction"); } - - instr => { - unreachable!("unimplemented instruction: {:?}", instr); - } }; self.cf.incr_instr_ptr(); diff --git a/crates/tinywasm/tests/generated/wasm-1.csv b/crates/tinywasm/tests/generated/wasm-1.csv index 1447fdf..9cb5102 100644 --- a/crates/tinywasm/tests/generated/wasm-1.csv +++ b/crates/tinywasm/tests/generated/wasm-1.csv @@ -5,3 +5,4 @@ 0.6.1,27572,335,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.7.0,27572,335,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.8.0,20360,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":128,"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":98,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_grow.wast","passed":104,"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.9.0-alpha.0,20360,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":128,"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":98,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_grow.wast","passed":104,"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/tinywasm/tests/generated/wasm-2.csv b/crates/tinywasm/tests/generated/wasm-2.csv index 548da5b..a4ef6b0 100644 --- a/crates/tinywasm/tests/generated/wasm-2.csv +++ b/crates/tinywasm/tests/generated/wasm-2.csv @@ -10,3 +10,4 @@ 0.6.1,20278,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.7.0,20278,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.8.0,28008,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":128,"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":117,"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":98,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_copy.wast","passed":4450,"failed":0},{"name":"memory_fill.wast","passed":100,"failed":0},{"name":"memory_grow.wast","passed":104,"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":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":16,"failed":0},{"name":"ref_null.wast","passed":3,"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-sub.wast","passed":2,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"table_copy.wast","passed":1728,"failed":0},{"name":"table_fill.wast","passed":45,"failed":0},{"name":"table_get.wast","passed":16,"failed":0},{"name":"table_grow.wast","passed":58,"failed":0},{"name":"table_init.wast","passed":780,"failed":0},{"name":"table_set.wast","passed":26,"failed":0},{"name":"table_size.wast","passed":39,"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.9.0-alpha.0,28008,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":128,"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":117,"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":98,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_copy.wast","passed":4450,"failed":0},{"name":"memory_fill.wast","passed":100,"failed":0},{"name":"memory_grow.wast","passed":104,"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":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":16,"failed":0},{"name":"ref_null.wast","passed":3,"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-sub.wast","passed":2,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"table_copy.wast","passed":1728,"failed":0},{"name":"table_fill.wast","passed":45,"failed":0},{"name":"table_get.wast","passed":16,"failed":0},{"name":"table_grow.wast","passed":58,"failed":0},{"name":"table_init.wast","passed":780,"failed":0},{"name":"table_set.wast","passed":26,"failed":0},{"name":"table_size.wast","passed":39,"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/tinywasm/tests/generated/wasm-annotations.csv b/crates/tinywasm/tests/generated/wasm-annotations.csv index 1e66217..a1c7fb6 100644 --- a/crates/tinywasm/tests/generated/wasm-annotations.csv +++ b/crates/tinywasm/tests/generated/wasm-annotations.csv @@ -1 +1,2 @@ 0.8.0,142,0,[{"name":"annotations.wast","passed":74,"failed":0},{"name":"annotations/simd_lane.wast (skipped)","passed":0,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"token.wast","passed":61,"failed":0}] +0.9.0-alpha.0,142,0,[{"name":"annotations.wast","passed":74,"failed":0},{"name":"annotations/simd_lane.wast (skipped)","passed":0,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"token.wast","passed":61,"failed":0}] diff --git a/crates/tinywasm/tests/generated/wasm-custom-page-sizes.csv b/crates/tinywasm/tests/generated/wasm-custom-page-sizes.csv index f9a7914..7f168a1 100644 --- a/crates/tinywasm/tests/generated/wasm-custom-page-sizes.csv +++ b/crates/tinywasm/tests/generated/wasm-custom-page-sizes.csv @@ -1 +1,2 @@ 0.8.0,57,0,[{"name":"custom-page-sizes-invalid.wast","passed":22,"failed":0},{"name":"custom-page-sizes.wast","passed":35,"failed":0}] +0.9.0-alpha.0,57,0,[{"name":"custom-page-sizes-invalid.wast","passed":22,"failed":0},{"name":"custom-page-sizes.wast","passed":35,"failed":0}] diff --git a/crates/tinywasm/tests/generated/wasm-multi-memory.csv b/crates/tinywasm/tests/generated/wasm-multi-memory.csv index 088ba86..0f70c8e 100644 --- a/crates/tinywasm/tests/generated/wasm-multi-memory.csv +++ b/crates/tinywasm/tests/generated/wasm-multi-memory.csv @@ -1 +1,2 @@ 0.8.0,1872,0,[{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"align.wast","passed":160,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"binary.wast","passed":126,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"imports.wast","passed":175,"failed":0},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"multi-memory/simd_memory-multi.wast (skipped)","passed":0,"failed":0},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"traps0.wast","passed":15,"failed":0}] +0.9.0-alpha.0,1872,0,[{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"align.wast","passed":160,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"binary.wast","passed":126,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"imports.wast","passed":175,"failed":0},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"multi-memory/simd_memory-multi.wast (skipped)","passed":0,"failed":0},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"traps0.wast","passed":15,"failed":0}] diff --git a/examples/rust/src/tinywasm_no_std.rs b/examples/rust/src/tinywasm_no_std.rs index 07a6a8d..9a31d20 100644 --- a/examples/rust/src/tinywasm_no_std.rs +++ b/examples/rust/src/tinywasm_no_std.rs @@ -5,6 +5,7 @@ use tinywasm::{Extern, FuncContext}; extern crate alloc; +#[cfg(not(feature = "std"))] #[panic_handler] fn panic(_info: &core::panic::PanicInfo) -> ! { loop {} From f6e214ba050010b9566e7f2a99cfe370dc49ce43 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Thu, 24 Oct 2024 19:47:18 +0200 Subject: [PATCH 20/54] chore: add root package version Signed-off-by: Henry Gressmann --- Cargo.lock | 38 ++++++++++----------- Cargo.toml | 1 + crates/tinywasm/src/interpreter/executor.rs | 4 +-- crates/tinywasm/src/interpreter/mod.rs | 2 +- 4 files changed, 22 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 03584d4..bf486d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -128,9 +128,9 @@ dependencies = [ [[package]] name = "bytes" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "cast" @@ -436,9 +436,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.159" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "libm" @@ -517,9 +517,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.87" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] @@ -584,9 +584,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -708,18 +708,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.210" +version = "1.0.213" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.213" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" dependencies = [ "proc-macro2", "quote", @@ -728,9 +728,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "itoa", "memchr", @@ -757,9 +757,9 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "syn" -version = "2.0.79" +version = "2.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" dependencies = [ "proc-macro2", "quote", @@ -841,7 +841,7 @@ dependencies = [ [[package]] name = "tinywasm-root" -version = "0.0.0" +version = "0.9.0-alpha.0" dependencies = [ "eyre", "pretty_env_logger", @@ -877,9 +877,9 @@ checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "uuid" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" [[package]] name = "version_check" diff --git a/Cargo.toml b/Cargo.toml index 0125c7b..413d364 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ repository="https://github.com/explodingcamera/tinywasm" [package] name="tinywasm-root" +version.workspace=true publish=false edition.workspace=true rust-version.workspace=true diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index f8e17f3..774927c 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -302,9 +302,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { LocalCopy128(from, to) => self.exec_local_copy::(*from, *to), LocalCopyRef(from, to) => self.exec_local_copy::(*from, *to), - Simd(_) => { - unreachable!("unimplemented sidm instruction"); - } + Simd(op) => unimplemented!("simd instruction {:?}", op), }; self.cf.incr_instr_ptr(); diff --git a/crates/tinywasm/src/interpreter/mod.rs b/crates/tinywasm/src/interpreter/mod.rs index c97708e..e5c1081 100644 --- a/crates/tinywasm/src/interpreter/mod.rs +++ b/crates/tinywasm/src/interpreter/mod.rs @@ -1,6 +1,6 @@ pub(crate) mod executor; pub(crate) mod num_helpers; -// pub(crate) mod simd; +pub(crate) mod simd; pub(crate) mod stack; mod values; From ca8800f7a00bdf1745c781839c583519dac8a59d Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Fri, 25 Oct 2024 12:33:25 +0200 Subject: [PATCH 21/54] fix: fix no_std build Signed-off-by: Henry Gressmann --- crates/tinywasm/src/interpreter/simd.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/tinywasm/src/interpreter/simd.rs b/crates/tinywasm/src/interpreter/simd.rs index bc2f402..05562c6 100644 --- a/crates/tinywasm/src/interpreter/simd.rs +++ b/crates/tinywasm/src/interpreter/simd.rs @@ -1,5 +1,8 @@ -// WIP +#[cfg(not(feature = "std"))] +#[allow(unused_imports)] +use super::no_std_floats::NoStdFloatExt; +// WIP struct V128([u8; 16]); impl V128 { From 0c1781fc62037181ae9698840fadb1d4578d2395 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Fri, 25 Oct 2024 12:35:06 +0200 Subject: [PATCH 22/54] fix: fix no_std build Signed-off-by: Henry Gressmann --- crates/tinywasm/src/interpreter/simd.rs | 238 ++++++++++++------------ 1 file changed, 119 insertions(+), 119 deletions(-) diff --git a/crates/tinywasm/src/interpreter/simd.rs b/crates/tinywasm/src/interpreter/simd.rs index 05562c6..eb798d4 100644 --- a/crates/tinywasm/src/interpreter/simd.rs +++ b/crates/tinywasm/src/interpreter/simd.rs @@ -1,133 +1,133 @@ -#[cfg(not(feature = "std"))] -#[allow(unused_imports)] -use super::no_std_floats::NoStdFloatExt; +// #[cfg(not(feature = "std"))] +// #[allow(unused_imports)] +// use super::no_std_floats::NoStdFloatExt; -// WIP -struct V128([u8; 16]); +// // WIP +// struct V128([u8; 16]); -impl V128 { - fn f32x4(&self) -> [f32; 4] { - let mut res = [0.0; 4]; - for i in 0..4 { - let mut f = [0; 4]; - for j in 0..4 { - f[j] = self.0[i * 4 + j]; - } - res[i] = f32::from_le_bytes(f); - } - res - } +// impl V128 { +// fn f32x4(&self) -> [f32; 4] { +// let mut res = [0.0; 4]; +// for i in 0..4 { +// let mut f = [0; 4]; +// for j in 0..4 { +// f[j] = self.0[i * 4 + j]; +// } +// res[i] = f32::from_le_bytes(f); +// } +// res +// } - fn i32x4(&self) -> [i32; 4] { - let mut res = [0; 4]; - for i in 0..4 { - let mut f = [0; 4]; - for j in 0..4 { - f[j] = self.0[i * 4 + j]; - } - res[i] = i32::from_le_bytes(f); - } - res - } +// fn i32x4(&self) -> [i32; 4] { +// let mut res = [0; 4]; +// for i in 0..4 { +// let mut f = [0; 4]; +// for j in 0..4 { +// f[j] = self.0[i * 4 + j]; +// } +// res[i] = i32::from_le_bytes(f); +// } +// res +// } - fn i64x2(&self) -> [i64; 2] { - let mut res = [0; 2]; - for i in 0..2 { - let mut f = [0; 8]; - for j in 0..8 { - f[j] = self.0[i * 8 + j]; - } - res[i] = i64::from_le_bytes(f); - } - res - } +// fn i64x2(&self) -> [i64; 2] { +// let mut res = [0; 2]; +// for i in 0..2 { +// let mut f = [0; 8]; +// for j in 0..8 { +// f[j] = self.0[i * 8 + j]; +// } +// res[i] = i64::from_le_bytes(f); +// } +// res +// } - fn f64x2(&self) -> [f64; 2] { - let mut res = [0.0; 2]; - for i in 0..2 { - let mut f = [0; 8]; - for j in 0..8 { - f[j] = self.0[i * 8 + j]; - } - res[i] = f64::from_le_bytes(f); - } - res - } +// fn f64x2(&self) -> [f64; 2] { +// let mut res = [0.0; 2]; +// for i in 0..2 { +// let mut f = [0; 8]; +// for j in 0..8 { +// f[j] = self.0[i * 8 + j]; +// } +// res[i] = f64::from_le_bytes(f); +// } +// res +// } - fn i16x8(&self) -> [i16; 8] { - let mut res = [0; 8]; - for i in 0..8 { - let mut f = [0; 2]; - for j in 0..2 { - f[j] = self.0[i * 2 + j]; - } - res[i] = i16::from_le_bytes(f); - } - res - } +// fn i16x8(&self) -> [i16; 8] { +// let mut res = [0; 8]; +// for i in 0..8 { +// let mut f = [0; 2]; +// for j in 0..2 { +// f[j] = self.0[i * 2 + j]; +// } +// res[i] = i16::from_le_bytes(f); +// } +// res +// } - fn i8x16(&self) -> [i8; 16] { - let mut res = [0; 16]; - for i in 0..16 { - res[i] = i8::from_le_bytes([self.0[i]]); - } - res - } -} +// fn i8x16(&self) -> [i8; 16] { +// let mut res = [0; 16]; +// for i in 0..16 { +// res[i] = i8::from_le_bytes([self.0[i]]); +// } +// res +// } +// } -fn vvunop(c1: V128) -> V128 { - let mut res = [0; 16]; - for i in 0..16 { - res[i] = !c1.0[i]; - } - V128(res) -} +// fn vvunop(c1: V128) -> V128 { +// let mut res = [0; 16]; +// for i in 0..16 { +// res[i] = !c1.0[i]; +// } +// V128(res) +// } -fn vvbinop(c1: V128, c2: V128) -> V128 { - let mut res = [0; 16]; - for i in 0..16 { - res[i] = c1.0[i] & c2.0[i]; - } - V128(res) -} +// fn vvbinop(c1: V128, c2: V128) -> V128 { +// let mut res = [0; 16]; +// for i in 0..16 { +// res[i] = c1.0[i] & c2.0[i]; +// } +// V128(res) +// } -fn vvternop(c1: V128, c2: V128, c3: V128) -> V128 { - let mut res = [0; 16]; - for i in 0..16 { - res[i] = c1.0[i] & c2.0[i] | !c1.0[i] & c3.0[i]; - } - V128(res) -} +// fn vvternop(c1: V128, c2: V128, c3: V128) -> V128 { +// let mut res = [0; 16]; +// for i in 0..16 { +// res[i] = c1.0[i] & c2.0[i] | !c1.0[i] & c3.0[i]; +// } +// V128(res) +// } -fn any_true(val: V128) -> bool { - val.0.iter().any(|&x| x != 0) -} +// fn any_true(val: V128) -> bool { +// val.0.iter().any(|&x| x != 0) +// } -fn i8x16_swizzle(c1: V128, c2: V128) -> V128 { - let mut res = [0; 16]; - for i in 0..16 { - res[i] = c1.0[c2.0[i] as usize]; - } - V128(res) -} +// fn i8x16_swizzle(c1: V128, c2: V128) -> V128 { +// let mut res = [0; 16]; +// for i in 0..16 { +// res[i] = c1.0[c2.0[i] as usize]; +// } +// V128(res) +// } -fn i18x16_shuffle(c1: V128, c2: V128) -> V128 { - let mut res = [0; 16]; - for i in 0..16 { - res[i] = c1.0[(c2.0[i] & 0xf) as usize]; - } - V128(res) -} +// fn i18x16_shuffle(c1: V128, c2: V128) -> V128 { +// let mut res = [0; 16]; +// for i in 0..16 { +// res[i] = c1.0[(c2.0[i] & 0xf) as usize]; +// } +// V128(res) +// } -fn f32x4_abs(val: V128) -> V128 { - let mut res = [0; 16]; - for i in 0..4 { - let f = val.f32x4(); - let f = f32::abs(f[i]); - let f = f.to_le_bytes(); - for j in 0..4 { - res[i * 4 + j] = f[j]; - } - } - V128(res) -} +// fn f32x4_abs(val: V128) -> V128 { +// let mut res = [0; 16]; +// for i in 0..4 { +// let f = val.f32x4(); +// let f = f32::abs(f[i]); +// let f = f.to_le_bytes(); +// for j in 0..4 { +// res[i * 4 + j] = f[j]; +// } +// } +// V128(res) +// } From 8485ad1af9090d47a5abb757d7f3922f9a31ff7f Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Wed, 13 Nov 2024 00:49:19 +0100 Subject: [PATCH 23/54] chore: update deps note: wasmparser now uses btree's Signed-off-by: Henry Gressmann --- Cargo.lock | 95 ++++++------------- Cargo.toml | 4 +- crates/parser/Cargo.toml | 2 +- crates/tinywasm/tests/generated/wasm-1.csv | 2 +- crates/tinywasm/tests/generated/wasm-2.csv | 2 +- .../tests/generated/wasm-extended-const.csv | 1 + .../tests/generated/wasm-memory64.csv | 1 + crates/tinywasm/tests/testsuite/run.rs | 5 +- crates/wasm-testsuite/data | 2 +- crates/wasm-testsuite/lib.rs | 4 +- 10 files changed, 43 insertions(+), 75 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bf486d9..34507f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,18 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "aho-corasick" version = "1.1.3" @@ -31,9 +19,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "argh" @@ -198,9 +186,9 @@ checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "cpufeatures" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6" dependencies = [ "libc", ] @@ -364,15 +352,12 @@ name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", -] [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" [[package]] name = "hermit-abi" @@ -399,7 +384,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.15.0", + "hashbrown 0.15.1", ] [[package]] @@ -436,15 +421,15 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.161" +version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" [[package]] name = "libm" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "log" @@ -596,9 +581,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -708,18 +693,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.213" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.213" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", @@ -757,9 +742,9 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "syn" -version = "2.0.85" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -871,9 +856,9 @@ checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-width" -version = "0.1.14" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" [[package]] name = "uuid" @@ -899,9 +884,9 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.219.1" +version = "0.220.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29cbbd772edcb8e7d524a82ee8cef8dd046fc14033796a754c3ad246d019fa54" +checksum = "ebf48234b389415b226a4daef6562933d38c7b28a8b8f64c5c4130dad1561ab7" dependencies = [ "leb128", "wasmparser", @@ -916,22 +901,20 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.219.1" +version = "0.220.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c771866898879073c53b565a6c7b49953795159836714ac56a5befb581227c5" +checksum = "e246c2772ce3ebc83f89a2d4487ac5794cad6c309b2071818a88c7db7c36d87b" dependencies = [ - "ahash", "bitflags", - "hashbrown 0.14.5", "indexmap", "semver", ] [[package]] name = "wast" -version = "219.0.1" +version = "220.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f79a9d9df79986a68689a6b40bcc8d5d40d807487b235bebc2ac69a242b54a1" +checksum = "4e708c8de08751fd66e70961a32bae9d71901f14a70871e181cb8461a3bb3165" dependencies = [ "bumpalo", "leb128", @@ -942,9 +925,9 @@ dependencies = [ [[package]] name = "wat" -version = "1.219.1" +version = "1.220.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bc3cf014fb336883a411cd662f987abf6a1d2a27f2f0008616a0070bbf6bd0d" +checksum = "de4f1d7d59614ba690541360102b995c4eb1b9ed373701d5102cc1a968b1c5a3" dependencies = [ "wast", ] @@ -1039,23 +1022,3 @@ name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/Cargo.toml b/Cargo.toml index 413d364..3eae13e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,8 +4,8 @@ default-members=[".", "crates/tinywasm", "crates/types", "crates/parser"] resolver="2" [workspace.dependencies] -wast="219" -wat="1.219" +wast="220" +wat="1.220" eyre="0.6" log="0.4" pretty_env_logger="0.5" diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index 83bb32b..a7b8826 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -9,7 +9,7 @@ repository.workspace=true rust-version.workspace=true [dependencies] -wasmparser={version="0.219", default-features=false, features=["validate", "features"]} +wasmparser={version="0.220", default-features=false, features=["validate", "features"]} log={workspace=true, optional=true} tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false} diff --git a/crates/tinywasm/tests/generated/wasm-1.csv b/crates/tinywasm/tests/generated/wasm-1.csv index 9cb5102..591123d 100644 --- a/crates/tinywasm/tests/generated/wasm-1.csv +++ b/crates/tinywasm/tests/generated/wasm-1.csv @@ -5,4 +5,4 @@ 0.6.1,27572,335,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.7.0,27572,335,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.8.0,20360,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":128,"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":98,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_grow.wast","passed":104,"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.9.0-alpha.0,20360,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":128,"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":98,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_grow.wast","passed":104,"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.9.0-alpha.0,20362,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":128,"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":172,"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":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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_grow.wast","passed":104,"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/tinywasm/tests/generated/wasm-2.csv b/crates/tinywasm/tests/generated/wasm-2.csv index a4ef6b0..a001172 100644 --- a/crates/tinywasm/tests/generated/wasm-2.csv +++ b/crates/tinywasm/tests/generated/wasm-2.csv @@ -10,4 +10,4 @@ 0.6.1,20278,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.7.0,20278,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.8.0,28008,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":128,"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":117,"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":98,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_copy.wast","passed":4450,"failed":0},{"name":"memory_fill.wast","passed":100,"failed":0},{"name":"memory_grow.wast","passed":104,"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":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":16,"failed":0},{"name":"ref_null.wast","passed":3,"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-sub.wast","passed":2,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"table_copy.wast","passed":1728,"failed":0},{"name":"table_fill.wast","passed":45,"failed":0},{"name":"table_get.wast","passed":16,"failed":0},{"name":"table_grow.wast","passed":58,"failed":0},{"name":"table_init.wast","passed":780,"failed":0},{"name":"table_set.wast","passed":26,"failed":0},{"name":"table_size.wast","passed":39,"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.9.0-alpha.0,28008,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":128,"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":117,"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":98,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_copy.wast","passed":4450,"failed":0},{"name":"memory_fill.wast","passed":100,"failed":0},{"name":"memory_grow.wast","passed":104,"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":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":16,"failed":0},{"name":"ref_null.wast","passed":3,"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-sub.wast","passed":2,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"table_copy.wast","passed":1728,"failed":0},{"name":"table_fill.wast","passed":45,"failed":0},{"name":"table_get.wast","passed":16,"failed":0},{"name":"table_grow.wast","passed":58,"failed":0},{"name":"table_init.wast","passed":780,"failed":0},{"name":"table_set.wast","passed":26,"failed":0},{"name":"table_size.wast","passed":39,"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.9.0-alpha.0,28010,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":128,"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":117,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":172,"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":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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_copy.wast","passed":4450,"failed":0},{"name":"memory_fill.wast","passed":100,"failed":0},{"name":"memory_grow.wast","passed":104,"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":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":16,"failed":0},{"name":"ref_null.wast","passed":3,"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-sub.wast","passed":2,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"table_copy.wast","passed":1728,"failed":0},{"name":"table_fill.wast","passed":45,"failed":0},{"name":"table_get.wast","passed":16,"failed":0},{"name":"table_grow.wast","passed":58,"failed":0},{"name":"table_init.wast","passed":780,"failed":0},{"name":"table_set.wast","passed":26,"failed":0},{"name":"table_size.wast","passed":39,"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/tinywasm/tests/generated/wasm-extended-const.csv b/crates/tinywasm/tests/generated/wasm-extended-const.csv index 1c80050..e20303d 100644 --- a/crates/tinywasm/tests/generated/wasm-extended-const.csv +++ b/crates/tinywasm/tests/generated/wasm-extended-const.csv @@ -1 +1,2 @@ 0.8.0,211,79,[{"name":"data.wast","passed":61,"failed":4},{"name":"elem.wast","passed":99,"failed":12},{"name":"global.wast","passed":51,"failed":63}] +0.9.0-alpha.0,211,79,[{"name":"data.wast","passed":61,"failed":4},{"name":"elem.wast","passed":99,"failed":12},{"name":"global.wast","passed":51,"failed":63}] diff --git a/crates/tinywasm/tests/generated/wasm-memory64.csv b/crates/tinywasm/tests/generated/wasm-memory64.csv index 774d1e1..6638c85 100644 --- a/crates/tinywasm/tests/generated/wasm-memory64.csv +++ b/crates/tinywasm/tests/generated/wasm-memory64.csv @@ -1 +1,2 @@ 0.8.0,15081,3214,[{"name":"address.wast","passed":260,"failed":0},{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"address64.wast","passed":0,"failed":242},{"name":"align.wast","passed":161,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"align64.wast","passed":83,"failed":73},{"name":"annotations.wast","passed":74,"failed":0},{"name":"array_copy.wast","passed":4,"failed":31},{"name":"array_fill.wast","passed":3,"failed":14},{"name":"array_init_data.wast","passed":2,"failed":31},{"name":"array_init_elem.wast","passed":3,"failed":20},{"name":"binary-gc.wast","passed":1,"failed":0},{"name":"binary-leb128.wast","passed":92,"failed":1},{"name":"binary.wast","passed":124,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"br_if.wast","passed":119,"failed":0},{"name":"br_on_cast.wast","passed":6,"failed":31},{"name":"br_on_cast_fail.wast","passed":6,"failed":31},{"name":"br_on_non_null.wast","passed":1,"failed":9},{"name":"br_on_null.wast","passed":1,"failed":9},{"name":"br_table.wast","passed":24,"failed":162},{"name":"call_indirect.wast","passed":47,"failed":124},{"name":"call_ref.wast","passed":4,"failed":31},{"name":"data.wast","passed":59,"failed":6},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"elem.wast","passed":137,"failed":14},{"name":"endianness64.wast","passed":0,"failed":69},{"name":"exports.wast","passed":97,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"float_memory64.wast","passed":0,"failed":90},{"name":"func.wast","passed":175,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":99,"failed":82},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking.wast","passed":122,"failed":41},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"load64.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_init.wast","passed":10,"failed":0},{"name":"local_tee.wast","passed":98,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory64.wast","passed":10,"failed":53},{"name":"memory64/array.wast (skipped)","passed":0,"failed":0},{"name":"memory64/extern.wast (skipped)","passed":0,"failed":0},{"name":"memory64/global.wast (skipped)","passed":0,"failed":0},{"name":"memory64/i31.wast (skipped)","passed":0,"failed":0},{"name":"memory64/ref_null.wast (skipped)","passed":0,"failed":0},{"name":"memory64/select.wast (skipped)","passed":0,"failed":0},{"name":"memory64/simd_address.wast (skipped)","passed":0,"failed":0},{"name":"memory64/simd_lane.wast (skipped)","passed":0,"failed":0},{"name":"memory64/struct.wast (skipped)","passed":0,"failed":0},{"name":"memory64/table.wast (skipped)","passed":0,"failed":0},{"name":"memory_copy.wast","passed":8385,"failed":515},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill.wast","passed":164,"failed":36},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_grow64.wast","passed":0,"failed":49},{"name":"memory_init.wast","passed":307,"failed":173},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_redundancy64.wast","passed":0,"failed":8},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"memory_trap64.wast","passed":0,"failed":172},{"name":"ref.wast","passed":12,"failed":1},{"name":"ref_as_non_null.wast","passed":1,"failed":6},{"name":"ref_cast.wast","passed":0,"failed":45},{"name":"ref_eq.wast","passed":6,"failed":83},{"name":"ref_is_null.wast","passed":2,"failed":20},{"name":"ref_test.wast","passed":0,"failed":71},{"name":"return_call.wast","passed":18,"failed":27},{"name":"return_call_indirect.wast","passed":31,"failed":45},{"name":"return_call_ref.wast","passed":11,"failed":40},{"name":"simd_memory-multi.wast","passed":0,"failed":1},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"table-sub.wast","passed":2,"failed":1},{"name":"table_copy.wast","passed":1742,"failed":30},{"name":"table_copy_mixed.wast","passed":3,"failed":1},{"name":"table_fill.wast","passed":9,"failed":71},{"name":"table_get.wast","passed":5,"failed":12},{"name":"table_grow.wast","passed":36,"failed":43},{"name":"table_init.wast","passed":588,"failed":288},{"name":"table_set.wast","passed":7,"failed":21},{"name":"table_size.wast","passed":2,"failed":38},{"name":"tag.wast","passed":1,"failed":8},{"name":"throw.wast","passed":3,"failed":10},{"name":"throw_ref.wast","passed":2,"failed":13},{"name":"token.wast","passed":61,"failed":0},{"name":"traps0.wast","passed":15,"failed":0},{"name":"try_table.wast","passed":11,"failed":51},{"name":"type-canon.wast","passed":0,"failed":2},{"name":"type-equivalence.wast","passed":12,"failed":20},{"name":"type-rec.wast","passed":6,"failed":14},{"name":"type-subtyping.wast","passed":16,"failed":86},{"name":"unreached-invalid.wast","passed":121,"failed":0},{"name":"unreached-valid.wast","passed":2,"failed":11}] +0.9.0-alpha.0,12505,1919,[{"name":"address.wast","passed":260,"failed":0},{"name":"address64.wast","passed":0,"failed":242},{"name":"align64.wast","passed":83,"failed":73},{"name":"binary-leb128.wast","passed":92,"failed":1},{"name":"binary.wast","passed":126,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"call_indirect.wast","passed":47,"failed":124},{"name":"endianness64.wast","passed":0,"failed":69},{"name":"float_memory64.wast","passed":0,"failed":90},{"name":"imports.wast","passed":169,"failed":90},{"name":"load64.wast","passed":59,"failed":38},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory64.wast","passed":10,"failed":53},{"name":"memory64/simd_address.wast (skipped)","passed":0,"failed":0},{"name":"memory64/table.wast (skipped)","passed":0,"failed":0},{"name":"memory_copy.wast","passed":8385,"failed":515},{"name":"memory_fill.wast","passed":164,"failed":36},{"name":"memory_grow64.wast","passed":0,"failed":49},{"name":"memory_init.wast","passed":307,"failed":173},{"name":"memory_redundancy64.wast","passed":0,"failed":8},{"name":"memory_trap64.wast","passed":0,"failed":172},{"name":"table_copy.wast","passed":1742,"failed":30},{"name":"table_copy_mixed.wast","passed":4,"failed":0},{"name":"table_fill.wast","passed":45,"failed":35},{"name":"table_get.wast","passed":16,"failed":1},{"name":"table_grow.wast","passed":58,"failed":21},{"name":"table_init.wast","passed":780,"failed":96},{"name":"table_set.wast","passed":26,"failed":2},{"name":"table_size.wast","passed":39,"failed":1}] diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index ac11eda..26d2e6d 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -368,7 +368,10 @@ impl TestSuite { Err(eyre!("test panicked: {:?}", try_downcast_panic(err))), ), Ok(Err(tinywasm::Error::Linker(err))) => { - if err.message() != message { + if err.message() != message + && (err.message() == "memory types incompatible" + && message != "incompatible import type") + { test_group.add_result( &format!("AssertUnlinkable({i})"), span.linecol_in(wast), diff --git a/crates/wasm-testsuite/data b/crates/wasm-testsuite/data index cbde6d5..eeb6dac 160000 --- a/crates/wasm-testsuite/data +++ b/crates/wasm-testsuite/data @@ -1 +1 @@ -Subproject commit cbde6d5f26ba12d4f455b65bd0648cdba4d95f15 +Subproject commit eeb6dac81be81151da0958ed955aba91230c1f25 diff --git a/crates/wasm-testsuite/lib.rs b/crates/wasm-testsuite/lib.rs index 2a2892c..8838fd2 100644 --- a/crates/wasm-testsuite/lib.rs +++ b/crates/wasm-testsuite/lib.rs @@ -23,7 +23,7 @@ struct CustomTests; /// /// Includes all proposals from #[rustfmt::skip] -pub const PROPOSALS: &[&str] = &["annotations", "exception-handling", "extended-const", "function-references", "gc", "memory64", "multi-memory", "relaxed-simd", "tail-call", "threads", "custom-page-sizes"]; +pub const PROPOSALS: &[&str] = &["annotations", "exception-handling", "extended-const", "function-references", "gc", "memory64", "multi-memory", "relaxed-simd", "tail-call", "threads", "custom-page-sizes", "wide-arithmetic"]; /// List of all tests that apply to the MVP (V1) spec /// Note that the tests are still for the latest spec, so the latest version of Wast is used. @@ -80,7 +80,7 @@ mod tests { let proposal = proposal.split('/').nth(1).unwrap(); unique_proposals.insert(proposal.to_owned()); - assert!(PROPOSALS.contains(&proposal)); + assert!(PROPOSALS.contains(&proposal), "Missing proposal: {}", proposal); } } } From 802a10ad70b285660806e8e074e382a03c413f09 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sun, 17 Nov 2024 21:46:30 +0100 Subject: [PATCH 24/54] ci: don't add -D warnings rust flags Signed-off-by: Henry Gressmann --- .github/workflows/test.yaml | 1 + Cargo.lock | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index ebf0487..0a75fb2 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -20,6 +20,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: stable + rustflags: "" target: wasm32-unknown-unknown - name: Install Binaryen and WABT run: sudo apt-get install -y binaryen wabt diff --git a/Cargo.lock b/Cargo.lock index 34507f8..bc9577a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,9 +77,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" +checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22" dependencies = [ "memchr", "serde", @@ -161,18 +161,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.20" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.20" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" dependencies = [ "anstyle", "clap_lex", @@ -180,9 +180,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" [[package]] name = "cpufeatures" @@ -421,9 +421,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.162" +version = "0.2.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" +checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" [[package]] name = "libm" @@ -713,9 +713,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", From 2d5899a38ef352f2aa056cc77d51c4668bf2c0a4 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Mon, 18 Nov 2024 14:18:50 +0100 Subject: [PATCH 25/54] chore: basic simd instructions Signed-off-by: Henry Gressmann --- crates/tinywasm/src/interpreter/executor.rs | 13 +- crates/tinywasm/src/interpreter/simd.rs | 165 ++++-------------- .../src/interpreter/stack/value_stack.rs | 14 +- crates/tinywasm/src/interpreter/values.rs | 8 +- crates/tinywasm/src/store/table.rs | 11 +- crates/tinywasm/tests/generated/wasm-simd.csv | 2 +- crates/tinywasm/tests/testsuite/util.rs | 2 +- crates/types/src/instructions.rs | 8 +- 8 files changed, 65 insertions(+), 158 deletions(-) diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index 774927c..2b64942 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -4,6 +4,7 @@ use super::no_std_floats::NoStdFloatExt; use alloc::{format, rc::Rc, string::ToString}; use core::ops::ControlFlow; +use interpreter::simd::exec_next_simd; use interpreter::stack::CallFrame; use tinywasm_types::*; @@ -12,11 +13,11 @@ use super::stack::{BlockFrame, BlockType, Stack}; use super::values::*; use crate::*; -pub(super) struct Executor<'store, 'stack> { - cf: CallFrame, - module: ModuleInstance, - store: &'store mut Store, - stack: &'stack mut Stack, +pub(crate) struct Executor<'store, 'stack> { + pub(crate) cf: CallFrame, + pub(crate) module: ModuleInstance, + pub(crate) store: &'store mut Store, + pub(crate) stack: &'stack mut Stack, } impl<'store, 'stack> Executor<'store, 'stack> { @@ -302,7 +303,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { LocalCopy128(from, to) => self.exec_local_copy::(*from, *to), LocalCopyRef(from, to) => self.exec_local_copy::(*from, *to), - Simd(op) => unimplemented!("simd instruction {:?}", op), + Simd(op) => exec_next_simd(self, *op).to_cf()?, }; self.cf.incr_instr_ptr(); diff --git a/crates/tinywasm/src/interpreter/simd.rs b/crates/tinywasm/src/interpreter/simd.rs index eb798d4..e996edc 100644 --- a/crates/tinywasm/src/interpreter/simd.rs +++ b/crates/tinywasm/src/interpreter/simd.rs @@ -1,133 +1,32 @@ -// #[cfg(not(feature = "std"))] -// #[allow(unused_imports)] -// use super::no_std_floats::NoStdFloatExt; - -// // WIP -// struct V128([u8; 16]); - -// impl V128 { -// fn f32x4(&self) -> [f32; 4] { -// let mut res = [0.0; 4]; -// for i in 0..4 { -// let mut f = [0; 4]; -// for j in 0..4 { -// f[j] = self.0[i * 4 + j]; -// } -// res[i] = f32::from_le_bytes(f); -// } -// res -// } - -// fn i32x4(&self) -> [i32; 4] { -// let mut res = [0; 4]; -// for i in 0..4 { -// let mut f = [0; 4]; -// for j in 0..4 { -// f[j] = self.0[i * 4 + j]; -// } -// res[i] = i32::from_le_bytes(f); -// } -// res -// } - -// fn i64x2(&self) -> [i64; 2] { -// let mut res = [0; 2]; -// for i in 0..2 { -// let mut f = [0; 8]; -// for j in 0..8 { -// f[j] = self.0[i * 8 + j]; -// } -// res[i] = i64::from_le_bytes(f); -// } -// res -// } - -// fn f64x2(&self) -> [f64; 2] { -// let mut res = [0.0; 2]; -// for i in 0..2 { -// let mut f = [0; 8]; -// for j in 0..8 { -// f[j] = self.0[i * 8 + j]; -// } -// res[i] = f64::from_le_bytes(f); -// } -// res -// } - -// fn i16x8(&self) -> [i16; 8] { -// let mut res = [0; 8]; -// for i in 0..8 { -// let mut f = [0; 2]; -// for j in 0..2 { -// f[j] = self.0[i * 2 + j]; -// } -// res[i] = i16::from_le_bytes(f); -// } -// res -// } - -// fn i8x16(&self) -> [i8; 16] { -// let mut res = [0; 16]; -// for i in 0..16 { -// res[i] = i8::from_le_bytes([self.0[i]]); -// } -// res -// } -// } - -// fn vvunop(c1: V128) -> V128 { -// let mut res = [0; 16]; -// for i in 0..16 { -// res[i] = !c1.0[i]; -// } -// V128(res) -// } - -// fn vvbinop(c1: V128, c2: V128) -> V128 { -// let mut res = [0; 16]; -// for i in 0..16 { -// res[i] = c1.0[i] & c2.0[i]; -// } -// V128(res) -// } - -// fn vvternop(c1: V128, c2: V128, c3: V128) -> V128 { -// let mut res = [0; 16]; -// for i in 0..16 { -// res[i] = c1.0[i] & c2.0[i] | !c1.0[i] & c3.0[i]; -// } -// V128(res) -// } - -// fn any_true(val: V128) -> bool { -// val.0.iter().any(|&x| x != 0) -// } - -// fn i8x16_swizzle(c1: V128, c2: V128) -> V128 { -// let mut res = [0; 16]; -// for i in 0..16 { -// res[i] = c1.0[c2.0[i] as usize]; -// } -// V128(res) -// } - -// fn i18x16_shuffle(c1: V128, c2: V128) -> V128 { -// let mut res = [0; 16]; -// for i in 0..16 { -// res[i] = c1.0[(c2.0[i] & 0xf) as usize]; -// } -// V128(res) -// } - -// fn f32x4_abs(val: V128) -> V128 { -// let mut res = [0; 16]; -// for i in 0..4 { -// let f = val.f32x4(); -// let f = f32::abs(f[i]); -// let f = f.to_le_bytes(); -// for j in 0..4 { -// res[i * 4 + j] = f[j]; -// } -// } -// V128(res) -// } +use tinywasm_types::SimdInstruction; + +use crate::Result; + +#[cfg(not(feature = "std"))] +#[allow(unused_imports)] +use super::no_std_floats::NoStdFloatExt; +use super::{executor::Executor, Value128}; + +#[inline(always)] +pub(crate) fn exec_next_simd(e: &mut Executor<'_, '_>, op: SimdInstruction) -> Result<()> { + match op { + // unops + SimdInstruction::V128Not => e.stack.values.replace_top_same(|a: Value128| Ok(!a))?, + // binops + SimdInstruction::V128And => e.stack.values.calculate_same(|a: Value128, b: Value128| Ok(a & b))?, + SimdInstruction::V128AndNot => e.stack.values.calculate_same(|a: Value128, b: Value128| Ok(a & !b))?, + SimdInstruction::V128Or => e.stack.values.calculate_same(|a: Value128, b: Value128| Ok(a | b))?, + SimdInstruction::V128Xor => e.stack.values.calculate_same(|a: Value128, b: Value128| Ok(a ^ b))?, + // ternops + SimdInstruction::V128Bitselect => { + let c: Value128 = e.stack.values.pop(); + e.stack.values.calculate(|a: Value128, b: Value128| Ok((a & b) | (!a & c)))?; + } + // shifts + _ => {} + } + Ok(()) +} + +// trait SimdExt {} +// impl SimdExt for Value128 {} diff --git a/crates/tinywasm/src/interpreter/stack/value_stack.rs b/crates/tinywasm/src/interpreter/stack/value_stack.rs index 7cbf612..ab739a3 100644 --- a/crates/tinywasm/src/interpreter/stack/value_stack.rs +++ b/crates/tinywasm/src/interpreter/stack/value_stack.rs @@ -67,12 +67,15 @@ impl ValueStack { } #[inline] - pub(crate) fn calculate_same(&mut self, func: fn(T, T) -> Result) -> Result<()> { + pub(crate) fn calculate_same(&mut self, func: impl FnOnce(T, T) -> Result) -> Result<()> { T::stack_calculate(self, func) } #[inline] - pub(crate) fn calculate(&mut self, func: fn(T, T) -> Result) -> Result<()> { + pub(crate) fn calculate( + &mut self, + func: impl FnOnce(T, T) -> Result, + ) -> Result<()> { let v2 = T::stack_pop(self); let v1 = T::stack_pop(self); U::stack_push(self, func(v1, v2)?); @@ -80,14 +83,17 @@ impl ValueStack { } #[inline] - pub(crate) fn replace_top(&mut self, func: fn(T) -> Result) -> Result<()> { + pub(crate) fn replace_top( + &mut self, + func: impl FnOnce(T) -> Result, + ) -> Result<()> { let v1 = T::stack_pop(self); U::stack_push(self, func(v1)?); Ok(()) } #[inline] - pub(crate) fn replace_top_same(&mut self, func: fn(T) -> Result) -> Result<()> { + pub(crate) fn replace_top_same(&mut self, func: impl Fn(T) -> Result) -> Result<()> { T::replace_top(self, func) } diff --git a/crates/tinywasm/src/interpreter/values.rs b/crates/tinywasm/src/interpreter/values.rs index 99cf443..efee9b8 100644 --- a/crates/tinywasm/src/interpreter/values.rs +++ b/crates/tinywasm/src/interpreter/values.rs @@ -146,10 +146,10 @@ mod sealed { pub(crate) trait InternalValue: sealed::Sealed + Into { fn stack_push(stack: &mut ValueStack, value: Self); - fn replace_top(stack: &mut ValueStack, func: fn(Self) -> Result) -> Result<()> + fn replace_top(stack: &mut ValueStack, func: impl FnOnce(Self) -> Result) -> Result<()> where Self: Sized; - fn stack_calculate(stack: &mut ValueStack, func: fn(Self, Self) -> Result) -> Result<()> + fn stack_calculate(stack: &mut ValueStack, func: impl FnOnce(Self, Self) -> Result) -> Result<()> where Self: Sized; @@ -197,7 +197,7 @@ macro_rules! impl_internalvalue { } #[inline(always)] - fn stack_calculate(stack: &mut ValueStack, func: fn(Self, Self) -> Result) -> Result<()> { + fn stack_calculate(stack: &mut ValueStack, func: impl FnOnce(Self, Self) -> Result) -> Result<()> { let v2 = stack.$stack.pop(); let v1 = stack.$stack.last_mut(); let (Some(v1), Some(v2)) = (v1, v2) else { @@ -209,7 +209,7 @@ macro_rules! impl_internalvalue { } #[inline(always)] - fn replace_top(stack: &mut ValueStack, func: fn(Self) -> Result) -> Result<()> { + fn replace_top(stack: &mut ValueStack, func: impl FnOnce(Self) -> Result) -> Result<()> { let Some(v) = stack.$stack.last_mut() else { unreachable!("ValueStack underflow, this is a bug"); }; diff --git a/crates/tinywasm/src/store/table.rs b/crates/tinywasm/src/store/table.rs index 200d331..5520faf 100644 --- a/crates/tinywasm/src/store/table.rs +++ b/crates/tinywasm/src/store/table.rs @@ -48,10 +48,11 @@ impl TableInstance { } pub(crate) fn get(&self, addr: TableAddr) -> Result<&TableElement> { - // self.elements.get(addr as usize).ok_or_else(|| Error::Trap(Trap::UndefinedElement { index: addr as usize })) - self.elements.get(addr as usize).ok_or({ - Error::Trap(Trap::TableOutOfBounds { offset: addr as usize, len: 1, max: self.elements.len() }) - }) + self.elements.get(addr as usize).ok_or(Error::Trap(Trap::TableOutOfBounds { + offset: addr as usize, + len: 1, + max: self.elements.len(), + })) } pub(crate) fn copy_from_slice(&mut self, dst: usize, src: &[TableElement]) -> Result<()> { @@ -172,7 +173,7 @@ impl TableElement { } } - pub(crate) fn map Addr>(self, f: F) -> Self { + pub(crate) fn map(self, f: impl FnOnce(Addr) -> Addr) -> Self { match self { TableElement::Uninitialized => TableElement::Uninitialized, TableElement::Initialized(addr) => TableElement::Initialized(f(addr)), diff --git a/crates/tinywasm/tests/generated/wasm-simd.csv b/crates/tinywasm/tests/generated/wasm-simd.csv index a7fc7ef..d695dfa 100644 --- a/crates/tinywasm/tests/generated/wasm-simd.csv +++ b/crates/tinywasm/tests/generated/wasm-simd.csv @@ -1,2 +1,2 @@ 0.8.0,1300,24679,[{"name":"simd_address.wast","passed":4,"failed":45},{"name":"simd_align.wast","passed":46,"failed":54},{"name":"simd_bit_shift.wast","passed":39,"failed":213},{"name":"simd_bitwise.wast","passed":28,"failed":141},{"name":"simd_boolean.wast","passed":16,"failed":261},{"name":"simd_const.wast","passed":301,"failed":456},{"name":"simd_conversions.wast","passed":48,"failed":234},{"name":"simd_f32x4.wast","passed":16,"failed":774},{"name":"simd_f32x4_arith.wast","passed":16,"failed":1806},{"name":"simd_f32x4_cmp.wast","passed":24,"failed":2583},{"name":"simd_f32x4_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f32x4_rounding.wast","passed":24,"failed":177},{"name":"simd_f64x2.wast","passed":8,"failed":795},{"name":"simd_f64x2_arith.wast","passed":16,"failed":1809},{"name":"simd_f64x2_cmp.wast","passed":24,"failed":2661},{"name":"simd_f64x2_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f64x2_rounding.wast","passed":24,"failed":177},{"name":"simd_i16x8_arith.wast","passed":11,"failed":183},{"name":"simd_i16x8_arith2.wast","passed":19,"failed":153},{"name":"simd_i16x8_cmp.wast","passed":30,"failed":435},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":4,"failed":17},{"name":"simd_i16x8_extmul_i8x16.wast","passed":12,"failed":105},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":3,"failed":27},{"name":"simd_i16x8_sat_arith.wast","passed":16,"failed":206},{"name":"simd_i32x4_arith.wast","passed":11,"failed":183},{"name":"simd_i32x4_arith2.wast","passed":26,"failed":123},{"name":"simd_i32x4_cmp.wast","passed":40,"failed":435},{"name":"simd_i32x4_dot_i16x8.wast","passed":3,"failed":27},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":4,"failed":17},{"name":"simd_i32x4_extmul_i16x8.wast","passed":12,"failed":105},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":4,"failed":103},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":4,"failed":103},{"name":"simd_i64x2_arith.wast","passed":11,"failed":189},{"name":"simd_i64x2_arith2.wast","passed":2,"failed":23},{"name":"simd_i64x2_cmp.wast","passed":10,"failed":103},{"name":"simd_i64x2_extmul_i32x4.wast","passed":12,"failed":105},{"name":"simd_i8x16_arith.wast","passed":8,"failed":123},{"name":"simd_i8x16_arith2.wast","passed":25,"failed":186},{"name":"simd_i8x16_cmp.wast","passed":30,"failed":415},{"name":"simd_i8x16_sat_arith.wast","passed":24,"failed":190},{"name":"simd_int_to_int_extend.wast","passed":24,"failed":229},{"name":"simd_lane.wast","passed":189,"failed":286},{"name":"simd_linking.wast","passed":0,"failed":3},{"name":"simd_load.wast","passed":8,"failed":31},{"name":"simd_load16_lane.wast","passed":3,"failed":33},{"name":"simd_load32_lane.wast","passed":3,"failed":21},{"name":"simd_load64_lane.wast","passed":3,"failed":13},{"name":"simd_load8_lane.wast","passed":3,"failed":49},{"name":"simd_load_extend.wast","passed":18,"failed":86},{"name":"simd_load_splat.wast","passed":12,"failed":114},{"name":"simd_load_zero.wast","passed":10,"failed":29},{"name":"simd_splat.wast","passed":23,"failed":162},{"name":"simd_store.wast","passed":9,"failed":19},{"name":"simd_store16_lane.wast","passed":3,"failed":33},{"name":"simd_store32_lane.wast","passed":3,"failed":21},{"name":"simd_store64_lane.wast","passed":3,"failed":13},{"name":"simd_store8_lane.wast","passed":3,"failed":49}] -0.9.0-alpha.0,1702,24277,[{"name":"simd_address.wast","passed":7,"failed":42},{"name":"simd_align.wast","passed":92,"failed":8},{"name":"simd_bit_shift.wast","passed":41,"failed":211},{"name":"simd_bitwise.wast","passed":30,"failed":139},{"name":"simd_boolean.wast","passed":18,"failed":259},{"name":"simd_const.wast","passed":551,"failed":206},{"name":"simd_conversions.wast","passed":50,"failed":232},{"name":"simd_f32x4.wast","passed":18,"failed":772},{"name":"simd_f32x4_arith.wast","passed":19,"failed":1803},{"name":"simd_f32x4_cmp.wast","passed":26,"failed":2581},{"name":"simd_f32x4_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f32x4_rounding.wast","passed":25,"failed":176},{"name":"simd_f64x2.wast","passed":10,"failed":793},{"name":"simd_f64x2_arith.wast","passed":19,"failed":1806},{"name":"simd_f64x2_cmp.wast","passed":26,"failed":2659},{"name":"simd_f64x2_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f64x2_rounding.wast","passed":25,"failed":176},{"name":"simd_i16x8_arith.wast","passed":13,"failed":181},{"name":"simd_i16x8_arith2.wast","passed":21,"failed":151},{"name":"simd_i16x8_cmp.wast","passed":32,"failed":433},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":5,"failed":16},{"name":"simd_i16x8_extmul_i8x16.wast","passed":13,"failed":104},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":4,"failed":26},{"name":"simd_i16x8_sat_arith.wast","passed":18,"failed":204},{"name":"simd_i32x4_arith.wast","passed":13,"failed":181},{"name":"simd_i32x4_arith2.wast","passed":28,"failed":121},{"name":"simd_i32x4_cmp.wast","passed":42,"failed":433},{"name":"simd_i32x4_dot_i16x8.wast","passed":4,"failed":26},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":5,"failed":16},{"name":"simd_i32x4_extmul_i16x8.wast","passed":13,"failed":104},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":5,"failed":102},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":5,"failed":102},{"name":"simd_i64x2_arith.wast","passed":13,"failed":187},{"name":"simd_i64x2_arith2.wast","passed":4,"failed":21},{"name":"simd_i64x2_cmp.wast","passed":11,"failed":102},{"name":"simd_i64x2_extmul_i32x4.wast","passed":13,"failed":104},{"name":"simd_i8x16_arith.wast","passed":10,"failed":121},{"name":"simd_i8x16_arith2.wast","passed":27,"failed":184},{"name":"simd_i8x16_cmp.wast","passed":32,"failed":413},{"name":"simd_i8x16_sat_arith.wast","passed":26,"failed":188},{"name":"simd_int_to_int_extend.wast","passed":25,"failed":228},{"name":"simd_lane.wast","passed":200,"failed":275},{"name":"simd_linking.wast","passed":0,"failed":3},{"name":"simd_load.wast","passed":22,"failed":17},{"name":"simd_load16_lane.wast","passed":4,"failed":32},{"name":"simd_load32_lane.wast","passed":4,"failed":20},{"name":"simd_load64_lane.wast","passed":4,"failed":12},{"name":"simd_load8_lane.wast","passed":4,"failed":48},{"name":"simd_load_extend.wast","passed":20,"failed":84},{"name":"simd_load_splat.wast","passed":14,"failed":112},{"name":"simd_load_zero.wast","passed":12,"failed":27},{"name":"simd_splat.wast","passed":26,"failed":159},{"name":"simd_store.wast","passed":11,"failed":17},{"name":"simd_store16_lane.wast","passed":3,"failed":33},{"name":"simd_store32_lane.wast","passed":3,"failed":21},{"name":"simd_store64_lane.wast","passed":3,"failed":13},{"name":"simd_store8_lane.wast","passed":3,"failed":49}] +0.9.0-alpha.0,1741,24238,[{"name":"simd_address.wast","passed":7,"failed":42},{"name":"simd_align.wast","passed":93,"failed":7},{"name":"simd_bit_shift.wast","passed":41,"failed":211},{"name":"simd_bitwise.wast","passed":30,"failed":139},{"name":"simd_boolean.wast","passed":18,"failed":259},{"name":"simd_const.wast","passed":551,"failed":206},{"name":"simd_conversions.wast","passed":50,"failed":232},{"name":"simd_f32x4.wast","passed":18,"failed":772},{"name":"simd_f32x4_arith.wast","passed":19,"failed":1803},{"name":"simd_f32x4_cmp.wast","passed":26,"failed":2581},{"name":"simd_f32x4_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f32x4_rounding.wast","passed":25,"failed":176},{"name":"simd_f64x2.wast","passed":10,"failed":793},{"name":"simd_f64x2_arith.wast","passed":19,"failed":1806},{"name":"simd_f64x2_cmp.wast","passed":26,"failed":2659},{"name":"simd_f64x2_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f64x2_rounding.wast","passed":25,"failed":176},{"name":"simd_i16x8_arith.wast","passed":13,"failed":181},{"name":"simd_i16x8_arith2.wast","passed":21,"failed":151},{"name":"simd_i16x8_cmp.wast","passed":32,"failed":433},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":5,"failed":16},{"name":"simd_i16x8_extmul_i8x16.wast","passed":13,"failed":104},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":4,"failed":26},{"name":"simd_i16x8_sat_arith.wast","passed":18,"failed":204},{"name":"simd_i32x4_arith.wast","passed":13,"failed":181},{"name":"simd_i32x4_arith2.wast","passed":28,"failed":121},{"name":"simd_i32x4_cmp.wast","passed":42,"failed":433},{"name":"simd_i32x4_dot_i16x8.wast","passed":4,"failed":26},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":5,"failed":16},{"name":"simd_i32x4_extmul_i16x8.wast","passed":13,"failed":104},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":5,"failed":102},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":5,"failed":102},{"name":"simd_i64x2_arith.wast","passed":13,"failed":187},{"name":"simd_i64x2_arith2.wast","passed":4,"failed":21},{"name":"simd_i64x2_cmp.wast","passed":11,"failed":102},{"name":"simd_i64x2_extmul_i32x4.wast","passed":13,"failed":104},{"name":"simd_i8x16_arith.wast","passed":10,"failed":121},{"name":"simd_i8x16_arith2.wast","passed":27,"failed":184},{"name":"simd_i8x16_cmp.wast","passed":32,"failed":413},{"name":"simd_i8x16_sat_arith.wast","passed":26,"failed":188},{"name":"simd_int_to_int_extend.wast","passed":25,"failed":228},{"name":"simd_lane.wast","passed":209,"failed":266},{"name":"simd_linking.wast","passed":0,"failed":3},{"name":"simd_load.wast","passed":24,"failed":15},{"name":"simd_load16_lane.wast","passed":4,"failed":32},{"name":"simd_load32_lane.wast","passed":4,"failed":20},{"name":"simd_load64_lane.wast","passed":4,"failed":12},{"name":"simd_load8_lane.wast","passed":4,"failed":48},{"name":"simd_load_extend.wast","passed":24,"failed":80},{"name":"simd_load_splat.wast","passed":17,"failed":109},{"name":"simd_load_zero.wast","passed":12,"failed":27},{"name":"simd_splat.wast","passed":37,"failed":148},{"name":"simd_store.wast","passed":20,"failed":8},{"name":"simd_store16_lane.wast","passed":3,"failed":33},{"name":"simd_store32_lane.wast","passed":3,"failed":21},{"name":"simd_store64_lane.wast","passed":3,"failed":13},{"name":"simd_store8_lane.wast","passed":3,"failed":49}] diff --git a/crates/tinywasm/tests/testsuite/util.rs b/crates/tinywasm/tests/testsuite/util.rs index 53eb5ff..a66a4da 100644 --- a/crates/tinywasm/tests/testsuite/util.rs +++ b/crates/tinywasm/tests/testsuite/util.rs @@ -46,7 +46,7 @@ pub fn exec_fn( instance.exported_func_untyped(&store, name)?.call(&mut store, args) } -pub fn catch_unwind_silent R, R>(f: F) -> std::thread::Result { +pub fn catch_unwind_silent(f: impl FnOnce() -> R) -> std::thread::Result { let prev_hook = panic::take_hook(); panic::set_hook(Box::new(|_| {})); let result = panic::catch_unwind(AssertUnwindSafe(f)); diff --git a/crates/types/src/instructions.rs b/crates/types/src/instructions.rs index 1edfef7..fb3c1cc 100644 --- a/crates/types/src/instructions.rs +++ b/crates/types/src/instructions.rs @@ -52,7 +52,7 @@ pub enum ConstInstruction { /// This makes it easier to implement the label stack iteratively. /// /// See -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] // should be kept as small as possible (16 bytes max) #[rustfmt::skip] @@ -193,10 +193,10 @@ impl From for Instruction { } } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] #[rustfmt::skip] -pub enum SimdInstruction { +pub enum SimdInstruction { V128Load(MemoryArg), V128Load8x8S(MemoryArg), V128Load8x8U(MemoryArg), V128Load16x4S(MemoryArg), V128Load16x4U(MemoryArg), @@ -204,7 +204,7 @@ pub enum SimdInstruction { V128Load8Splat(MemoryArg), V128Load16Splat(MemoryArg), V128Load32Splat(MemoryArg), V128Load64Splat(MemoryArg), V128Load8Lane(MemoryArg, u8), V128Load16Lane(MemoryArg, u8), V128Load32Lane(MemoryArg, u8), V128Load64Lane(MemoryArg, u8), - + V128Load32Zero(MemoryArg), V128Load64Zero(MemoryArg), V128Store(MemoryArg), V128Store8Lane(MemoryArg, u8), V128Store16Lane(MemoryArg, u8), V128Store32Lane(MemoryArg, u8), V128Store64Lane(MemoryArg, u8), From 37f4dc5db72a2d4df7a7e4993053842a44fc54ed Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Thu, 21 Nov 2024 02:04:52 +0100 Subject: [PATCH 26/54] chore: update wasm testsuite Signed-off-by: Henry Gressmann --- Cargo.lock | 8 +++--- .../tests/test-wasm-custom-page-sizes.rs | 28 +++++++++---------- crates/wasm-testsuite/data | 2 +- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bc9577a..a13594b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -409,9 +409,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2" [[package]] name = "leb128" @@ -850,9 +850,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-width" diff --git a/crates/tinywasm/tests/test-wasm-custom-page-sizes.rs b/crates/tinywasm/tests/test-wasm-custom-page-sizes.rs index ab8d36e..ee9c732 100644 --- a/crates/tinywasm/tests/test-wasm-custom-page-sizes.rs +++ b/crates/tinywasm/tests/test-wasm-custom-page-sizes.rs @@ -1,20 +1,20 @@ mod testsuite; -use eyre::{eyre, Result}; -use owo_colors::OwoColorize; -use testsuite::TestSuite; +use eyre::Result; fn main() -> Result<()> { - let mut test_suite = TestSuite::new(); + println!("Skipping Wasm Custom Page Sizes tests (Wast doesn't support the syntax yet)"); + Ok(()) - TestSuite::set_log_level(log::LevelFilter::Off); - test_suite.run_spec_group(wasm_testsuite::get_proposal_tests("custom-page-sizes"))?; - test_suite.save_csv("./tests/generated/wasm-custom-page-sizes.csv", env!("CARGO_PKG_VERSION"))?; + // let mut test_suite = TestSuite::new(); + // TestSuite::set_log_level(log::LevelFilter::Off); + // test_suite.run_spec_group(wasm_testsuite::get_proposal_tests("custom-page-sizes"))?; + // test_suite.save_csv("./tests/generated/wasm-custom-page-sizes.csv", env!("CARGO_PKG_VERSION"))?; - if test_suite.failed() { - println!(); - Err(eyre!(format!("{}:\n{:#?}", "failed one or more tests".red().bold(), test_suite,))) - } else { - println!("\n\npassed all tests:\n{test_suite:#?}"); - Ok(()) - } + // if test_suite.failed() { + // println!(); + // Err(eyre!(format!("{}:\n{:#?}", "failed one or more tests".red().bold(), test_suite,))) + // } else { + // println!("\n\npassed all tests:\n{test_suite:#?}"); + // Ok(()) + // } } diff --git a/crates/wasm-testsuite/data b/crates/wasm-testsuite/data index eeb6dac..9b4b015 160000 --- a/crates/wasm-testsuite/data +++ b/crates/wasm-testsuite/data @@ -1 +1 @@ -Subproject commit eeb6dac81be81151da0958ed955aba91230c1f25 +Subproject commit 9b4b01574c36fb19e594fb68fa25747bab2d84c8 From 6dec3f91f0901c3e96de27767a196ced05503d1d Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Thu, 21 Nov 2024 12:45:04 +0100 Subject: [PATCH 27/54] ci: fix tests Signed-off-by: Henry Gressmann --- crates/wasm-testsuite/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/wasm-testsuite/lib.rs b/crates/wasm-testsuite/lib.rs index 8838fd2..b2cc7d2 100644 --- a/crates/wasm-testsuite/lib.rs +++ b/crates/wasm-testsuite/lib.rs @@ -23,7 +23,7 @@ struct CustomTests; /// /// Includes all proposals from #[rustfmt::skip] -pub const PROPOSALS: &[&str] = &["annotations", "exception-handling", "extended-const", "function-references", "gc", "memory64", "multi-memory", "relaxed-simd", "tail-call", "threads", "custom-page-sizes", "wide-arithmetic"]; +pub const PROPOSALS: &[&str] = &["annotations", "exception-handling", "extended-const", "function-references", "gc", "memory64", "multi-memory", "relaxed-simd", "tail-call", "threads", "custom-page-sizes", "wide-arithmetic", "wasm-3.0"]; /// List of all tests that apply to the MVP (V1) spec /// Note that the tests are still for the latest spec, so the latest version of Wast is used. From 53c9bcbb726b6accaabaaec430117b0c0ad14388 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Thu, 28 Nov 2024 18:50:42 +0100 Subject: [PATCH 28/54] chore: update wasmparser Signed-off-by: Henry Gressmann --- Cargo.lock | 62 +++++++------- Cargo.toml | 4 +- crates/parser/Cargo.toml | 2 +- crates/parser/src/visit.rs | 165 +++++++++++++++++++++++-------------- crates/tinywasm/Cargo.toml | 1 - crates/wasm-testsuite/data | 2 +- 6 files changed, 136 insertions(+), 100 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a13594b..539cb8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -116,9 +116,9 @@ dependencies = [ [[package]] name = "bytes" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "cast" @@ -186,9 +186,9 @@ checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" [[package]] name = "cpufeatures" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] @@ -349,15 +349,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" - -[[package]] -name = "hashbrown" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "hermit-abi" @@ -384,7 +378,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.15.1", + "hashbrown", ] [[package]] @@ -409,9 +403,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "leb128" @@ -421,9 +415,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.164" +version = "0.2.166" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" +checksum = "c2ccc108bbc0b1331bd061864e7cd823c0cab660bbe6970e66e2c0614decde36" [[package]] name = "libm" @@ -502,9 +496,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -607,13 +601,13 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395027076c569819ea6035ee62e664f5e03d74e281744f55261dd1afd939212b" +checksum = "b11a153aec4a6ab60795f8ebe2923c597b16b05bb1504377451e705ef1a45323" dependencies = [ "bytecheck", "bytes", - "hashbrown 0.14.5", + "hashbrown", "indexmap", "munge", "ptr_meta", @@ -626,9 +620,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cb82b74b4810f07e460852c32f522e979787691b0b7b7439fe473e49d49b2f" +checksum = "beb382a4d9f53bd5c0be86b10d8179c3f8a14c30bf774ff77096ed6581e35981" dependencies = [ "proc-macro2", "quote", @@ -742,9 +736,9 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "syn" -version = "2.0.87" +version = "2.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" dependencies = [ "proc-macro2", "quote", @@ -884,9 +878,9 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.220.0" +version = "0.221.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebf48234b389415b226a4daef6562933d38c7b28a8b8f64c5c4130dad1561ab7" +checksum = "de35b6c3ef1f53ac7a31b5e69bc00f1542ea337e7e7162dc34c68b537ff82690" dependencies = [ "leb128", "wasmparser", @@ -901,9 +895,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.220.0" +version = "0.221.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e246c2772ce3ebc83f89a2d4487ac5794cad6c309b2071818a88c7db7c36d87b" +checksum = "8659e755615170cfe20da468865c989da78c5da16d8652e69a75acda02406a92" dependencies = [ "bitflags", "indexmap", @@ -912,9 +906,9 @@ dependencies = [ [[package]] name = "wast" -version = "220.0.0" +version = "221.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e708c8de08751fd66e70961a32bae9d71901f14a70871e181cb8461a3bb3165" +checksum = "9d8eb1933d493dd07484a255c3f52236123333f5befaa3be36182a50d393ec54" dependencies = [ "bumpalo", "leb128", @@ -925,9 +919,9 @@ dependencies = [ [[package]] name = "wat" -version = "1.220.0" +version = "1.221.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de4f1d7d59614ba690541360102b995c4eb1b9ed373701d5102cc1a968b1c5a3" +checksum = "c813fd4e5b2b97242830b56e7b7dc5479bc17aaa8730109be35e61909af83993" dependencies = [ "wast", ] diff --git a/Cargo.toml b/Cargo.toml index 3eae13e..ca93037 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,8 +4,8 @@ default-members=[".", "crates/tinywasm", "crates/types", "crates/parser"] resolver="2" [workspace.dependencies] -wast="220" -wat="1.220" +wast="221" +wat="1.221" eyre="0.6" log="0.4" pretty_env_logger="0.5" diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index a7b8826..02b7003 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -9,7 +9,7 @@ repository.workspace=true rust-version.workspace=true [dependencies] -wasmparser={version="0.220", default-features=false, features=["validate", "features"]} +wasmparser={version="0.221", default-features=false, features=["validate", "features", "simd"]} log={workspace=true, optional=true} tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false} diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs index 2e80d20..a94b3a1 100644 --- a/crates/parser/src/visit.rs +++ b/crates/parser/src/visit.rs @@ -4,9 +4,12 @@ use crate::conversion::{convert_heaptype, convert_valtype}; use alloc::string::ToString; use alloc::{boxed::Box, vec::Vec}; use tinywasm_types::{Instruction, MemoryArg, SimdInstruction, WasmFunctionData}; -use wasmparser::{FuncValidator, FuncValidatorAllocations, FunctionBody, VisitOperator, WasmModuleResources}; +use wasmparser::{ + FuncValidator, FuncValidatorAllocations, FunctionBody, VisitOperator, VisitSimdOperator, WasmModuleResources, +}; struct ValidateThenVisit<'a, R: WasmModuleResources>(usize, &'a mut FunctionBuilder); + macro_rules! validate_then_visit { ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {$( fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output { @@ -17,9 +20,27 @@ macro_rules! validate_then_visit { )*}; } +macro_rules! validate_then_visit_simd { + ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {$( + fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output { + self.1.$visit($($($arg.clone()),*)?); + self.1.validator_visitor(self.0).simd_visitor().expect("simd_visitor is supported by the validator").$visit($($($arg),*)?)?; + Ok(()) + } + )*}; +} + impl<'a, R: WasmModuleResources> VisitOperator<'a> for ValidateThenVisit<'_, R> { type Output = Result<()>; - wasmparser::for_each_operator!(validate_then_visit); + wasmparser::for_each_visit_operator!(validate_then_visit); + + fn simd_visitor(&mut self) -> Option<&mut dyn VisitSimdOperator<'a, Output = Self::Output>> { + Some(self) + } +} + +impl VisitSimdOperator<'_> for ValidateThenVisit<'_, R> { + wasmparser::for_each_visit_simd_operator!(validate_then_visit_simd); } pub(crate) fn process_operators_and_validate( @@ -162,9 +183,13 @@ macro_rules! impl_visit_operator { }; } -impl wasmparser::VisitOperator<'_> for FunctionBuilder { +impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuilder { type Output = (); - wasmparser::for_each_operator!(impl_visit_operator); + wasmparser::for_each_visit_operator!(impl_visit_operator); + + fn simd_visitor(&mut self) -> Option<&mut dyn VisitSimdOperator<'a, Output = Self::Output>> { + Some(self) + } define_mem_operands! { visit_i32_load(I32Load), visit_i64_load(I64Load), visit_f32_load(F32Load), visit_f64_load(F64Load), visit_i32_load8_s(I32Load8S), visit_i32_load8_u(I32Load8U), visit_i32_load16_s(I32Load16S), visit_i32_load16_u(I32Load16U), visit_i64_load8_s(I64Load8S), visit_i64_load8_u(I64Load8U), visit_i64_load16_s(I64Load16S), visit_i64_load16_u(I64Load16U), visit_i64_load32_s(I64Load32S), visit_i64_load32_u(I64Load32U), visit_i32_store( I32Store), visit_i64_store(I64Store), visit_f32_store(F32Store), visit_f64_store(F64Store), visit_i32_store8(I32Store8), visit_i32_store16(I32Store16), visit_i64_store8(I64Store8), visit_i64_store16(I64Store16), visit_i64_store32(I64Store32) @@ -187,63 +212,6 @@ impl wasmparser::VisitOperator<'_> for FunctionBuilder Self::Output { - self.v128_constants.push(u128::from_le_bytes(lanes)); - self.instructions.push(SimdInstruction::I8x16Shuffle(self.v128_constants.len() as u32 - 1).into()); - } - - fn visit_v128_const(&mut self, value: wasmparser::V128) -> Self::Output { - self.v128_constants.push(value.i128() as u128); - self.instructions.push(SimdInstruction::V128Const(self.v128_constants.len() as u32 - 1).into()); - } - // fn visit_return_call(&mut self, function_index: u32) -> Self::Output { // self.instructions.push(Instruction::ReturnCall(function_index)); // } @@ -519,3 +487,78 @@ impl wasmparser::VisitOperator<'_> for FunctionBuilder $visit:ident ($($ann:tt)*))*) => { + $(impl_visit_operator!(@@$proposal $op $({ $($arg: $argty),* })? => $visit ($($ann:tt)*));)* + }; + + (@@simd $($rest:tt)* ) => {}; + (@@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*)) => { + #[cold] + fn $visit(&mut self $($(,$arg: $argty)*)?) { + self.unsupported(stringify!($visit)) + } + }; +} + +impl wasmparser::VisitSimdOperator<'_> for FunctionBuilder { + wasmparser::for_each_visit_simd_operator!(impl_visit_simd_operator); + + // simd + define_mem_operands_simd! { + visit_v128_load(V128Load), visit_v128_load8x8_s(V128Load8x8S), visit_v128_load8x8_u(V128Load8x8U), visit_v128_load16x4_s(V128Load16x4S), visit_v128_load16x4_u(V128Load16x4U), visit_v128_load32x2_s(V128Load32x2S), visit_v128_load32x2_u(V128Load32x2U), visit_v128_load8_splat(V128Load8Splat), visit_v128_load16_splat(V128Load16Splat), visit_v128_load32_splat(V128Load32Splat), visit_v128_load64_splat(V128Load64Splat), visit_v128_load32_zero(V128Load32Zero), visit_v128_load64_zero(V128Load64Zero), visit_v128_store(V128Store) + } + define_mem_operands_simd_lane! { + visit_v128_load8_lane(V128Load8Lane), visit_v128_load16_lane(V128Load16Lane), visit_v128_load32_lane(V128Load32Lane), visit_v128_load64_lane(V128Load64Lane), + visit_v128_store8_lane(V128Store8Lane), visit_v128_store16_lane(V128Store16Lane), visit_v128_store32_lane(V128Store32Lane), visit_v128_store64_lane(V128Store64Lane) + } + define_operands_simd! { + visit_v128_not(V128Not), visit_v128_and(V128And), visit_v128_andnot(V128AndNot), visit_v128_or(V128Or), visit_v128_xor(V128Xor), visit_v128_bitselect(V128Bitselect), visit_v128_any_true(V128AnyTrue), + visit_i8x16_splat(I8x16Splat), visit_i8x16_swizzle(I8x16Swizzle), visit_i8x16_eq(I8x16Eq), visit_i8x16_ne(I8x16Ne), visit_i8x16_lt_s(I8x16LtS), visit_i8x16_lt_u(I8x16LtU), visit_i8x16_gt_s(I8x16GtS), visit_i8x16_gt_u(I8x16GtU), visit_i8x16_le_s(I8x16LeS), visit_i8x16_le_u(I8x16LeU), visit_i8x16_ge_s(I8x16GeS), visit_i8x16_ge_u(I8x16GeU), + visit_i16x8_splat(I16x8Splat), visit_i16x8_eq(I16x8Eq), visit_i16x8_ne(I16x8Ne), visit_i16x8_lt_s(I16x8LtS), visit_i16x8_lt_u(I16x8LtU), visit_i16x8_gt_s(I16x8GtS), visit_i16x8_gt_u(I16x8GtU), visit_i16x8_le_s(I16x8LeS), visit_i16x8_le_u(I16x8LeU), visit_i16x8_ge_s(I16x8GeS), visit_i16x8_ge_u(I16x8GeU), + visit_i32x4_splat(I32x4Splat), visit_i32x4_eq(I32x4Eq), visit_i32x4_ne(I32x4Ne), visit_i32x4_lt_s(I32x4LtS), visit_i32x4_lt_u(I32x4LtU), visit_i32x4_gt_s(I32x4GtS), visit_i32x4_gt_u(I32x4GtU), visit_i32x4_le_s(I32x4LeS), visit_i32x4_le_u(I32x4LeU), visit_i32x4_ge_s(I32x4GeS), visit_i32x4_ge_u(I32x4GeU), + visit_i64x2_splat(I64x2Splat), visit_i64x2_eq(I64x2Eq), visit_i64x2_ne(I64x2Ne), visit_i64x2_lt_s(I64x2LtS), visit_i64x2_gt_s(I64x2GtS), visit_i64x2_le_s(I64x2LeS), visit_i64x2_ge_s(I64x2GeS), + visit_f32x4_splat(F32x4Splat), visit_f32x4_eq(F32x4Eq), visit_f32x4_ne(F32x4Ne), visit_f32x4_lt(F32x4Lt), visit_f32x4_gt(F32x4Gt), visit_f32x4_le(F32x4Le), visit_f32x4_ge(F32x4Ge), + visit_f64x2_splat(F64x2Splat), visit_f64x2_eq(F64x2Eq), visit_f64x2_ne(F64x2Ne), visit_f64x2_lt(F64x2Lt), visit_f64x2_gt(F64x2Gt), visit_f64x2_le(F64x2Le), visit_f64x2_ge(F64x2Ge), + visit_i8x16_abs(I8x16Abs), visit_i8x16_neg(I8x16Neg), visit_i8x16_all_true(I8x16AllTrue), visit_i8x16_bitmask(I8x16Bitmask), visit_i8x16_shl(I8x16Shl), visit_i8x16_shr_s(I8x16ShrS), visit_i8x16_shr_u(I8x16ShrU), visit_i8x16_add(I8x16Add), visit_i8x16_sub(I8x16Sub), visit_i8x16_min_s(I8x16MinS), visit_i8x16_min_u(I8x16MinU), visit_i8x16_max_s(I8x16MaxS), visit_i8x16_max_u(I8x16MaxU), + visit_i16x8_abs(I16x8Abs), visit_i16x8_neg(I16x8Neg), visit_i16x8_all_true(I16x8AllTrue), visit_i16x8_bitmask(I16x8Bitmask), visit_i16x8_shl(I16x8Shl), visit_i16x8_shr_s(I16x8ShrS), visit_i16x8_shr_u(I16x8ShrU), visit_i16x8_add(I16x8Add), visit_i16x8_sub(I16x8Sub), visit_i16x8_min_s(I16x8MinS), visit_i16x8_min_u(I16x8MinU), visit_i16x8_max_s(I16x8MaxS), visit_i16x8_max_u(I16x8MaxU), + visit_i32x4_abs(I32x4Abs), visit_i32x4_neg(I32x4Neg), visit_i32x4_all_true(I32x4AllTrue), visit_i32x4_bitmask(I32x4Bitmask), visit_i32x4_shl(I32x4Shl), visit_i32x4_shr_s(I32x4ShrS), visit_i32x4_shr_u(I32x4ShrU), visit_i32x4_add(I32x4Add), visit_i32x4_sub(I32x4Sub), visit_i32x4_min_s(I32x4MinS), visit_i32x4_min_u(I32x4MinU), visit_i32x4_max_s(I32x4MaxS), visit_i32x4_max_u(I32x4MaxU), + visit_i64x2_abs(I64x2Abs), visit_i64x2_neg(I64x2Neg), visit_i64x2_all_true(I64x2AllTrue), visit_i64x2_bitmask(I64x2Bitmask), visit_i64x2_shl(I64x2Shl), visit_i64x2_shr_s(I64x2ShrS), visit_i64x2_shr_u(I64x2ShrU), visit_i64x2_add(I64x2Add), visit_i64x2_sub(I64x2Sub), visit_i64x2_mul(I64x2Mul), + visit_i8x16_narrow_i16x8_s(I8x16NarrowI16x8S), visit_i8x16_narrow_i16x8_u(I8x16NarrowI16x8U), visit_i8x16_add_sat_s(I8x16AddSatS), visit_i8x16_add_sat_u(I8x16AddSatU), visit_i8x16_sub_sat_s(I8x16SubSatS), visit_i8x16_sub_sat_u(I8x16SubSatU), visit_i8x16_avgr_u(I8x16AvgrU), + visit_i16x8_narrow_i32x4_s(I16x8NarrowI32x4S), visit_i16x8_narrow_i32x4_u(I16x8NarrowI32x4U), visit_i16x8_add_sat_s(I16x8AddSatS), visit_i16x8_add_sat_u(I16x8AddSatU), visit_i16x8_sub_sat_s(I16x8SubSatS), visit_i16x8_sub_sat_u(I16x8SubSatU), visit_i16x8_avgr_u(I16x8AvgrU), + visit_i16x8_extadd_pairwise_i8x16_s(I16x8ExtAddPairwiseI8x16S), visit_i16x8_extadd_pairwise_i8x16_u(I16x8ExtAddPairwiseI8x16U), visit_i16x8_mul(I16x8Mul), + visit_i32x4_extadd_pairwise_i16x8_s(I32x4ExtAddPairwiseI16x8S), visit_i32x4_extadd_pairwise_i16x8_u(I32x4ExtAddPairwiseI16x8U), visit_i32x4_mul(I32x4Mul), + visit_i16x8_extmul_low_i8x16_s(I16x8ExtMulLowI8x16S), visit_i16x8_extmul_low_i8x16_u(I16x8ExtMulLowI8x16U), visit_i16x8_extmul_high_i8x16_s(I16x8ExtMulHighI8x16S), visit_i16x8_extmul_high_i8x16_u(I16x8ExtMulHighI8x16U), + visit_i32x4_extmul_low_i16x8_s(I32x4ExtMulLowI16x8S), visit_i32x4_extmul_low_i16x8_u(I32x4ExtMulLowI16x8U), visit_i32x4_extmul_high_i16x8_s(I32x4ExtMulHighI16x8S), visit_i32x4_extmul_high_i16x8_u(I32x4ExtMulHighI16x8U), + visit_i64x2_extmul_low_i32x4_s(I64x2ExtMulLowI32x4S), visit_i64x2_extmul_low_i32x4_u(I64x2ExtMulLowI32x4U), visit_i64x2_extmul_high_i32x4_s(I64x2ExtMulHighI32x4S), visit_i64x2_extmul_high_i32x4_u(I64x2ExtMulHighI32x4U), + visit_i16x8_extend_low_i8x16_s(I16x8ExtendLowI8x16S), visit_i16x8_extend_low_i8x16_u(I16x8ExtendLowI8x16U), visit_i16x8_extend_high_i8x16_s(I16x8ExtendHighI8x16S), visit_i16x8_extend_high_i8x16_u(I16x8ExtendHighI8x16U), + visit_i32x4_extend_low_i16x8_s(I32x4ExtendLowI16x8S), visit_i32x4_extend_low_i16x8_u(I32x4ExtendLowI16x8U), visit_i32x4_extend_high_i16x8_s(I32x4ExtendHighI16x8S), visit_i32x4_extend_high_i16x8_u(I32x4ExtendHighI16x8U), + visit_i64x2_extend_low_i32x4_s(I64x2ExtendLowI32x4S), visit_i64x2_extend_low_i32x4_u(I64x2ExtendLowI32x4U), visit_i64x2_extend_high_i32x4_s(I64x2ExtendHighI32x4S), visit_i64x2_extend_high_i32x4_u(I64x2ExtendHighI32x4U), + visit_i8x16_popcnt(I8x16Popcnt), visit_i16x8_q15mulr_sat_s(I16x8Q15MulrSatS), visit_i32x4_dot_i16x8_s(I32x4DotI16x8S), + visit_f32x4_ceil(F32x4Ceil), visit_f32x4_floor(F32x4Floor), visit_f32x4_trunc(F32x4Trunc), visit_f32x4_nearest(F32x4Nearest), visit_f32x4_abs(F32x4Abs), visit_f32x4_neg(F32x4Neg), visit_f32x4_sqrt(F32x4Sqrt), visit_f32x4_add(F32x4Add), visit_f32x4_sub(F32x4Sub), visit_f32x4_mul(F32x4Mul), visit_f32x4_div(F32x4Div), visit_f32x4_min(F32x4Min), visit_f32x4_max(F32x4Max), visit_f32x4_pmin(F32x4PMin), visit_f32x4_pmax(F32x4PMax), + visit_f64x2_ceil(F64x2Ceil), visit_f64x2_floor(F64x2Floor), visit_f64x2_trunc(F64x2Trunc), visit_f64x2_nearest(F64x2Nearest), visit_f64x2_abs(F64x2Abs), visit_f64x2_neg(F64x2Neg), visit_f64x2_sqrt(F64x2Sqrt), visit_f64x2_add(F64x2Add), visit_f64x2_sub(F64x2Sub), visit_f64x2_mul(F64x2Mul), visit_f64x2_div(F64x2Div), visit_f64x2_min(F64x2Min), visit_f64x2_max(F64x2Max), visit_f64x2_pmin(F64x2PMin), visit_f64x2_pmax(F64x2PMax), + visit_i32x4_trunc_sat_f32x4_s(I32x4TruncSatF32x4S), visit_i32x4_trunc_sat_f32x4_u(I32x4TruncSatF32x4U), + visit_f32x4_convert_i32x4_s(F32x4ConvertI32x4S), visit_f32x4_convert_i32x4_u(F32x4ConvertI32x4U), + visit_i32x4_trunc_sat_f64x2_s_zero(I32x4TruncSatF64x2SZero), visit_i32x4_trunc_sat_f64x2_u_zero(I32x4TruncSatF64x2UZero), + visit_f64x2_convert_low_i32x4_s(F64x2ConvertLowI32x4S), visit_f64x2_convert_low_i32x4_u(F64x2ConvertLowI32x4U), + visit_f32x4_demote_f64x2_zero(F32x4DemoteF64x2Zero), visit_f64x2_promote_low_f32x4(F64x2PromoteLowF32x4), + + visit_i8x16_extract_lane_s(I8x16ExtractLaneS, u8), visit_i8x16_extract_lane_u(I8x16ExtractLaneU, u8), visit_i8x16_replace_lane(I8x16ReplaceLane, u8), + visit_i16x8_extract_lane_s(I16x8ExtractLaneS, u8), visit_i16x8_extract_lane_u(I16x8ExtractLaneU, u8), visit_i16x8_replace_lane(I16x8ReplaceLane, u8), + visit_i32x4_extract_lane(I32x4ExtractLane, u8), visit_i32x4_replace_lane(I32x4ReplaceLane, u8), + visit_i64x2_extract_lane(I64x2ExtractLane, u8), visit_i64x2_replace_lane(I64x2ReplaceLane, u8), + visit_f32x4_extract_lane(F32x4ExtractLane, u8), visit_f32x4_replace_lane(F32x4ReplaceLane, u8), + visit_f64x2_extract_lane(F64x2ExtractLane, u8), visit_f64x2_replace_lane(F64x2ReplaceLane, u8) + } + + fn visit_i8x16_shuffle(&mut self, lanes: [u8; 16]) -> Self::Output { + self.v128_constants.push(u128::from_le_bytes(lanes)); + self.instructions.push(SimdInstruction::I8x16Shuffle(self.v128_constants.len() as u32 - 1).into()); + } + + fn visit_v128_const(&mut self, value: wasmparser::V128) -> Self::Output { + self.v128_constants.push(value.i128() as u128); + self.instructions.push(SimdInstruction::V128Const(self.v128_constants.len() as u32 - 1).into()); + } +} diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index 401e3de..d111e89 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -35,7 +35,6 @@ logging=["log", "tinywasm-parser?/logging", "tinywasm-types/logging"] std=["tinywasm-parser?/std", "tinywasm-types/std"] parser=["dep:tinywasm-parser"] archive=["tinywasm-types/archive"] -# nightly=[] [[test]] name="test-wasm-1" diff --git a/crates/wasm-testsuite/data b/crates/wasm-testsuite/data index 9b4b015..3d176e3 160000 --- a/crates/wasm-testsuite/data +++ b/crates/wasm-testsuite/data @@ -1 +1 @@ -Subproject commit 9b4b01574c36fb19e594fb68fa25747bab2d84c8 +Subproject commit 3d176e3d5dfe70cb2f95afa2e590119d85e62603 From c098668a2b0a70fe314209ba1c3e23f576e210ee Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Wed, 4 Dec 2024 23:20:29 +0100 Subject: [PATCH 29/54] chore: update wasmparser to use new simd_visitor Signed-off-by: Henry Gressmann --- Cargo.lock | 36 ++++++++++++++++++------------------ crates/parser/src/visit.rs | 27 +++++---------------------- 2 files changed, 23 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 539cb8c..bc521f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -161,18 +161,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.21" +version = "4.5.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" +checksum = "69371e34337c4c984bbe322360c2547210bf632eb2814bbe78a6e87a2935bd2b" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.21" +version = "4.5.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" +checksum = "6e24c1b4099818523236a8ca881d2b45db98dadfb4625cf6608c12069fcbbde1" dependencies = [ "anstyle", "clap_lex", @@ -373,9 +373,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", "hashbrown", @@ -415,9 +415,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.166" +version = "0.2.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ccc108bbc0b1331bd061864e7cd823c0cab660bbe6970e66e2c0614decde36" +checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" [[package]] name = "libm" @@ -736,9 +736,9 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "syn" -version = "2.0.89" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -878,9 +878,9 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.221.0" +version = "0.221.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de35b6c3ef1f53ac7a31b5e69bc00f1542ea337e7e7162dc34c68b537ff82690" +checksum = "c17a3bd88f2155da63a1f2fcb8a56377a24f0b6dfed12733bb5f544e86f690c5" dependencies = [ "leb128", "wasmparser", @@ -895,9 +895,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.221.0" +version = "0.221.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8659e755615170cfe20da468865c989da78c5da16d8652e69a75acda02406a92" +checksum = "9845c470a2e10b61dd42c385839cdd6496363ed63b5c9e420b5488b77bd22083" dependencies = [ "bitflags", "indexmap", @@ -906,9 +906,9 @@ dependencies = [ [[package]] name = "wast" -version = "221.0.0" +version = "221.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d8eb1933d493dd07484a255c3f52236123333f5befaa3be36182a50d393ec54" +checksum = "fcc4470b9de917ba199157d1f0ae104f2ae362be728c43e68c571c7715bd629e" dependencies = [ "bumpalo", "leb128", @@ -919,9 +919,9 @@ dependencies = [ [[package]] name = "wat" -version = "1.221.0" +version = "1.221.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c813fd4e5b2b97242830b56e7b7dc5479bc17aaa8730109be35e61909af83993" +checksum = "6b1f3c6d82af47286494c6caea1d332037f5cbeeac82bbf5ef59cb8c201c466e" dependencies = [ "wast", ] diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs index a94b3a1..098caf9 100644 --- a/crates/parser/src/visit.rs +++ b/crates/parser/src/visit.rs @@ -20,16 +20,6 @@ macro_rules! validate_then_visit { )*}; } -macro_rules! validate_then_visit_simd { - ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {$( - fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output { - self.1.$visit($($($arg.clone()),*)?); - self.1.validator_visitor(self.0).simd_visitor().expect("simd_visitor is supported by the validator").$visit($($($arg),*)?)?; - Ok(()) - } - )*}; -} - impl<'a, R: WasmModuleResources> VisitOperator<'a> for ValidateThenVisit<'_, R> { type Output = Result<()>; wasmparser::for_each_visit_operator!(validate_then_visit); @@ -40,7 +30,7 @@ impl<'a, R: WasmModuleResources> VisitOperator<'a> for ValidateThenVisit<'_, R> } impl VisitSimdOperator<'_> for ValidateThenVisit<'_, R> { - wasmparser::for_each_visit_simd_operator!(validate_then_visit_simd); + wasmparser::for_each_visit_simd_operator!(validate_then_visit); } pub(crate) fn process_operators_and_validate( @@ -137,8 +127,8 @@ impl FunctionBuilder { pub(crate) fn validator_visitor( &mut self, offset: usize, - ) -> impl VisitOperator<'_, Output = Result<(), wasmparser::BinaryReaderError>> { - self.validator.visitor(offset) + ) -> impl VisitOperator<'_, Output = Result<(), wasmparser::BinaryReaderError>> + VisitSimdOperator<'_> { + self.validator.simd_visitor(offset) } pub(crate) fn validator_finish(&mut self, offset: usize) -> Result<(), wasmparser::BinaryReaderError> { @@ -173,8 +163,8 @@ macro_rules! impl_visit_operator { (@@sign_extension $($rest:tt)* ) => {}; (@@saturating_float_to_int $($rest:tt)* ) => {}; (@@bulk_memory $($rest:tt)* ) => {}; - // (@@tail_call $($rest:tt)* ) => {}; (@@simd $($rest:tt)* ) => {}; + (@@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*)) => { #[cold] fn $visit(&mut self $($(,$arg: $argty)*)?) { @@ -212,14 +202,6 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild visit_memory_init(MemoryInit, u32, u32), visit_memory_copy(MemoryCopy, u32, u32), visit_table_init(TableInit, u32, u32), visit_memory_fill(MemoryFill, u32), visit_data_drop(DataDrop, u32), visit_elem_drop(ElemDrop, u32) } - // fn visit_return_call(&mut self, function_index: u32) -> Self::Output { - // self.instructions.push(Instruction::ReturnCall(function_index)); - // } - - // fn visit_return_call_indirect(&mut self, type_index: u32, table_index: u32) -> Self::Output { - // self.instructions.push(Instruction::ReturnCallIndirect(type_index, table_index)); - // } - fn visit_global_set(&mut self, global_index: u32) -> Self::Output { match self.validator.get_operand_type(0) { Some(Some(t)) => self.instructions.push(match t { @@ -247,6 +229,7 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild _ => self.visit_unreachable(), } } + fn visit_select(&mut self) -> Self::Output { match self.validator.get_operand_type(1) { Some(Some(t)) => self.visit_typed_select(t), From de0d556e72bc90f58077f05a6232b1083503f89a Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sat, 7 Dec 2024 00:40:43 +0100 Subject: [PATCH 30/54] chore: move wasm-testsuite to a seperate repo & update tests Signed-off-by: Henry Gressmann --- CHANGELOG.md | 2 +- Cargo.lock | 168 ++++-------------- crates/tinywasm/Cargo.toml | 5 +- crates/tinywasm/tests/generated/wasm-2.csv | 2 +- .../tests/generated/wasm-annotations.csv | 2 +- .../tests/generated/wasm-multi-memory.csv | 2 +- crates/tinywasm/tests/test-wasm-1.rs | 23 +-- crates/tinywasm/tests/test-wasm-2.rs | 19 +- .../tinywasm/tests/test-wasm-annotations.rs | 21 +-- .../tests/test-wasm-custom-page-sizes.rs | 13 -- .../tests/test-wasm-extended-const.rs | 19 +- crates/tinywasm/tests/test-wasm-memory64.rs | 14 +- .../tinywasm/tests/test-wasm-multi-memory.rs | 21 +-- .../tinywasm/tests/test-wasm-relaxed-simd.rs | 13 ++ crates/tinywasm/tests/test-wasm-simd.rs | 20 --- crates/tinywasm/tests/testsuite/indexmap.rs | 31 ---- crates/tinywasm/tests/testsuite/mod.rs | 16 +- crates/tinywasm/tests/testsuite/run.rs | 145 ++++++++------- crates/tinywasm/tests/testsuite/util.rs | 4 +- crates/wasm-testsuite/Cargo.toml | 19 -- crates/wasm-testsuite/README.md | 20 --- crates/wasm-testsuite/data | 1 - crates/wasm-testsuite/lib.rs | 86 --------- .../custom-page-sizes-invalid.wast | 112 ------------ .../custom-page-sizes/custom-page-sizes.wast | 110 ------------ 25 files changed, 176 insertions(+), 712 deletions(-) create mode 100644 crates/tinywasm/tests/test-wasm-relaxed-simd.rs delete mode 100644 crates/tinywasm/tests/test-wasm-simd.rs delete mode 100644 crates/tinywasm/tests/testsuite/indexmap.rs delete mode 100644 crates/wasm-testsuite/Cargo.toml delete mode 100644 crates/wasm-testsuite/README.md delete mode 160000 crates/wasm-testsuite/data delete mode 100644 crates/wasm-testsuite/lib.rs delete mode 100644 crates/wasm-testsuite/tests/proposals/custom-page-sizes/custom-page-sizes-invalid.wast delete mode 100644 crates/wasm-testsuite/tests/proposals/custom-page-sizes/custom-page-sizes.wast diff --git a/CHANGELOG.md b/CHANGELOG.md index b84e6ba..a660685 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - **Breaking:**: New backwards-incompatible version of the twasm format (upgraded `rkyv` to 0.8.0) -- Increased MSRV to 1.81.0 +- Increased MSRV to 1.83.0 ### Fixed diff --git a/Cargo.lock b/Cargo.lock index bc521f0..7e6cacc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -66,25 +66,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bstr" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "bumpalo" version = "3.16.0" @@ -161,18 +142,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.22" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69371e34337c4c984bbe322360c2547210bf632eb2814bbe78a6e87a2935bd2b" +checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.22" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e24c1b4099818523236a8ca881d2b45db98dadfb4625cf6608c12069fcbbde1" +checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" dependencies = [ "anstyle", "clap_lex", @@ -180,18 +161,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" - -[[package]] -name = "cpufeatures" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" -dependencies = [ - "libc", -] +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "criterion" @@ -259,26 +231,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - [[package]] name = "either" version = "1.13.0" @@ -314,29 +266,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "globset" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" -dependencies = [ - "aho-corasick", - "bstr", - "log", - "regex-automata", - "regex-syntax", -] - [[package]] name = "half" version = "2.4.1" @@ -365,6 +294,25 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "include_dir" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd" +dependencies = [ + "include_dir_macros", +] + +[[package]] +name = "include_dir_macros" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75" +dependencies = [ + "proc-macro2", + "quote", +] + [[package]] name = "indenter" version = "0.3.3" @@ -629,41 +577,6 @@ dependencies = [ "syn", ] -[[package]] -name = "rust-embed" -version = "8.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa66af4a4fdd5e7ebc276f115e895611a34739a9c1c01028383d612d550953c0" -dependencies = [ - "rust-embed-impl", - "rust-embed-utils", - "walkdir", -] - -[[package]] -name = "rust-embed-impl" -version = "8.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6125dbc8867951125eec87294137f4e9c2c96566e61bf72c45095a7c77761478" -dependencies = [ - "proc-macro2", - "quote", - "rust-embed-utils", - "syn", - "walkdir", -] - -[[package]] -name = "rust-embed-utils" -version = "8.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e5347777e9aacb56039b0e1f28785929a8a3b709e87482e7442c72e7c12529d" -dependencies = [ - "globset", - "sha2", - "walkdir", -] - [[package]] name = "ryu" version = "1.0.18" @@ -717,17 +630,6 @@ dependencies = [ "serde", ] -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - [[package]] name = "simdutf8" version = "0.1.5" @@ -785,6 +687,7 @@ version = "0.9.0-alpha.0" dependencies = [ "criterion", "eyre", + "indexmap", "libm", "log", "owo-colors", @@ -836,12 +739,6 @@ dependencies = [ "rkyv", ] -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - [[package]] name = "unicode-ident" version = "1.0.14" @@ -860,12 +757,6 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - [[package]] name = "walkdir" version = "2.5.0" @@ -888,9 +779,12 @@ dependencies = [ [[package]] name = "wasm-testsuite" -version = "0.6.0-alpha.0" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dc81f607820a4f651559ad68709106d53bf50c20f01effe90f4da6954d4885d" dependencies = [ - "rust-embed", + "include_dir", + "wast", ] [[package]] diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index d111e89..80f148c 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -20,7 +20,8 @@ tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false libm={version="0.2", default-features=false} [dev-dependencies] -wasm-testsuite={path="../wasm-testsuite"} +wasm-testsuite={version="0.3.2"} +indexmap="2.7" wast={workspace=true} eyre={workspace=true} pretty_env_logger={workspace=true} @@ -67,7 +68,7 @@ harness=false test=false [[test]] -name="test-wasm-simd" +name="test-wasm-relaxed-simd" harness=false test=false diff --git a/crates/tinywasm/tests/generated/wasm-2.csv b/crates/tinywasm/tests/generated/wasm-2.csv index a001172..b0949ec 100644 --- a/crates/tinywasm/tests/generated/wasm-2.csv +++ b/crates/tinywasm/tests/generated/wasm-2.csv @@ -10,4 +10,4 @@ 0.6.1,20278,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.7.0,20278,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.8.0,28008,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":128,"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":117,"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":98,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_copy.wast","passed":4450,"failed":0},{"name":"memory_fill.wast","passed":100,"failed":0},{"name":"memory_grow.wast","passed":104,"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":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":16,"failed":0},{"name":"ref_null.wast","passed":3,"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-sub.wast","passed":2,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"table_copy.wast","passed":1728,"failed":0},{"name":"table_fill.wast","passed":45,"failed":0},{"name":"table_get.wast","passed":16,"failed":0},{"name":"table_grow.wast","passed":58,"failed":0},{"name":"table_init.wast","passed":780,"failed":0},{"name":"table_set.wast","passed":26,"failed":0},{"name":"table_size.wast","passed":39,"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.9.0-alpha.0,28010,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":128,"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":117,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":172,"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":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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_copy.wast","passed":4450,"failed":0},{"name":"memory_fill.wast","passed":100,"failed":0},{"name":"memory_grow.wast","passed":104,"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":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":16,"failed":0},{"name":"ref_null.wast","passed":3,"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-sub.wast","passed":2,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"table_copy.wast","passed":1728,"failed":0},{"name":"table_fill.wast","passed":45,"failed":0},{"name":"table_get.wast","passed":16,"failed":0},{"name":"table_grow.wast","passed":58,"failed":0},{"name":"table_init.wast","passed":780,"failed":0},{"name":"table_set.wast","passed":26,"failed":0},{"name":"table_size.wast","passed":39,"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.9.0-alpha.0,27826,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":81,"failed":0},{"name":"binary.wast","passed":162,"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":117,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":169,"failed":0},{"name":"comments.wast","passed":4,"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":58,"failed":0},{"name":"elem.wast","passed":74,"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":161,"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":108,"failed":0},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":239,"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":17,"failed":0},{"name":"ref_is_null.wast","passed":16,"failed":0},{"name":"ref_null.wast","passed":3,"failed":0},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":147,"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":1728,"failed":0},{"name":"table_fill.wast","passed":45,"failed":0},{"name":"table_get.wast","passed":16,"failed":0},{"name":"table_grow.wast","passed":50,"failed":0},{"name":"table_init.wast","passed":780,"failed":0},{"name":"table_set.wast","passed":26,"failed":0},{"name":"table_size.wast","passed":39,"failed":0},{"name":"token.wast","passed":2,"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":6,"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/wasm-annotations.csv b/crates/tinywasm/tests/generated/wasm-annotations.csv index a1c7fb6..1b99033 100644 --- a/crates/tinywasm/tests/generated/wasm-annotations.csv +++ b/crates/tinywasm/tests/generated/wasm-annotations.csv @@ -1,2 +1,2 @@ 0.8.0,142,0,[{"name":"annotations.wast","passed":74,"failed":0},{"name":"annotations/simd_lane.wast (skipped)","passed":0,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"token.wast","passed":61,"failed":0}] -0.9.0-alpha.0,142,0,[{"name":"annotations.wast","passed":74,"failed":0},{"name":"annotations/simd_lane.wast (skipped)","passed":0,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"token.wast","passed":61,"failed":0}] +0.9.0-alpha.0,142,0,[{"name":"annotations.wast","passed":74,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"simd_lane.wast (skipped)","passed":0,"failed":0},{"name":"token.wast","passed":61,"failed":0}] diff --git a/crates/tinywasm/tests/generated/wasm-multi-memory.csv b/crates/tinywasm/tests/generated/wasm-multi-memory.csv index 0f70c8e..ae9ba03 100644 --- a/crates/tinywasm/tests/generated/wasm-multi-memory.csv +++ b/crates/tinywasm/tests/generated/wasm-multi-memory.csv @@ -1,2 +1,2 @@ 0.8.0,1872,0,[{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"align.wast","passed":160,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"binary.wast","passed":126,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"imports.wast","passed":175,"failed":0},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"multi-memory/simd_memory-multi.wast (skipped)","passed":0,"failed":0},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"traps0.wast","passed":15,"failed":0}] -0.9.0-alpha.0,1872,0,[{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"align.wast","passed":160,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"binary.wast","passed":126,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"imports.wast","passed":175,"failed":0},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"multi-memory/simd_memory-multi.wast (skipped)","passed":0,"failed":0},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"traps0.wast","passed":15,"failed":0}] +0.9.0-alpha.0,1872,0,[{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"align.wast","passed":160,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"binary.wast","passed":126,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"imports.wast","passed":175,"failed":0},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"simd_memory-multi.wast (skipped)","passed":0,"failed":0},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"traps0.wast","passed":15,"failed":0}] diff --git a/crates/tinywasm/tests/test-wasm-1.rs b/crates/tinywasm/tests/test-wasm-1.rs index 77694c5..e6a9dd9 100644 --- a/crates/tinywasm/tests/test-wasm-1.rs +++ b/crates/tinywasm/tests/test-wasm-1.rs @@ -1,20 +1,13 @@ mod testsuite; -use eyre::{eyre, Result}; -use owo_colors::OwoColorize; -use testsuite::TestSuite; +use eyre::Result; fn main() -> Result<()> { - let mut test_suite = TestSuite::new(); + println!("Skipping 1.0 tests (False positives due to relaxed validation in later versions)"); + Ok(()) + // TestSuite::set_log_level(log::LevelFilter::Off); - TestSuite::set_log_level(log::LevelFilter::Off); - test_suite.run_spec_group(wasm_testsuite::MVP_TESTS)?; - test_suite.save_csv("./tests/generated/wasm-1.csv", env!("CARGO_PKG_VERSION"))?; - - if test_suite.failed() { - println!(); - Err(eyre!(format!("{}:\n{:#?}", "failed one or more tests".red().bold(), test_suite,))) - } else { - println!("\n\npassed all tests:\n{test_suite:#?}"); - Ok(()) - } + // let mut test_suite = TestSuite::new(); + // test_suite.run_files(spec(&SpecVersion::V1))?; + // test_suite.save_csv("./tests/generated/wasm-1.csv", env!("CARGO_PKG_VERSION"))?; + // test_suite.report_status() } diff --git a/crates/tinywasm/tests/test-wasm-2.rs b/crates/tinywasm/tests/test-wasm-2.rs index 336632f..9b30ac0 100644 --- a/crates/tinywasm/tests/test-wasm-2.rs +++ b/crates/tinywasm/tests/test-wasm-2.rs @@ -1,20 +1,13 @@ mod testsuite; -use eyre::{eyre, Result}; -use owo_colors::OwoColorize; +use eyre::Result; use testsuite::TestSuite; +use wasm_testsuite::data::{spec, SpecVersion}; fn main() -> Result<()> { - let mut test_suite = TestSuite::new(); - TestSuite::set_log_level(log::LevelFilter::Off); - test_suite.run_spec_group(wasm_testsuite::V2_TESTS)?; - test_suite.save_csv("./tests/generated/wasm-2.csv", env!("CARGO_PKG_VERSION"))?; - if test_suite.failed() { - println!(); - Err(eyre!(format!("{}:\n{:#?}", "failed one or more tests".red().bold(), test_suite,))) - } else { - println!("\n\npassed all tests:\n{test_suite:#?}"); - Ok(()) - } + let mut test_suite = TestSuite::new(); + test_suite.run_files(spec(&SpecVersion::V2))?; + test_suite.save_csv("./tests/generated/wasm-2.csv", env!("CARGO_PKG_VERSION"))?; + test_suite.report_status() } diff --git a/crates/tinywasm/tests/test-wasm-annotations.rs b/crates/tinywasm/tests/test-wasm-annotations.rs index c521156..3170241 100644 --- a/crates/tinywasm/tests/test-wasm-annotations.rs +++ b/crates/tinywasm/tests/test-wasm-annotations.rs @@ -1,21 +1,14 @@ mod testsuite; -use eyre::{eyre, Result}; -use owo_colors::OwoColorize; +use eyre::Result; use testsuite::TestSuite; +use wasm_testsuite::data::{proposal, Proposal}; fn main() -> Result<()> { - let mut test_suite = TestSuite::new(); - TestSuite::set_log_level(log::LevelFilter::Off); - test_suite.skip("annotations/simd_lane.wast"); - test_suite.run_spec_group(wasm_testsuite::get_proposal_tests("annotations"))?; - test_suite.save_csv("./tests/generated/wasm-annotations.csv", env!("CARGO_PKG_VERSION"))?; - if test_suite.failed() { - println!(); - Err(eyre!(format!("{}:\n{:#?}", "failed one or more tests".red().bold(), test_suite,))) - } else { - println!("\n\npassed all tests:\n{test_suite:#?}"); - Ok(()) - } + let mut test_suite = TestSuite::new(); + test_suite.skip("simd_lane.wast"); + test_suite.run_files(proposal(&Proposal::Annotations))?; + test_suite.save_csv("./tests/generated/wasm-annotations.csv", env!("CARGO_PKG_VERSION"))?; + test_suite.report_status() } diff --git a/crates/tinywasm/tests/test-wasm-custom-page-sizes.rs b/crates/tinywasm/tests/test-wasm-custom-page-sizes.rs index ee9c732..d49d89a 100644 --- a/crates/tinywasm/tests/test-wasm-custom-page-sizes.rs +++ b/crates/tinywasm/tests/test-wasm-custom-page-sizes.rs @@ -4,17 +4,4 @@ use eyre::Result; fn main() -> Result<()> { println!("Skipping Wasm Custom Page Sizes tests (Wast doesn't support the syntax yet)"); Ok(()) - - // let mut test_suite = TestSuite::new(); - // TestSuite::set_log_level(log::LevelFilter::Off); - // test_suite.run_spec_group(wasm_testsuite::get_proposal_tests("custom-page-sizes"))?; - // test_suite.save_csv("./tests/generated/wasm-custom-page-sizes.csv", env!("CARGO_PKG_VERSION"))?; - - // if test_suite.failed() { - // println!(); - // Err(eyre!(format!("{}:\n{:#?}", "failed one or more tests".red().bold(), test_suite,))) - // } else { - // println!("\n\npassed all tests:\n{test_suite:#?}"); - // Ok(()) - // } } diff --git a/crates/tinywasm/tests/test-wasm-extended-const.rs b/crates/tinywasm/tests/test-wasm-extended-const.rs index f544b35..7c9a304 100644 --- a/crates/tinywasm/tests/test-wasm-extended-const.rs +++ b/crates/tinywasm/tests/test-wasm-extended-const.rs @@ -1,20 +1,13 @@ mod testsuite; -use eyre::{eyre, Result}; -use owo_colors::OwoColorize; +use eyre::Result; use testsuite::TestSuite; +use wasm_testsuite::data::{proposal, Proposal}; fn main() -> Result<()> { - let mut test_suite = TestSuite::new(); - TestSuite::set_log_level(log::LevelFilter::Off); - test_suite.run_spec_group(wasm_testsuite::get_proposal_tests("extended-const"))?; - test_suite.save_csv("./tests/generated/wasm-extended-const.csv", env!("CARGO_PKG_VERSION"))?; - if test_suite.failed() { - println!(); - Err(eyre!(format!("{}:\n{:#?}", "failed one or more tests".red().bold(), test_suite,))) - } else { - println!("\n\npassed all tests:\n{test_suite:#?}"); - Ok(()) - } + let mut test_suite = TestSuite::new(); + test_suite.run_files(proposal(&Proposal::ExtendedConst))?; + test_suite.save_csv("./tests/generated/wasm-extended-const.csv", env!("CARGO_PKG_VERSION"))?; + test_suite.report_status() } diff --git a/crates/tinywasm/tests/test-wasm-memory64.rs b/crates/tinywasm/tests/test-wasm-memory64.rs index 0dfe2b8..391a1ef 100644 --- a/crates/tinywasm/tests/test-wasm-memory64.rs +++ b/crates/tinywasm/tests/test-wasm-memory64.rs @@ -4,6 +4,8 @@ use owo_colors::OwoColorize; use testsuite::TestSuite; fn main() -> Result<()> { + TestSuite::set_log_level(log::LevelFilter::Off); + let mut test_suite = TestSuite::new(); test_suite.skip("memory64/array.wast"); test_suite.skip("memory64/extern.wast"); @@ -16,15 +18,7 @@ fn main() -> Result<()> { test_suite.skip("memory64/struct.wast"); test_suite.skip("memory64/table.wast"); - TestSuite::set_log_level(log::LevelFilter::Off); - test_suite.run_spec_group(wasm_testsuite::get_proposal_tests("memory64"))?; + test_suite.run_files(proposal(&Proposal::Memory64))?; test_suite.save_csv("./tests/generated/wasm-memory64.csv", env!("CARGO_PKG_VERSION"))?; - - if test_suite.failed() { - println!(); - Err(eyre!(format!("{}:\n{:#?}", "failed one or more tests".red().bold(), test_suite,))) - } else { - println!("\n\npassed all tests:\n{test_suite:#?}"); - Ok(()) - } + test_suite.report_status() } diff --git a/crates/tinywasm/tests/test-wasm-multi-memory.rs b/crates/tinywasm/tests/test-wasm-multi-memory.rs index 9b1f8b7..d491fb1 100644 --- a/crates/tinywasm/tests/test-wasm-multi-memory.rs +++ b/crates/tinywasm/tests/test-wasm-multi-memory.rs @@ -1,21 +1,14 @@ mod testsuite; -use eyre::{eyre, Result}; -use owo_colors::OwoColorize; +use eyre::Result; use testsuite::TestSuite; +use wasm_testsuite::data::{proposal, Proposal}; fn main() -> Result<()> { - let mut test_suite = TestSuite::new(); - TestSuite::set_log_level(log::LevelFilter::Off); - test_suite.skip("multi-memory/simd_memory-multi.wast"); - test_suite.run_spec_group(wasm_testsuite::get_proposal_tests("multi-memory"))?; - test_suite.save_csv("./tests/generated/wasm-multi-memory.csv", env!("CARGO_PKG_VERSION"))?; - if test_suite.failed() { - println!(); - Err(eyre!(format!("{}:\n{:#?}", "failed one or more tests".red().bold(), test_suite,))) - } else { - println!("\n\npassed all tests:\n{test_suite:#?}"); - Ok(()) - } + let mut test_suite = TestSuite::new(); + test_suite.skip("simd_memory-multi.wast"); + test_suite.run_files(proposal(&Proposal::MultiMemory))?; + test_suite.save_csv("./tests/generated/wasm-multi-memory.csv", env!("CARGO_PKG_VERSION"))?; + test_suite.report_status() } diff --git a/crates/tinywasm/tests/test-wasm-relaxed-simd.rs b/crates/tinywasm/tests/test-wasm-relaxed-simd.rs new file mode 100644 index 0000000..7af830a --- /dev/null +++ b/crates/tinywasm/tests/test-wasm-relaxed-simd.rs @@ -0,0 +1,13 @@ +mod testsuite; +use eyre::Result; +use testsuite::TestSuite; +use wasm_testsuite::data::{proposal, Proposal}; + +fn main() -> Result<()> { + TestSuite::set_log_level(log::LevelFilter::Off); + + let mut test_suite = TestSuite::new(); + test_suite.run_files(proposal(&Proposal::RelaxedSimd))?; + test_suite.save_csv("./tests/generated/wasm-relaxed-simd.csv", env!("CARGO_PKG_VERSION"))?; + test_suite.report_status() +} diff --git a/crates/tinywasm/tests/test-wasm-simd.rs b/crates/tinywasm/tests/test-wasm-simd.rs deleted file mode 100644 index 289bf2b..0000000 --- a/crates/tinywasm/tests/test-wasm-simd.rs +++ /dev/null @@ -1,20 +0,0 @@ -mod testsuite; -use eyre::{eyre, Result}; -use owo_colors::OwoColorize; -use testsuite::TestSuite; - -fn main() -> Result<()> { - let mut test_suite = TestSuite::new(); - - TestSuite::set_log_level(log::LevelFilter::Off); - test_suite.run_spec_group(wasm_testsuite::SIMD_TESTS)?; - test_suite.save_csv("./tests/generated/wasm-simd.csv", env!("CARGO_PKG_VERSION"))?; - - if test_suite.failed() { - println!(); - Err(eyre!(format!("{}:\n{:#?}", "failed one or more tests".red().bold(), test_suite,))) - } else { - println!("\n\npassed all tests:\n{test_suite:#?}"); - Ok(()) - } -} diff --git a/crates/tinywasm/tests/testsuite/indexmap.rs b/crates/tinywasm/tests/testsuite/indexmap.rs deleted file mode 100644 index 0c75e4c..0000000 --- a/crates/tinywasm/tests/testsuite/indexmap.rs +++ /dev/null @@ -1,31 +0,0 @@ -/// A naive implementation of an index map for use in the test suite -pub struct IndexMap { - map: std::collections::HashMap, - keys: Vec, -} - -impl IndexMap -where - K: std::cmp::Eq + std::hash::Hash + Clone, -{ - pub fn new() -> Self { - Self { map: std::collections::HashMap::new(), keys: Vec::new() } - } - - pub fn insert(&mut self, key: K, value: V) -> Option { - if let std::collections::hash_map::Entry::Occupied(mut e) = self.map.entry(key.clone()) { - return Some(e.insert(value)); - } - - self.keys.push(key.clone()); - self.map.insert(key, value) - } - - pub fn iter(&self) -> impl Iterator { - self.keys.iter().map(move |k| (k, self.map.get(k).unwrap())) - } - - pub fn values(&self) -> impl Iterator { - self.map.values() - } -} diff --git a/crates/tinywasm/tests/testsuite/mod.rs b/crates/tinywasm/tests/testsuite/mod.rs index 3c23e00..ee0336e 100644 --- a/crates/tinywasm/tests/testsuite/mod.rs +++ b/crates/tinywasm/tests/testsuite/mod.rs @@ -1,5 +1,6 @@ #![allow(unused)] -use eyre::Result; +use eyre::{eyre, Result}; +use indexmap::IndexMap; use owo_colors::OwoColorize; use std::io::{BufRead, Seek, SeekFrom}; use std::{ @@ -8,14 +9,11 @@ use std::{ io::BufReader, }; -mod indexmap; mod run; mod util; use serde::{Deserialize, Serialize}; -use self::indexmap::IndexMap; - #[derive(Serialize, Deserialize)] pub struct TestGroupResult { pub name: String, @@ -30,6 +28,16 @@ impl TestSuite { pretty_env_logger::formatted_builder().filter_level(level).init(); } + pub fn report_status(&self) -> Result<()> { + if self.failed() { + println!(); + Err(eyre!(format!("{}:\n{:#?}", "failed one or more tests".red().bold(), self))) + } else { + println!("\n\npassed all tests:\n{self:#?}"); + Ok(()) + } + } + pub fn print_errors(&self) { for (group_name, group) in &self.0 { let tests = &group.tests; diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index 26d2e6d..6324a5b 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -3,20 +3,22 @@ use std::{borrow::Cow, collections::HashMap}; use super::TestSuite; use eyre::{eyre, Result}; +use indexmap::IndexMap; use log::{debug, error, info}; use tinywasm::{Extern, Imports, ModuleInstance}; use tinywasm_types::{ExternVal, MemoryType, ModuleInstanceAddr, TableType, ValType, WasmValue}; +use wasm_testsuite::data::TestFile; use wast::{lexer::Lexer, parser::ParseBuffer, Wast}; #[derive(Default)] -struct RegisteredModules { +struct ModuleRegistry { modules: HashMap, named_modules: HashMap, last_module: Option, } -impl RegisteredModules { +impl ModuleRegistry { fn modules(&self) -> &HashMap { &self.modules } @@ -70,10 +72,15 @@ impl RegisteredModules { impl TestSuite { pub fn run_paths(&mut self, tests: &[&str]) -> Result<()> { - for group in tests { - let group_wast = std::fs::read(group).expect("failed to read test wast"); - let group_wast = Cow::Owned(group_wast); - self.run_group(group, group_wast).expect("failed to run group"); + for file_name in tests { + let group_wast = std::fs::read(file_name).expect("failed to read test wast"); + let file = TestFile { + contents: std::str::from_utf8(&group_wast).expect("failed to convert to utf8"), + name: file_name.to_string(), + parent: "(custom group)".into(), + }; + + self.run_file(file).expect("failed to run group"); } Ok(()) @@ -147,40 +154,33 @@ impl TestSuite { Ok(imports) } - pub fn run_spec_group>(&mut self, tests: impl IntoIterator) -> Result<()> { + pub fn run_files<'a>(&mut self, tests: impl IntoIterator>) -> Result<()> { tests.into_iter().for_each(|group| { - println!("running group: {}", group.as_ref()); - let group = group.as_ref(); - let group_wast = wasm_testsuite::get_test_wast(group).expect("failed to get test wast"); - if self.1.contains(&(*group).to_string()) { - info!("skipping group: {}", group); - self.test_group(&format!("{group} (skipped)"), group); + let name = group.name(); + println!("running group: {}", name); + if self.1.contains(&name.to_string()) { + info!("skipping group: {name}"); + self.test_group(&format!("{name} (skipped)"), name); return; } - self.run_group(group, group_wast).expect("failed to run group"); + self.run_file(group).expect("failed to run group"); }); Ok(()) } - pub fn run_group(&mut self, group_name: &str, group_wast: Cow<'_, [u8]>) -> Result<()> { - let file_name = group_name.split('/').last().unwrap_or(group_name); - let test_group = self.test_group(file_name, group_name); - let wast = std::str::from_utf8(&group_wast).expect("failed to convert wast to utf8"); - - let mut lexer = Lexer::new(wast); - // we need to allow confusing unicode characters since they are technically valid wasm - lexer.allow_confusing_unicode(true); - - let buf = ParseBuffer::new_with_lexer(lexer).expect("failed to create parse buffer"); - let wast_data = wast::parser::parse::(&buf).expect("failed to parse wat"); + pub fn run_file<'a>(&mut self, file: TestFile<'a>) -> Result<()> { + let test_group = self.test_group(file.name(), file.parent()); + let wast_raw = file.raw(); + let wast = file.wast()?; + let directives = wast.directives()?; let mut store = tinywasm::Store::default(); - let mut registered_modules = RegisteredModules::default(); + let mut module_registry = ModuleRegistry::default(); - println!("running {} tests for group: {}", wast_data.directives.len(), group_name); - for (i, directive) in wast_data.directives.into_iter().enumerate() { + println!("running {} tests for group: {}", directives.len(), file.name()); + for (i, directive) in directives.into_iter().enumerate() { let span = directive.span(); use wast::WastDirective::{ AssertExhaustion, AssertInvalid, AssertMalformed, AssertReturn, AssertTrap, AssertUnlinkable, Invoke, @@ -189,16 +189,16 @@ impl TestSuite { match directive { Register { span, name, .. } => { - let Some(last) = registered_modules.last(&store) else { + let Some(last) = module_registry.last(&store) else { test_group.add_result( &format!("Register({i})"), - span.linecol_in(wast), + span.linecol_in(wast_raw), Err(eyre!("no module to register")), ); continue; }; - registered_modules.register(name.to_string(), last.id()); - test_group.add_result(&format!("Register({i})"), span.linecol_in(wast), Ok(())); + module_registry.register(name.to_string(), last.id()); + test_group.add_result(&format!("Register({i})"), span.linecol_in(wast_raw), Ok(())); } Wat(module) => { @@ -208,7 +208,7 @@ impl TestSuite { let m = parse_module_bytes(&bytes).expect("failed to parse module bytes"); let module_instance = tinywasm::Module::from(m) - .instantiate(&mut store, Some(Self::imports(registered_modules.modules()).unwrap())) + .instantiate(&mut store, Some(Self::imports(module_registry.modules()).unwrap())) .expect("failed to instantiate module"); (name, module_instance) @@ -217,15 +217,15 @@ impl TestSuite { match &result { Err(err) => debug!("failed to parse module: {:?}", err), - Ok((name, module)) => registered_modules.update_last_module(module.id(), name.clone()), + Ok((name, module)) => module_registry.update_last_module(module.id(), name.clone()), }; - test_group.add_result(&format!("Wat({i})"), span.linecol_in(wast), result.map(|_| ())); + test_group.add_result(&format!("Wat({i})"), span.linecol_in(wast_raw), result.map(|_| ())); } AssertMalformed { span, mut module, message } => { let Ok(module) = module.encode() else { - test_group.add_result(&format!("AssertMalformed({i})"), span.linecol_in(wast), Ok(())); + test_group.add_result(&format!("AssertMalformed({i})"), span.linecol_in(wast_raw), Ok(())); continue; }; @@ -235,12 +235,13 @@ impl TestSuite { test_group.add_result( &format!("AssertMalformed({i})"), - span.linecol_in(wast), + span.linecol_in(wast_raw), match res { Ok(_) => { - // // skip "zero byte expected" as the magic number is not checked by wasmparser - // (Don't need to error on this, doesn't matter if it's malformed) - if message == "zero byte expected" { + // - skip "zero byte expected" as the magic number is not checked by wasmparser + // (Don't need to error on this, doesn't matter if it's malformed) + // - skip "integer representation too long" as this has some false positives + if message == "zero byte expected" || message == "integer representation too long" { continue; } @@ -253,7 +254,7 @@ impl TestSuite { AssertInvalid { span, mut module, message } => { if ["multiple memories"].contains(&message) { - test_group.add_result(&format!("AssertInvalid({i})"), span.linecol_in(wast), Ok(())); + test_group.add_result(&format!("AssertInvalid({i})"), span.linecol_in(wast_raw), Ok(())); continue; } @@ -263,7 +264,7 @@ impl TestSuite { test_group.add_result( &format!("AssertInvalid({i})"), - span.linecol_in(wast), + span.linecol_in(wast_raw), match res { Ok(_) => Err(eyre!("expected module to be invalid")), Err(_) => Ok(()), @@ -272,7 +273,7 @@ impl TestSuite { } AssertExhaustion { call, message, span } => { - let module = registered_modules.get_idx(call.module); + let module = module_registry.get_idx(call.module); let args = convert_wastargs(call.args).expect("failed to convert args"); let res = catch_unwind_silent(|| exec_fn_instance(module, &mut store, call.name, &args).map(|_| ())); @@ -280,7 +281,7 @@ impl TestSuite { let Ok(Err(tinywasm::Error::Trap(trap))) = res else { test_group.add_result( &format!("AssertExhaustion({i})"), - span.linecol_in(wast), + span.linecol_in(wast_raw), Err(eyre!("expected trap")), ); continue; @@ -289,13 +290,13 @@ impl TestSuite { if !message.starts_with(trap.message()) { test_group.add_result( &format!("AssertExhaustion({i})"), - span.linecol_in(wast), + span.linecol_in(wast_raw), Err(eyre!("expected trap: {}, got: {}", message, trap.message())), ); continue; } - test_group.add_result(&format!("AssertExhaustion({i})"), span.linecol_in(wast), Ok(())); + test_group.add_result(&format!("AssertExhaustion({i})"), span.linecol_in(wast_raw), Ok(())); } AssertTrap { exec, message, span } => { @@ -305,10 +306,8 @@ impl TestSuite { let module = parse_module_bytes(&wat.encode().expect("failed to encode module")) .expect("failed to parse module"); let module = tinywasm::Module::from(module); - module.instantiate( - &mut store, - Some(Self::imports(registered_modules.modules()).unwrap()), - )?; + module + .instantiate(&mut store, Some(Self::imports(module_registry.modules()).unwrap()))?; return Ok(()); } wast::WastExecute::Get { module: _, global: _, .. } => { @@ -317,7 +316,7 @@ impl TestSuite { wast::WastExecute::Invoke(invoke) => invoke, }; - let module = registered_modules.get_idx(invoke.module); + let module = module_registry.get_idx(invoke.module); let args = convert_wastargs(invoke.args).expect("failed to convert args"); exec_fn_instance(module, &mut store, invoke.name, &args).map(|_| ()) }); @@ -325,29 +324,29 @@ impl TestSuite { match res { Err(err) => test_group.add_result( &format!("AssertTrap({i})"), - span.linecol_in(wast), + span.linecol_in(wast_raw), Err(eyre!("test panicked: {:?}", try_downcast_panic(err))), ), Ok(Err(tinywasm::Error::Trap(trap))) => { if !message.starts_with(trap.message()) { test_group.add_result( &format!("AssertTrap({i})"), - span.linecol_in(wast), + span.linecol_in(wast_raw), Err(eyre!("expected trap: {}, got: {}", message, trap.message())), ); continue; } - test_group.add_result(&format!("AssertTrap({i})"), span.linecol_in(wast), Ok(())); + test_group.add_result(&format!("AssertTrap({i})"), span.linecol_in(wast_raw), Ok(())); } Ok(Err(err)) => test_group.add_result( &format!("AssertTrap({i})"), - span.linecol_in(wast), + span.linecol_in(wast_raw), Err(eyre!("expected trap, {}, got: {:?}", message, err)), ), Ok(Ok(())) => test_group.add_result( &format!("AssertTrap({i})"), - span.linecol_in(wast), + span.linecol_in(wast_raw), Err(eyre!("expected trap {}, got Ok", message)), ), } @@ -358,13 +357,13 @@ impl TestSuite { let module = parse_module_bytes(&module.encode().expect("failed to encode module")) .expect("failed to parse module"); let module = tinywasm::Module::from(module); - module.instantiate(&mut store, Some(Self::imports(registered_modules.modules()).unwrap())) + module.instantiate(&mut store, Some(Self::imports(module_registry.modules()).unwrap())) }); match res { Err(err) => test_group.add_result( &format!("AssertUnlinkable({i})"), - span.linecol_in(wast), + span.linecol_in(wast_raw), Err(eyre!("test panicked: {:?}", try_downcast_panic(err))), ), Ok(Err(tinywasm::Error::Linker(err))) => { @@ -374,22 +373,22 @@ impl TestSuite { { test_group.add_result( &format!("AssertUnlinkable({i})"), - span.linecol_in(wast), + span.linecol_in(wast_raw), Err(eyre!("expected linker error: {}, got: {}", message, err.message())), ); continue; } - test_group.add_result(&format!("AssertUnlinkable({i})"), span.linecol_in(wast), Ok(())); + test_group.add_result(&format!("AssertUnlinkable({i})"), span.linecol_in(wast_raw), Ok(())); } Ok(Err(err)) => test_group.add_result( &format!("AssertUnlinkable({i})"), - span.linecol_in(wast), + span.linecol_in(wast_raw), Err(eyre!("expected linker error, {}, got: {:?}", message, err)), ), Ok(Ok(_)) => test_group.add_result( &format!("AssertUnlinkable({i})"), - span.linecol_in(wast), + span.linecol_in(wast_raw), Err(eyre!("expected linker error {}, got Ok", message)), ), } @@ -400,7 +399,7 @@ impl TestSuite { let res: Result, _> = catch_unwind_silent(|| { let args = convert_wastargs(invoke.args)?; - let module = registered_modules.get_idx(invoke.module); + let module = module_registry.get_idx(invoke.module); exec_fn_instance(module, &mut store, invoke.name, &args).map_err(|e| { error!("failed to execute function: {:?}", e); e @@ -409,7 +408,7 @@ impl TestSuite { }); let res = res.map_err(|e| eyre!("test panicked: {:?}", try_downcast_panic(e))).and_then(|r| r); - test_group.add_result(&format!("Invoke({name}-{i})"), span.linecol_in(wast), res); + test_group.add_result(&format!("Invoke({name}-{i})"), span.linecol_in(wast_raw), res); } AssertReturn { span, exec, results } => { @@ -419,11 +418,11 @@ impl TestSuite { let invoke = match match exec { wast::WastExecute::Wat(_) => Err(eyre!("wat not supported")), wast::WastExecute::Get { module: module_id, global, .. } => { - let module = registered_modules.get(module_id, &store); + let module = module_registry.get(module_id, &store); let Some(module) = module else { test_group.add_result( &format!("AssertReturn(unsupported-{i})"), - span.linecol_in(wast), + span.linecol_in(wast_raw), Err(eyre!("no module to get global from")), ); continue; @@ -437,7 +436,7 @@ impl TestSuite { Err(err) => { test_group.add_result( &format!("AssertReturn(unsupported-{i})"), - span.linecol_in(wast), + span.linecol_in(wast_raw), Err(eyre!("failed to get global: {:?}", err)), ); continue; @@ -449,7 +448,7 @@ impl TestSuite { if !module_global.eq_loose(expected) { test_group.add_result( &format!("AssertReturn(unsupported-{i})"), - span.linecol_in(wast), + span.linecol_in(wast_raw), Err(eyre!("global value did not match: {:?} != {:?}", module_global, expected)), ); continue; @@ -457,7 +456,7 @@ impl TestSuite { test_group.add_result( &format!("AssertReturn({global}-{i})"), - span.linecol_in(wast), + span.linecol_in(wast_raw), Ok(()), ); @@ -470,7 +469,7 @@ impl TestSuite { Err(err) => { test_group.add_result( &format!("AssertReturn(unsupported-{i})"), - span.linecol_in(wast), + span.linecol_in(wast_raw), Err(eyre!("unsupported directive: {:?}", err)), ); continue; @@ -481,7 +480,7 @@ impl TestSuite { let res: Result, _> = catch_unwind_silent(|| { debug!("invoke: {:?}", invoke); let args = convert_wastargs(invoke.args)?; - let module = registered_modules.get_idx(invoke.module); + let module = module_registry.get_idx(invoke.module); let outcomes = exec_fn_instance(module, &mut store, invoke.name, &args).map_err(|e| { error!("failed to execute function: {:?}", e); e @@ -504,11 +503,11 @@ impl TestSuite { }); let res = res.map_err(|e| eyre!("test panicked: {:?}", try_downcast_panic(e))).and_then(|r| r); - test_group.add_result(&format!("AssertReturn({invoke_name}-{i})"), span.linecol_in(wast), res); + test_group.add_result(&format!("AssertReturn({invoke_name}-{i})"), span.linecol_in(wast_raw), res); } _ => test_group.add_result( &format!("Unknown({i})"), - span.linecol_in(wast), + span.linecol_in(wast_raw), Err(eyre!("unsupported directive")), ), } diff --git a/crates/tinywasm/tests/testsuite/util.rs b/crates/tinywasm/tests/testsuite/util.rs index a66a4da..3229455 100644 --- a/crates/tinywasm/tests/testsuite/util.rs +++ b/crates/tinywasm/tests/testsuite/util.rs @@ -8,7 +8,6 @@ pub fn try_downcast_panic(panic: Box) -> String { let info = panic.downcast_ref::().or(None).map(ToString::to_string).clone(); let info_string = panic.downcast_ref::().cloned(); let info_str = panic.downcast::<&str>().ok().map(|s| *s); - info.unwrap_or(info_str.unwrap_or(&info_string.unwrap_or("unknown panic".to_owned())).to_string()) } @@ -171,6 +170,7 @@ enum Bits { U32(u32), U64(u64), } + trait FloatToken { fn bits(&self) -> Bits; fn canonical_nan() -> WasmValue; @@ -182,6 +182,7 @@ trait FloatToken { } } } + impl FloatToken for wast::token::F32 { fn bits(&self) -> Bits { Bits::U32(self.bits) @@ -195,6 +196,7 @@ impl FloatToken for wast::token::F32 { WasmValue::F32(f32::NAN) } } + impl FloatToken for wast::token::F64 { fn bits(&self) -> Bits { Bits::U64(self.bits) diff --git a/crates/wasm-testsuite/Cargo.toml b/crates/wasm-testsuite/Cargo.toml deleted file mode 100644 index 46df77f..0000000 --- a/crates/wasm-testsuite/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name="wasm-testsuite" -version="0.6.0-alpha.0" -description="Mirror of the WebAssembly core testsuite for use in testing WebAssembly implementations" -license="Apache-2.0" -readme="README.md" -edition.workspace=true -authors.workspace=true -repository.workspace=true -rust-version.workspace=true - -[lib] -path="lib.rs" - -[package.metadata.workspaces] -independent=true - -[dependencies] -rust-embed={version="8.4", features=["include-exclude"]} diff --git a/crates/wasm-testsuite/README.md b/crates/wasm-testsuite/README.md deleted file mode 100644 index 51d574c..0000000 --- a/crates/wasm-testsuite/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# `wasm-testsuite` - -This crate embeds the latest version of the [WebAssembly Test Suite](https://github.com/WebAssembly/spec/tree/main/test). It is currently mainly used for testing the `tinywasm-parser` crate. Check out the [documentation](https://docs.rs/wasm-testsuite) for more information. - -## Usage - -```rust -use wasm_testsuite::{MVP_TESTS, get_test_wast}; - -MVP_TESTS.iter().for_each(|test| { - let wast_bytes = get_test_wast(test).expect("Failed to get wast bytes"); - let wast = std::str::from_utf8(&wast_bytes).expect("failed to convert wast to utf8"); - - // Do something with the wast (e.g. parse it using the `wast` crate) -}); -``` - -## License - -This crate is licensed under the [Apache License, Version 2.0](https://github.com/WebAssembly/spec/blob/main/test/LICENSE). \ No newline at end of file diff --git a/crates/wasm-testsuite/data b/crates/wasm-testsuite/data deleted file mode 160000 index 3d176e3..0000000 --- a/crates/wasm-testsuite/data +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 3d176e3d5dfe70cb2f95afa2e590119d85e62603 diff --git a/crates/wasm-testsuite/lib.rs b/crates/wasm-testsuite/lib.rs deleted file mode 100644 index b2cc7d2..0000000 --- a/crates/wasm-testsuite/lib.rs +++ /dev/null @@ -1,86 +0,0 @@ -#![doc = include_str!("README.md")] -#![forbid(unsafe_code)] -#![doc(test( - no_crate_inject, - attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_assignments, unused_variables)) -))] -#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms, unreachable_pub)] - -use rust_embed::RustEmbed; -use std::borrow::Cow; - -#[derive(RustEmbed)] -#[folder = "data/"] -#[include = "*.wast"] -struct OfficialTests; - -#[derive(RustEmbed)] -#[folder = "tests/"] -#[include = "*.wast"] -struct CustomTests; - -/// List of all supported proposals. Can be used to filter tests. -/// -/// Includes all proposals from -#[rustfmt::skip] -pub const PROPOSALS: &[&str] = &["annotations", "exception-handling", "extended-const", "function-references", "gc", "memory64", "multi-memory", "relaxed-simd", "tail-call", "threads", "custom-page-sizes", "wide-arithmetic", "wasm-3.0"]; - -/// List of all tests that apply to the MVP (V1) spec -/// Note that the tests are still for the latest spec, so the latest version of Wast is used. -#[rustfmt::skip] // removed: "break-drop.wast", -pub const MVP_TESTS: &[&str] = &["address.wast", "align.wast", "binary-leb128.wast", "binary.wast", "block.wast", "br.wast", "br_if.wast", "br_table.wast", "call.wast", "call_indirect.wast", "comments.wast", "const.wast", "conversions.wast", "custom.wast", "data.wast", "elem.wast", "endianness.wast", "exports.wast", "f32.wast", "f32_bitwise.wast", "f32_cmp.wast", "f64.wast", "f64_bitwise.wast", "f64_cmp.wast", "fac.wast", "float_exprs.wast", "float_literals.wast", "float_memory.wast", "float_misc.wast", "forward.wast", "func.wast", "func_ptrs.wast", "global.wast", "i32.wast", "i64.wast", "if.wast", "imports.wast", "inline-module.wast", "int_exprs.wast", "int_literals.wast", "labels.wast", "left-to-right.wast", "linking.wast", "load.wast", "local_get.wast", "local_set.wast", "local_tee.wast", "loop.wast", "memory.wast", "memory_grow.wast", "memory_redundancy.wast", "memory_size.wast", "memory_trap.wast", "names.wast", "nop.wast", "return.wast", "select.wast", "skip-stack-guard-page.wast", "stack.wast", "start.wast", "store.wast", "switch.wast", "table.wast", "token.wast", "traps.wast", "type.wast", "unreachable.wast", "unreached-valid.wast", "unreached-invalid.wast", "unwind.wast", "utf8-custom-section-id.wast", "utf8-import-field.wast", "utf8-import-module.wast", "utf8-invalid-encoding.wast"]; - -/// List of all tests that apply to the V2 draft 1 spec. -#[rustfmt::skip] -pub const V2_TESTS: &[&str] = &["address.wast", "align.wast", "binary-leb128.wast", "binary.wast", "block.wast", "br.wast", "br_if.wast", "br_table.wast", "bulk.wast", "call.wast", "call_indirect.wast", "comments.wast", "const.wast", "conversions.wast", "custom.wast", "data.wast", "elem.wast", "endianness.wast", "exports.wast", "f32.wast", "f32_bitwise.wast", "f32_cmp.wast", "f64.wast", "f64_bitwise.wast", "f64_cmp.wast", "fac.wast", "float_exprs.wast", "float_literals.wast", "float_memory.wast", "float_misc.wast", "forward.wast", "func.wast", "func_ptrs.wast", "global.wast", "i32.wast", "i64.wast", "if.wast", "imports.wast", "inline-module.wast", "int_exprs.wast", "int_literals.wast", "labels.wast", "left-to-right.wast", "linking.wast", "load.wast", "local_get.wast", "local_set.wast", "local_tee.wast", "loop.wast", "memory.wast", "memory_copy.wast", "memory_fill.wast", "memory_grow.wast", "memory_init.wast", "memory_redundancy.wast", "memory_size.wast", "memory_trap.wast", "names.wast", "nop.wast", "obsolete-keywords.wast", "ref_func.wast", "ref_is_null.wast", "ref_null.wast", "return.wast", "select.wast", "skip-stack-guard-page.wast", "stack.wast", "start.wast", "store.wast", "switch.wast", "table-sub.wast", "table.wast", "table_copy.wast", "table_fill.wast", "table_get.wast", "table_grow.wast", "table_init.wast", "table_set.wast", "table_size.wast", "token.wast", "traps.wast", "type.wast", "unreachable.wast", "unreached-invalid.wast", "unreached-valid.wast", "unwind.wast", "utf8-custom-section-id.wast", "utf8-import-field.wast", "utf8-import-module.wast", "utf8-invalid-encoding.wast"]; - -/// List of all tests that apply to the simd proposal -#[rustfmt::skip] -pub const SIMD_TESTS: &[&str] = &["simd_address.wast", "simd_align.wast", "simd_bit_shift.wast", "simd_bitwise.wast", "simd_boolean.wast", "simd_const.wast", "simd_conversions.wast", "simd_f32x4.wast", "simd_f32x4_arith.wast", "simd_f32x4_cmp.wast", "simd_f32x4_pmin_pmax.wast", "simd_f32x4_rounding.wast", "simd_f64x2.wast", "simd_f64x2_arith.wast", "simd_f64x2_cmp.wast", "simd_f64x2_pmin_pmax.wast", "simd_f64x2_rounding.wast", "simd_i16x8_arith.wast", "simd_i16x8_arith2.wast", "simd_i16x8_cmp.wast", "simd_i16x8_extadd_pairwise_i8x16.wast", "simd_i16x8_extmul_i8x16.wast", "simd_i16x8_q15mulr_sat_s.wast", "simd_i16x8_sat_arith.wast", "simd_i32x4_arith.wast", "simd_i32x4_arith2.wast", "simd_i32x4_cmp.wast", "simd_i32x4_dot_i16x8.wast", "simd_i32x4_extadd_pairwise_i16x8.wast", "simd_i32x4_extmul_i16x8.wast", "simd_i32x4_trunc_sat_f32x4.wast", "simd_i32x4_trunc_sat_f64x2.wast", "simd_i64x2_arith.wast", "simd_i64x2_arith2.wast", "simd_i64x2_cmp.wast", "simd_i64x2_extmul_i32x4.wast", "simd_i8x16_arith.wast", "simd_i8x16_arith2.wast", "simd_i8x16_cmp.wast", "simd_i8x16_sat_arith.wast", "simd_int_to_int_extend.wast", "simd_lane.wast", "simd_linking.wast", "simd_load.wast", "simd_load16_lane.wast", "simd_load32_lane.wast", "simd_load64_lane.wast", "simd_load8_lane.wast", "simd_load_extend.wast", "simd_load_splat.wast", "simd_load_zero.wast", "simd_splat.wast", "simd_store.wast", "simd_store16_lane.wast", "simd_store32_lane.wast", "simd_store64_lane.wast", "simd_store8_lane.wast"]; - -/// List of all tests that apply to a specific proposal. -pub fn get_proposal_tests(proposal: &str) -> impl Iterator + '_ { - OfficialTests::iter().chain(CustomTests::iter()).filter_map(move |x| { - let mut parts = x.split('/'); - if parts.next() == Some("proposals") && parts.next() == Some(proposal) { - Some(format!("{}/{}", proposal, parts.next().unwrap_or_default())) - } else { - None - } - }) -} - -/// Get the WAST file as a byte slice. -pub fn get_test_wast(name: &str) -> Option> { - assert!(name.ends_with(".wast"), "Expected .wast file. Got: {name}"); - - match name.contains('/') { - true => OfficialTests::get(&format!("proposals/{name}")) - .or_else(|| CustomTests::get(&format!("proposals/{name}"))) - .map(|x| x.data), - false => OfficialTests::get(name).or_else(|| CustomTests::get(name)).map(|x| x.data), - } -} - -#[cfg(test)] -mod tests { - use std::collections::HashSet; - - use super::*; - - #[test] - fn test_proposals() { - let mut unique_proposals = HashSet::new(); - - // check that all proposals are present - for proposal in OfficialTests::iter() { - if !proposal.starts_with("proposals/") { - continue; - } - - let proposal = proposal.split('/').nth(1).unwrap(); - unique_proposals.insert(proposal.to_owned()); - assert!(PROPOSALS.contains(&proposal), "Missing proposal: {}", proposal); - } - } -} diff --git a/crates/wasm-testsuite/tests/proposals/custom-page-sizes/custom-page-sizes-invalid.wast b/crates/wasm-testsuite/tests/proposals/custom-page-sizes/custom-page-sizes-invalid.wast deleted file mode 100644 index 150f58b..0000000 --- a/crates/wasm-testsuite/tests/proposals/custom-page-sizes/custom-page-sizes-invalid.wast +++ /dev/null @@ -1,112 +0,0 @@ -;; from https://github.com/WebAssembly/custom-page-sizes/blob/main/test/core/custom-page-sizes/custom-page-sizes-invalid.wast - -;; Page size that is not a power of two. -(assert_malformed - (module quote "(memory 0 (pagesize 3))") - "invalid custom page size" -) - -;; Power-of-two page sizes that are not 1 or 64KiB. -(assert_invalid - (module (memory 0 (pagesize 2))) - "invalid custom page size" -) -(assert_invalid - (module (memory 0 (pagesize 4))) - "invalid custom page size" -) -(assert_invalid - (module (memory 0 (pagesize 8))) - "invalid custom page size" -) -(assert_invalid - (module (memory 0 (pagesize 16))) - "invalid custom page size" -) -(assert_invalid - (module (memory 0 (pagesize 32))) - "invalid custom page size" -) -(assert_invalid - (module (memory 0 (pagesize 64))) - "invalid custom page size" -) -(assert_invalid - (module (memory 0 (pagesize 128))) - "invalid custom page size" -) -(assert_invalid - (module (memory 0 (pagesize 256))) - "invalid custom page size" -) -(assert_invalid - (module (memory 0 (pagesize 512))) - "invalid custom page size" -) -(assert_invalid - (module (memory 0 (pagesize 1024))) - "invalid custom page size" -) -(assert_invalid - (module (memory 0 (pagesize 2048))) - "invalid custom page size" -) -(assert_invalid - (module (memory 0 (pagesize 4096))) - "invalid custom page size" -) -(assert_invalid - (module (memory 0 (pagesize 8192))) - "invalid custom page size" -) -(assert_invalid - (module (memory 0 (pagesize 16384))) - "invalid custom page size" -) -(assert_invalid - (module (memory 0 (pagesize 32768))) - "invalid custom page size" -) - -;; Power-of-two page size that is larger than 64KiB. -(assert_invalid - (module (memory 0 (pagesize 0x20000))) - "invalid custom page size" -) - -;; Power of two page size that cannot fit in a u64 to exercise checks against -;; shift overflow. -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\05\04\01" ;; Memory section - - ;; memory 0 - "\08" ;; flags w/ custom page size - "\00" ;; minimum = 0 - "\41" ;; pagesize = 2**65 - ) - "invalid custom page size" -) - -;; Importing a memory with the wrong page size. - -(module $m - (memory (export "small-pages-memory") 0 (pagesize 1)) - (memory (export "large-pages-memory") 0 (pagesize 65536)) -) -(register "m" $m) - -(assert_unlinkable - (module - (memory (import "m" "small-pages-memory") 0 (pagesize 65536)) - ) - "incompatible import type" -) - -(assert_unlinkable - (module - (memory (import "m" "large-pages-memory") 0 (pagesize 1)) - ) - "incompatible import type" -) diff --git a/crates/wasm-testsuite/tests/proposals/custom-page-sizes/custom-page-sizes.wast b/crates/wasm-testsuite/tests/proposals/custom-page-sizes/custom-page-sizes.wast deleted file mode 100644 index f59d52b..0000000 --- a/crates/wasm-testsuite/tests/proposals/custom-page-sizes/custom-page-sizes.wast +++ /dev/null @@ -1,110 +0,0 @@ -;; from https://github.com/WebAssembly/custom-page-sizes/blob/main/test/core/custom-page-sizes/custom-page-sizes.wast - -;; Check all the valid custom page sizes. -(module (memory 1 (pagesize 1))) -(module (memory 1 (pagesize 65536))) - -;; Check them all again with maximums specified. -(module (memory 1 2 (pagesize 1))) -(module (memory 1 2 (pagesize 65536))) - -;; Check the behavior of memories with page size 1. -(module - (memory 0 (pagesize 1)) - (func (export "size") (result i32) - memory.size - ) - (func (export "grow") (param i32) (result i32) - (memory.grow (local.get 0)) - ) - (func (export "load") (param i32) (result i32) - (i32.load8_u (local.get 0)) - ) - (func (export "store") (param i32 i32) - (i32.store8 (local.get 0) (local.get 1)) - ) -) - -(assert_return (invoke "size") (i32.const 0)) -(assert_trap (invoke "load" (i32.const 0)) "out of bounds memory access") - -(assert_return (invoke "grow" (i32.const 65536)) (i32.const 0)) -(assert_return (invoke "size") (i32.const 65536)) -(assert_return (invoke "load" (i32.const 65535)) (i32.const 0)) -(assert_return (invoke "store" (i32.const 65535) (i32.const 1))) -(assert_return (invoke "load" (i32.const 65535)) (i32.const 1)) -(assert_trap (invoke "load" (i32.const 65536)) "out of bounds memory access") - -(assert_return (invoke "grow" (i32.const 65536)) (i32.const 65536)) -(assert_return (invoke "size") (i32.const 131072)) -(assert_return (invoke "load" (i32.const 131071)) (i32.const 0)) -(assert_return (invoke "store" (i32.const 131071) (i32.const 1))) -(assert_return (invoke "load" (i32.const 131071)) (i32.const 1)) -(assert_trap (invoke "load" (i32.const 131072)) "out of bounds memory access") - -;; Although smaller page sizes let us get to memories larger than 2**16 pages, -;; we can't do that with the default page size, even if we explicitly state it -;; as a custom page size. -(module - (memory 0 (pagesize 65536)) - (func (export "size") (result i32) - memory.size - ) - (func (export "grow") (param i32) (result i32) - (memory.grow (local.get 0)) - ) -) -(assert_return (invoke "size") (i32.const 0)) -(assert_return (invoke "grow" (i32.const 65537)) (i32.const -1)) -(assert_return (invoke "size") (i32.const 0)) - -;; Can copy between memories of different page sizes. -(module - (memory $small 10 (pagesize 1)) - (memory $large 1 (pagesize 65536)) - - (data (memory $small) (i32.const 0) "\11\22\33\44") - (data (memory $large) (i32.const 0) "\55\66\77\88") - - (func (export "copy-small-to-large") (param i32 i32 i32) - (memory.copy $large $small (local.get 0) (local.get 1) (local.get 2)) - ) - - (func (export "copy-large-to-small") (param i32 i32 i32) - (memory.copy $small $large (local.get 0) (local.get 1) (local.get 2)) - ) - - (func (export "load8-small") (param i32) (result i32) - (i32.load8_u $small (local.get 0)) - ) - - (func (export "load8-large") (param i32) (result i32) - (i32.load8_u $large (local.get 0)) - ) -) - -(assert_return (invoke "copy-small-to-large" (i32.const 6) (i32.const 0) (i32.const 2))) -(assert_return (invoke "load8-large" (i32.const 6)) (i32.const 0x11)) -(assert_return (invoke "load8-large" (i32.const 7)) (i32.const 0x22)) - -(assert_return (invoke "copy-large-to-small" (i32.const 4) (i32.const 1) (i32.const 3))) -(assert_return (invoke "load8-small" (i32.const 4)) (i32.const 0x66)) -(assert_return (invoke "load8-small" (i32.const 5)) (i32.const 0x77)) -(assert_return (invoke "load8-small" (i32.const 6)) (i32.const 0x88)) - -;; Can link together modules that export and import memories with custom page -;; sizes. - -(module $m - (memory (export "small-pages-memory") 0 (pagesize 1)) - (memory (export "large-pages-memory") 0 (pagesize 65536)) -) -(register "m" $m) - -(module - (memory (import "m" "small-pages-memory") 0 (pagesize 1)) -) - -(module - (memory (import "m" "large-pages-memory") 0 (pagesize 65536)) -) From 76a65cc51e031e32cdbbad5a67283870b981d7c3 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Mon, 9 Dec 2024 00:05:53 +0100 Subject: [PATCH 31/54] chore: improve testsuite Signed-off-by: Henry Gressmann --- .cargo/config.toml | 1 + Cargo.lock | 4 +- crates/tinywasm/Cargo.toml | 6 ++- crates/tinywasm/tests/generated/wasm-1.csv | 2 +- crates/tinywasm/tests/generated/wasm-3.csv | 1 + .../tinywasm/tests/generated/wasm-latest.csv | 1 + crates/tinywasm/tests/test-wasm-1.rs | 14 +++--- crates/tinywasm/tests/test-wasm-3.rs | 18 ++++++++ crates/tinywasm/tests/test-wast.rs | 44 +++++++------------ crates/tinywasm/tests/testsuite/run.rs | 22 +++++++--- crates/tinywasm/tests/testsuite/util.rs | 18 ++++---- 11 files changed, 77 insertions(+), 54 deletions(-) create mode 100644 crates/tinywasm/tests/generated/wasm-3.csv create mode 100644 crates/tinywasm/tests/generated/wasm-latest.csv create mode 100644 crates/tinywasm/tests/test-wasm-3.rs diff --git a/.cargo/config.toml b/.cargo/config.toml index fc2d7f9..b27192b 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -2,4 +2,5 @@ version-dev="workspaces version --no-git-commit --force tinywasm*" test-wasm-1="test --package tinywasm --test test-wasm-1 --release" test-wasm-2="test --package tinywasm --test test-wasm-2 --release" +test-wasm-3="test --package tinywasm --test test-wasm-3 --release" test-wast="test --package tinywasm --test test-wast" diff --git a/Cargo.lock b/Cargo.lock index 7e6cacc..64d907b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -779,9 +779,9 @@ dependencies = [ [[package]] name = "wasm-testsuite" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dc81f607820a4f651559ad68709106d53bf50c20f01effe90f4da6954d4885d" +checksum = "aec2d7c897c2af9a57776b7c705a9d3f5f7c4d782eeaa0cf91520f8086ab0382" dependencies = [ "include_dir", "wast", diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index 80f148c..2d5c6dd 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -20,7 +20,7 @@ tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false libm={version="0.2", default-features=false} [dev-dependencies] -wasm-testsuite={version="0.3.2"} +wasm-testsuite={version="0.3.3"} indexmap="2.7" wast={workspace=true} eyre={workspace=true} @@ -45,6 +45,10 @@ harness=false name="test-wasm-2" harness=false +[[test]] +name="test-wasm-3" +harness=false + [[test]] name="test-wasm-multi-memory" harness=false diff --git a/crates/tinywasm/tests/generated/wasm-1.csv b/crates/tinywasm/tests/generated/wasm-1.csv index 591123d..d403e3b 100644 --- a/crates/tinywasm/tests/generated/wasm-1.csv +++ b/crates/tinywasm/tests/generated/wasm-1.csv @@ -5,4 +5,4 @@ 0.6.1,27572,335,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.7.0,27572,335,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.8.0,20360,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":128,"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":98,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_grow.wast","passed":104,"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.9.0-alpha.0,20362,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":128,"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":172,"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":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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_grow.wast","passed":104,"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.9.0-alpha.0,19243,0,[{"name":"address.wast","passed":243,"failed":0},{"name":"align.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":79,"failed":0},{"name":"binary.wast","passed":67,"failed":0},{"name":"block.wast","passed":171,"failed":0},{"name":"br.wast","passed":84,"failed":0},{"name":"br_if.wast","passed":118,"failed":0},{"name":"br_table.wast","passed":168,"failed":0},{"name":"break-drop.wast","passed":4,"failed":0},{"name":"call.wast","passed":82,"failed":0},{"name":"call_indirect.wast","passed":152,"failed":0},{"name":"comments.wast","passed":4,"failed":0},{"name":"const.wast","passed":668,"failed":0},{"name":"conversions.wast","passed":435,"failed":0},{"name":"custom.wast","passed":10,"failed":0},{"name":"data.wast","passed":45,"failed":0},{"name":"elem.wast","passed":55,"failed":0},{"name":"endianness.wast","passed":69,"failed":0},{"name":"exports.wast","passed":82,"failed":0},{"name":"f32.wast","passed":2512,"failed":0},{"name":"f32_bitwise.wast","passed":364,"failed":0},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":2512,"failed":0},{"name":"f64_bitwise.wast","passed":364,"failed":0},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":7,"failed":0},{"name":"float_exprs.wast","passed":900,"failed":0},{"name":"float_literals.wast","passed":161,"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":121,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"globals.wast","passed":78,"failed":0},{"name":"i32.wast","passed":443,"failed":0},{"name":"i64.wast","passed":389,"failed":0},{"name":"if.wast","passed":151,"failed":0},{"name":"imports.wast","passed":146,"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":116,"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":81,"failed":0},{"name":"memory.wast","passed":71,"failed":0},{"name":"memory_grow.wast","passed":94,"failed":0},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":42,"failed":0},{"name":"memory_trap.wast","passed":173,"failed":0},{"name":"names.wast","passed":483,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":111,"failed":0},{"name":"skip-stack-guard-page.wast","passed":11,"failed":0},{"name":"stack.wast","passed":5,"failed":0},{"name":"start.wast","passed":19,"failed":0},{"name":"store.wast","passed":68,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"token.wast","passed":2,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":62,"failed":0},{"name":"unreached-invalid.wast","passed":110,"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/wasm-3.csv b/crates/tinywasm/tests/generated/wasm-3.csv new file mode 100644 index 0000000..ed301e4 --- /dev/null +++ b/crates/tinywasm/tests/generated/wasm-3.csv @@ -0,0 +1 @@ +0.9.0-alpha.0,32305,2591,[{"name":"address.wast","passed":260,"failed":0},{"name":"address64.wast","passed":0,"failed":242},{"name":"align.wast","passed":161,"failed":0},{"name":"align64.wast","passed":83,"failed":73},{"name":"annotations.wast","passed":74,"failed":0},{"name":"binary-leb128.wast","passed":92,"failed":1},{"name":"binary.wast","passed":126,"failed":0},{"name":"block.wast","passed":223,"failed":0},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":119,"failed":0},{"name":"br_on_non_null.wast","passed":1,"failed":9},{"name":"br_on_null.wast","passed":1,"failed":9},{"name":"br_table.wast","passed":24,"failed":162},{"name":"bulk.wast","passed":117,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":49,"failed":124},{"name":"call_ref.wast","passed":4,"failed":31},{"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":59,"failed":6},{"name":"elem.wast","passed":137,"failed":14},{"name":"endianness.wast","passed":69,"failed":0},{"name":"endianness64.wast","passed":0,"failed":69},{"name":"exports.wast","passed":97,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_memory64.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":471,"failed":0},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":175,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"global.wast","passed":53,"failed":71},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":169,"failed":90},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"instance.wast","passed":0,"failed":23},{"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":142,"failed":21},{"name":"load.wast","passed":118,"failed":0},{"name":"load64.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_init.wast","passed":10,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":98,"failed":0},{"name":"loop.wast","passed":120,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":89,"failed":0},{"name":"memory64.wast","passed":14,"failed":53},{"name":"memory_copy.wast","passed":8385,"failed":515},{"name":"memory_fill.wast","passed":164,"failed":36},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_grow64.wast","passed":0,"failed":49},{"name":"memory_init.wast","passed":307,"failed":173},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_redundancy64.wast","passed":0,"failed":8},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"memory_trap64.wast","passed":0,"failed":172},{"name":"names.wast","passed":486,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref.wast","passed":12,"failed":1},{"name":"ref_as_non_null.wast","passed":1,"failed":6},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":2,"failed":20},{"name":"ref_null.wast","passed":0,"failed":34},{"name":"return.wast","passed":84,"failed":0},{"name":"return_call.wast","passed":11,"failed":34},{"name":"return_call_indirect.wast","passed":26,"failed":50},{"name":"return_call_ref.wast","passed":11,"failed":40},{"name":"select.wast","passed":155,"failed":2},{"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":111,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"table-sub.wast","passed":2,"failed":1},{"name":"table.wast","passed":47,"failed":9},{"name":"table_copy.wast","passed":1742,"failed":30},{"name":"table_copy_mixed.wast","passed":4,"failed":0},{"name":"table_fill.wast","passed":45,"failed":35},{"name":"table_get.wast","passed":16,"failed":1},{"name":"table_grow.wast","passed":58,"failed":21},{"name":"table_init.wast","passed":780,"failed":96},{"name":"table_set.wast","passed":26,"failed":2},{"name":"table_size.wast","passed":39,"failed":1},{"name":"tag.wast","passed":1,"failed":8},{"name":"throw.wast","passed":3,"failed":10},{"name":"throw_ref.wast","passed":2,"failed":13},{"name":"token.wast","passed":61,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"try_table.wast","passed":11,"failed":51},{"name":"type-canon.wast","passed":0,"failed":2},{"name":"type-equivalence.wast","passed":12,"failed":20},{"name":"type-rec.wast","passed":6,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":121,"failed":0},{"name":"unreached-valid.wast","passed":2,"failed":11},{"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/wasm-latest.csv b/crates/tinywasm/tests/generated/wasm-latest.csv new file mode 100644 index 0000000..27a4e86 --- /dev/null +++ b/crates/tinywasm/tests/generated/wasm-latest.csv @@ -0,0 +1 @@ +0.9.0-alpha.0,28010,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":128,"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":117,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":172,"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":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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_copy.wast","passed":4450,"failed":0},{"name":"memory_fill.wast","passed":100,"failed":0},{"name":"memory_grow.wast","passed":104,"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":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":16,"failed":0},{"name":"ref_null.wast","passed":3,"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-sub.wast","passed":2,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"table_copy.wast","passed":1728,"failed":0},{"name":"table_fill.wast","passed":45,"failed":0},{"name":"table_get.wast","passed":16,"failed":0},{"name":"table_grow.wast","passed":58,"failed":0},{"name":"table_init.wast","passed":780,"failed":0},{"name":"table_set.wast","passed":26,"failed":0},{"name":"table_size.wast","passed":39,"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/tinywasm/tests/test-wasm-1.rs b/crates/tinywasm/tests/test-wasm-1.rs index e6a9dd9..94c83f9 100644 --- a/crates/tinywasm/tests/test-wasm-1.rs +++ b/crates/tinywasm/tests/test-wasm-1.rs @@ -1,13 +1,13 @@ mod testsuite; use eyre::Result; +use testsuite::TestSuite; +use wasm_testsuite::data::{spec, SpecVersion}; fn main() -> Result<()> { - println!("Skipping 1.0 tests (False positives due to relaxed validation in later versions)"); - Ok(()) - // TestSuite::set_log_level(log::LevelFilter::Off); + TestSuite::set_log_level(log::LevelFilter::Off); - // let mut test_suite = TestSuite::new(); - // test_suite.run_files(spec(&SpecVersion::V1))?; - // test_suite.save_csv("./tests/generated/wasm-1.csv", env!("CARGO_PKG_VERSION"))?; - // test_suite.report_status() + let mut test_suite = TestSuite::new(); + test_suite.run_files(spec(&SpecVersion::V1))?; + test_suite.save_csv("./tests/generated/wasm-1.csv", env!("CARGO_PKG_VERSION"))?; + test_suite.report_status() } diff --git a/crates/tinywasm/tests/test-wasm-3.rs b/crates/tinywasm/tests/test-wasm-3.rs new file mode 100644 index 0000000..0bd2cb0 --- /dev/null +++ b/crates/tinywasm/tests/test-wasm-3.rs @@ -0,0 +1,18 @@ +mod testsuite; +use eyre::Result; +use testsuite::TestSuite; +use wasm_testsuite::data::{spec, SpecVersion}; + +fn main() -> Result<()> { + if std::env::args().find(|x| x == "--enable").is_none() { + println!("Skipping wasm-3 tests, use --enable to run"); + return Ok(()); + } + + TestSuite::set_log_level(log::LevelFilter::Off); + + let mut test_suite = TestSuite::new(); + test_suite.run_files(spec(&SpecVersion::V3))?; + test_suite.save_csv("./tests/generated/wasm-3.csv", env!("CARGO_PKG_VERSION"))?; + test_suite.report_status() +} diff --git a/crates/tinywasm/tests/test-wast.rs b/crates/tinywasm/tests/test-wast.rs index f79681c..33c716c 100644 --- a/crates/tinywasm/tests/test-wast.rs +++ b/crates/tinywasm/tests/test-wast.rs @@ -12,37 +12,25 @@ fn main() -> Result<()> { bail!("usage: cargo test-wast ") }; - // cwd for relative paths, absolute paths are kept as-is - let cwd = std::env::current_dir()?; - - // if current dir is crates/tinywasm, then we want to go up 2 levels - let mut wast_file = if cwd.ends_with("crates/tinywasm") { PathBuf::from("../../") } else { PathBuf::from("./") }; + let mut cwd = std::env::current_dir()?; + if cwd.ends_with("crates/tinywasm/") { + cwd.pop(); + cwd.pop(); + } - wast_file.push(&args[1]); - let wast_file = cwd.join(wast_file); + // if its a folder, run all the wast files in the folder + let arg = PathBuf::from(cwd.clone()).join(&args[1]); + println!("running tests in {:?}", arg); - test_wast(wast_file.to_str().expect("wast_file is not a valid path"))?; - Ok(()) -} + let files = if arg.is_dir() { + std::fs::read_dir(&arg)?.map(|entry| entry.map(|e| e.path())).collect::, _>>()? + } else { + vec![arg] + }; -fn test_wast(wast_file: &str) -> Result<()> { TestSuite::set_log_level(log::LevelFilter::Debug); - - let args = std::env::args().collect::>(); - println!("args: {args:?}"); - let mut test_suite = TestSuite::new(); - println!("running wast file: {wast_file}"); - - test_suite.run_paths(&[wast_file])?; - - if test_suite.failed() { - println!(); - test_suite.print_errors(); - println!(); - Err(eyre!(format!("{}:\n{:#?}", "failed one or more tests".red().bold(), test_suite,))) - } else { - println!("\n\npassed all tests:\n{test_suite:#?}"); - Ok(()) - } + test_suite.run_paths(&files)?; + test_suite.print_errors(); + test_suite.report_status() } diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index 6324a5b..f2a4fa3 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -1,5 +1,5 @@ use crate::testsuite::util::*; -use std::{borrow::Cow, collections::HashMap}; +use std::{borrow::Cow, collections::HashMap, fs::canonicalize, path::PathBuf}; use super::TestSuite; use eyre::{eyre, Result}; @@ -71,12 +71,12 @@ impl ModuleRegistry { } impl TestSuite { - pub fn run_paths(&mut self, tests: &[&str]) -> Result<()> { + pub fn run_paths(&mut self, tests: &[PathBuf]) -> Result<()> { for file_name in tests { let group_wast = std::fs::read(file_name).expect("failed to read test wast"); let file = TestFile { contents: std::str::from_utf8(&group_wast).expect("failed to convert to utf8"), - name: file_name.to_string(), + name: canonicalize(file_name).expect("failed to canonicalize file name").to_string_lossy().to_string(), parent: "(custom group)".into(), }; @@ -240,12 +240,12 @@ impl TestSuite { Ok(_) => { // - skip "zero byte expected" as the magic number is not checked by wasmparser // (Don't need to error on this, doesn't matter if it's malformed) - // - skip "integer representation too long" as this has some false positives + // - skip "integer representation too long" as this has some false positives on older tests if message == "zero byte expected" || message == "integer representation too long" { continue; } - Err(eyre!("expected module to be malformed")) + Err(eyre!("expected module to be malformed: {message}")) } Err(_) => Ok(()), }, @@ -413,7 +413,17 @@ impl TestSuite { AssertReturn { span, exec, results } => { info!("AssertReturn: {:?}", exec); - let expected = convert_wastret(results.into_iter())?; + let expected = match convert_wastret(results.into_iter()) { + Err(err) => { + test_group.add_result( + &format!("AssertReturn(unsupported-{i})"), + span.linecol_in(wast_raw), + Err(eyre!("failed to convert expected results: {:?}", err)), + ); + continue; + } + Ok(expected) => expected, + }; let invoke = match match exec { wast::WastExecute::Wat(_) => Err(eyre!("wat not supported")), diff --git a/crates/tinywasm/tests/testsuite/util.rs b/crates/tinywasm/tests/testsuite/util.rs index 3229455..ca844a4 100644 --- a/crates/tinywasm/tests/testsuite/util.rs +++ b/crates/tinywasm/tests/testsuite/util.rs @@ -1,6 +1,6 @@ use std::panic::{self, AssertUnwindSafe}; -use eyre::{eyre, Result}; +use eyre::{bail, eyre, Result}; use tinywasm_types::{ModuleInstanceAddr, TinyWasmModule, ValType, WasmValue}; use wast::{core::AbstractHeapType, QuoteWat}; @@ -92,7 +92,7 @@ pub fn convert_wastret<'a>(args: impl Iterator>) -> Res fn wastarg2tinywasmvalue(arg: wast::WastArg) -> Result { let wast::WastArg::Core(arg) = arg else { - return Err(eyre!("unsupported arg type: Component")); + bail!("unsupported arg type: Component"); }; use wast::core::WastArgCore::{RefExtern, RefNull, F32, F64, I32, I64, V128}; @@ -110,9 +110,9 @@ fn wastarg2tinywasmvalue(arg: wast::WastArg) -> Result { WasmValue::RefNull(ValType::RefExtern) } - _ => return Err(eyre!("unsupported arg type: refnull: {:?}", t)), + _ => bail!("unsupported arg type: refnull: {:?}", t), }, - v => return Err(eyre!("unsupported arg type: {:?}", v)), + v => bail!("unsupported arg type: {:?}", v), }) } @@ -133,7 +133,7 @@ fn wast_i128_to_i128(i: wast::core::V128Pattern) -> u128 { fn wastret2tinywasmvalue(ret: wast::WastRet) -> Result { let wast::WastRet::Core(ret) = ret else { - return Err(eyre!("unsupported arg type")); + bail!("unsupported arg type"); }; use wast::core::WastRetCore::{RefExtern, RefFunc, RefNull, F32, F64, I32, I64, V128}; @@ -150,19 +150,19 @@ fn wastret2tinywasmvalue(ret: wast::WastRet) -> Result { WasmValue::RefNull(ValType::RefExtern) } - _ => return Err(eyre!("unsupported arg type: refnull: {:?}", t)), + _ => bail!("unsupported arg type: refnull: {:?}", t), }, RefExtern(v) => match v { Some(v) => WasmValue::RefExtern(v), None => WasmValue::RefNull(ValType::RefExtern), - _ => return Err(eyre!("unsupported arg type: refextern: {:?}", v)), + _ => bail!("unsupported arg type: refextern: {:?}", v), }, RefFunc(v) => match v { Some(wast::token::Index::Num(n, _)) => WasmValue::RefFunc(n), None => WasmValue::RefNull(ValType::RefFunc), - _ => return Err(eyre!("unsupported arg type: reffunc: {:?}", v)), + _ => bail!("unsupported arg type: reffunc: {:?}", v), }, - a => return Err(eyre!("unsupported arg type {:?}", a)), + a => bail!("unsupported arg type {:?}", a), }) } From 5797ee77faeeaed8eb54f2eb09dd4a07c3c01017 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sat, 28 Dec 2024 17:45:24 +0100 Subject: [PATCH 32/54] chore: update deps Signed-off-by: Henry Gressmann --- Cargo.lock | 20 ++++++++++---------- Cargo.toml | 4 ++-- crates/parser/Cargo.toml | 2 +- crates/parser/src/lib.rs | 1 + crates/tinywasm/Cargo.toml | 2 +- crates/tinywasm/tests/testsuite/run.rs | 3 ++- crates/tinywasm/tests/testsuite/util.rs | 3 ++- 7 files changed, 19 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 64d907b..14e8e5f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -769,9 +769,9 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.221.2" +version = "0.222.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17a3bd88f2155da63a1f2fcb8a56377a24f0b6dfed12733bb5f544e86f690c5" +checksum = "3432682105d7e994565ef928ccf5856cf6af4ba3dddebedb737f61caed70f956" dependencies = [ "leb128", "wasmparser", @@ -779,9 +779,9 @@ dependencies = [ [[package]] name = "wasm-testsuite" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aec2d7c897c2af9a57776b7c705a9d3f5f7c4d782eeaa0cf91520f8086ab0382" +checksum = "d01e1e4857b055d8ad6d542d95074106b5b2afd411d3e26ae6da37a560053c97" dependencies = [ "include_dir", "wast", @@ -789,9 +789,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.221.2" +version = "0.222.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9845c470a2e10b61dd42c385839cdd6496363ed63b5c9e420b5488b77bd22083" +checksum = "4adf50fde1b1a49c1add6a80d47aea500c88db70551805853aa8b88f3ea27ab5" dependencies = [ "bitflags", "indexmap", @@ -800,9 +800,9 @@ dependencies = [ [[package]] name = "wast" -version = "221.0.2" +version = "222.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc4470b9de917ba199157d1f0ae104f2ae362be728c43e68c571c7715bd629e" +checksum = "5ce7191f4b7da0dd300cc32476abae6457154e4625d9b1bc26890828a9a26f6e" dependencies = [ "bumpalo", "leb128", @@ -813,9 +813,9 @@ dependencies = [ [[package]] name = "wat" -version = "1.221.2" +version = "1.222.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b1f3c6d82af47286494c6caea1d332037f5cbeeac82bbf5ef59cb8c201c466e" +checksum = "8fde61b4b52f9a84ae31b5e8902a2cd3162ea45d8bf564c729c3288fe52f4334" dependencies = [ "wast", ] diff --git a/Cargo.toml b/Cargo.toml index ca93037..0c2f571 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,8 +4,8 @@ default-members=[".", "crates/tinywasm", "crates/types", "crates/parser"] resolver="2" [workspace.dependencies] -wast="221" -wat="1.221" +wast="222" +wat="1.222" eyre="0.6" log="0.4" pretty_env_logger="0.5" diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index 02b7003..61224fd 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -9,7 +9,7 @@ repository.workspace=true rust-version.workspace=true [dependencies] -wasmparser={version="0.221", default-features=false, features=["validate", "features", "simd"]} +wasmparser={version="0.222", default-features=false, features=["validate", "features", "simd"]} log={workspace=true, optional=true} tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false} diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index 2222ffa..dcb05f0 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -81,6 +81,7 @@ impl Parser { shared_everything_threads: false, component_model_multiple_returns: false, legacy_exceptions: false, + component_model_async: false, }; Validator::new_with_features(features.into()) } diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index 2d5c6dd..d8f8b06 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -20,7 +20,7 @@ tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false libm={version="0.2", default-features=false} [dev-dependencies] -wasm-testsuite={version="0.3.3"} +wasm-testsuite={version="0.4.0"} indexmap="2.7" wast={workspace=true} eyre={workspace=true} diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index f2a4fa3..7534142 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -8,7 +8,8 @@ use log::{debug, error, info}; use tinywasm::{Extern, Imports, ModuleInstance}; use tinywasm_types::{ExternVal, MemoryType, ModuleInstanceAddr, TableType, ValType, WasmValue}; use wasm_testsuite::data::TestFile; -use wast::{lexer::Lexer, parser::ParseBuffer, Wast}; +use wasm_testsuite::wast::{lexer::Lexer, parser::ParseBuffer, Wast}; +use wasm_testsuite::wast; #[derive(Default)] struct ModuleRegistry { diff --git a/crates/tinywasm/tests/testsuite/util.rs b/crates/tinywasm/tests/testsuite/util.rs index ca844a4..e3aafcb 100644 --- a/crates/tinywasm/tests/testsuite/util.rs +++ b/crates/tinywasm/tests/testsuite/util.rs @@ -2,7 +2,8 @@ use std::panic::{self, AssertUnwindSafe}; use eyre::{bail, eyre, Result}; use tinywasm_types::{ModuleInstanceAddr, TinyWasmModule, ValType, WasmValue}; -use wast::{core::AbstractHeapType, QuoteWat}; +use wasm_testsuite::wast::{core::AbstractHeapType, QuoteWat}; +use wasm_testsuite::wast; pub fn try_downcast_panic(panic: Box) -> String { let info = panic.downcast_ref::().or(None).map(ToString::to_string).clone(); From 0202878e1cdf5448fb007cc080c98cce707c889f Mon Sep 17 00:00:00 2001 From: WhaleKit Date: Mon, 6 Jan 2025 18:25:53 +0600 Subject: [PATCH 33/54] Check returns in untyped host functions (#27) --------- Signed-off-by: Henry Gressmann Co-authored-by: Henry Gressmann --- CHANGELOG.md | 1 + Cargo.lock | 1 + crates/tinywasm/Cargo.toml | 1 + crates/tinywasm/src/error.rs | 14 +- crates/tinywasm/src/func.rs | 4 +- crates/tinywasm/src/imports.rs | 21 ++- crates/tinywasm/src/interpreter/executor.rs | 4 +- .../tests/host_func_signature_check.rs | 173 ++++++++++++++++++ 8 files changed, 211 insertions(+), 8 deletions(-) create mode 100644 crates/tinywasm/tests/host_func_signature_check.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index a660685..e52cdc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Fixed archive **no_std** support which was broken in the previous release, and added more tests to ensure it stays working +- Check returns in untyped host functions ([#27](https://github.com/explodingcamera/tinywasm/pull/27)) (thanks [@WhaleKit](https://github.com/WhaleKit)) ## [0.8.0] - 2024-08-29 diff --git a/Cargo.lock b/Cargo.lock index 14e8e5f..5333d98 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -698,6 +698,7 @@ dependencies = [ "tinywasm-types", "wasm-testsuite", "wast", + "wat", ] [[package]] diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index d8f8b06..5dc0447 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -23,6 +23,7 @@ libm={version="0.2", default-features=false} wasm-testsuite={version="0.4.0"} indexmap="2.7" wast={workspace=true} +wat={workspace=true} eyre={workspace=true} pretty_env_logger={workspace=true} criterion={workspace=true} diff --git a/crates/tinywasm/src/error.rs b/crates/tinywasm/src/error.rs index ebc71af..e0510b2 100644 --- a/crates/tinywasm/src/error.rs +++ b/crates/tinywasm/src/error.rs @@ -1,4 +1,5 @@ use alloc::string::{String, ToString}; +use alloc::vec::Vec; use core::{fmt::Display, ops::ControlFlow}; use tinywasm_types::FuncType; @@ -20,8 +21,13 @@ pub enum Error { /// An unknown error occurred Other(String), - /// A function did not return a value - FuncDidNotReturn, + /// A host function returned an invalid value + InvalidHostFnReturn { + /// The expected type + expected: FuncType, + /// The actual value + actual: Vec, + }, /// An invalid label type was encountered InvalidLabelType, @@ -183,7 +189,9 @@ impl Display for Error { Self::InvalidLabelType => write!(f, "invalid label type"), Self::Other(message) => write!(f, "unknown error: {message}"), Self::UnsupportedFeature(feature) => write!(f, "unsupported feature: {feature}"), - Self::FuncDidNotReturn => write!(f, "function did not return"), + Self::InvalidHostFnReturn { expected, actual } => { + write!(f, "invalid host function return: expected={expected:?}, actual={actual:?}") + } Self::InvalidStore => write!(f, "invalid store"), } } diff --git a/crates/tinywasm/src/func.rs b/crates/tinywasm/src/func.rs index 7035109..47a2cdf 100644 --- a/crates/tinywasm/src/func.rs +++ b/crates/tinywasm/src/func.rs @@ -51,9 +51,9 @@ impl FuncHandle { let func_inst = store.get_func(self.addr); let wasm_func = match &func_inst.func { Function::Host(host_func) => { - let func = &host_func.clone().func; + let host_func = host_func.clone(); let ctx = FuncContext { store, module_addr: self.module_addr }; - return (func)(ctx, params); + return host_func.call(ctx, params); } Function::Wasm(wasm_func) => wasm_func, }; diff --git a/crates/tinywasm/src/imports.rs b/crates/tinywasm/src/imports.rs index 7cc5bbb..0797470 100644 --- a/crates/tinywasm/src/imports.rs +++ b/crates/tinywasm/src/imports.rs @@ -139,7 +139,26 @@ impl Extern { ty: &tinywasm_types::FuncType, func: impl Fn(FuncContext<'_>, &[WasmValue]) -> Result> + 'static, ) -> Self { - Self::Function(Function::Host(Rc::new(HostFunction { func: Box::new(func), ty: ty.clone() }))) + let _ty = ty.clone(); + let inner_func = move |ctx: FuncContext<'_>, args: &[WasmValue]| -> Result> { + let _ty = _ty.clone(); + let result = func(ctx, args)?; + + 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, ty)| { + if val.val_type() != *ty { + return Err(crate::Error::InvalidHostFnReturn { expected: _ty.clone(), actual: result.clone() }); + } + Ok(()) + })?; + + Ok(result) + }; + + Self::Function(Function::Host(Rc::new(HostFunction { func: Box::new(inner_func), ty: ty.clone() }))) } /// Create a new typed function import diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index 2b64942..f05ae30 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -331,7 +331,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { let func = &host_func.clone(); let params = self.stack.values.pop_params(&host_func.ty.params); let res = - (func.func)(FuncContext { store: self.store, module_addr: self.module.id() }, ¶ms).to_cf()?; + func.call(FuncContext { store: self.store, module_addr: self.module.id() }, ¶ms).to_cf()?; self.stack.values.extend_from_wasmvalues(&res); self.cf.incr_instr_ptr(); return ControlFlow::Continue(()); @@ -370,7 +370,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { let host_func = host_func.clone(); let params = self.stack.values.pop_params(&host_func.ty.params); let res = - match (host_func.func)(FuncContext { store: self.store, module_addr: self.module.id() }, ¶ms) { + match host_func.call(FuncContext { store: self.store, module_addr: self.module.id() }, ¶ms) { Ok(res) => res, Err(e) => return ControlFlow::Break(Some(e)), }; diff --git a/crates/tinywasm/tests/host_func_signature_check.rs b/crates/tinywasm/tests/host_func_signature_check.rs new file mode 100644 index 0000000..787b24a --- /dev/null +++ b/crates/tinywasm/tests/host_func_signature_check.rs @@ -0,0 +1,173 @@ +use eyre::Result; +use std::fmt::Write; +use tinywasm::{ + types::{FuncType, ValType, WasmValue}, + Extern, FuncContext, Imports, Module, Store, +}; + +const VAL_LISTS: &[&[WasmValue]] = &[ + &[], + &[WasmValue::I32(0)], + &[WasmValue::I32(0), WasmValue::I32(0)], // 2 of the same + &[WasmValue::I32(0), WasmValue::I32(0), WasmValue::F64(0.0)], // add another type + &[WasmValue::I32(0), WasmValue::F64(0.0), WasmValue::I32(0)], // reorder + &[WasmValue::RefExtern(0), WasmValue::F64(0.0), WasmValue::I32(0)], // all different types +]; +// (f64, i32, i32) and (f64) can be used to "match_none" + +fn get_type_lists() -> impl Iterator + Clone> + Clone { + VAL_LISTS.iter().map(|l| l.iter().map(WasmValue::val_type)) +} +fn get_modules() -> Vec<(Module, FuncType, Vec)> { + let mut result = Vec::<(Module, FuncType, Vec)>::new(); + let val_and_tys = get_type_lists().zip(VAL_LISTS); + for res_types in get_type_lists() { + for (arg_types, arg_vals) in val_and_tys.clone() { + let ty = FuncType { results: res_types.clone().collect(), params: arg_types.collect() }; + result.push((proxy_module(&ty), ty, arg_vals.to_vec())); + } + } + result +} + +#[test] +fn test_return_invalid_type() -> Result<()> { + // try to return from host functions types that don't match their signatures + let mod_list = get_modules(); + + for (module, func_ty, test_args) in mod_list { + for result_to_try in VAL_LISTS { + println!("trying"); + let mut store = Store::default(); + let mut imports = Imports::new(); + imports + .define("host", "hfn", Extern::func(&func_ty, |_: FuncContext<'_>, _| Ok(result_to_try.to_vec()))) + .unwrap(); + + let instance = module.clone().instantiate(&mut store, Some(imports)).unwrap(); + let caller = instance.exported_func_untyped(&store, "call_hfn").unwrap(); + let res_types_returned = result_to_try.iter().map(WasmValue::val_type); + dbg!(&res_types_returned, &func_ty); + let res_types_expected = &func_ty.results; + let should_succeed = res_types_returned.eq(res_types_expected.iter().cloned()); + // Extern::func that returns wrong type(s) can only be detected when it runs + let call_res = caller.call(&mut store, &test_args); + dbg!(&call_res); + assert_eq!(call_res.is_ok(), should_succeed); + println!("this time ok"); + } + } + Ok(()) +} + +#[test] +fn test_linking_invalid_untyped_func() -> Result<()> { + // try to import host functions with function types no matching those expected by modules + let mod_list = get_modules(); + for (module, actual_func_ty, _) in &mod_list { + for (_, func_ty_to_try, _) in &mod_list { + let tried_fn = Extern::func(func_ty_to_try, |_: FuncContext<'_>, _| panic!("not intended to be called")); + let mut store = Store::default(); + let mut imports = Imports::new(); + imports.define("host", "hfn", tried_fn).unwrap(); + + let should_succeed = func_ty_to_try == actual_func_ty; + let link_res = module.clone().instantiate(&mut store, Some(imports)); + + assert_eq!(link_res.is_ok(), should_succeed); + } + } + Ok(()) +} + +#[test] +fn test_linking_invalid_typed_func() -> Result<()> { + type Existing = (i32, i32, f64); + type NonMatchingOne = f64; + type NonMatchingMul = (f64, i32, i32); + const DONT_CALL: &str = "not meant to be called"; + + // they don't match any signature from get_modules() + #[rustfmt::skip] // to make it table-like + let matching_none= &[ + Extern::typed_func(|_, _: NonMatchingMul| -> tinywasm::Result { panic!("{DONT_CALL}") } ), + Extern::typed_func(|_, _: NonMatchingMul| -> tinywasm::Result<()> { panic!("{DONT_CALL}") } ), + Extern::typed_func(|_, _: NonMatchingOne| -> tinywasm::Result { panic!("{DONT_CALL}") } ), + Extern::typed_func(|_, _: NonMatchingOne| -> tinywasm::Result<()> { panic!("{DONT_CALL}") } ), + Extern::typed_func(|_, _: Existing | -> tinywasm::Result { panic!("{DONT_CALL}") } ), + Extern::typed_func(|_, _: Existing | -> tinywasm::Result { panic!("{DONT_CALL}") } ), + Extern::typed_func(|_, _: () | -> tinywasm::Result { panic!("{DONT_CALL}") } ), + Extern::typed_func(|_, _: () | -> tinywasm::Result { panic!("{DONT_CALL}") } ), + Extern::typed_func(|_, _: NonMatchingOne| -> tinywasm::Result { panic!("{DONT_CALL}") } ), + Extern::typed_func(|_, _: NonMatchingOne| -> tinywasm::Result { panic!("{DONT_CALL}") } ), + ]; + + let mod_list = get_modules(); + for (module, _, _) in mod_list { + for typed_fn in matching_none.clone() { + let mut store = Store::default(); + let mut imports = Imports::new(); + imports.define("host", "hfn", typed_fn).unwrap(); + let link_failure = module.clone().instantiate(&mut store, Some(imports)); + link_failure.expect_err("no func in matching_none list should link to any mod"); + } + } + + // the valid cases are well-checked in other tests + Ok(()) +} + +fn to_name(ty: &ValType) -> &str { + match ty { + ValType::I32 => "i32", + ValType::I64 => "i64", + ValType::F32 => "f32", + ValType::F64 => "f64", + ValType::V128 => "v128", + ValType::RefFunc => "funcref", + ValType::RefExtern => "externref", + } +} + +// make a module with imported function {module:"host", name:"hfn"} that takes specified results and returns specified params +// and 2 wasm functions: call_hfn takes params, passes them to hfn and returns it's results +// and 2 wasm functions: call_hfn_discard takes params, passes them to hfn and drops it's results +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| { + if list.is_empty() { + return "".to_string(); + } + let step = list.iter().map(|ty| format!("{} ", to_name(ty)).to_string()).collect::(); + format!("({keyword} {step})") + }; + + let results_text = join_surround(results, "result"); + let params_text = join_surround(params, "param"); + + // let params_gets: String = params.iter().enumerate().map(|(num, _)| format!("(local.get {num})\n")).collect(); + let params_gets: String = params.iter().enumerate().fold(String::new(), |mut acc, (num, _)| { + let _ = writeln!(acc, "(local.get {num})", num = num); + acc + }); + + let result_drops = "(drop)\n".repeat(results.len()).to_string(); + let wasm_text = format!( + r#"(module + (import "host" "hfn" (func $host_fn {params_text} {results_text})) + (func (export "call_hfn") {params_text} {results_text} + {params_gets} + (call $host_fn) + ) + (func (export "call_hfn_discard") {params_text} + {params_gets} + (call $host_fn) + {result_drops} + ) + ) + "# + ); + let wasm = wat::parse_str(wasm_text).expect("failed to parse wat"); + Module::parse_bytes(&wasm).expect("failed to make module") +} From 9f1bc8d77b5fa691eb64d851ff39f68a77b5032c Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Mon, 6 Jan 2025 21:40:21 +0100 Subject: [PATCH 34/54] feat: replace `RefNull` with new `FuncRef` and `ExternRef` structs Signed-off-by: Henry Gressmann --- CHANGELOG.md | 1 + Cargo.lock | 59 +++++---- crates/parser/src/conversion.rs | 8 +- crates/parser/src/lib.rs | 2 +- crates/tinywasm/src/func.rs | 18 ++- .../src/interpreter/stack/value_stack.rs | 12 +- crates/tinywasm/src/interpreter/values.rs | 16 +-- crates/tinywasm/src/module.rs | 1 + crates/tinywasm/src/store/mod.rs | 17 ++- crates/tinywasm/src/store/table.rs | 6 +- .../tests/host_func_signature_check.rs | 5 +- crates/tinywasm/tests/testsuite/util.rs | 27 ++-- crates/types/src/instructions.rs | 6 +- crates/types/src/value.rs | 122 ++++++++++++++---- 14 files changed, 192 insertions(+), 108 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e52cdc6..ab30d8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - **Breaking:**: New backwards-incompatible version of the twasm format (upgraded `rkyv` to 0.8.0) +- **Breaking:**: `RefNull` has been removed and replaced with new `FuncRef` and `ExternRef` structs - Increased MSRV to 1.83.0 ### Fixed diff --git a/Cargo.lock b/Cargo.lock index 5333d98..c31c41f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,19 +25,20 @@ checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "argh" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7af5ba06967ff7214ce4c7419c7d185be7ecd6cc4965a8f6e1d8ce0398aad219" +checksum = "34ff18325c8a36b82f992e533ece1ec9f9a9db446bd1c14d4f936bac88fcd240" dependencies = [ "argh_derive", "argh_shared", + "rust-fuzzy-search", ] [[package]] name = "argh_derive" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56df0aeedf6b7a2fc67d06db35b09684c3e8da0c95f8f27685cb17e08413d87a" +checksum = "adb7b2b83a50d329d5d8ccc620f5c7064028828538bdf5646acd60dc1f767803" dependencies = [ "argh_shared", "proc-macro2", @@ -47,9 +48,9 @@ dependencies = [ [[package]] name = "argh_shared" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5693f39141bda5760ecc4111ab08da40565d1771038c4a0250f03457ec707531" +checksum = "a464143cc82dedcdc3928737445362466b7674b5db4e2eb8e869846d6d84f4f6" dependencies = [ "serde", ] @@ -202,9 +203,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -221,9 +222,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" @@ -363,9 +364,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.167" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libm" @@ -473,9 +474,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -577,6 +578,12 @@ dependencies = [ "syn", ] +[[package]] +name = "rust-fuzzy-search" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a157657054ffe556d8858504af8a672a054a6e0bd9e8ee531059100c0fa11bb2" + [[package]] name = "ryu" version = "1.0.18" @@ -594,24 +601,24 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" [[package]] name = "serde" -version = "1.0.215" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.215" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", @@ -620,9 +627,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.133" +version = "1.0.134" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" +checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" dependencies = [ "itoa", "memchr", @@ -638,9 +645,9 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "syn" -version = "2.0.90" +version = "2.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" dependencies = [ "proc-macro2", "quote", @@ -668,9 +675,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" dependencies = [ "tinyvec_macros", ] diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs index 1ebe392..273dd44 100644 --- a/crates/parser/src/conversion.rs +++ b/crates/parser/src/conversion.rs @@ -251,8 +251,12 @@ pub(crate) fn process_const_operators(ops: OperatorsReader<'_>) -> Result Ok(ConstInstruction::RefNull(convert_heaptype(*hty))), - wasmparser::Operator::RefFunc { function_index } => Ok(ConstInstruction::RefFunc(*function_index)), + wasmparser::Operator::RefNull { hty } => match convert_heaptype(*hty) { + ValType::RefFunc => Ok(ConstInstruction::RefFunc(None)), + ValType::RefExtern => Ok(ConstInstruction::RefExtern(None)), + _ => unimplemented!("Unsupported heap type: {:?}", hty), + }, + wasmparser::Operator::RefFunc { function_index } => Ok(ConstInstruction::RefFunc(Some(*function_index))), wasmparser::Operator::I32Const { value } => Ok(ConstInstruction::I32Const(*value)), wasmparser::Operator::I64Const { value } => Ok(ConstInstruction::I64Const(*value)), wasmparser::Operator::F32Const { value } => Ok(ConstInstruction::F32Const(f32::from_bits(value.bits()))), diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index dcb05f0..04da9da 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -65,6 +65,7 @@ impl Parser { memory64: true, custom_page_sizes: true, + extended_const: false, wide_arithmetic: false, gc_types: true, stack_switching: false, @@ -73,7 +74,6 @@ impl Parser { component_model_values: false, component_model_more_flags: false, exceptions: false, - extended_const: false, gc: false, memory_control: false, relaxed_simd: false, diff --git a/crates/tinywasm/src/func.rs b/crates/tinywasm/src/func.rs index 47a2cdf..f5a9873 100644 --- a/crates/tinywasm/src/func.rs +++ b/crates/tinywasm/src/func.rs @@ -2,7 +2,7 @@ use crate::interpreter::stack::{CallFrame, Stack}; use crate::{log, unlikely, Function}; use crate::{Error, FuncContext, Result, Store}; use alloc::{boxed::Box, format, string::String, string::ToString, vec, vec::Vec}; -use tinywasm_types::{FuncType, ModuleInstanceAddr, ValType, WasmValue}; +use tinywasm_types::{ExternRef, FuncRef, FuncType, ModuleInstanceAddr, ValType, WasmValue}; #[derive(Debug)] /// A function handle @@ -219,6 +219,18 @@ impl ToValType for f64 { } } +impl ToValType for FuncRef { + fn to_val_type() -> ValType { + ValType::RefFunc + } +} + +impl ToValType for ExternRef { + fn to_val_type() -> ValType { + ValType::RefExtern + } +} + macro_rules! impl_val_types_from_tuple { ($($t:ident),+) => { impl<$($t),+> ValTypesFromTuple for ($($t,)+) @@ -251,11 +263,15 @@ impl_from_wasm_value_tuple_single!(i32); impl_from_wasm_value_tuple_single!(i64); impl_from_wasm_value_tuple_single!(f32); impl_from_wasm_value_tuple_single!(f64); +impl_from_wasm_value_tuple_single!(FuncRef); +impl_from_wasm_value_tuple_single!(ExternRef); impl_into_wasm_value_tuple_single!(i32); impl_into_wasm_value_tuple_single!(i64); impl_into_wasm_value_tuple_single!(f32); impl_into_wasm_value_tuple_single!(f64); +impl_into_wasm_value_tuple_single!(FuncRef); +impl_into_wasm_value_tuple_single!(ExternRef); impl_val_types_from_tuple!(T1); impl_val_types_from_tuple!(T1, T2); diff --git a/crates/tinywasm/src/interpreter/stack/value_stack.rs b/crates/tinywasm/src/interpreter/stack/value_stack.rs index ab739a3..ea6a082 100644 --- a/crates/tinywasm/src/interpreter/stack/value_stack.rs +++ b/crates/tinywasm/src/interpreter/stack/value_stack.rs @@ -1,5 +1,5 @@ use alloc::vec::Vec; -use tinywasm_types::{ValType, ValueCounts, ValueCountsSmall, WasmValue}; +use tinywasm_types::{ExternRef, FuncRef, ValType, ValueCounts, ValueCountsSmall, WasmValue}; use crate::{interpreter::*, Result}; @@ -173,14 +173,8 @@ impl ValueStack { ValType::V128 => WasmValue::V128(self.pop()), ValType::F32 => WasmValue::F32(self.pop()), ValType::F64 => WasmValue::F64(self.pop()), - ValType::RefExtern => match self.pop() { - Some(v) => WasmValue::RefExtern(v), - None => WasmValue::RefNull(ValType::RefExtern), - }, - ValType::RefFunc => match self.pop() { - Some(v) => WasmValue::RefFunc(v), - None => WasmValue::RefNull(ValType::RefFunc), - }, + ValType::RefExtern => WasmValue::RefExtern(ExternRef::new(self.pop())), + ValType::RefFunc => WasmValue::RefFunc(FuncRef::new(self.pop())), } } diff --git a/crates/tinywasm/src/interpreter/values.rs b/crates/tinywasm/src/interpreter/values.rs index efee9b8..712baf7 100644 --- a/crates/tinywasm/src/interpreter/values.rs +++ b/crates/tinywasm/src/interpreter/values.rs @@ -1,5 +1,5 @@ use crate::Result; -use tinywasm_types::{LocalAddr, ValType, WasmValue}; +use tinywasm_types::{ExternRef, FuncRef, LocalAddr, ValType, WasmValue}; use super::stack::{Locals, ValueStack}; @@ -107,14 +107,8 @@ impl TinyWasmValue { ValType::F32 => WasmValue::F32(f32::from_bits(self.unwrap_32())), ValType::F64 => WasmValue::F64(f64::from_bits(self.unwrap_64())), ValType::V128 => WasmValue::V128(self.unwrap_128()), - ValType::RefExtern => match self.unwrap_ref() { - Some(v) => WasmValue::RefExtern(v), - None => WasmValue::RefNull(ValType::RefExtern), - }, - ValType::RefFunc => match self.unwrap_ref() { - Some(v) => WasmValue::RefFunc(v), - None => WasmValue::RefNull(ValType::RefFunc), - }, + ValType::RefExtern => WasmValue::RefExtern(ExternRef::new(self.unwrap_ref())), + ValType::RefFunc => WasmValue::RefFunc(FuncRef::new(self.unwrap_ref())), } } } @@ -127,8 +121,8 @@ impl From<&WasmValue> for TinyWasmValue { WasmValue::V128(v) => TinyWasmValue::Value128(*v), WasmValue::F32(v) => TinyWasmValue::Value32(v.to_bits()), WasmValue::F64(v) => TinyWasmValue::Value64(v.to_bits()), - WasmValue::RefFunc(v) | WasmValue::RefExtern(v) => TinyWasmValue::ValueRef(Some(*v)), - WasmValue::RefNull(_) => TinyWasmValue::ValueRef(None), + WasmValue::RefExtern(v) => TinyWasmValue::ValueRef(v.addr()), + WasmValue::RefFunc(v) => TinyWasmValue::ValueRef(v.addr()), } } } diff --git a/crates/tinywasm/src/module.rs b/crates/tinywasm/src/module.rs index f6e8e04..26cea9c 100644 --- a/crates/tinywasm/src/module.rs +++ b/crates/tinywasm/src/module.rs @@ -47,6 +47,7 @@ impl Module { /// Instantiate the module in the given store /// /// Runs the start function if it exists + /// /// If you want to run the start function yourself, use `ModuleInstance::instantiate` /// /// See diff --git a/crates/tinywasm/src/store/mod.rs b/crates/tinywasm/src/store/mod.rs index d4bbf33..86cbb5d 100644 --- a/crates/tinywasm/src/store/mod.rs +++ b/crates/tinywasm/src/store/mod.rs @@ -278,12 +278,13 @@ impl Store { fn elem_addr(&self, item: &ElementItem, globals: &[Addr], funcs: &[FuncAddr]) -> Result> { let res = match item { - ElementItem::Func(addr) | ElementItem::Expr(ConstInstruction::RefFunc(addr)) => { + ElementItem::Func(addr) | ElementItem::Expr(ConstInstruction::RefFunc(Some(addr))) => { Some(funcs.get(*addr as usize).copied().ok_or_else(|| { Error::Other(format!("function {addr} not found. This should have been caught by the validator")) })?) } - ElementItem::Expr(ConstInstruction::RefNull(_ty)) => None, + ElementItem::Expr(ConstInstruction::RefFunc(None)) => None, + ElementItem::Expr(ConstInstruction::RefExtern(None)) => None, ElementItem::Expr(ConstInstruction::GlobalGet(addr)) => { let addr = globals.get(*addr as usize).copied().ok_or_else(|| { Error::Other(format!("global {addr} not found. This should have been caught by the validator")) @@ -450,10 +451,14 @@ impl Store { self.data.globals.get(*addr as usize).expect("global not found. This should be unreachable"); global.value.get() } - RefNull(t) => t.default_value().into(), - RefFunc(idx) => TinyWasmValue::ValueRef(Some(*module_func_addrs.get(*idx as usize).ok_or_else(|| { - Error::Other(format!("function {idx} not found. This should have been caught by the validator")) - })?)), + RefFunc(None) => TinyWasmValue::ValueRef(None), + RefExtern(None) => TinyWasmValue::ValueRef(None), + RefFunc(Some(idx)) => { + TinyWasmValue::ValueRef(Some(*module_func_addrs.get(*idx as usize).ok_or_else(|| { + Error::Other(format!("function {idx} not found. This should have been caught by the validator")) + })?)) + } + _ => return Err(Error::Other("unsupported const instruction".to_string())), }; Ok(val) } diff --git a/crates/tinywasm/src/store/table.rs b/crates/tinywasm/src/store/table.rs index 5520faf..0cbd054 100644 --- a/crates/tinywasm/src/store/table.rs +++ b/crates/tinywasm/src/store/table.rs @@ -30,8 +30,8 @@ impl TableInstance { let val = self.get(addr)?.addr(); Ok(match self.kind.element_type { - ValType::RefFunc => val.map_or(WasmValue::RefNull(ValType::RefFunc), WasmValue::RefFunc), - ValType::RefExtern => val.map_or(WasmValue::RefNull(ValType::RefExtern), WasmValue::RefExtern), + ValType::RefFunc => WasmValue::RefFunc(FuncRef::new(val)), + ValType::RefExtern => WasmValue::RefExtern(ExternRef::new(val)), _ => Err(Error::UnsupportedFeature("non-ref table".into()))?, }) } @@ -211,7 +211,7 @@ mod tests { } match table_instance.get_wasm_val(1) { - Ok(WasmValue::RefNull(ValType::RefFunc)) => {} + Ok(WasmValue::RefFunc(f)) if f.is_null() => {} _ => panic!("get_wasm_val failed to return the correct WasmValue"), } diff --git a/crates/tinywasm/tests/host_func_signature_check.rs b/crates/tinywasm/tests/host_func_signature_check.rs index 787b24a..c60ade2 100644 --- a/crates/tinywasm/tests/host_func_signature_check.rs +++ b/crates/tinywasm/tests/host_func_signature_check.rs @@ -4,6 +4,7 @@ use tinywasm::{ types::{FuncType, ValType, WasmValue}, Extern, FuncContext, Imports, Module, Store, }; +use tinywasm_types::ExternRef; const VAL_LISTS: &[&[WasmValue]] = &[ &[], @@ -11,7 +12,7 @@ const VAL_LISTS: &[&[WasmValue]] = &[ &[WasmValue::I32(0), WasmValue::I32(0)], // 2 of the same &[WasmValue::I32(0), WasmValue::I32(0), WasmValue::F64(0.0)], // add another type &[WasmValue::I32(0), WasmValue::F64(0.0), WasmValue::I32(0)], // reorder - &[WasmValue::RefExtern(0), WasmValue::F64(0.0), WasmValue::I32(0)], // all different types + &[WasmValue::RefExtern(ExternRef::null()), WasmValue::F64(0.0), WasmValue::I32(0)], // all different types ]; // (f64, i32, i32) and (f64) can be used to "match_none" @@ -37,7 +38,6 @@ fn test_return_invalid_type() -> Result<()> { for (module, func_ty, test_args) in mod_list { for result_to_try in VAL_LISTS { - println!("trying"); let mut store = Store::default(); let mut imports = Imports::new(); imports @@ -146,7 +146,6 @@ fn proxy_module(func_ty: &FuncType) -> Module { let results_text = join_surround(results, "result"); let params_text = join_surround(params, "param"); - // let params_gets: String = params.iter().enumerate().map(|(num, _)| format!("(local.get {num})\n")).collect(); let params_gets: String = params.iter().enumerate().fold(String::new(), |mut acc, (num, _)| { let _ = writeln!(acc, "(local.get {num})", num = num); acc diff --git a/crates/tinywasm/tests/testsuite/util.rs b/crates/tinywasm/tests/testsuite/util.rs index e3aafcb..b555153 100644 --- a/crates/tinywasm/tests/testsuite/util.rs +++ b/crates/tinywasm/tests/testsuite/util.rs @@ -1,9 +1,9 @@ use std::panic::{self, AssertUnwindSafe}; use eyre::{bail, eyre, Result}; -use tinywasm_types::{ModuleInstanceAddr, TinyWasmModule, ValType, WasmValue}; -use wasm_testsuite::wast::{core::AbstractHeapType, QuoteWat}; +use tinywasm_types::{ExternRef, FuncRef, ModuleInstanceAddr, TinyWasmModule, ValType, WasmValue}; use wasm_testsuite::wast; +use wasm_testsuite::wast::{core::AbstractHeapType, QuoteWat}; pub fn try_downcast_panic(panic: Box) -> String { let info = panic.downcast_ref::().or(None).map(ToString::to_string).clone(); @@ -103,13 +103,13 @@ fn wastarg2tinywasmvalue(arg: wast::WastArg) -> Result WasmValue::I32(i), I64(i) => WasmValue::I64(i), V128(i) => WasmValue::V128(i128::from_le_bytes(i.to_le_bytes()).try_into().unwrap()), - RefExtern(v) => WasmValue::RefExtern(v), + RefExtern(v) => WasmValue::RefExtern(ExternRef::new(Some(v))), RefNull(t) => match t { wast::core::HeapType::Abstract { shared: false, ty: AbstractHeapType::Func } => { - WasmValue::RefNull(ValType::RefFunc) + WasmValue::RefFunc(FuncRef::null()) } wast::core::HeapType::Abstract { shared: false, ty: AbstractHeapType::Extern } => { - WasmValue::RefNull(ValType::RefExtern) + WasmValue::RefExtern(ExternRef::null()) } _ => bail!("unsupported arg type: refnull: {:?}", t), }, @@ -146,23 +146,18 @@ fn wastret2tinywasmvalue(ret: wast::WastRet) -> Result WasmValue::V128(wast_i128_to_i128(i)), RefNull(t) => match t { Some(wast::core::HeapType::Abstract { shared: false, ty: AbstractHeapType::Func }) => { - WasmValue::RefNull(ValType::RefFunc) + WasmValue::RefFunc(FuncRef::null()) } Some(wast::core::HeapType::Abstract { shared: false, ty: AbstractHeapType::Extern }) => { - WasmValue::RefNull(ValType::RefExtern) + WasmValue::RefExtern(ExternRef::null()) } _ => bail!("unsupported arg type: refnull: {:?}", t), }, - RefExtern(v) => match v { - Some(v) => WasmValue::RefExtern(v), - None => WasmValue::RefNull(ValType::RefExtern), - _ => bail!("unsupported arg type: refextern: {:?}", v), - }, - RefFunc(v) => match v { - Some(wast::token::Index::Num(n, _)) => WasmValue::RefFunc(n), - None => WasmValue::RefNull(ValType::RefFunc), + RefExtern(v) => WasmValue::RefExtern(ExternRef::new(v)), + RefFunc(v) => WasmValue::RefFunc(FuncRef::new(match v { + Some(wast::token::Index::Num(n, _)) => Some(n), _ => bail!("unsupported arg type: reffunc: {:?}", v), - }, + })), a => bail!("unsupported arg type {:?}", a), }) } diff --git a/crates/types/src/instructions.rs b/crates/types/src/instructions.rs index fb3c1cc..8f77b31 100644 --- a/crates/types/src/instructions.rs +++ b/crates/types/src/instructions.rs @@ -1,5 +1,5 @@ use super::{FuncAddr, GlobalAddr, LabelAddr, LocalAddr, TableAddr, TypeAddr, ValType}; -use crate::{ConstIdx, DataAddr, ElemAddr, MemAddr}; +use crate::{ConstIdx, DataAddr, ElemAddr, ExternAddr, MemAddr}; /// Represents a memory immediate in a WebAssembly memory instruction. #[derive(Debug, Copy, Clone, PartialEq)] @@ -37,8 +37,8 @@ pub enum ConstInstruction { F32Const(f32), F64Const(f64), GlobalGet(GlobalAddr), - RefNull(ValType), - RefFunc(FuncAddr), + RefFunc(Option), + RefExtern(Option), } /// A WebAssembly Instruction diff --git a/crates/types/src/value.rs b/crates/types/src/value.rs index 8bbcaf2..6651c0e 100644 --- a/crates/types/src/value.rs +++ b/crates/types/src/value.rs @@ -19,12 +19,92 @@ pub enum WasmValue { // /// A 128-bit vector V128(u128), - RefExtern(ExternAddr), - RefFunc(FuncAddr), - RefNull(ValType), + RefExtern(ExternRef), + RefFunc(FuncRef), +} + +#[derive(Clone, Copy, PartialEq)] +pub struct ExternRef(Option); + +#[derive(Clone, Copy, PartialEq)] +pub struct FuncRef(Option); + +impl Debug for ExternRef { + fn fmt(&self, f: &mut alloc::fmt::Formatter<'_>) -> alloc::fmt::Result { + match self.0 { + Some(addr) => write!(f, "extern({:?})", addr), + None => write!(f, "extern(null)"), + } + } +} + +impl Debug for FuncRef { + fn fmt(&self, f: &mut alloc::fmt::Formatter<'_>) -> alloc::fmt::Result { + match self.0 { + Some(addr) => write!(f, "func({:?})", addr), + None => write!(f, "func(null)"), + } + } +} + +impl FuncRef { + /// Create a new `FuncRef` from a `FuncAddr`. + /// Should only be used by the runtime. + #[doc(hidden)] + #[inline] + pub const fn new(addr: Option) -> Self { + Self(addr) + } + + /// Create a null `FuncRef`. + #[inline] + pub const fn null() -> Self { + Self(None) + } + + /// Check if the `FuncRef` is null. + #[inline] + pub const fn is_null(&self) -> bool { + self.0.is_none() + } + + /// Get the `FuncAddr` from the `FuncRef`. + #[inline] + pub const fn addr(&self) -> Option { + self.0 + } +} + +impl ExternRef { + /// Create a new `ExternRef` from an `ExternAddr`. + /// Should only be used by the runtime. + #[doc(hidden)] + #[inline] + pub const fn new(addr: Option) -> Self { + Self(addr) + } + + /// Create a null `ExternRef`. + #[inline] + pub const fn null() -> Self { + Self(None) + } + + /// Check if the `ExternRef` is null. + #[inline] + pub const fn is_null(&self) -> bool { + self.0.is_none() + } + + /// Get the `ExternAddr` from the `ExternRef`. + #[inline] + pub const fn addr(&self) -> Option { + self.0 + } } impl WasmValue { + #[doc(hidden)] #[inline] pub fn const_instr(&self) -> ConstInstruction { match self { @@ -32,10 +112,7 @@ impl WasmValue { Self::I64(i) => ConstInstruction::I64Const(*i), Self::F32(i) => ConstInstruction::F32Const(*i), Self::F64(i) => ConstInstruction::F64Const(*i), - Self::RefFunc(i) => ConstInstruction::RefFunc(*i), - Self::RefNull(ty) => ConstInstruction::RefNull(*ty), - - // Self::RefExtern(addr) => ConstInstruction::RefExtern(*addr), + Self::RefFunc(i) => ConstInstruction::RefFunc(i.addr()), _ => unimplemented!("no const_instr for {:?}", self), } } @@ -49,17 +126,17 @@ impl WasmValue { ValType::F32 => Self::F32(0.0), ValType::F64 => Self::F64(0.0), ValType::V128 => Self::V128(0), - ValType::RefFunc => Self::RefNull(ValType::RefFunc), - ValType::RefExtern => Self::RefNull(ValType::RefExtern), + ValType::RefFunc => Self::RefFunc(FuncRef::null()), + ValType::RefExtern => Self::RefExtern(ExternRef::null()), } } + /// Check if two values are equal, ignoring differences in NaN values. #[inline] pub fn eq_loose(&self, other: &Self) -> bool { match (self, other) { (Self::I32(a), Self::I32(b)) => a == b, (Self::I64(a), Self::I64(b)) => a == b, - (Self::RefNull(v), Self::RefNull(v2)) => v == v2, (Self::RefExtern(addr), Self::RefExtern(addr2)) => addr == addr2, (Self::RefFunc(addr), Self::RefFunc(addr2)) => addr == addr2, (Self::F32(a), Self::F32(b)) => { @@ -121,25 +198,17 @@ impl WasmValue { } #[doc(hidden)] - pub fn as_ref_extern(&self) -> Option { - match self { - Self::RefExtern(addr) => Some(*addr), - _ => None, - } - } - - #[doc(hidden)] - pub fn as_ref_func(&self) -> Option { + pub fn as_ref_extern(&self) -> Option { match self { - Self::RefFunc(addr) => Some(*addr), + Self::RefExtern(ref_extern) => Some(*ref_extern), _ => None, } } #[doc(hidden)] - pub fn as_ref_null(&self) -> Option { + pub fn as_ref_func(&self) -> Option { match self { - Self::RefNull(ty) => Some(*ty), + Self::RefFunc(ref_func) => Some(*ref_func), _ => None, } } @@ -156,9 +225,8 @@ impl Debug for WasmValue { WasmValue::F32(i) => write!(f, "f32({i})"), WasmValue::F64(i) => write!(f, "f64({i})"), WasmValue::V128(i) => write!(f, "v128({i:?})"), - WasmValue::RefExtern(addr) => write!(f, "ref.extern({addr:?})"), - WasmValue::RefFunc(addr) => write!(f, "ref.func({addr:?})"), - WasmValue::RefNull(ty) => write!(f, "ref.null({ty:?})"), + WasmValue::RefExtern(i) => write!(f, "ref({i:?})"), + WasmValue::RefFunc(i) => write!(f, "func({i:?})"), } } } @@ -175,7 +243,6 @@ impl WasmValue { Self::V128(_) => ValType::V128, Self::RefExtern(_) => ValType::RefExtern, Self::RefFunc(_) => ValType::RefFunc, - Self::RefNull(ty) => *ty, } } } @@ -206,6 +273,7 @@ impl ValType { WasmValue::default_for(*self) } + #[doc(hidden)] #[inline] pub fn is_simd(&self) -> bool { matches!(self, ValType::V128) @@ -241,4 +309,4 @@ macro_rules! impl_conversion_for_wasmvalue { } } -impl_conversion_for_wasmvalue! { i32 => I32, i64 => I64, f32 => F32, f64 => F64, u128 => V128 } +impl_conversion_for_wasmvalue! { i32 => I32, i64 => I64, f32 => F32, f64 => F64, u128 => V128, ExternRef => RefExtern, FuncRef => RefFunc } From 1a64f4092af9304694e98f441b79f0a93ee1c194 Mon Sep 17 00:00:00 2001 From: WhaleKit Date: Tue, 14 Jan 2025 21:22:22 +0600 Subject: [PATCH 35/54] docs: reference types for typed functions (#28) --- examples/funcref_callbacks.rs | 152 ++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 examples/funcref_callbacks.rs diff --git a/examples/funcref_callbacks.rs b/examples/funcref_callbacks.rs new file mode 100644 index 0000000..08332cb --- /dev/null +++ b/examples/funcref_callbacks.rs @@ -0,0 +1,152 @@ +use eyre::Result; +use tinywasm::{types::FuncRef, Extern, FuncContext, Imports, Module, Store}; +use wat; + +fn main() -> Result<()> { + by_func_ref_passed()?; + by_func_ref_returned()?; + Ok(()) +} + +/// example of passing wasm functions (as funcref) to imported host function +/// and imported host function calling them +fn by_func_ref_passed() -> Result<()> { + // a module with: + // imported function "host.call_this" that accepts a callback + // exported wasm function "tell_host_to_call" that calls "host.call_this" with wasm functions $add and $sub + // wasm functions $add and $sub and imported function $mul used as callbacks + // (just to show that imported functions can be referenced too) + // exported wasm function "call_binop_by_ref" is a proxy used by host to call func-references of type (i32, i32)->i32 + const WASM: &str = r#" + (module + (import "host" "call_this" (func $host_callback_caller (param funcref))) + (import "host" "mul" (func $host_mul (param $x i32) (param $y i32) (result i32))) + + (func $tell_host_to_call (export "tell_host_to_call") + (call $host_callback_caller (ref.func $add)) + (call $host_callback_caller (ref.func $sub)) + (call $host_callback_caller (ref.func $host_mul)) + ) + + (type $binop (func (param i32 i32) (result i32))) + + (table 3 funcref) + (elem (i32.const 0) $add $sub $host_mul) ;; function can only be taken reference of if it's added to a table + (func $add (param $x i32) (param $y i32) (result i32) + local.get $x + local.get $y + i32.add + ) + (func $sub (param $x i32) (param $y i32) (result i32) + local.get $x + local.get $y + i32.sub + ) + + (table $callback_register 1 funcref) + (func (export "call_binop_by_ref") (param funcref i32 i32) (result i32) + (table.set $callback_register (i32.const 0) (local.get 0)) + (call_indirect $callback_register (type $binop) (local.get 1)(local.get 2)(i32.const 0)) + ) + ) + "#; + + let wasm = wat::parse_str(WASM).expect("failed to parse wat"); + let module = Module::parse_bytes(&wasm)?; + let mut store = Store::default(); + let mut imports = Imports::new(); + // import host function that takes callbacks and calls them + imports.define( + "host", + "call_this", + Extern::typed_func(|mut ctx: FuncContext<'_>, fn_ref: FuncRef| -> tinywasm::Result<()> { + let proxy_caller = + ctx.module().exported_func::<(FuncRef, i32, i32), i32>(ctx.store(), "call_binop_by_ref")?; + // call callback we got as argument using call_binop_by_ref + let res = proxy_caller.call(ctx.store_mut(), (fn_ref, 5, 3))?; + println!("(funcref {fn_ref:?})(5,3) results in {res}"); + + Ok(()) + }), + )?; + // import host.mul function (one of the functions whose references are taken) + imports.define( + "host", + "mul", + Extern::typed_func(|_, args: (i32, i32)| -> tinywasm::Result { Ok(args.0 * args.1) }), + )?; + let instance = module.instantiate(&mut store, Some(imports))?; + let caller = instance.exported_func::<(), ()>(&mut store, "tell_host_to_call")?; + // call the tell_host_to_call + caller.call(&mut store, ())?; + // interesting detail is that neither $add $sub $mul were exported, + // but with a little help from proxy "call_binop_by_ref" references to them host was able to call them + Ok(()) +} + +/// example of returning wasm function as callback to host function +/// and host function calling it +fn by_func_ref_returned() -> Result<()> { + // a module with: + // an exported function "what_should_host_call" that returns 3 funcrefs + // wasm functions $add and $sub and imported function $mul used as callbacks + // (just to show that imported functions can be referenced too) + // exported wasm function "call_binop_by_ref" is a proxy used by host to call func-references of type (i32, i32)->i32 + const WASM: &str = r#" + (module + (import "host" "mul" (func $host_mul (param $x i32) (param $y i32) (result i32))) + (type $binop (func (param i32 i32) (result i32))) + (table 3 funcref) + (elem (i32.const 0) $add $sub $host_mul) + (func $add (param $x i32) (param $y i32) (result i32) + local.get $x + local.get $y + i32.add + ) + (func $sub (param $x i32) (param $y i32) (result i32) + local.get $x + local.get $y + i32.sub + ) + (func $ref_to_funcs (export "what_should_host_call") (result funcref funcref funcref) + (ref.func $add) + (ref.func $sub) + (ref.func $host_mul) + ) + + (table $callback_register 1 funcref) + (func $call (export "call_binop_by_ref") (param funcref i32 i32) (result i32) + (table.set $callback_register (i32.const 0) (local.get 0)) + (call_indirect $callback_register (type $binop) (local.get 1)(local.get 2)(i32.const 0)) + ) + ) + "#; + + let wasm = wat::parse_str(WASM).expect("failed to parse wat"); + let module = Module::parse_bytes(&wasm)?; + let mut store = Store::default(); + let mut imports = Imports::new(); + // import host.mul function (one of the possible operations) + imports.define( + "host", + "mul", + Extern::typed_func(|_, args: (i32, i32)| -> tinywasm::Result { Ok(args.0 * args.1) }), + )?; + + let instance = module.instantiate(&mut store, Some(imports))?; + { + // ask module what should we call + let funcrefs = { + let address_getter = + instance.exported_func::<(), (FuncRef, FuncRef, FuncRef)>(&mut store, "what_should_host_call")?; + address_getter.call(&mut store, ())? + }; + let proxy_caller = instance.exported_func::<(FuncRef, i32, i32), i32>(&mut store, "call_binop_by_ref")?; + for (idx, func_ref) in [funcrefs.0, funcrefs.1, funcrefs.2].iter().enumerate() { + // call those funcrefs via "call_binop_by_ref" + let res = proxy_caller.call(&mut store, (*func_ref, 5, 3))?; + println!("at idx: {idx} funcref {func_ref:?}(5,3) results in {res}"); + } + } + Ok(()) +} From 40e570cf8bdd948c1e7e9dd85e5ac24d9a062d2a Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Tue, 14 Jan 2025 17:41:29 +0100 Subject: [PATCH 36/54] chore: update deps, spelling Signed-off-by: Henry Gressmann --- Cargo.lock | 52 +++++++++--- Cargo.toml | 4 +- README.md | 17 ++-- crates/parser/Cargo.toml | 2 +- crates/tinywasm/tests/test-wasm-3.rs | 2 +- crates/tinywasm/tests/testsuite/run.rs | 4 +- crates/tinywasm/tests/testsuite/util.rs | 12 +-- examples/archive.rs | 6 +- examples/funcref_callbacks.rs | 101 +++++++++++++----------- examples/linking.rs | 9 +++ examples/wasm-rust.rs | 3 +- 11 files changed, 129 insertions(+), 83 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c31c41f..d7b7d99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -704,7 +704,7 @@ dependencies = [ "tinywasm-parser", "tinywasm-types", "wasm-testsuite", - "wast", + "wast 223.0.0", "wat", ] @@ -717,7 +717,7 @@ dependencies = [ "log", "pretty_env_logger", "tinywasm", - "wast", + "wast 223.0.0", ] [[package]] @@ -726,7 +726,7 @@ version = "0.9.0-alpha.0" dependencies = [ "log", "tinywasm-types", - "wasmparser", + "wasmparser 0.223.0", ] [[package]] @@ -782,7 +782,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3432682105d7e994565ef928ccf5856cf6af4ba3dddebedb737f61caed70f956" dependencies = [ "leb128", - "wasmparser", + "wasmparser 0.222.0", +] + +[[package]] +name = "wasm-encoder" +version = "0.223.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e636076193fa68103e937ac951b5f2f587624097017d764b8984d9c0f149464" +dependencies = [ + "leb128", + "wasmparser 0.223.0", ] [[package]] @@ -792,7 +802,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d01e1e4857b055d8ad6d542d95074106b5b2afd411d3e26ae6da37a560053c97" dependencies = [ "include_dir", - "wast", + "wast 222.0.0", ] [[package]] @@ -806,6 +816,17 @@ dependencies = [ "semver", ] +[[package]] +name = "wasmparser" +version = "0.223.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5a99faceb1a5a84dd6084ec4bfa4b2ab153b5793b43fd8f58b89232634afc35" +dependencies = [ + "bitflags", + "indexmap", + "semver", +] + [[package]] name = "wast" version = "222.0.0" @@ -816,16 +837,29 @@ dependencies = [ "leb128", "memchr", "unicode-width", - "wasm-encoder", + "wasm-encoder 0.222.0", +] + +[[package]] +name = "wast" +version = "223.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59b2ba8a2ff9f06194b7be9524f92e45e70149f4dacc0d0c7ad92b59ac875e4" +dependencies = [ + "bumpalo", + "leb128", + "memchr", + "unicode-width", + "wasm-encoder 0.223.0", ] [[package]] name = "wat" -version = "1.222.0" +version = "1.223.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fde61b4b52f9a84ae31b5e8902a2cd3162ea45d8bf564c729c3288fe52f4334" +checksum = "662786915c427e4918ff01eabb3c4756d4d947cd8f635761526b4cc9da2eaaad" dependencies = [ - "wast", + "wast 223.0.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 0c2f571..119dc45 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,8 +4,8 @@ default-members=[".", "crates/tinywasm", "crates/types", "crates/parser"] resolver="2" [workspace.dependencies] -wast="222" -wat="1.222" +wast="223" +wat="1.223" eyre="0.6" log="0.4" pretty_env_logger="0.5" diff --git a/README.md b/README.md index a963ea7..8db5a84 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ - **Tiny**: TinyWasm is designed to be as small as possible without significantly compromising performance or functionality (< 4000 LLOC). - **Portable**: TinyWasm runs on any platform that Rust can target, including `no_std`, with minimal external dependencies. -- **Safe**: No unsafe code is used in the runtime (`rkyv` which uses unsafe code can be used for serialization, but is optional). +- **Safe**: No unsafe code is used in the runtime (`rkyv`, which uses unsafe code, can be used for serialization but is optional). ## Status @@ -24,7 +24,7 @@ TinyWasm passes all WebAssembly MVP tests from the [WebAssembly core testsuite]( **Legend**\ 🌑 -- not available\ -🚧 -- in development / partialy supported\ +🚧 -- in development/partially supported\ 🟢 -- fully supported | Proposal | Status | TinyWasm Version | @@ -61,24 +61,21 @@ $ tinywasm-cli --help - **`archive`**\ Enables pre-parsing of archives. This is enabled by default. -With all these features disabled, TinyWasm only depends on `core`, `alloc` ,and `libm` and can be used in `no_std` environments. -Since `libm` is not as performant as the compiler's math intrinsics, it is recommended to use the `std` feature if possible (at least [for now](https://github.com/rust-lang/rfcs/issues/2505)), especially on wasm32 targets. +With all these features disabled, TinyWasm only depends on `core`, `alloc`, and `libm` and can be used in `no_std` environments. Since `libm` is not as performant as the compiler's math intrinsics, it is recommended to use the `std` feature if possible (at least [for now](https://github.com/rust-lang/rfcs/issues/2505)), especially on `wasm32` targets. ## Inspiration Big thanks to the authors of the following projects, which have inspired and influenced TinyWasm: -- [wasmi](https://github.com/wasmi-labs/wasmi) - an efficient and lightweight WebAssembly interpreter that also runs on `no_std` environments -- [wasm3](https://github.com/wasm3/wasm3) - a high performance WebAssembly interpreter written in C -- [wazero](https://wazero.io/) - a zero-dependency WebAssembly interpreter written in go +- [wasmi](https://github.com/wasmi-labs/wasmi) - an efficient and lightweight WebAssembly interpreter that also runs in `no_std` environments +- [wasm3](https://github.com/wasm3/wasm3) - a high-performance WebAssembly interpreter written in C +- [wazero](https://wazero.io/) - a zero-dependency WebAssembly interpreter written in Go - [wain](https://github.com/rhysd/wain) - a zero-dependency WebAssembly interpreter written in Rust -I encourage you to check these projects out if you're looking for more mature and feature-complete WebAssembly Runtimes. +I encourage you to check these projects out if you're looking for more mature and feature-complete WebAssembly runtimes. ## License Licensed under either of [Apache License, Version 2.0](./LICENSE-APACHE) or [MIT license](./LICENSE-MIT) at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in TinyWasm by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. - -**Note:** The GitHub repository contains a Submodule (`crates/tinywasm-parser/data`) which is licensed only under the [Apache License, Version 2.0](https://github.com/WebAssembly/spec/blob/main/test/LICENSE). This data is generated from the [WebAssembly Specification](https://github.com/WebAssembly/spec/tree/main/test) and is only used for testing purposes and not included in the final binary. diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index 61224fd..f8eabb4 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -9,7 +9,7 @@ repository.workspace=true rust-version.workspace=true [dependencies] -wasmparser={version="0.222", default-features=false, features=["validate", "features", "simd"]} +wasmparser={version="0.223", default-features=false, features=["validate", "features", "simd"]} log={workspace=true, optional=true} tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false} diff --git a/crates/tinywasm/tests/test-wasm-3.rs b/crates/tinywasm/tests/test-wasm-3.rs index 0bd2cb0..a0e2543 100644 --- a/crates/tinywasm/tests/test-wasm-3.rs +++ b/crates/tinywasm/tests/test-wasm-3.rs @@ -4,7 +4,7 @@ use testsuite::TestSuite; use wasm_testsuite::data::{spec, SpecVersion}; fn main() -> Result<()> { - if std::env::args().find(|x| x == "--enable").is_none() { + if !std::env::args().any(|x| &x == "--enable") { println!("Skipping wasm-3 tests, use --enable to run"); return Ok(()); } diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index 7534142..0804266 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -8,8 +8,8 @@ use log::{debug, error, info}; use tinywasm::{Extern, Imports, ModuleInstance}; use tinywasm_types::{ExternVal, MemoryType, ModuleInstanceAddr, TableType, ValType, WasmValue}; use wasm_testsuite::data::TestFile; -use wasm_testsuite::wast::{lexer::Lexer, parser::ParseBuffer, Wast}; use wasm_testsuite::wast; +use wasm_testsuite::wast::{lexer::Lexer, parser::ParseBuffer, Wast}; #[derive(Default)] struct ModuleRegistry { @@ -171,7 +171,7 @@ impl TestSuite { Ok(()) } - pub fn run_file<'a>(&mut self, file: TestFile<'a>) -> Result<()> { + pub fn run_file(&mut self, file: TestFile<'_>) -> Result<()> { let test_group = self.test_group(file.name(), file.parent()); let wast_raw = file.raw(); let wast = file.wast()?; diff --git a/crates/tinywasm/tests/testsuite/util.rs b/crates/tinywasm/tests/testsuite/util.rs index b555153..f8f862b 100644 --- a/crates/tinywasm/tests/testsuite/util.rs +++ b/crates/tinywasm/tests/testsuite/util.rs @@ -120,15 +120,15 @@ fn wastarg2tinywasmvalue(arg: wast::WastArg) -> Result u128 { match i { wast::core::V128Pattern::F32x4(f) => { - f.iter().fold(0, |acc, &f| acc << 32 | nanpattern2tinywasmvalue(f).unwrap().as_f32().unwrap() as u128) + f.iter().fold(0, |acc, &f| (acc << 32) | nanpattern2tinywasmvalue(f).unwrap().as_f32().unwrap() as u128) } wast::core::V128Pattern::F64x2(f) => { - f.iter().fold(0, |acc, &f| acc << 64 | nanpattern2tinywasmvalue(f).unwrap().as_f64().unwrap() as u128) + f.iter().fold(0, |acc, &f| (acc << 64) | nanpattern2tinywasmvalue(f).unwrap().as_f64().unwrap() as u128) } - wast::core::V128Pattern::I16x8(f) => f.iter().fold(0, |acc, &f| acc << 16 | f as u128), - wast::core::V128Pattern::I32x4(f) => f.iter().fold(0, |acc, &f| acc << 32 | f as u128), - wast::core::V128Pattern::I64x2(f) => f.iter().fold(0, |acc, &f| acc << 64 | f as u128), - wast::core::V128Pattern::I8x16(f) => f.iter().fold(0, |acc, &f| acc << 8 | f as u128), + wast::core::V128Pattern::I16x8(f) => f.iter().fold(0, |acc, &f| (acc << 16) | f as u128), + wast::core::V128Pattern::I32x4(f) => f.iter().fold(0, |acc, &f| (acc << 32) | f as u128), + wast::core::V128Pattern::I64x2(f) => f.iter().fold(0, |acc, &f| (acc << 64) | f as u128), + wast::core::V128Pattern::I8x16(f) => f.iter().fold(0, |acc, &f| (acc << 8) | f as u128), } } diff --git a/examples/archive.rs b/examples/archive.rs index ea82c51..f1a19b6 100644 --- a/examples/archive.rs +++ b/examples/archive.rs @@ -11,12 +11,12 @@ const WASM: &str = r#" "#; fn main() -> Result<()> { - let wasm = wat::parse_str(WASM).expect("failed to parse wat"); + let wasm = wat::parse_str(WASM).expect("Failed to parse WAT"); let module = Parser::default().parse_module_bytes(wasm)?; let twasm = module.serialize_twasm(); - // now, you could e.g. write twasm to a file called `add.twasm` - // and load it later in a different program + // Now, you could e.g. write `twasm` to a file called `add.twasm` + // and load it later in a different program. let module: Module = TinyWasmModule::from_twasm(&twasm)?.into(); let mut store = Store::default(); diff --git a/examples/funcref_callbacks.rs b/examples/funcref_callbacks.rs index 08332cb..df50e75 100644 --- a/examples/funcref_callbacks.rs +++ b/examples/funcref_callbacks.rs @@ -1,6 +1,5 @@ use eyre::Result; use tinywasm::{types::FuncRef, Extern, FuncContext, Imports, Module, Store}; -use wat; fn main() -> Result<()> { by_func_ref_passed()?; @@ -8,30 +7,30 @@ fn main() -> Result<()> { Ok(()) } -/// example of passing wasm functions (as funcref) to imported host function -/// and imported host function calling them +/// Example of passing Wasm functions (as `funcref`) to an imported host function +/// and the imported host function calling them. fn by_func_ref_passed() -> Result<()> { - // a module with: - // imported function "host.call_this" that accepts a callback - // exported wasm function "tell_host_to_call" that calls "host.call_this" with wasm functions $add and $sub - // wasm functions $add and $sub and imported function $mul used as callbacks - // (just to show that imported functions can be referenced too) - // exported wasm function "call_binop_by_ref" is a proxy used by host to call func-references of type (i32, i32)->i32 + // A module with: + // - Imported function "host.call_this" that accepts a callback. + // - Exported Wasm function "tell_host_to_call" that calls "host.call_this" with Wasm functions $add and $sub. + // - Wasm functions $add and $sub and an imported function $mul used as callbacks + // (just to show that imported functions can be referenced too). + // - Exported Wasm function "call_binop_by_ref", a proxy used by the host to call func-references of type (i32, i32) -> i32. const WASM: &str = r#" (module (import "host" "call_this" (func $host_callback_caller (param funcref))) (import "host" "mul" (func $host_mul (param $x i32) (param $y i32) (result i32))) (func $tell_host_to_call (export "tell_host_to_call") - (call $host_callback_caller (ref.func $add)) - (call $host_callback_caller (ref.func $sub)) - (call $host_callback_caller (ref.func $host_mul)) + (call $host_callback_caller (ref.func $add)) + (call $host_callback_caller (ref.func $sub)) + (call $host_callback_caller (ref.func $host_mul)) ) (type $binop (func (param i32 i32) (result i32))) (table 3 funcref) - (elem (i32.const 0) $add $sub $host_mul) ;; function can only be taken reference of if it's added to a table + (elem (i32.const 0) $add $sub $host_mul) ;; Function can only be referenced if added to a table. (func $add (param $x i32) (param $y i32) (result i32) local.get $x local.get $y @@ -45,59 +44,63 @@ fn by_func_ref_passed() -> Result<()> { (table $callback_register 1 funcref) (func (export "call_binop_by_ref") (param funcref i32 i32) (result i32) - (table.set $callback_register (i32.const 0) (local.get 0)) + (table.set $callback_register (i32.const 0) (local.get 0)) (call_indirect $callback_register (type $binop) (local.get 1)(local.get 2)(i32.const 0)) ) ) "#; - let wasm = wat::parse_str(WASM).expect("failed to parse wat"); + let wasm = wat::parse_str(WASM).expect("Failed to parse WAT"); let module = Module::parse_bytes(&wasm)?; let mut store = Store::default(); let mut imports = Imports::new(); - // import host function that takes callbacks and calls them + + // Import host function that takes callbacks and calls them. imports.define( "host", "call_this", Extern::typed_func(|mut ctx: FuncContext<'_>, fn_ref: FuncRef| -> tinywasm::Result<()> { let proxy_caller = ctx.module().exported_func::<(FuncRef, i32, i32), i32>(ctx.store(), "call_binop_by_ref")?; - // call callback we got as argument using call_binop_by_ref + // Call the callback we got as an argument using "call_binop_by_ref". let res = proxy_caller.call(ctx.store_mut(), (fn_ref, 5, 3))?; println!("(funcref {fn_ref:?})(5,3) results in {res}"); Ok(()) }), )?; - // import host.mul function (one of the functions whose references are taken) + + // Import host.mul function (one of the functions whose references are taken). imports.define( "host", "mul", Extern::typed_func(|_, args: (i32, i32)| -> tinywasm::Result { Ok(args.0 * args.1) }), )?; + let instance = module.instantiate(&mut store, Some(imports))?; - let caller = instance.exported_func::<(), ()>(&mut store, "tell_host_to_call")?; - // call the tell_host_to_call + let caller = instance.exported_func::<(), ()>(&store, "tell_host_to_call")?; + + // Call "tell_host_to_call". caller.call(&mut store, ())?; - // interesting detail is that neither $add $sub $mul were exported, - // but with a little help from proxy "call_binop_by_ref" references to them host was able to call them + // An interesting detail is that neither $add, $sub, nor $mul were exported, + // but with a little help from the proxy "call_binop_by_ref", references to them are callable by the host. Ok(()) } -/// example of returning wasm function as callback to host function -/// and host function calling it +/// Example of returning a Wasm function as a callback to a host function +/// and the host function calling it. fn by_func_ref_returned() -> Result<()> { - // a module with: - // an exported function "what_should_host_call" that returns 3 funcrefs - // wasm functions $add and $sub and imported function $mul used as callbacks - // (just to show that imported functions can be referenced too) - // exported wasm function "call_binop_by_ref" is a proxy used by host to call func-references of type (i32, i32)->i32 + // A module with: + // - An exported function "what_should_host_call" that returns 3 `funcref`s. + // - Wasm functions $add and $sub and an imported function $mul used as callbacks + // (just to show that imported functions can be referenced too). + // - Another exported Wasm function "call_binop_by_ref", a proxy used by the host to call func-references of type (i32, i32) -> i32 const WASM: &str = r#" (module (import "host" "mul" (func $host_mul (param $x i32) (param $y i32) (result i32))) (type $binop (func (param i32 i32) (result i32))) (table 3 funcref) - (elem (i32.const 0) $add $sub $host_mul) + (elem (i32.const 0) $add $sub $host_mul) (func $add (param $x i32) (param $y i32) (result i32) local.get $x local.get $y @@ -109,24 +112,25 @@ fn by_func_ref_returned() -> Result<()> { i32.sub ) (func $ref_to_funcs (export "what_should_host_call") (result funcref funcref funcref) - (ref.func $add) - (ref.func $sub) + (ref.func $add) + (ref.func $sub) (ref.func $host_mul) ) (table $callback_register 1 funcref) (func $call (export "call_binop_by_ref") (param funcref i32 i32) (result i32) - (table.set $callback_register (i32.const 0) (local.get 0)) + (table.set $callback_register (i32.const 0) (local.get 0)) (call_indirect $callback_register (type $binop) (local.get 1)(local.get 2)(i32.const 0)) ) ) "#; - let wasm = wat::parse_str(WASM).expect("failed to parse wat"); + let wasm = wat::parse_str(WASM).expect("Failed to parse WAT"); let module = Module::parse_bytes(&wasm)?; let mut store = Store::default(); let mut imports = Imports::new(); - // import host.mul function (one of the possible operations) + + // Import host.mul function (one of the possible operations). imports.define( "host", "mul", @@ -134,19 +138,20 @@ fn by_func_ref_returned() -> Result<()> { )?; let instance = module.instantiate(&mut store, Some(imports))?; - { - // ask module what should we call - let funcrefs = { - let address_getter = - instance.exported_func::<(), (FuncRef, FuncRef, FuncRef)>(&mut store, "what_should_host_call")?; - address_getter.call(&mut store, ())? - }; - let proxy_caller = instance.exported_func::<(FuncRef, i32, i32), i32>(&mut store, "call_binop_by_ref")?; - for (idx, func_ref) in [funcrefs.0, funcrefs.1, funcrefs.2].iter().enumerate() { - // call those funcrefs via "call_binop_by_ref" - let res = proxy_caller.call(&mut store, (*func_ref, 5, 3))?; - println!("at idx: {idx} funcref {func_ref:?}(5,3) results in {res}"); - } + + // Ask the module what to call. + let funcrefs = { + let address_getter = + instance.exported_func::<(), (FuncRef, FuncRef, FuncRef)>(&store, "what_should_host_call")?; + address_getter.call(&mut store, ())? + }; + + let proxy_caller = instance.exported_func::<(FuncRef, i32, i32), i32>(&store, "call_binop_by_ref")?; + + for (idx, func_ref) in [funcrefs.0, funcrefs.1, funcrefs.2].iter().enumerate() { + // Call those `funcref`s via "call_binop_by_ref". + let res = proxy_caller.call(&mut store, (*func_ref, 5, 3))?; + println!("At idx: {idx}, funcref {func_ref:?}(5,3) results in {res}"); } Ok(()) } diff --git a/examples/linking.rs b/examples/linking.rs index d215898..f94773a 100644 --- a/examples/linking.rs +++ b/examples/linking.rs @@ -1,6 +1,7 @@ use eyre::Result; use tinywasm::{Module, Store}; +// WebAssembly module defining and exporting an `add` function. const WASM_ADD: &str = r#" (module (func $add (param $lhs i32) (param $rhs i32) (result i32) @@ -10,6 +11,7 @@ const WASM_ADD: &str = r#" (export "add" (func $add))) "#; +// WebAssembly module importing an `add` function and using it. const WASM_IMPORT: &str = r#" (module (import "adder" "add" (func $add (param i32 i32) (result i32))) @@ -29,13 +31,20 @@ fn main() -> Result<()> { let import_module = Module::parse_bytes(&wasm_import)?; let mut store = Store::default(); + + // Instantiate the `add` module. let add_instance = add_module.instantiate(&mut store, None)?; + // Link the `adder` namespace to the `add` module's instance. let mut imports = tinywasm::Imports::new(); imports.link_module("adder", add_instance.id())?; + + // Instantiate the `import` module with the linked imports. let import_instance = import_module.instantiate(&mut store, Some(imports))?; + // Call the `main` function, which uses the imported `add` function. let main = import_instance.exported_func::<(), i32>(&store, "main")?; assert_eq!(main.call(&mut store, ())?, 3); + Ok(()) } diff --git a/examples/wasm-rust.rs b/examples/wasm-rust.rs index 89203c1..429bdcb 100644 --- a/examples/wasm-rust.rs +++ b/examples/wasm-rust.rs @@ -14,7 +14,8 @@ use tinywasm::{Extern, FuncContext, Imports, MemoryStringExt, Module, Store}; /// ./examples/rust/build.sh /// ``` /// -/// This requires the `wasm32-unknown-unknown` target, `binaryen` and `wabt` to be installed. +/// This requires the `wasm32-unknown-unknown` target, `binaryen`, and `wabt` to be installed: +/// /// `rustup target add wasm32-unknown-unknown`. /// /// From 83ffeb62071e28db5e4f57de21bbd8faa65ea1d9 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Thu, 16 Jan 2025 14:32:09 +0100 Subject: [PATCH 37/54] chore: expose rkyv errors Signed-off-by: Henry Gressmann --- crates/types/src/archive.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/crates/types/src/archive.rs b/crates/types/src/archive.rs index cc60314..30b54c7 100644 --- a/crates/types/src/archive.rs +++ b/crates/types/src/archive.rs @@ -30,12 +30,12 @@ fn validate_magic(wasm: &[u8]) -> Result { Ok(TWASM_MAGIC.len()) } -#[derive(Debug, PartialEq)] +#[derive(Debug)] pub enum TwasmError { InvalidMagic, InvalidVersion, InvalidPadding, - InvalidArchive, + InvalidArchive(rkyv::rancor::Error), } impl Display for TwasmError { @@ -44,7 +44,7 @@ impl Display for TwasmError { TwasmError::InvalidMagic => write!(f, "Invalid twasm: invalid magic number"), TwasmError::InvalidVersion => write!(f, "Invalid twasm: invalid version"), TwasmError::InvalidPadding => write!(f, "Invalid twasm: invalid padding"), - TwasmError::InvalidArchive => write!(f, "Invalid twasm: invalid archive"), + TwasmError::InvalidArchive(e) => write!(f, "Invalid twasm: {}", e), } } } @@ -58,9 +58,8 @@ impl TinyWasmModule { /// Creates a `TinyWasmModule` from a slice of bytes. pub fn from_twasm(wasm: &[u8]) -> Result { let len = validate_magic(wasm)?; - let root = - access::, rkyv::rancor::Error>(&wasm[len..]).map_err(|_| TwasmError::InvalidArchive)?; - deserialize::(root).map_err(|_e| TwasmError::InvalidArchive) + let root = access::, rkyv::rancor::Error>(&wasm[len..]).map_err(TwasmError::InvalidArchive)?; + deserialize::(root).map_err(TwasmError::InvalidArchive) } /// Serializes the `TinyWasmModule` into a vector of bytes. @@ -93,7 +92,7 @@ mod tests { let wasm = TinyWasmModule::default(); let mut twasm = wasm.serialize_twasm(); twasm[0] = 0; - assert_eq!(TinyWasmModule::from_twasm(&twasm), Err(TwasmError::InvalidMagic)); + assert!(matches!(TinyWasmModule::from_twasm(&twasm), Err(TwasmError::InvalidMagic))); } #[test] @@ -101,6 +100,6 @@ mod tests { let wasm = TinyWasmModule::default(); let mut twasm = wasm.serialize_twasm(); twasm[4] = 0; - assert_eq!(TinyWasmModule::from_twasm(&twasm), Err(TwasmError::InvalidVersion)); + assert!(matches!(TinyWasmModule::from_twasm(&twasm), Err(TwasmError::InvalidVersion))); } } From e9782276a3a51f3b9ff4cdc6b56c447b1ab0d463 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Mon, 10 Feb 2025 22:34:51 +0100 Subject: [PATCH 38/54] chore: update deps Signed-off-by: Henry Gressmann --- Cargo.lock | 157 ++++++++++++++++++------------------- Cargo.toml | 4 +- crates/parser/Cargo.toml | 2 +- crates/tinywasm/Cargo.toml | 2 +- 4 files changed, 81 insertions(+), 84 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7b7d99..fcfca76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,21 +63,21 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] name = "bytecheck" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c8f430744b23b54ad15161fcbc22d82a29b73eacbe425fea23ec822600bc6f" +checksum = "50690fb3370fb9fe3550372746084c46f2ac8c9685c583d2be10eefd89d3d1a3" dependencies = [ "bytecheck_derive", "ptr_meta", @@ -87,9 +87,9 @@ dependencies = [ [[package]] name = "bytecheck_derive" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523363cbe1df49b68215efdf500b103ac3b0fb4836aed6d15689a076eadb8fff" +checksum = "efb7846e0cb180355c2dec69e721edafa36919850f1a9f52ffba4ebc0393cb71" dependencies = [ "proc-macro2", "quote", @@ -98,9 +98,9 @@ dependencies = [ [[package]] name = "bytes" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" +checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" [[package]] name = "cast" @@ -143,18 +143,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.23" +version = "4.5.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" +checksum = "3e77c3243bd94243c03672cb5154667347c457ca271254724f9f393aee1c05ff" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.23" +version = "4.5.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" +checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7" dependencies = [ "anstyle", "clap_lex", @@ -228,9 +228,9 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" [[package]] name = "either" @@ -322,9 +322,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "2.7.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" dependencies = [ "equivalent", "hashbrown", @@ -332,13 +332,13 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.13" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" +checksum = "e19b23d53f35ce9f56aebc7d1bb4e6ac1e9c0db7ac85c8d1760c04379edced37" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -362,6 +362,12 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + [[package]] name = "libc" version = "0.2.169" @@ -376,9 +382,9 @@ checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "log" -version = "0.4.22" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" [[package]] name = "memchr" @@ -417,9 +423,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.2" +version = "1.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" [[package]] name = "oorandom" @@ -445,9 +451,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.92" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] @@ -550,9 +556,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b11a153aec4a6ab60795f8ebe2923c597b16b05bb1504377451e705ef1a45323" +checksum = "1e147371c75553e1e2fcdb483944a8540b8438c31426279553b9a8182a9b7b65" dependencies = [ "bytecheck", "bytes", @@ -569,9 +575,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beb382a4d9f53bd5c0be86b10d8179c3f8a14c30bf774ff77096ed6581e35981" +checksum = "246b40ac189af6c675d124b802e8ef6d5246c53e17367ce9501f8f66a81abb7a" dependencies = [ "proc-macro2", "quote", @@ -586,9 +592,9 @@ checksum = "a157657054ffe556d8858504af8a672a054a6e0bd9e8ee531059100c0fa11bb2" [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" [[package]] name = "same-file" @@ -601,9 +607,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" +checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03" [[package]] name = "serde" @@ -627,9 +633,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.134" +version = "1.0.138" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" +checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" dependencies = [ "itoa", "memchr", @@ -645,9 +651,9 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "syn" -version = "2.0.95" +version = "2.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" dependencies = [ "proc-macro2", "quote", @@ -704,7 +710,7 @@ dependencies = [ "tinywasm-parser", "tinywasm-types", "wasm-testsuite", - "wast 223.0.0", + "wast 225.0.0", "wat", ] @@ -717,7 +723,7 @@ dependencies = [ "log", "pretty_env_logger", "tinywasm", - "wast 223.0.0", + "wast 225.0.0", ] [[package]] @@ -726,7 +732,7 @@ version = "0.9.0-alpha.0" dependencies = [ "log", "tinywasm-types", - "wasmparser 0.223.0", + "wasmparser 0.225.0", ] [[package]] @@ -749,9 +755,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" [[package]] name = "unicode-width" @@ -761,9 +767,9 @@ checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" [[package]] name = "uuid" -version = "1.11.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" +checksum = "ced87ca4be083373936a67f8de945faa23b6b42384bd5b64434850802c6dccd0" [[package]] name = "walkdir" @@ -777,39 +783,39 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.222.0" +version = "0.224.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3432682105d7e994565ef928ccf5856cf6af4ba3dddebedb737f61caed70f956" +checksum = "1ab7a13a23790fe91ea4eb7526a1f3131001d874e3e00c2976c48861f2e82920" dependencies = [ "leb128", - "wasmparser 0.222.0", + "wasmparser 0.224.1", ] [[package]] name = "wasm-encoder" -version = "0.223.0" +version = "0.225.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e636076193fa68103e937ac951b5f2f587624097017d764b8984d9c0f149464" +checksum = "6f7eac0445cac73bcf09e6a97f83248d64356dccf9f2b100199769b6b42464e5" dependencies = [ - "leb128", - "wasmparser 0.223.0", + "leb128fmt", + "wasmparser 0.225.0", ] [[package]] name = "wasm-testsuite" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d01e1e4857b055d8ad6d542d95074106b5b2afd411d3e26ae6da37a560053c97" +checksum = "8a4e25e8fd04d2da04479453bb74448dfffb960c5a0ed74df97a4cdddcaab85c" dependencies = [ "include_dir", - "wast 222.0.0", + "wast 224.0.1", ] [[package]] name = "wasmparser" -version = "0.222.0" +version = "0.224.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4adf50fde1b1a49c1add6a80d47aea500c88db70551805853aa8b88f3ea27ab5" +checksum = "04f17a5917c2ddd3819e84c661fae0d6ba29d7b9c1f0e96c708c65a9c4188e11" dependencies = [ "bitflags", "indexmap", @@ -818,9 +824,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.223.0" +version = "0.225.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5a99faceb1a5a84dd6084ec4bfa4b2ab153b5793b43fd8f58b89232634afc35" +checksum = "36e5456165f81e64cb9908a0fe9b9d852c2c74582aa3fe2be3c2da57f937d3ae" dependencies = [ "bitflags", "indexmap", @@ -829,37 +835,37 @@ dependencies = [ [[package]] name = "wast" -version = "222.0.0" +version = "224.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce7191f4b7da0dd300cc32476abae6457154e4625d9b1bc26890828a9a26f6e" +checksum = "ddf8e902015ff670011613811be3310408d2dba911217eea711aa98c89584aca" dependencies = [ "bumpalo", "leb128", "memchr", "unicode-width", - "wasm-encoder 0.222.0", + "wasm-encoder 0.224.1", ] [[package]] name = "wast" -version = "223.0.0" +version = "225.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59b2ba8a2ff9f06194b7be9524f92e45e70149f4dacc0d0c7ad92b59ac875e4" +checksum = "c61496027ff707f9fa9e0b22c34ec163eb7adb1070df565e32a9180a76e4300b" dependencies = [ "bumpalo", - "leb128", + "leb128fmt", "memchr", "unicode-width", - "wasm-encoder 0.223.0", + "wasm-encoder 0.225.0", ] [[package]] name = "wat" -version = "1.223.0" +version = "1.225.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662786915c427e4918ff01eabb3c4756d4d947cd8f635761526b4cc9da2eaaad" +checksum = "89e72a33942234fd0794bcdac30e43b448de3187512414267678e511c6755f11" dependencies = [ - "wast 223.0.0", + "wast 225.0.0", ] [[package]] @@ -868,16 +874,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", + "windows-sys", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 119dc45..e92c4ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,8 +4,8 @@ default-members=[".", "crates/tinywasm", "crates/types", "crates/parser"] resolver="2" [workspace.dependencies] -wast="223" -wat="1.223" +wast="225" +wat="1.225" eyre="0.6" log="0.4" pretty_env_logger="0.5" diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index f8eabb4..fec21b3 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -9,7 +9,7 @@ repository.workspace=true rust-version.workspace=true [dependencies] -wasmparser={version="0.223", default-features=false, features=["validate", "features", "simd"]} +wasmparser={version="0.225", default-features=false, features=["validate", "features", "simd"]} log={workspace=true, optional=true} tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false} diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index 5dc0447..0623f35 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -20,7 +20,7 @@ tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false libm={version="0.2", default-features=false} [dev-dependencies] -wasm-testsuite={version="0.4.0"} +wasm-testsuite={version="0.4.2"} indexmap="2.7" wast={workspace=true} wat={workspace=true} From 7e668f9e321c941f38395e47a29501dce0fc81a9 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Wed, 12 Feb 2025 18:42:10 +0100 Subject: [PATCH 39/54] feat: use postcard for new twasm format Closes #32, #31 Co-authored-by: Mateusz Signed-off-by: Henry Gressmann --- CHANGELOG.md | 2 +- Cargo.lock | 185 ++++---------------- crates/parser/src/visit.rs | 18 +- crates/tinywasm/benches/argon2id.rs | 16 +- crates/tinywasm/benches/fibonacci.rs | 14 +- crates/tinywasm/benches/tinywasm.rs | 14 +- crates/tinywasm/src/interpreter/executor.rs | 3 +- crates/tinywasm/src/interpreter/mod.rs | 1 - crates/tinywasm/src/interpreter/simd.rs | 32 ---- crates/types/Cargo.toml | 8 +- crates/types/src/archive.rs | 37 ++-- crates/types/src/instructions.rs | 25 +-- crates/types/src/lib.rs | 40 ++--- crates/types/src/value.rs | 2 +- examples/archive.rs | 2 +- 15 files changed, 109 insertions(+), 290 deletions(-) delete mode 100644 crates/tinywasm/src/interpreter/simd.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index ab30d8d..0222a0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- **Breaking:**: New backwards-incompatible version of the twasm format (upgraded `rkyv` to 0.8.0) +- **Breaking:**: New backwards-incompatible version of the twasm format based on `postcard` (thanks [@dragonnn](https://github.com/dragonnn)) - **Breaking:**: `RefNull` has been removed and replaced with new `FuncRef` and `ExternRef` structs - Increased MSRV to 1.83.0 diff --git a/Cargo.lock b/Cargo.lock index fcfca76..ccb8fa3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,35 +73,6 @@ version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" -[[package]] -name = "bytecheck" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50690fb3370fb9fe3550372746084c46f2ac8c9685c583d2be10eefd89d3d1a3" -dependencies = [ - "bytecheck_derive", - "ptr_meta", - "rancor", - "simdutf8", -] - -[[package]] -name = "bytecheck_derive" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb7846e0cb180355c2dec69e721edafa36919850f1a9f52ffba4ebc0393cb71" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "bytes" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" - [[package]] name = "cast" version = "0.3.0" @@ -143,18 +114,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.28" +version = "4.5.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e77c3243bd94243c03672cb5154667347c457ca271254724f9f393aee1c05ff" +checksum = "8acebd8ad879283633b343856142139f2da2317c96b05b4dd6181c61e2480184" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.27" +version = "4.5.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7" +checksum = "f6ba32cbda51c7e1dfd49acc1457ba1a7dec5b64fe360e828acb13ca8dc9c2f9" dependencies = [ "anstyle", "clap_lex", @@ -166,6 +137,12 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + [[package]] name = "criterion" version = "0.5.1" @@ -238,6 +215,18 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + [[package]] name = "env_logger" version = "0.10.2" @@ -392,26 +381,6 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" -[[package]] -name = "munge" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64142d38c84badf60abf06ff9bd80ad2174306a5b11bd4706535090a30a419df" -dependencies = [ - "munge_macro", -] - -[[package]] -name = "munge_macro" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bb5c1d8184f13f7d0ccbeeca0def2f9a181bce2624302793005f5ca8aa62e5e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -439,6 +408,18 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" +[[package]] +name = "postcard" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "170a2601f67cc9dba8edd8c4870b15f71a6a2dc196daec8c83f72b59dff628a8" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "serde", +] + [[package]] name = "pretty_env_logger" version = "0.5.0" @@ -458,26 +439,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "ptr_meta" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9e76f66d3f9606f44e45598d155cb13ecf09f4a28199e48daf8c8fc937ea90" -dependencies = [ - "ptr_meta_derive", -] - -[[package]] -name = "ptr_meta_derive" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca414edb151b4c8d125c12566ab0d74dc9cdba36fb80eb7b848c15f495fd32d1" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "quote" version = "1.0.38" @@ -487,15 +448,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rancor" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf5f7161924b9d1cea0e4cabc97c372cea92b5f927fc13c6bca67157a0ad947" -dependencies = [ - "ptr_meta", -] - [[package]] name = "rayon" version = "1.10.0" @@ -545,45 +497,6 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" -[[package]] -name = "rend" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35e8a6bf28cd121053a66aa2e6a2e3eaffad4a60012179f0e864aa5ffeff215" -dependencies = [ - "bytecheck", -] - -[[package]] -name = "rkyv" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e147371c75553e1e2fcdb483944a8540b8438c31426279553b9a8182a9b7b65" -dependencies = [ - "bytecheck", - "bytes", - "hashbrown", - "indexmap", - "munge", - "ptr_meta", - "rancor", - "rend", - "rkyv_derive", - "tinyvec", - "uuid", -] - -[[package]] -name = "rkyv_derive" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "246b40ac189af6c675d124b802e8ef6d5246c53e17367ce9501f8f66a81abb7a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "rust-fuzzy-search" version = "0.1.1" @@ -643,12 +556,6 @@ dependencies = [ "serde", ] -[[package]] -name = "simdutf8" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" - [[package]] name = "syn" version = "2.0.98" @@ -679,21 +586,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "tinyvec" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - [[package]] name = "tinywasm" version = "0.9.0-alpha.0" @@ -750,7 +642,8 @@ name = "tinywasm-types" version = "0.9.0-alpha.0" dependencies = [ "log", - "rkyv", + "postcard", + "serde", ] [[package]] @@ -765,12 +658,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" -[[package]] -name = "uuid" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced87ca4be083373936a67f8de945faa23b6b42384bd5b64434850802c6dccd0" - [[package]] name = "walkdir" version = "2.5.0" diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs index 098caf9..89c27d1 100644 --- a/crates/parser/src/visit.rs +++ b/crates/parser/src/visit.rs @@ -3,7 +3,7 @@ use crate::Result; use crate::conversion::{convert_heaptype, convert_valtype}; use alloc::string::ToString; use alloc::{boxed::Box, vec::Vec}; -use tinywasm_types::{Instruction, MemoryArg, SimdInstruction, WasmFunctionData}; +use tinywasm_types::{Instruction, MemoryArg, WasmFunctionData}; use wasmparser::{ FuncValidator, FuncValidatorAllocations, FunctionBody, VisitOperator, VisitSimdOperator, WasmModuleResources, }; @@ -84,12 +84,6 @@ macro_rules! define_operands { )*}; } -macro_rules! define_operands_simd { - ($($name:ident($instr:ident $(,$ty:ty)*)),*) => {$( - define_operand!($name(SimdInstruction::$instr $(,$ty)*)); - )*}; -} - macro_rules! define_mem_operands { ($($name:ident($instr:ident)),*) => {$( fn $name(&mut self, memarg: wasmparser::MemArg) -> Self::Output { @@ -101,7 +95,7 @@ macro_rules! define_mem_operands { macro_rules! define_mem_operands_simd { ($($name:ident($instr:ident)),*) => {$( fn $name(&mut self, memarg: wasmparser::MemArg) -> Self::Output { - self.instructions.push(SimdInstruction::$instr(MemoryArg::new(memarg.offset, memarg.memory)).into()); + self.instructions.push(Instruction::$instr(MemoryArg::new(memarg.offset, memarg.memory)).into()); } )*}; } @@ -109,7 +103,7 @@ macro_rules! define_mem_operands_simd { macro_rules! define_mem_operands_simd_lane { ($($name:ident($instr:ident)),*) => {$( fn $name(&mut self, memarg: wasmparser::MemArg, lane: u8) -> Self::Output { - self.instructions.push(SimdInstruction::$instr(MemoryArg::new(memarg.offset, memarg.memory), lane).into()); + self.instructions.push(Instruction::$instr(MemoryArg::new(memarg.offset, memarg.memory), lane).into()); } )*}; } @@ -496,7 +490,7 @@ impl wasmparser::VisitSimdOperator<'_> for FunctionBuild visit_v128_load8_lane(V128Load8Lane), visit_v128_load16_lane(V128Load16Lane), visit_v128_load32_lane(V128Load32Lane), visit_v128_load64_lane(V128Load64Lane), visit_v128_store8_lane(V128Store8Lane), visit_v128_store16_lane(V128Store16Lane), visit_v128_store32_lane(V128Store32Lane), visit_v128_store64_lane(V128Store64Lane) } - define_operands_simd! { + define_operands! { visit_v128_not(V128Not), visit_v128_and(V128And), visit_v128_andnot(V128AndNot), visit_v128_or(V128Or), visit_v128_xor(V128Xor), visit_v128_bitselect(V128Bitselect), visit_v128_any_true(V128AnyTrue), visit_i8x16_splat(I8x16Splat), visit_i8x16_swizzle(I8x16Swizzle), visit_i8x16_eq(I8x16Eq), visit_i8x16_ne(I8x16Ne), visit_i8x16_lt_s(I8x16LtS), visit_i8x16_lt_u(I8x16LtU), visit_i8x16_gt_s(I8x16GtS), visit_i8x16_gt_u(I8x16GtU), visit_i8x16_le_s(I8x16LeS), visit_i8x16_le_u(I8x16LeU), visit_i8x16_ge_s(I8x16GeS), visit_i8x16_ge_u(I8x16GeU), visit_i16x8_splat(I16x8Splat), visit_i16x8_eq(I16x8Eq), visit_i16x8_ne(I16x8Ne), visit_i16x8_lt_s(I16x8LtS), visit_i16x8_lt_u(I16x8LtU), visit_i16x8_gt_s(I16x8GtS), visit_i16x8_gt_u(I16x8GtU), visit_i16x8_le_s(I16x8LeS), visit_i16x8_le_u(I16x8LeU), visit_i16x8_ge_s(I16x8GeS), visit_i16x8_ge_u(I16x8GeU), @@ -537,11 +531,11 @@ impl wasmparser::VisitSimdOperator<'_> for FunctionBuild fn visit_i8x16_shuffle(&mut self, lanes: [u8; 16]) -> Self::Output { self.v128_constants.push(u128::from_le_bytes(lanes)); - self.instructions.push(SimdInstruction::I8x16Shuffle(self.v128_constants.len() as u32 - 1).into()); + self.instructions.push(Instruction::I8x16Shuffle(self.v128_constants.len() as u32 - 1).into()); } fn visit_v128_const(&mut self, value: wasmparser::V128) -> Self::Output { self.v128_constants.push(value.i128() as u128); - self.instructions.push(SimdInstruction::V128Const(self.v128_constants.len() as u32 - 1).into()); + self.instructions.push(Instruction::V128Const(self.v128_constants.len() as u32 - 1).into()); } } diff --git a/crates/tinywasm/benches/argon2id.rs b/crates/tinywasm/benches/argon2id.rs index 6dd5ae4..d977352 100644 --- a/crates/tinywasm/benches/argon2id.rs +++ b/crates/tinywasm/benches/argon2id.rs @@ -1,7 +1,7 @@ use criterion::{criterion_group, criterion_main, Criterion}; use eyre::Result; use tinywasm::{types, ModuleInstance, Store}; -use types::{archive::AlignedVec, TinyWasmModule}; +use types::TinyWasmModule; const WASM: &[u8] = include_bytes!("../../../examples/rust/out/argon2id.opt.wasm"); @@ -11,13 +11,13 @@ fn argon2id_parse() -> Result { Ok(data) } -fn argon2id_to_twasm(module: TinyWasmModule) -> Result { - let twasm = module.serialize_twasm(); +fn argon2id_to_twasm(module: &TinyWasmModule) -> Result> { + let twasm = module.serialize_twasm()?; Ok(twasm) } -fn argon2id_from_twasm(twasm: AlignedVec) -> Result { - let module = TinyWasmModule::from_twasm(&twasm)?; +fn argon2id_from_twasm(twasm: &[u8]) -> Result { + let module = TinyWasmModule::from_twasm(twasm)?; Ok(module) } @@ -31,11 +31,11 @@ fn argon2id_run(module: TinyWasmModule) -> Result<()> { fn criterion_benchmark(c: &mut Criterion) { let module = argon2id_parse().expect("argon2id_parse"); - let twasm = argon2id_to_twasm(module.clone()).expect("argon2id_to_twasm"); + let twasm = argon2id_to_twasm(&module).expect("argon2id_to_twasm"); c.bench_function("argon2id_parse", |b| b.iter(argon2id_parse)); - c.bench_function("argon2id_to_twasm", |b| b.iter(|| argon2id_to_twasm(module.clone()))); - c.bench_function("argon2id_from_twasm", |b| b.iter(|| argon2id_from_twasm(twasm.clone()))); + c.bench_function("argon2id_to_twasm", |b| b.iter(|| argon2id_to_twasm(&module))); + c.bench_function("argon2id_from_twasm", |b| b.iter(|| argon2id_from_twasm(&twasm))); c.bench_function("argon2id", |b| b.iter(|| argon2id_run(module.clone()))); } diff --git a/crates/tinywasm/benches/fibonacci.rs b/crates/tinywasm/benches/fibonacci.rs index 9c994ca..dcf6eb9 100644 --- a/crates/tinywasm/benches/fibonacci.rs +++ b/crates/tinywasm/benches/fibonacci.rs @@ -1,7 +1,7 @@ use criterion::{criterion_group, criterion_main, Criterion}; use eyre::Result; use tinywasm::{types, ModuleInstance, Store}; -use types::{archive::AlignedVec, TinyWasmModule}; +use types::TinyWasmModule; const WASM: &[u8] = include_bytes!("../../../examples/rust/out/fibonacci.opt.wasm"); @@ -11,12 +11,12 @@ fn fibonacci_parse() -> Result { Ok(data) } -fn fibonacci_to_twasm(module: TinyWasmModule) -> Result { - let twasm = module.serialize_twasm(); +fn fibonacci_to_twasm(module: &TinyWasmModule) -> Result> { + let twasm = module.serialize_twasm()?; Ok(twasm) } -fn fibonacci_from_twasm(twasm: AlignedVec) -> Result { +fn fibonacci_from_twasm(twasm: &[u8]) -> Result { let module = TinyWasmModule::from_twasm(&twasm)?; Ok(module) } @@ -37,11 +37,11 @@ fn fibonacci_run(module: TinyWasmModule, recursive: bool, n: i32) -> Result<()> fn criterion_benchmark(c: &mut Criterion) { let module = fibonacci_parse().expect("fibonacci_parse"); - let twasm = fibonacci_to_twasm(module.clone()).expect("fibonacci_to_twasm"); + let twasm = fibonacci_to_twasm(&module).expect("fibonacci_to_twasm"); c.bench_function("fibonacci_parse", |b| b.iter(fibonacci_parse)); - c.bench_function("fibonacci_to_twasm", |b| b.iter(|| fibonacci_to_twasm(module.clone()))); - c.bench_function("fibonacci_from_twasm", |b| b.iter(|| fibonacci_from_twasm(twasm.clone()))); + c.bench_function("fibonacci_to_twasm", |b| b.iter(|| fibonacci_to_twasm(&module))); + c.bench_function("fibonacci_from_twasm", |b| b.iter(|| fibonacci_from_twasm(&twasm))); c.bench_function("fibonacci_iterative_60", |b| b.iter(|| fibonacci_run(module.clone(), false, 60))); c.bench_function("fibonacci_recursive_26", |b| b.iter(|| fibonacci_run(module.clone(), true, 26))); } diff --git a/crates/tinywasm/benches/tinywasm.rs b/crates/tinywasm/benches/tinywasm.rs index da16eb8..8552d6c 100644 --- a/crates/tinywasm/benches/tinywasm.rs +++ b/crates/tinywasm/benches/tinywasm.rs @@ -1,7 +1,7 @@ use criterion::{criterion_group, criterion_main, Criterion}; use eyre::Result; use tinywasm::{types, Extern, FuncContext, Imports, ModuleInstance, Store}; -use types::{archive::AlignedVec, TinyWasmModule}; +use types::TinyWasmModule; const WASM: &[u8] = include_bytes!("../../../examples/rust/out/tinywasm.opt.wasm"); @@ -11,12 +11,12 @@ fn tinywasm_parse() -> Result { Ok(data) } -fn tinywasm_to_twasm(module: TinyWasmModule) -> Result { - let twasm = module.serialize_twasm(); +fn tinywasm_to_twasm(module: &TinyWasmModule) -> Result> { + let twasm = module.serialize_twasm()?; Ok(twasm) } -fn tinywasm_from_twasm(twasm: AlignedVec) -> Result { +fn tinywasm_from_twasm(twasm: &[u8]) -> Result { let module = TinyWasmModule::from_twasm(&twasm)?; Ok(module) } @@ -33,11 +33,11 @@ fn tinywasm_run(module: TinyWasmModule) -> Result<()> { fn criterion_benchmark(c: &mut Criterion) { let module = tinywasm_parse().expect("tinywasm_parse"); - let twasm = tinywasm_to_twasm(module.clone()).expect("tinywasm_to_twasm"); + let twasm = tinywasm_to_twasm(&module).expect("tinywasm_to_twasm"); c.bench_function("tinywasm_parse", |b| b.iter(tinywasm_parse)); - c.bench_function("tinywasm_to_twasm", |b| b.iter(|| tinywasm_to_twasm(module.clone()))); - c.bench_function("tinywasm_from_twasm", |b| b.iter(|| tinywasm_from_twasm(twasm.clone()))); + c.bench_function("tinywasm_to_twasm", |b| b.iter(|| tinywasm_to_twasm(&module))); + c.bench_function("tinywasm_from_twasm", |b| b.iter(|| tinywasm_from_twasm(&twasm))); c.bench_function("tinywasm", |b| b.iter(|| tinywasm_run(module.clone()))); } diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index f05ae30..3c579c1 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -4,7 +4,6 @@ use super::no_std_floats::NoStdFloatExt; use alloc::{format, rc::Rc, string::ToString}; use core::ops::ControlFlow; -use interpreter::simd::exec_next_simd; use interpreter::stack::CallFrame; use tinywasm_types::*; @@ -303,7 +302,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { LocalCopy128(from, to) => self.exec_local_copy::(*from, *to), LocalCopyRef(from, to) => self.exec_local_copy::(*from, *to), - Simd(op) => exec_next_simd(self, *op).to_cf()?, + i => return ControlFlow::Break(Some(Error::UnsupportedFeature(format!("unimplemented opcode: {i:?}")))), }; self.cf.incr_instr_ptr(); diff --git a/crates/tinywasm/src/interpreter/mod.rs b/crates/tinywasm/src/interpreter/mod.rs index e5c1081..0b7df2f 100644 --- a/crates/tinywasm/src/interpreter/mod.rs +++ b/crates/tinywasm/src/interpreter/mod.rs @@ -1,6 +1,5 @@ pub(crate) mod executor; pub(crate) mod num_helpers; -pub(crate) mod simd; pub(crate) mod stack; mod values; diff --git a/crates/tinywasm/src/interpreter/simd.rs b/crates/tinywasm/src/interpreter/simd.rs deleted file mode 100644 index e996edc..0000000 --- a/crates/tinywasm/src/interpreter/simd.rs +++ /dev/null @@ -1,32 +0,0 @@ -use tinywasm_types::SimdInstruction; - -use crate::Result; - -#[cfg(not(feature = "std"))] -#[allow(unused_imports)] -use super::no_std_floats::NoStdFloatExt; -use super::{executor::Executor, Value128}; - -#[inline(always)] -pub(crate) fn exec_next_simd(e: &mut Executor<'_, '_>, op: SimdInstruction) -> Result<()> { - match op { - // unops - SimdInstruction::V128Not => e.stack.values.replace_top_same(|a: Value128| Ok(!a))?, - // binops - SimdInstruction::V128And => e.stack.values.calculate_same(|a: Value128, b: Value128| Ok(a & b))?, - SimdInstruction::V128AndNot => e.stack.values.calculate_same(|a: Value128, b: Value128| Ok(a & !b))?, - SimdInstruction::V128Or => e.stack.values.calculate_same(|a: Value128, b: Value128| Ok(a | b))?, - SimdInstruction::V128Xor => e.stack.values.calculate_same(|a: Value128, b: Value128| Ok(a ^ b))?, - // ternops - SimdInstruction::V128Bitselect => { - let c: Value128 = e.stack.values.pop(); - e.stack.values.calculate(|a: Value128, b: Value128| Ok((a & b) | (!a & c)))?; - } - // shifts - _ => {} - } - Ok(()) -} - -// trait SimdExt {} -// impl SimdExt for Value128 {} diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index 9d9f9af..fda8a86 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -10,10 +10,12 @@ rust-version.workspace=true [dependencies] log={workspace=true, optional=true} -rkyv={version="0.8.1", optional=true, default-features=false, features=["alloc", "bytecheck"]} +postcard={version="1.1", optional=true, default-features=false, features=["alloc"]} +serde={version="1.0", optional=true, default-features=false, features=["alloc"]} [features] default=["std", "logging", "archive"] -std=["rkyv?/std"] -archive=["dep:rkyv"] + +std=["serde?/std"] +archive=["dep:postcard", "dep:serde"] logging=["dep:log"] diff --git a/crates/types/src/archive.rs b/crates/types/src/archive.rs index 30b54c7..a725e3d 100644 --- a/crates/types/src/archive.rs +++ b/crates/types/src/archive.rs @@ -1,21 +1,14 @@ use core::fmt::{Display, Formatter}; +use alloc::vec::Vec; + use crate::TinyWasmModule; -use rkyv::{ - access, - api::high::to_bytes_in_with_alloc, - deserialize, - ser::{allocator::Arena, WriterExt}, - Archived, -}; const TWASM_MAGIC_PREFIX: &[u8; 4] = b"TWAS"; -const TWASM_VERSION: &[u8; 2] = b"02"; +const TWASM_VERSION: &[u8; 2] = b"03"; #[rustfmt::skip] const TWASM_MAGIC: [u8; 16] = [ TWASM_MAGIC_PREFIX[0], TWASM_MAGIC_PREFIX[1], TWASM_MAGIC_PREFIX[2], TWASM_MAGIC_PREFIX[3], TWASM_VERSION[0], TWASM_VERSION[1], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; -pub use rkyv::util::AlignedVec; - fn validate_magic(wasm: &[u8]) -> Result { if wasm.len() < TWASM_MAGIC.len() || &wasm[..TWASM_MAGIC_PREFIX.len()] != TWASM_MAGIC_PREFIX { return Err(TwasmError::InvalidMagic); @@ -35,7 +28,7 @@ pub enum TwasmError { InvalidMagic, InvalidVersion, InvalidPadding, - InvalidArchive(rkyv::rancor::Error), + InvalidArchive(postcard::Error), } impl Display for TwasmError { @@ -58,20 +51,14 @@ impl TinyWasmModule { /// Creates a `TinyWasmModule` from a slice of bytes. pub fn from_twasm(wasm: &[u8]) -> Result { let len = validate_magic(wasm)?; - let root = access::, rkyv::rancor::Error>(&wasm[len..]).map_err(TwasmError::InvalidArchive)?; - deserialize::(root).map_err(TwasmError::InvalidArchive) + + postcard::from_bytes(&wasm[len..]).map_err(|e| TwasmError::InvalidArchive(e)) } /// Serializes the `TinyWasmModule` into a vector of bytes. - /// `AlignedVec` can be deferenced as a slice of bytes and - /// implements `io::Write` when the `std` feature is enabled. - pub fn serialize_twasm(&self) -> AlignedVec { - let mut arena = Arena::new(); - let mut bytes = AlignedVec::new(); - >::pad(&mut bytes, TWASM_MAGIC.len()).unwrap(); - let mut bytes = to_bytes_in_with_alloc::<_, _, rkyv::rancor::Error>(self, bytes, arena.acquire()).unwrap(); - bytes[..TWASM_MAGIC.len()].copy_from_slice(&TWASM_MAGIC); - bytes + pub fn serialize_twasm(&self) -> Result, TwasmError> { + let buf = Vec::from(TWASM_MAGIC); + postcard::to_extend(self, buf).map_err(|e| TwasmError::InvalidArchive(e)) } } @@ -82,7 +69,7 @@ mod tests { #[test] fn test_serialize() { let wasm = TinyWasmModule::default(); - let twasm = wasm.serialize_twasm(); + let twasm = wasm.serialize_twasm().expect("should serialize"); let wasm2 = TinyWasmModule::from_twasm(&twasm).unwrap(); assert_eq!(wasm, wasm2); } @@ -90,7 +77,7 @@ mod tests { #[test] fn test_invalid_magic() { let wasm = TinyWasmModule::default(); - let mut twasm = wasm.serialize_twasm(); + let mut twasm = wasm.serialize_twasm().expect("should serialize"); twasm[0] = 0; assert!(matches!(TinyWasmModule::from_twasm(&twasm), Err(TwasmError::InvalidMagic))); } @@ -98,7 +85,7 @@ mod tests { #[test] fn test_invalid_version() { let wasm = TinyWasmModule::default(); - let mut twasm = wasm.serialize_twasm(); + let mut twasm = wasm.serialize_twasm().expect("should serialize"); twasm[4] = 0; assert!(matches!(TinyWasmModule::from_twasm(&twasm), Err(TwasmError::InvalidVersion))); } diff --git a/crates/types/src/instructions.rs b/crates/types/src/instructions.rs index 8f77b31..c61a02f 100644 --- a/crates/types/src/instructions.rs +++ b/crates/types/src/instructions.rs @@ -3,7 +3,7 @@ use crate::{ConstIdx, DataAddr, ElemAddr, ExternAddr, MemAddr}; /// Represents a memory immediate in a WebAssembly memory instruction. #[derive(Debug, Copy, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct MemoryArg([u8; 12]); @@ -30,7 +30,7 @@ type EndOffset = u32; type ElseOffset = u32; #[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub enum ConstInstruction { I32Const(i32), I64Const(i64), @@ -53,7 +53,7 @@ pub enum ConstInstruction { /// /// See #[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] // should be kept as small as possible (16 bytes max) #[rustfmt::skip] pub enum Instruction { @@ -184,19 +184,6 @@ pub enum Instruction { ElemDrop(ElemAddr), // > SIMD Instructions - Simd(SimdInstruction), -} - -impl From for Instruction { - fn from(instr: SimdInstruction) -> Self { - Instruction::Simd(instr) - } -} - -#[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] -#[rustfmt::skip] -pub enum SimdInstruction { V128Load(MemoryArg), V128Load8x8S(MemoryArg), V128Load8x8U(MemoryArg), V128Load16x4S(MemoryArg), V128Load16x4U(MemoryArg), @@ -256,12 +243,8 @@ pub enum SimdInstruction { I32x4TruncSatF64x2SZero, I32x4TruncSatF64x2UZero, F64x2ConvertLowI32x4S, F64x2ConvertLowI32x4U, F32x4DemoteF64x2Zero, F64x2PromoteLowF32x4, -} -#[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] -#[rustfmt::skip] -pub enum RelaxedSimd { + // > Relaxed SIMD I8x16RelaxedSwizzle, I32x4RelaxedTruncF32x4S, I32x4RelaxedTruncF32x4U, I32x4RelaxedTruncF64x2SZero, I32x4RelaxedTruncF64x2UZero, diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index 58120fe..81eec13 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -51,7 +51,7 @@ pub mod archive; /// `TinyWasmModules` are validated before being created, so they are guaranteed to be valid (as long as they were created by `TinyWasm`). /// This means you should not trust a `TinyWasmModule` created by a third party to be valid. #[derive(Debug, Clone, Default, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct TinyWasmModule { /// Optional address of the start function /// @@ -108,7 +108,7 @@ pub struct TinyWasmModule { /// /// See #[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub enum ExternalKind { /// A WebAssembly Function. Func, @@ -180,14 +180,14 @@ impl ExternVal { /// /// See #[derive(Debug, Clone, PartialEq, Default)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct FuncType { pub params: Box<[ValType]>, pub results: Box<[ValType]>, } #[derive(Debug, Default, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct ValueCounts { pub c32: u32, pub c64: u32, @@ -196,7 +196,7 @@ pub struct ValueCounts { } #[derive(Debug, Default, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct ValueCountsSmall { pub c32: u16, pub c64: u16, @@ -235,7 +235,7 @@ impl<'a, T: IntoIterator> From for ValueCountsSmall { } #[derive(Debug, Clone, PartialEq, Default)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct WasmFunction { pub instructions: Box<[Instruction]>, pub data: WasmFunctionData, @@ -245,14 +245,14 @@ pub struct WasmFunction { } #[derive(Debug, Clone, PartialEq, Default)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct WasmFunctionData { pub v128_constants: Box<[u128]>, } /// A WebAssembly Module Export #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct Export { /// The name of the export. pub name: Box, @@ -263,21 +263,21 @@ pub struct Export { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct Global { pub ty: GlobalType, pub init: ConstInstruction, } #[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct GlobalType { pub mutable: bool, pub ty: ValType, } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct TableType { pub element_type: ValType, pub size_initial: u32, @@ -296,7 +296,7 @@ impl TableType { /// Represents a memory's type. #[derive(Debug, Copy, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct MemoryType { arch: MemoryArch, page_count_initial: u64, @@ -335,14 +335,14 @@ impl MemoryType { } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub enum MemoryArch { I32, I64, } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct Import { pub module: Box, pub name: Box, @@ -350,7 +350,7 @@ pub struct Import { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub enum ImportKind { Function(TypeAddr), Table(TableType), @@ -371,7 +371,7 @@ impl From<&ImportKind> for ExternalKind { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct Data { pub data: Box<[u8]>, pub range: Range, @@ -379,14 +379,14 @@ pub struct Data { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub enum DataKind { Active { mem: MemAddr, offset: ConstInstruction }, Passive, } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct Element { pub kind: ElementKind, pub items: Box<[ElementItem]>, @@ -395,7 +395,7 @@ pub struct Element { } #[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub enum ElementKind { Passive, Active { table: TableAddr, offset: ConstInstruction }, @@ -403,7 +403,7 @@ pub enum ElementKind { } #[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub enum ElementItem { Func(FuncAddr), Expr(ConstInstruction), diff --git a/crates/types/src/value.rs b/crates/types/src/value.rs index 6651c0e..01a31d5 100644 --- a/crates/types/src/value.rs +++ b/crates/types/src/value.rs @@ -249,7 +249,7 @@ impl WasmValue { /// Type of a WebAssembly value. #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub enum ValType { /// A 32-bit integer. I32, diff --git a/examples/archive.rs b/examples/archive.rs index f1a19b6..6a3d54e 100644 --- a/examples/archive.rs +++ b/examples/archive.rs @@ -13,7 +13,7 @@ const WASM: &str = r#" fn main() -> Result<()> { let wasm = wat::parse_str(WASM).expect("Failed to parse WAT"); let module = Parser::default().parse_module_bytes(wasm)?; - let twasm = module.serialize_twasm(); + let twasm = module.serialize_twasm()?; // Now, you could e.g. write `twasm` to a file called `add.twasm` // and load it later in a different program. From d6493c277eb1104aaf72a8e0e6959ce3d1cc4932 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Wed, 12 Feb 2025 19:13:23 +0100 Subject: [PATCH 40/54] fix: fix build, improve error handling Signed-off-by: Henry Gressmann --- CHANGELOG.md | 7 +++--- crates/tinywasm/src/error.rs | 17 ++++++++++--- .../tinywasm/src/interpreter/no_std_floats.rs | 9 ------- crates/types/src/lib.rs | 12 ++++++++++ examples/rust/Cargo.toml | 4 ++++ examples/rust/build.sh | 4 ++-- examples/rust/src/argon2id.rs | 2 +- examples/rust/src/fibonacci.rs | 4 ++-- examples/rust/src/hello.rs | 8 +++---- examples/rust/src/host_fn.rs | 11 +++++++++ examples/rust/src/print.rs | 4 ++-- examples/rust/src/tinywasm.rs | 4 ++-- examples/rust/src/tinywasm_no_std.rs | 6 ++--- examples/wasm-rust.rs | 24 +++++++++++++++++++ 14 files changed, 85 insertions(+), 31 deletions(-) create mode 100644 examples/rust/src/host_fn.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 0222a0b..c01787f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,11 +11,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for the custom memory page sizes proposal ([#22](https://github.com/explodingcamera/tinywasm/pull/22) by [@danielstuart14](https://github.com/danielstuart14)) -### Changed +### Breaking Changes -- **Breaking:**: New backwards-incompatible version of the twasm format based on `postcard` (thanks [@dragonnn](https://github.com/dragonnn)) -- **Breaking:**: `RefNull` has been removed and replaced with new `FuncRef` and `ExternRef` structs +- New backwards-incompatible version of the twasm format based on `postcard` (thanks [@dragonnn](https://github.com/dragonnn)) +- `RefNull` has been removed and replaced with new `FuncRef` and `ExternRef` structs - Increased MSRV to 1.83.0 +- `tinywasm::Error` is now `non_exhaustive`, `Error::ParseError` has been rename to `Error::Parser` and `Error::Twasm` has been added. ### Fixed diff --git a/crates/tinywasm/src/error.rs b/crates/tinywasm/src/error.rs index e0510b2..1d488d8 100644 --- a/crates/tinywasm/src/error.rs +++ b/crates/tinywasm/src/error.rs @@ -1,6 +1,7 @@ use alloc::string::{String, ToString}; use alloc::vec::Vec; use core::{fmt::Display, ops::ControlFlow}; +use tinywasm_types::archive::TwasmError; use tinywasm_types::FuncType; #[cfg(feature = "parser")] @@ -8,6 +9,7 @@ pub use tinywasm_parser::ParseError; /// Errors that can occur for `TinyWasm` operations #[derive(Debug)] +#[non_exhaustive] pub enum Error { /// A WebAssembly trap occurred Trap(Trap), @@ -41,7 +43,10 @@ pub enum Error { #[cfg(feature = "parser")] /// A parsing error occurred - ParseError(ParseError), + Parser(ParseError), + + /// A serialization error occurred + Twasm(TwasmError), } #[derive(Debug)] @@ -169,6 +174,11 @@ impl From for Error { } } +impl From for Error { + fn from(value: TwasmError) -> Self { + Self::Twasm(value) + } +} impl From for Error { fn from(value: Trap) -> Self { Self::Trap(value) @@ -179,11 +189,12 @@ impl Display for Error { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { #[cfg(feature = "parser")] - Self::ParseError(err) => write!(f, "error parsing module: {err:?}"), + Self::Parser(err) => write!(f, "error parsing module: {err:?}"), #[cfg(feature = "std")] Self::Io(err) => write!(f, "I/O error: {err}"), + Self::Twasm(err) => write!(f, "serialization error: {err}"), Self::Trap(trap) => write!(f, "trap: {trap}"), Self::Linker(err) => write!(f, "linking error: {err}"), Self::InvalidLabelType => write!(f, "invalid label type"), @@ -238,7 +249,7 @@ impl core::error::Error for Error {} #[cfg(feature = "parser")] impl From for Error { fn from(value: tinywasm_parser::ParseError) -> Self { - Self::ParseError(value) + Self::Parser(value) } } diff --git a/crates/tinywasm/src/interpreter/no_std_floats.rs b/crates/tinywasm/src/interpreter/no_std_floats.rs index 5b9471e..e273184 100644 --- a/crates/tinywasm/src/interpreter/no_std_floats.rs +++ b/crates/tinywasm/src/interpreter/no_std_floats.rs @@ -1,34 +1,25 @@ pub(super) trait NoStdFloatExt { fn round(self) -> Self; - fn abs(self) -> Self; - fn signum(self) -> Self; fn ceil(self) -> Self; fn floor(self) -> Self; fn trunc(self) -> Self; fn sqrt(self) -> Self; - fn copysign(self, other: Self) -> Self; } #[rustfmt::skip] impl NoStdFloatExt for f64 { #[inline] fn round(self) -> Self { libm::round(self) } - #[inline] fn abs(self) -> Self { libm::fabs(self) } - #[inline] fn signum(self) -> Self { libm::copysign(1.0, self) } #[inline] fn ceil(self) -> Self { libm::ceil(self) } #[inline] fn floor(self) -> Self { libm::floor(self) } #[inline] fn trunc(self) -> Self { libm::trunc(self) } #[inline] fn sqrt(self) -> Self { libm::sqrt(self) } - #[inline] fn copysign(self, other: Self) -> Self { libm::copysign(self, other) } } #[rustfmt::skip] impl NoStdFloatExt for f32 { #[inline] fn round(self) -> Self { libm::roundf(self) } - #[inline] fn abs(self) -> Self { libm::fabsf(self) } - #[inline] fn signum(self) -> Self { libm::copysignf(1.0, self) } #[inline] fn ceil(self) -> Self { libm::ceilf(self) } #[inline] fn floor(self) -> Self { libm::floorf(self) } #[inline] fn trunc(self) -> Self { libm::truncf(self) } #[inline] fn sqrt(self) -> Self { libm::sqrtf(self) } - #[inline] fn copysign(self, other: Self) -> Self { libm::copysignf(self, other) } } diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index 81eec13..d9f2234 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -45,6 +45,18 @@ pub use value::*; #[cfg(feature = "archive")] pub mod archive; +#[cfg(not(feature = "archive"))] +pub mod archive { + #[derive(Debug)] + pub enum TwasmError {} + impl core::fmt::Display for TwasmError { + fn fmt(&self, _: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + Err(core::fmt::Error) + } + } + impl core::error::Error for TwasmError {} +} + /// A `TinyWasm` WebAssembly Module /// /// This is the internal representation of a WebAssembly module in `TinyWasm`. diff --git a/examples/rust/Cargo.toml b/examples/rust/Cargo.toml index 5c6b710..da238ad 100644 --- a/examples/rust/Cargo.toml +++ b/examples/rust/Cargo.toml @@ -22,6 +22,10 @@ std=["tinywasm/std"] name="hello" path="src/hello.rs" +[[bin]] +name="host_fn" +path="src/host_fn.rs" + [[bin]] name="print" path="src/print.rs" diff --git a/examples/rust/build.sh b/examples/rust/build.sh index d0415ac..e1d320f 100755 --- a/examples/rust/build.sh +++ b/examples/rust/build.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -cd "$(dirname "$0")" +cd "$(dirname "$0")" || exit -bins=("hello" "fibonacci" "print" "tinywasm" "argon2id") +bins=("host_fn" "hello" "fibonacci" "print" "tinywasm" "argon2id") exclude_wat=("tinywasm") out_dir="./target/wasm32-unknown-unknown/wasm" dest_dir="out" diff --git a/examples/rust/src/argon2id.rs b/examples/rust/src/argon2id.rs index 01ea7ca..ff17d04 100644 --- a/examples/rust/src/argon2id.rs +++ b/examples/rust/src/argon2id.rs @@ -1,6 +1,6 @@ #![no_main] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn argon2id(m_cost: i32, t_cost: i32, p_cost: i32) -> i32 { let password = b"password"; let salt = b"some random salt"; diff --git a/examples/rust/src/fibonacci.rs b/examples/rust/src/fibonacci.rs index b847ad5..ec4a371 100644 --- a/examples/rust/src/fibonacci.rs +++ b/examples/rust/src/fibonacci.rs @@ -1,6 +1,6 @@ #![no_main] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn fibonacci(n: i32) -> i32 { let mut sum = 0; let mut last = 0; @@ -13,7 +13,7 @@ pub extern "C" fn fibonacci(n: i32) -> i32 { sum } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn fibonacci_recursive(n: i32) -> i32 { if n <= 1 { return n; diff --git a/examples/rust/src/hello.rs b/examples/rust/src/hello.rs index c8e2ac3..3d9f400 100644 --- a/examples/rust/src/hello.rs +++ b/examples/rust/src/hello.rs @@ -1,23 +1,23 @@ #![no_main] #[link(wasm_import_module = "env")] -extern "C" { +unsafe extern "C" { fn print_utf8(location: i64, len: i32); } const ARG: &[u8] = &[0u8; 100]; -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn arg_ptr() -> i32 { ARG.as_ptr() as i32 } -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn arg_size() -> i32 { ARG.len() as i32 } -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn hello(len: i32) { let arg = core::str::from_utf8(&ARG[0..len as usize]).unwrap(); let res = format!("Hello, {}!", arg).as_bytes().to_vec(); diff --git a/examples/rust/src/host_fn.rs b/examples/rust/src/host_fn.rs new file mode 100644 index 0000000..ada74bd --- /dev/null +++ b/examples/rust/src/host_fn.rs @@ -0,0 +1,11 @@ +#![no_main] + +#[link(wasm_import_module = "env")] +unsafe extern "C" { + fn bar(left: i64, right: i32) -> i32; +} + +#[unsafe(no_mangle)] +pub fn foo() -> i32 { + unsafe { bar(1, 2) } +} diff --git a/examples/rust/src/print.rs b/examples/rust/src/print.rs index d04daa3..d2934f0 100644 --- a/examples/rust/src/print.rs +++ b/examples/rust/src/print.rs @@ -1,11 +1,11 @@ #![no_main] #[link(wasm_import_module = "env")] -extern "C" { +unsafe extern "C" { fn printi32(x: i32); } -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn add_and_print(lh: i32, rh: i32) { printi32(lh + rh); } diff --git a/examples/rust/src/tinywasm.rs b/examples/rust/src/tinywasm.rs index c3bf2d2..d3b3f8c 100644 --- a/examples/rust/src/tinywasm.rs +++ b/examples/rust/src/tinywasm.rs @@ -2,11 +2,11 @@ use tinywasm::{Extern, FuncContext}; #[link(wasm_import_module = "env")] -extern "C" { +unsafe extern "C" { fn printi32(x: i32); } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn hello() { let _ = run(); } diff --git a/examples/rust/src/tinywasm_no_std.rs b/examples/rust/src/tinywasm_no_std.rs index 9a31d20..46f1785 100644 --- a/examples/rust/src/tinywasm_no_std.rs +++ b/examples/rust/src/tinywasm_no_std.rs @@ -16,11 +16,11 @@ static ALLOCATOR: AssumeSingleThreaded = unsafe { AssumeSingleThreaded::new(FreeListAllocator::new()) }; #[link(wasm_import_module = "env")] -extern "C" { +unsafe extern "C" { fn printi32(x: i32); } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn hello() { let _ = run(); } @@ -30,7 +30,7 @@ fn run() -> tinywasm::Result<()> { let mut imports = tinywasm::Imports::new(); let res = tinywasm::parser::Parser::new().parse_module_bytes(include_bytes!("./print.wasm"))?; - let twasm = res.serialize_twasm(); + let twasm = res.serialize_twasm()?; let module = tinywasm::Module::parse_bytes(&twasm)?; imports.define( diff --git a/examples/wasm-rust.rs b/examples/wasm-rust.rs index 429bdcb..95769f4 100644 --- a/examples/wasm-rust.rs +++ b/examples/wasm-rust.rs @@ -33,6 +33,7 @@ fn main() -> Result<()> { println!("Available examples:"); println!(" hello"); println!(" printi32"); + println!(" host_fn"); println!(" fibonacci - calculate fibonacci(30)"); println!(" tinywasm - run printi32 inside of tinywasm inside of itself"); println!(" argon2id - run argon2id(1000, 2, 1)"); @@ -46,6 +47,7 @@ fn main() -> Result<()> { "tinywasm" => tinywasm()?, "tinywasm_no_std" => tinywasm_no_std()?, "argon2id" => argon2id()?, + "host_fn" => host_fn()?, "all" => { println!("Running all examples"); println!("\nhello.wasm:"); @@ -60,6 +62,8 @@ fn main() -> Result<()> { tinywasm_no_std()?; println!("argon2id.wasm:"); argon2id()?; + println!("\nhost_fn.wasm:"); + host_fn()?; } _ => {} } @@ -126,6 +130,26 @@ fn hello() -> Result<()> { Ok(()) } +fn host_fn() -> Result<()> { + let module = Module::parse_file("./examples/rust/out/host_fn.wasm")?; + let mut store = Store::default(); + let mut imports = Imports::new(); + imports.define( + "env", + "bar", + Extern::typed_func(|_: FuncContext<'_>, (left, right): (i64, i32)| { + assert_eq!(left, 1); + assert_eq!(right, 2); + Ok(left as i32 + right) + }), + )?; + + let instance = module.instantiate(&mut store, Some(imports))?; + let host_fn = instance.exported_func::<(), i32>(&store, "foo")?; + assert_eq!(host_fn.call(&mut store, ())?, 3); + Ok(()) +} + fn printi32() -> Result<()> { let module = Module::parse_file("./examples/rust/out/print.opt.wasm")?; let mut store = Store::default(); From 60bea1e5e52d6672509dc394ab0df1e8b8423b00 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Tue, 25 Feb 2025 19:39:51 +0100 Subject: [PATCH 41/54] chore: update to rust 2024 Signed-off-by: Henry Gressmann --- Cargo.lock | 118 ++++++------------ Cargo.toml | 9 +- crates/parser/Cargo.toml | 2 +- crates/parser/src/conversion.rs | 4 +- crates/parser/src/lib.rs | 2 - crates/parser/src/module.rs | 2 +- crates/parser/src/visit.rs | 4 +- crates/tinywasm/Cargo.toml | 2 +- crates/tinywasm/benches/argon2id.rs | 4 +- crates/tinywasm/benches/fibonacci.rs | 7 +- crates/tinywasm/benches/tinywasm.rs | 6 +- crates/tinywasm/src/error.rs | 2 +- crates/tinywasm/src/func.rs | 2 +- crates/tinywasm/src/imports.rs | 6 +- .../src/interpreter/stack/call_stack.rs | 4 +- .../src/interpreter/stack/value_stack.rs | 2 +- crates/tinywasm/src/store/memory.rs | 2 +- crates/tinywasm/src/store/mod.rs | 2 +- crates/types/src/archive.rs | 4 +- 19 files changed, 71 insertions(+), 113 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ccb8fa3..1178a8a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -114,18 +114,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.29" +version = "4.5.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acebd8ad879283633b343856142139f2da2317c96b05b4dd6181c61e2480184" +checksum = "027bb0d98429ae334a8698531da7077bdf906419543a35a55c2cb1b66437d767" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.29" +version = "4.5.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ba32cbda51c7e1dfd49acc1457ba1a7dec5b64fe360e828acb13ca8dc9c2f9" +checksum = "5589e0cba072e0f3d23791efac0fd8627b49c829c196a492e88168e6a669d863" dependencies = [ "anstyle", "clap_lex", @@ -211,9 +211,9 @@ checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" [[package]] name = "either" -version = "1.13.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "b7914353092ddf589ad78f25c5c1c21b7f80b0ff8621e7c814c3485b5306da9d" [[package]] name = "embedded-io" @@ -242,9 +242,9 @@ dependencies = [ [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "eyre" @@ -345,12 +345,6 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" -[[package]] -name = "leb128" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" - [[package]] name = "leb128fmt" version = "0.1.0" @@ -359,9 +353,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.169" +version = "0.2.170" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" [[package]] name = "libm" @@ -371,9 +365,9 @@ checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "log" -version = "0.4.25" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" +checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" [[package]] name = "memchr" @@ -404,9 +398,9 @@ checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "owo-colors" -version = "4.1.0" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" +checksum = "1036865bb9422d3300cf723f657c2851d0e9ab12567854b1f4eba3d77decf564" [[package]] name = "postcard" @@ -526,18 +520,18 @@ checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03" [[package]] name = "serde" -version = "1.0.217" +version = "1.0.218" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.217" +version = "1.0.218" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" dependencies = [ "proc-macro2", "quote", @@ -546,9 +540,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.138" +version = "1.0.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" +checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6" dependencies = [ "itoa", "memchr", @@ -602,7 +596,7 @@ dependencies = [ "tinywasm-parser", "tinywasm-types", "wasm-testsuite", - "wast 225.0.0", + "wast", "wat", ] @@ -615,7 +609,7 @@ dependencies = [ "log", "pretty_env_logger", "tinywasm", - "wast 225.0.0", + "wast", ] [[package]] @@ -624,7 +618,7 @@ version = "0.9.0-alpha.0" dependencies = [ "log", "tinywasm-types", - "wasmparser 0.225.0", + "wasmparser", ] [[package]] @@ -648,9 +642,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" +checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" [[package]] name = "unicode-width" @@ -670,89 +664,55 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.224.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ab7a13a23790fe91ea4eb7526a1f3131001d874e3e00c2976c48861f2e82920" -dependencies = [ - "leb128", - "wasmparser 0.224.1", -] - -[[package]] -name = "wasm-encoder" -version = "0.225.0" +version = "0.226.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f7eac0445cac73bcf09e6a97f83248d64356dccf9f2b100199769b6b42464e5" +checksum = "f7d81b727619aec227dce83e7f7420d4e56c79acd044642a356ea045b98d4e13" dependencies = [ "leb128fmt", - "wasmparser 0.225.0", + "wasmparser", ] [[package]] name = "wasm-testsuite" -version = "0.4.2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a4e25e8fd04d2da04479453bb74448dfffb960c5a0ed74df97a4cdddcaab85c" +checksum = "fea6edc2d1ffad1d673091e3e3e98961e7c1a8c0f24cbf2431fa02d861e071bd" dependencies = [ "include_dir", - "wast 224.0.1", + "wast", ] [[package]] name = "wasmparser" -version = "0.224.1" +version = "0.226.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04f17a5917c2ddd3819e84c661fae0d6ba29d7b9c1f0e96c708c65a9c4188e11" +checksum = "bc28600dcb2ba68d7e5f1c3ba4195c2bddc918c0243fd702d0b6dbd05689b681" dependencies = [ "bitflags", "indexmap", "semver", ] -[[package]] -name = "wasmparser" -version = "0.225.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36e5456165f81e64cb9908a0fe9b9d852c2c74582aa3fe2be3c2da57f937d3ae" -dependencies = [ - "bitflags", - "indexmap", - "semver", -] - -[[package]] -name = "wast" -version = "224.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddf8e902015ff670011613811be3310408d2dba911217eea711aa98c89584aca" -dependencies = [ - "bumpalo", - "leb128", - "memchr", - "unicode-width", - "wasm-encoder 0.224.1", -] - [[package]] name = "wast" -version = "225.0.0" +version = "226.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61496027ff707f9fa9e0b22c34ec163eb7adb1070df565e32a9180a76e4300b" +checksum = "0bb903956d0151eabb6c30a2304dd61e5c8d7182805226120c2b6d611fb09a26" dependencies = [ "bumpalo", "leb128fmt", "memchr", "unicode-width", - "wasm-encoder 0.225.0", + "wasm-encoder", ] [[package]] name = "wat" -version = "1.225.0" +version = "1.226.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e72a33942234fd0794bcdac30e43b448de3187512414267678e511c6755f11" +checksum = "5f89a90ef2c401b8b5b2b704020bfa7a7f69b93c3034c7a4b4a88e21e9966581" dependencies = [ - "wast 225.0.0", + "wast", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index e92c4ad..e433260 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,8 +4,9 @@ default-members=[".", "crates/tinywasm", "crates/types", "crates/parser"] resolver="2" [workspace.dependencies] -wast="225" -wat="1.225" +wast="226" +wat="1.226" +wasmparser={version="0.226", default-features=false} eyre="0.6" log="0.4" pretty_env_logger="0.5" @@ -13,8 +14,8 @@ criterion={version="0.5", default-features=false, features=["cargo_bench_support [workspace.package] version="0.9.0-alpha.0" -rust-version="1.81" -edition="2021" +rust-version="1.85" +edition="2024" license="MIT OR Apache-2.0" authors=["Henry Gressmann "] repository="https://github.com/explodingcamera/tinywasm" diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index fec21b3..7bd9cad 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -9,7 +9,7 @@ repository.workspace=true rust-version.workspace=true [dependencies] -wasmparser={version="0.225", default-features=false, features=["validate", "features", "simd"]} +wasmparser={workspace=true, features=["validate", "features", "simd"]} log={workspace=true, optional=true} tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false} diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs index 273dd44..86548d6 100644 --- a/crates/parser/src/conversion.rs +++ b/crates/parser/src/conversion.rs @@ -92,7 +92,7 @@ pub(crate) fn convert_module_import(import: wasmparser::Import<'_>) -> Result { - return Err(crate::ParseError::UnsupportedOperator(format!("Unsupported import kind: {ty:?}"))) + return Err(crate::ParseError::UnsupportedOperator(format!("Unsupported import kind: {ty:?}"))); } }, }) @@ -157,7 +157,7 @@ pub(crate) fn convert_module_export(export: wasmparser::Export<'_>) -> Result ExternalKind::Memory, wasmparser::ExternalKind::Global => ExternalKind::Global, wasmparser::ExternalKind::Tag => { - return Err(crate::ParseError::UnsupportedOperator(format!("Unsupported export kind: {:?}", export.kind))) + return Err(crate::ParseError::UnsupportedOperator(format!("Unsupported export kind: {:?}", export.kind))); } }; diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index 04da9da..e5022c5 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -72,14 +72,12 @@ impl Parser { component_model: false, component_model_nested_names: false, component_model_values: false, - component_model_more_flags: false, exceptions: false, gc: false, memory_control: false, relaxed_simd: false, threads: false, shared_everything_threads: false, - component_model_multiple_returns: false, legacy_exceptions: false, component_model_async: false, }; diff --git a/crates/parser/src/module.rs b/crates/parser/src/module.rs index 9b31f9e..ff6b22b 100644 --- a/crates/parser/src/module.rs +++ b/crates/parser/src/module.rs @@ -1,5 +1,5 @@ use crate::log::debug; -use crate::{conversion, ParseError, Result}; +use crate::{ParseError, Result, conversion}; use alloc::string::ToString; use alloc::{boxed::Box, format, vec::Vec}; use tinywasm_types::{ diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs index 89c27d1..2830d3a 100644 --- a/crates/parser/src/visit.rs +++ b/crates/parser/src/visit.rs @@ -531,11 +531,11 @@ impl wasmparser::VisitSimdOperator<'_> for FunctionBuild fn visit_i8x16_shuffle(&mut self, lanes: [u8; 16]) -> Self::Output { self.v128_constants.push(u128::from_le_bytes(lanes)); - self.instructions.push(Instruction::I8x16Shuffle(self.v128_constants.len() as u32 - 1).into()); + self.instructions.push(Instruction::I8x16Shuffle(self.v128_constants.len() as u32 - 1)); } fn visit_v128_const(&mut self, value: wasmparser::V128) -> Self::Output { self.v128_constants.push(value.i128() as u128); - self.instructions.push(Instruction::V128Const(self.v128_constants.len() as u32 - 1).into()); + self.instructions.push(Instruction::V128Const(self.v128_constants.len() as u32 - 1)); } } diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index 0623f35..2cad2e4 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -20,7 +20,7 @@ tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false libm={version="0.2", default-features=false} [dev-dependencies] -wasm-testsuite={version="0.4.2"} +wasm-testsuite={version="0.4.4"} indexmap="2.7" wast={workspace=true} wat={workspace=true} diff --git a/crates/tinywasm/benches/argon2id.rs b/crates/tinywasm/benches/argon2id.rs index d977352..aa8b38b 100644 --- a/crates/tinywasm/benches/argon2id.rs +++ b/crates/tinywasm/benches/argon2id.rs @@ -1,6 +1,6 @@ -use criterion::{criterion_group, criterion_main, Criterion}; +use criterion::{Criterion, criterion_group, criterion_main}; use eyre::Result; -use tinywasm::{types, ModuleInstance, Store}; +use tinywasm::{ModuleInstance, Store, types}; use types::TinyWasmModule; const WASM: &[u8] = include_bytes!("../../../examples/rust/out/argon2id.opt.wasm"); diff --git a/crates/tinywasm/benches/fibonacci.rs b/crates/tinywasm/benches/fibonacci.rs index dcf6eb9..a5f1c72 100644 --- a/crates/tinywasm/benches/fibonacci.rs +++ b/crates/tinywasm/benches/fibonacci.rs @@ -1,6 +1,6 @@ -use criterion::{criterion_group, criterion_main, Criterion}; +use criterion::{Criterion, criterion_group, criterion_main}; use eyre::Result; -use tinywasm::{types, ModuleInstance, Store}; +use tinywasm::{ModuleInstance, Store, types}; use types::TinyWasmModule; const WASM: &[u8] = include_bytes!("../../../examples/rust/out/fibonacci.opt.wasm"); @@ -17,8 +17,7 @@ fn fibonacci_to_twasm(module: &TinyWasmModule) -> Result> { } fn fibonacci_from_twasm(twasm: &[u8]) -> Result { - let module = TinyWasmModule::from_twasm(&twasm)?; - Ok(module) + Ok(TinyWasmModule::from_twasm(twasm)?) } fn fibonacci_run(module: TinyWasmModule, recursive: bool, n: i32) -> Result<()> { diff --git a/crates/tinywasm/benches/tinywasm.rs b/crates/tinywasm/benches/tinywasm.rs index 8552d6c..4848a4a 100644 --- a/crates/tinywasm/benches/tinywasm.rs +++ b/crates/tinywasm/benches/tinywasm.rs @@ -1,6 +1,6 @@ -use criterion::{criterion_group, criterion_main, Criterion}; +use criterion::{Criterion, criterion_group, criterion_main}; use eyre::Result; -use tinywasm::{types, Extern, FuncContext, Imports, ModuleInstance, Store}; +use tinywasm::{Extern, FuncContext, Imports, ModuleInstance, Store, types}; use types::TinyWasmModule; const WASM: &[u8] = include_bytes!("../../../examples/rust/out/tinywasm.opt.wasm"); @@ -17,7 +17,7 @@ fn tinywasm_to_twasm(module: &TinyWasmModule) -> Result> { } fn tinywasm_from_twasm(twasm: &[u8]) -> Result { - let module = TinyWasmModule::from_twasm(&twasm)?; + let module = TinyWasmModule::from_twasm(twasm)?; Ok(module) } diff --git a/crates/tinywasm/src/error.rs b/crates/tinywasm/src/error.rs index 1d488d8..9637521 100644 --- a/crates/tinywasm/src/error.rs +++ b/crates/tinywasm/src/error.rs @@ -1,8 +1,8 @@ use alloc::string::{String, ToString}; use alloc::vec::Vec; use core::{fmt::Display, ops::ControlFlow}; -use tinywasm_types::archive::TwasmError; use tinywasm_types::FuncType; +use tinywasm_types::archive::TwasmError; #[cfg(feature = "parser")] pub use tinywasm_parser::ParseError; diff --git a/crates/tinywasm/src/func.rs b/crates/tinywasm/src/func.rs index f5a9873..2eeabca 100644 --- a/crates/tinywasm/src/func.rs +++ b/crates/tinywasm/src/func.rs @@ -1,6 +1,6 @@ use crate::interpreter::stack::{CallFrame, Stack}; -use crate::{log, unlikely, Function}; use crate::{Error, FuncContext, Result, Store}; +use crate::{Function, log, unlikely}; use alloc::{boxed::Box, format, string::String, string::ToString, vec, vec::Vec}; use tinywasm_types::{ExternRef, FuncRef, FuncType, ModuleInstanceAddr, ValType, WasmValue}; diff --git a/crates/tinywasm/src/imports.rs b/crates/tinywasm/src/imports.rs index 0797470..12876c8 100644 --- a/crates/tinywasm/src/imports.rs +++ b/crates/tinywasm/src/imports.rs @@ -6,7 +6,7 @@ use alloc::vec::Vec; use core::fmt::Debug; use crate::func::{FromWasmValueTuple, IntoWasmValueTuple, ValTypesFromTuple}; -use crate::{log, LinkingError, MemoryRef, MemoryRefMut, Result}; +use crate::{LinkingError, MemoryRef, MemoryRefMut, Result, log}; use tinywasm_types::*; /// The internal representation of a function @@ -322,7 +322,7 @@ impl Imports { match (expected.size_max, actual.size_max) { (None, Some(_)) => return Err(LinkingError::incompatible_import_type(import).into()), (Some(expected_max), Some(actual_max)) if actual_max < expected_max => { - return Err(LinkingError::incompatible_import_type(import).into()) + return Err(LinkingError::incompatible_import_type(import).into()); } _ => {} } @@ -339,7 +339,7 @@ impl Imports { Self::compare_types(import, &expected.arch(), &actual.arch())?; if actual.page_count_initial() > expected.page_count_initial() - && real_size.map_or(true, |size| actual.page_count_initial() > size as u64) + && real_size.is_none_or(|size| actual.page_count_initial() > size as u64) { return Err(LinkingError::incompatible_import_type(import).into()); } diff --git a/crates/tinywasm/src/interpreter/stack/call_stack.rs b/crates/tinywasm/src/interpreter/stack/call_stack.rs index f0e8d18..9b6c3fd 100644 --- a/crates/tinywasm/src/interpreter/stack/call_stack.rs +++ b/crates/tinywasm/src/interpreter/stack/call_stack.rs @@ -1,9 +1,9 @@ use core::ops::ControlFlow; use super::BlockType; -use crate::interpreter::values::*; use crate::Trap; -use crate::{unlikely, Error}; +use crate::interpreter::values::*; +use crate::{Error, unlikely}; use alloc::boxed::Box; use alloc::{rc::Rc, vec, vec::Vec}; diff --git a/crates/tinywasm/src/interpreter/stack/value_stack.rs b/crates/tinywasm/src/interpreter/stack/value_stack.rs index ea6a082..9830c01 100644 --- a/crates/tinywasm/src/interpreter/stack/value_stack.rs +++ b/crates/tinywasm/src/interpreter/stack/value_stack.rs @@ -1,7 +1,7 @@ use alloc::vec::Vec; use tinywasm_types::{ExternRef, FuncRef, ValType, ValueCounts, ValueCountsSmall, WasmValue}; -use crate::{interpreter::*, Result}; +use crate::{Result, interpreter::*}; use super::Locals; pub(crate) const STACK_32_SIZE: usize = 1024 * 32; diff --git a/crates/tinywasm/src/store/memory.rs b/crates/tinywasm/src/store/memory.rs index 4826b65..d204c67 100644 --- a/crates/tinywasm/src/store/memory.rs +++ b/crates/tinywasm/src/store/memory.rs @@ -2,7 +2,7 @@ use alloc::vec; use alloc::vec::Vec; use tinywasm_types::{MemoryType, ModuleInstanceAddr}; -use crate::{cold, log, Error, Result}; +use crate::{Error, Result, cold, log}; /// A WebAssembly Memory Instance /// diff --git a/crates/tinywasm/src/store/mod.rs b/crates/tinywasm/src/store/mod.rs index 86cbb5d..5730631 100644 --- a/crates/tinywasm/src/store/mod.rs +++ b/crates/tinywasm/src/store/mod.rs @@ -4,7 +4,7 @@ use core::sync::atomic::{AtomicUsize, Ordering}; use tinywasm_types::*; use crate::interpreter::{self, InterpreterRuntime, TinyWasmValue}; -use crate::{cold, Error, Function, ModuleInstance, Result, Trap}; +use crate::{Error, Function, ModuleInstance, Result, Trap, cold}; mod data; mod element; diff --git a/crates/types/src/archive.rs b/crates/types/src/archive.rs index a725e3d..cbc22ad 100644 --- a/crates/types/src/archive.rs +++ b/crates/types/src/archive.rs @@ -52,13 +52,13 @@ impl TinyWasmModule { pub fn from_twasm(wasm: &[u8]) -> Result { let len = validate_magic(wasm)?; - postcard::from_bytes(&wasm[len..]).map_err(|e| TwasmError::InvalidArchive(e)) + postcard::from_bytes(&wasm[len..]).map_err(TwasmError::InvalidArchive) } /// Serializes the `TinyWasmModule` into a vector of bytes. pub fn serialize_twasm(&self) -> Result, TwasmError> { let buf = Vec::from(TWASM_MAGIC); - postcard::to_extend(self, buf).map_err(|e| TwasmError::InvalidArchive(e)) + postcard::to_extend(self, buf).map_err(TwasmError::InvalidArchive) } } From d0264fcae4ba4ffb7e5417ddce464e663de66940 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Fri, 28 Feb 2025 23:28:19 +0100 Subject: [PATCH 42/54] wip: initial simd support Signed-off-by: Henry Gressmann --- crates/cli/src/args.rs | 1 + crates/tinywasm/Cargo.toml | 3 +- crates/tinywasm/src/interpreter/executor.rs | 78 ++++++++++++++++++- crates/tinywasm/src/interpreter/mod.rs | 3 + crates/tinywasm/src/interpreter/simd.rs | 18 +++++ .../src/interpreter/stack/value_stack.rs | 12 ++- crates/tinywasm/src/interpreter/values.rs | 36 ++++++++- crates/tinywasm/src/lib.rs | 2 +- crates/tinywasm/tests/generated/wasm-3.csv | 2 +- crates/types/src/instructions.rs | 7 +- 10 files changed, 150 insertions(+), 12 deletions(-) create mode 100644 crates/tinywasm/src/interpreter/simd.rs diff --git a/crates/cli/src/args.rs b/crates/cli/src/args.rs index 96c3605..a23f1f4 100644 --- a/crates/cli/src/args.rs +++ b/crates/cli/src/args.rs @@ -25,6 +25,7 @@ impl FromStr for WasmArg { "i64" => val.parse::().map_err(|e| format!("invalid argument value for i64: {e:?}"))?.into(), "f32" => val.parse::().map_err(|e| format!("invalid argument value for f32: {e:?}"))?.into(), "f64" => val.parse::().map_err(|e| format!("invalid argument value for f64: {e:?}"))?.into(), + "v128" => val.parse::().map_err(|e| format!("invalid argument value for v128: {e:?}"))?.into(), t => return Err(format!("Invalid arg type: {t}")), }; diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index 2cad2e4..0ea406c 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -32,11 +32,12 @@ serde_json={version="1.0"} serde={version="1.0", features=["derive"]} [features] -default=["std", "parser", "logging", "archive"] +default=["std", "parser", "logging", "archive", "simd"] logging=["log", "tinywasm-parser?/logging", "tinywasm-types/logging"] std=["tinywasm-parser?/std", "tinywasm-types/std"] parser=["dep:tinywasm-parser"] archive=["tinywasm-types/archive"] +simd=[] [[test]] name="test-wasm-1" diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index 3c579c1..291ab64 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -3,10 +3,15 @@ use super::no_std_floats::NoStdFloatExt; use alloc::{format, rc::Rc, string::ToString}; -use core::ops::ControlFlow; +use core::ops::{ControlFlow, Not}; +use core::simd::cmp::{SimdPartialEq, SimdPartialOrd}; +use core::simd::num::SimdUint; use interpreter::stack::CallFrame; use tinywasm_types::*; +#[cfg(feature = "simd")] +use super::simd::*; + use super::num_helpers::*; use super::stack::{BlockFrame, BlockType, Stack}; use super::values::*; @@ -41,6 +46,8 @@ impl<'store, 'stack> Executor<'store, 'stack> { #[inline(always)] fn exec_next(&mut self) -> ControlFlow> { use tinywasm_types::Instruction::*; + + #[rustfmt::skip] match self.cf.fetch_instr() { Nop | BrLabel(_) | I32ReinterpretF32 | I64ReinterpretF64 | F32ReinterpretI32 | F64ReinterpretI64 => {} Unreachable => self.exec_unreachable()?, @@ -302,6 +309,75 @@ impl<'store, 'stack> Executor<'store, 'stack> { LocalCopy128(from, to) => self.exec_local_copy::(*from, *to), LocalCopyRef(from, to) => self.exec_local_copy::(*from, *to), + V128Not => self.stack.values.replace_top_same::(|v| Ok(!v)).to_cf()?, + V128And => self.stack.values.calculate_same::(|a, b| Ok(a & b)).to_cf()?, + V128AndNot => self.stack.values.calculate_same::(|a, b| Ok(a & (!b))).to_cf()?, + V128Or => self.stack.values.calculate_same::(|a, b| Ok(a | b)).to_cf()?, + V128Xor => self.stack.values.calculate_same::(|a, b| Ok(a ^ b)).to_cf()?, + V128Bitselect => self.stack.values.calculate_same_3::(|v1, v2, c| Ok((v1 & c) | (v2 & !c))).to_cf()?, + V128AnyTrue => self.stack.values.replace_top::(|v| Ok((v.reduce_sum() != 0) as i32)).to_cf()?, + + I8x16Swizzle => self.stack.values.calculate_same::(|a, s| Ok(a.swizzle_dyn(s))).to_cf()?, + + I8x16Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v as i8).to_ne_bytes())).to_cf()?, + I16x8Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v as i16).to_ne_bytes())).to_cf()?, + I32x4Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v).to_ne_bytes())).to_cf()?, + I64x2Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v).to_ne_bytes())).to_cf()?, + F32x4Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v).to_ne_bytes())).to_cf()?, + F64x2Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v).to_ne_bytes())).to_cf()?, + + I8x16Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int().to_ne_bytes())).to_cf()?, + I16x8Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int().to_ne_bytes())).to_cf()?, + I32x4Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int().to_ne_bytes())).to_cf()?, + F32x4Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int().to_ne_bytes())).to_cf()?, + F64x2Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int().to_ne_bytes())).to_cf()?, + + I8x16Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int().to_ne_bytes())).to_cf()?, + I16x8Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int().to_ne_bytes())).to_cf()?, + I32x4Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int().to_ne_bytes())).to_cf()?, + F32x4Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int().to_ne_bytes())).to_cf()?, + F64x2Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int().to_ne_bytes())).to_cf()?, + + I8x16LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int().to_ne_bytes())).to_cf()?, + I16x8LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int().to_ne_bytes())).to_cf()?, + I32x4LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int().to_ne_bytes())).to_cf()?, + I64x2LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int().to_ne_bytes())).to_cf()?, + F32x4Lt => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int().to_ne_bytes())).to_cf()?, + F64x2Lt => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int().to_ne_bytes())).to_cf()?, + + I8x16LtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int().to_ne_bytes())).to_cf()?, + I16x8LtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int().to_ne_bytes())).to_cf()?, + I32x4LtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int().to_ne_bytes())).to_cf()?, + I64x2GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int().to_ne_bytes())).to_cf()?, + F32x4Gt => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int().to_ne_bytes())).to_cf()?, + F64x2Gt => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int().to_ne_bytes())).to_cf()?, + + I8x16GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int().to_ne_bytes())).to_cf()?, + I16x8GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int().to_ne_bytes())).to_cf()?, + I32x4GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int().to_ne_bytes())).to_cf()?, + I64x2LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int().to_ne_bytes())).to_cf()?, + F32x4Le => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int().to_ne_bytes())).to_cf()?, + F64x2Le => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int().to_ne_bytes())).to_cf()?, + + I8x16GtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int().to_ne_bytes())).to_cf()?, + I16x8GtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int().to_ne_bytes())).to_cf()?, + I32x4GtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int().to_ne_bytes())).to_cf()?, + I64x2GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int().to_ne_bytes())).to_cf()?, + F32x4Ge => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int().to_ne_bytes())).to_cf()?, + F64x2Ge => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int().to_ne_bytes())).to_cf()?, + + I8x16LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int().to_ne_bytes())).to_cf()?, + I16x8LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int().to_ne_bytes())).to_cf()?, + I32x4LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int().to_ne_bytes())).to_cf()?, + + I8x16LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int().to_ne_bytes())).to_cf()?, + I16x8LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int().to_ne_bytes())).to_cf()?, + I32x4LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int().to_ne_bytes())).to_cf()?, + + I8x16GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int().to_ne_bytes())).to_cf()?, + I16x8GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int().to_ne_bytes())).to_cf()?, + I32x4GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int().to_ne_bytes())).to_cf()?, + i => return ControlFlow::Break(Some(Error::UnsupportedFeature(format!("unimplemented opcode: {i:?}")))), }; diff --git a/crates/tinywasm/src/interpreter/mod.rs b/crates/tinywasm/src/interpreter/mod.rs index 0b7df2f..269bcfb 100644 --- a/crates/tinywasm/src/interpreter/mod.rs +++ b/crates/tinywasm/src/interpreter/mod.rs @@ -6,6 +6,9 @@ mod values; #[cfg(not(feature = "std"))] mod no_std_floats; +#[cfg(feature = "simd")] +mod simd; + use crate::{Result, Store}; pub use values::*; diff --git a/crates/tinywasm/src/interpreter/simd.rs b/crates/tinywasm/src/interpreter/simd.rs new file mode 100644 index 0000000..53c64e3 --- /dev/null +++ b/crates/tinywasm/src/interpreter/simd.rs @@ -0,0 +1,18 @@ +pub(super) use core::ops::Neg; + +pub(super) use core::simd::Simd; +pub(super) use core::simd::ToBytes; +pub(super) use core::simd::num::SimdFloat; +pub(super) use core::simd::num::SimdInt; + +macro_rules! impl_wasm_simd_val { + ($($v:ident),*) => { + $( + pub(super) fn $v(f: core::simd::u8x16) -> core::simd::$v { + core::simd::$v::from_ne_bytes(f) + } + )* + }; +} + +impl_wasm_simd_val!(i8x16, i16x8, i32x4, i64x2, f32x4, f64x2); diff --git a/crates/tinywasm/src/interpreter/stack/value_stack.rs b/crates/tinywasm/src/interpreter/stack/value_stack.rs index 9830c01..843723a 100644 --- a/crates/tinywasm/src/interpreter/stack/value_stack.rs +++ b/crates/tinywasm/src/interpreter/stack/value_stack.rs @@ -71,6 +71,11 @@ impl ValueStack { T::stack_calculate(self, func) } + #[inline] + pub(crate) fn calculate_same_3(&mut self, func: impl FnOnce(T, T, T) -> Result) -> Result<()> { + T::stack_calculate3(self, func) + } + #[inline] pub(crate) fn calculate( &mut self, @@ -170,11 +175,16 @@ impl ValueStack { match val_type { ValType::I32 => WasmValue::I32(self.pop()), ValType::I64 => WasmValue::I64(self.pop()), - ValType::V128 => WasmValue::V128(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())), + + #[cfg(not(feature = "simd"))] + ValType::V128 => WasmValue::V128(self.pop()), + + #[cfg(feature = "simd")] + ValType::V128 => WasmValue::V128(u128::from_ne_bytes(self.pop::().to_array())), } } diff --git a/crates/tinywasm/src/interpreter/values.rs b/crates/tinywasm/src/interpreter/values.rs index 712baf7..7a2a916 100644 --- a/crates/tinywasm/src/interpreter/values.rs +++ b/crates/tinywasm/src/interpreter/values.rs @@ -5,9 +5,13 @@ use super::stack::{Locals, ValueStack}; pub(crate) type Value32 = u32; pub(crate) type Value64 = u64; -pub(crate) type Value128 = u128; pub(crate) type ValueRef = Option; +#[cfg(feature = "simd")] +pub(crate) type Value128 = core::simd::u8x16; +#[cfg(not(feature = "simd"))] +pub(crate) type Value128 = u128; + #[derive(Debug, Clone, Copy, PartialEq)] /// A untyped WebAssembly value pub enum TinyWasmValue { @@ -106,9 +110,14 @@ impl TinyWasmValue { ValType::I64 => WasmValue::I64(self.unwrap_64() as i64), ValType::F32 => WasmValue::F32(f32::from_bits(self.unwrap_32())), ValType::F64 => WasmValue::F64(f64::from_bits(self.unwrap_64())), - ValType::V128 => WasmValue::V128(self.unwrap_128()), ValType::RefExtern => WasmValue::RefExtern(ExternRef::new(self.unwrap_ref())), ValType::RefFunc => WasmValue::RefFunc(FuncRef::new(self.unwrap_ref())), + + #[cfg(feature = "simd")] + ValType::V128 => WasmValue::V128(u128::from_ne_bytes(self.unwrap_128().to_array())), + + #[cfg(not(feature = "simd"))] + ValType::V128 => WasmValue::V128(self.unwrap_128()), } } } @@ -118,11 +127,16 @@ impl From<&WasmValue> for TinyWasmValue { match value { WasmValue::I32(v) => TinyWasmValue::Value32(*v as u32), WasmValue::I64(v) => TinyWasmValue::Value64(*v as u64), - WasmValue::V128(v) => TinyWasmValue::Value128(*v), WasmValue::F32(v) => TinyWasmValue::Value32(v.to_bits()), WasmValue::F64(v) => TinyWasmValue::Value64(v.to_bits()), WasmValue::RefExtern(v) => TinyWasmValue::ValueRef(v.addr()), WasmValue::RefFunc(v) => TinyWasmValue::ValueRef(v.addr()), + + #[cfg(not(feature = "simd"))] + WasmValue::V128(v) => TinyWasmValue::Value128(*v), + + #[cfg(feature = "simd")] + WasmValue::V128(v) => TinyWasmValue::Value128(v.to_ne_bytes().into()), } } } @@ -144,6 +158,9 @@ pub(crate) trait InternalValue: sealed::Sealed + Into { where Self: Sized; fn stack_calculate(stack: &mut ValueStack, func: impl FnOnce(Self, Self) -> Result) -> Result<()> + where + Self: Sized; + fn stack_calculate3(stack: &mut ValueStack, func: impl FnOnce(Self, Self, Self) -> Result) -> Result<()> where Self: Sized; @@ -202,6 +219,19 @@ macro_rules! impl_internalvalue { return Ok(()) } + #[inline(always)] + fn stack_calculate3(stack: &mut ValueStack, func: impl FnOnce(Self, Self, Self) -> Result) -> Result<()> { + let v3 = stack.$stack.pop(); + let v2 = stack.$stack.pop(); + let v1 = stack.$stack.last_mut(); + let (Some(v1), Some(v2), Some(v3)) = (v1, v2, v3) else { + unreachable!("ValueStack underflow, this is a bug"); + }; + + *v1 = $to_internal(func($to_outer(*v1), $to_outer(v2), $to_outer(v3))?); + return Ok(()) + } + #[inline(always)] fn replace_top(stack: &mut ValueStack, func: impl FnOnce(Self) -> Result) -> Result<()> { let Some(v) = stack.$stack.last_mut() else { diff --git a/crates/tinywasm/src/lib.rs b/crates/tinywasm/src/lib.rs index d3431e2..72c38cd 100644 --- a/crates/tinywasm/src/lib.rs +++ b/crates/tinywasm/src/lib.rs @@ -5,7 +5,7 @@ ))] #![warn(missing_docs, missing_debug_implementations, rust_2018_idioms, unreachable_pub)] #![forbid(unsafe_code)] -// #![cfg_attr(feature = "nightly", feature(portable_simd))] +#![cfg_attr(feature = "simd", feature(portable_simd))] //! A tiny WebAssembly Runtime written in Rust //! diff --git a/crates/tinywasm/tests/generated/wasm-3.csv b/crates/tinywasm/tests/generated/wasm-3.csv index ed301e4..26f2937 100644 --- a/crates/tinywasm/tests/generated/wasm-3.csv +++ b/crates/tinywasm/tests/generated/wasm-3.csv @@ -1 +1 @@ -0.9.0-alpha.0,32305,2591,[{"name":"address.wast","passed":260,"failed":0},{"name":"address64.wast","passed":0,"failed":242},{"name":"align.wast","passed":161,"failed":0},{"name":"align64.wast","passed":83,"failed":73},{"name":"annotations.wast","passed":74,"failed":0},{"name":"binary-leb128.wast","passed":92,"failed":1},{"name":"binary.wast","passed":126,"failed":0},{"name":"block.wast","passed":223,"failed":0},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":119,"failed":0},{"name":"br_on_non_null.wast","passed":1,"failed":9},{"name":"br_on_null.wast","passed":1,"failed":9},{"name":"br_table.wast","passed":24,"failed":162},{"name":"bulk.wast","passed":117,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":49,"failed":124},{"name":"call_ref.wast","passed":4,"failed":31},{"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":59,"failed":6},{"name":"elem.wast","passed":137,"failed":14},{"name":"endianness.wast","passed":69,"failed":0},{"name":"endianness64.wast","passed":0,"failed":69},{"name":"exports.wast","passed":97,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_memory64.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":471,"failed":0},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":175,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"global.wast","passed":53,"failed":71},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":169,"failed":90},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"instance.wast","passed":0,"failed":23},{"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":142,"failed":21},{"name":"load.wast","passed":118,"failed":0},{"name":"load64.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_init.wast","passed":10,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":98,"failed":0},{"name":"loop.wast","passed":120,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":89,"failed":0},{"name":"memory64.wast","passed":14,"failed":53},{"name":"memory_copy.wast","passed":8385,"failed":515},{"name":"memory_fill.wast","passed":164,"failed":36},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_grow64.wast","passed":0,"failed":49},{"name":"memory_init.wast","passed":307,"failed":173},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_redundancy64.wast","passed":0,"failed":8},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"memory_trap64.wast","passed":0,"failed":172},{"name":"names.wast","passed":486,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref.wast","passed":12,"failed":1},{"name":"ref_as_non_null.wast","passed":1,"failed":6},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":2,"failed":20},{"name":"ref_null.wast","passed":0,"failed":34},{"name":"return.wast","passed":84,"failed":0},{"name":"return_call.wast","passed":11,"failed":34},{"name":"return_call_indirect.wast","passed":26,"failed":50},{"name":"return_call_ref.wast","passed":11,"failed":40},{"name":"select.wast","passed":155,"failed":2},{"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":111,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"table-sub.wast","passed":2,"failed":1},{"name":"table.wast","passed":47,"failed":9},{"name":"table_copy.wast","passed":1742,"failed":30},{"name":"table_copy_mixed.wast","passed":4,"failed":0},{"name":"table_fill.wast","passed":45,"failed":35},{"name":"table_get.wast","passed":16,"failed":1},{"name":"table_grow.wast","passed":58,"failed":21},{"name":"table_init.wast","passed":780,"failed":96},{"name":"table_set.wast","passed":26,"failed":2},{"name":"table_size.wast","passed":39,"failed":1},{"name":"tag.wast","passed":1,"failed":8},{"name":"throw.wast","passed":3,"failed":10},{"name":"throw_ref.wast","passed":2,"failed":13},{"name":"token.wast","passed":61,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"try_table.wast","passed":11,"failed":51},{"name":"type-canon.wast","passed":0,"failed":2},{"name":"type-equivalence.wast","passed":12,"failed":20},{"name":"type-rec.wast","passed":6,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":121,"failed":0},{"name":"unreached-valid.wast","passed":2,"failed":11},{"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.9.0-alpha.0,32305,2598,[{"name":"address.wast","passed":260,"failed":0},{"name":"address64.wast","passed":0,"failed":242},{"name":"align.wast","passed":161,"failed":0},{"name":"align64.wast","passed":83,"failed":73},{"name":"annotations.wast","passed":74,"failed":0},{"name":"binary-leb128.wast","passed":92,"failed":1},{"name":"binary.wast","passed":126,"failed":0},{"name":"block.wast","passed":223,"failed":0},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":119,"failed":0},{"name":"br_on_non_null.wast","passed":1,"failed":9},{"name":"br_on_null.wast","passed":1,"failed":9},{"name":"br_table.wast","passed":24,"failed":162},{"name":"bulk.wast","passed":117,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":49,"failed":124},{"name":"call_ref.wast","passed":4,"failed":31},{"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":59,"failed":6},{"name":"elem.wast","passed":137,"failed":14},{"name":"endianness.wast","passed":69,"failed":0},{"name":"endianness64.wast","passed":0,"failed":69},{"name":"exports.wast","passed":97,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_memory64.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":471,"failed":0},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":175,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"global.wast","passed":53,"failed":71},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":169,"failed":90},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"instance.wast","passed":0,"failed":23},{"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":142,"failed":21},{"name":"load.wast","passed":118,"failed":0},{"name":"load64.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_init.wast","passed":10,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":98,"failed":0},{"name":"loop.wast","passed":120,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":89,"failed":1},{"name":"memory64.wast","passed":14,"failed":55},{"name":"memory_copy.wast","passed":8385,"failed":515},{"name":"memory_fill.wast","passed":164,"failed":36},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_grow64.wast","passed":0,"failed":49},{"name":"memory_init.wast","passed":307,"failed":173},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_redundancy64.wast","passed":0,"failed":8},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"memory_trap64.wast","passed":0,"failed":172},{"name":"names.wast","passed":486,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref.wast","passed":12,"failed":1},{"name":"ref_as_non_null.wast","passed":1,"failed":6},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":2,"failed":20},{"name":"ref_null.wast","passed":0,"failed":34},{"name":"return.wast","passed":84,"failed":0},{"name":"return_call.wast","passed":11,"failed":34},{"name":"return_call_indirect.wast","passed":26,"failed":50},{"name":"return_call_ref.wast","passed":11,"failed":40},{"name":"select.wast","passed":155,"failed":2},{"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":111,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"table-sub.wast","passed":2,"failed":1},{"name":"table.wast","passed":47,"failed":13},{"name":"table_copy.wast","passed":1742,"failed":30},{"name":"table_copy_mixed.wast","passed":4,"failed":0},{"name":"table_fill.wast","passed":45,"failed":35},{"name":"table_get.wast","passed":16,"failed":1},{"name":"table_grow.wast","passed":58,"failed":21},{"name":"table_init.wast","passed":780,"failed":96},{"name":"table_set.wast","passed":26,"failed":2},{"name":"table_size.wast","passed":39,"failed":1},{"name":"tag.wast","passed":1,"failed":8},{"name":"throw.wast","passed":3,"failed":10},{"name":"throw_ref.wast","passed":2,"failed":13},{"name":"token.wast","passed":61,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"try_table.wast","passed":11,"failed":51},{"name":"type-canon.wast","passed":0,"failed":2},{"name":"type-equivalence.wast","passed":12,"failed":20},{"name":"type-rec.wast","passed":6,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":121,"failed":0},{"name":"unreached-valid.wast","passed":2,"failed":11},{"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/instructions.rs b/crates/types/src/instructions.rs index c61a02f..e3e30f6 100644 --- a/crates/types/src/instructions.rs +++ b/crates/types/src/instructions.rs @@ -206,12 +206,11 @@ pub enum Instruction { F32x4ExtractLane(u8), F32x4ReplaceLane(u8), F64x2ExtractLane(u8), F64x2ReplaceLane(u8), - V128Not, V128And, V128AndNot, V128Or, V128Xor, V128Bitselect, V128AnyTrue, - - I8x16Splat, I8x16Swizzle, I8x16Eq, I8x16Ne, I8x16LtS, I8x16LtU, I8x16GtS, I8x16GtU, I8x16LeS, I8x16LeU, I8x16GeS, I8x16GeU, + V128Not, V128And, V128AndNot, V128Or, V128Xor, V128Bitselect, V128AnyTrue, I8x16Swizzle, + I8x16Splat, I8x16Eq, I8x16Ne, I8x16LtS, I8x16LtU, I8x16GtS, I8x16GtU, I8x16LeS, I8x16LeU, I8x16GeS, I8x16GeU, I16x8Splat, I16x8Eq, I16x8Ne, I16x8LtS, I16x8LtU, I16x8GtS, I16x8GtU, I16x8LeS, I16x8LeU, I16x8GeS, I16x8GeU, I32x4Splat, I32x4Eq, I32x4Ne, I32x4LtS, I32x4LtU, I32x4GtS, I32x4GtU, I32x4LeS, I32x4LeU, I32x4GeS, I32x4GeU, - I64x2Splat, I64x2Eq, I64x2Ne, I64x2LtS, I64x2GtS, I64x2LeS, I64x2GeS, + I64x2Splat, I64x2Eq, I64x2Ne, I64x2LtS, I64x2GtS, I64x2LeS, I64x2GeS, F32x4Splat, F32x4Eq, F32x4Ne, F32x4Lt, F32x4Gt, F32x4Le, F32x4Ge, F64x2Splat, F64x2Eq, F64x2Ne, F64x2Lt, F64x2Gt, F64x2Le, F64x2Ge, From 741a3d6e94970f097d0cd19cbe9f9a7266b67fb4 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sat, 1 Mar 2025 00:34:17 +0100 Subject: [PATCH 43/54] chore: add back simd testsuite Signed-off-by: Henry Gressmann --- Cargo.lock | 6 +- crates/tinywasm/Cargo.toml | 7 +- crates/tinywasm/src/interpreter/executor.rs | 124 +++++++++--------- crates/tinywasm/src/interpreter/simd.rs | 17 +-- crates/tinywasm/src/interpreter/values.rs | 20 ++- crates/tinywasm/tests/generated/wasm-simd.csv | 2 +- crates/tinywasm/tests/test-wasm-simd.rs | 13 ++ crates/types/src/instructions.rs | 2 +- 8 files changed, 108 insertions(+), 83 deletions(-) create mode 100644 crates/tinywasm/tests/test-wasm-simd.rs diff --git a/Cargo.lock b/Cargo.lock index 1178a8a..6aca5b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -674,9 +674,9 @@ dependencies = [ [[package]] name = "wasm-testsuite" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea6edc2d1ffad1d673091e3e3e98961e7c1a8c0f24cbf2431fa02d861e071bd" +checksum = "3439010f90930c46aead98a232d3e38c147d9543db7e6a40289297b2eda13941" dependencies = [ "include_dir", "wast", diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index 0ea406c..734a962 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -20,7 +20,7 @@ tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false libm={version="0.2", default-features=false} [dev-dependencies] -wasm-testsuite={version="0.4.4"} +wasm-testsuite={version="0.4.5"} indexmap="2.7" wast={workspace=true} wat={workspace=true} @@ -78,6 +78,11 @@ name="test-wasm-relaxed-simd" harness=false test=false +[[test]] +name="test-wasm-simd" +harness=false +test=false + [[test]] name="test-wast" harness=false diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index 291ab64..100075b 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -3,7 +3,7 @@ use super::no_std_floats::NoStdFloatExt; use alloc::{format, rc::Rc, string::ToString}; -use core::ops::{ControlFlow, Not}; +use core::ops::ControlFlow; use core::simd::cmp::{SimdPartialEq, SimdPartialOrd}; use core::simd::num::SimdUint; use interpreter::stack::CallFrame; @@ -316,67 +316,71 @@ impl<'store, 'stack> Executor<'store, 'stack> { V128Xor => self.stack.values.calculate_same::(|a, b| Ok(a ^ b)).to_cf()?, V128Bitselect => self.stack.values.calculate_same_3::(|v1, v2, c| Ok((v1 & c) | (v2 & !c))).to_cf()?, V128AnyTrue => self.stack.values.replace_top::(|v| Ok((v.reduce_sum() != 0) as i32)).to_cf()?, - I8x16Swizzle => self.stack.values.calculate_same::(|a, s| Ok(a.swizzle_dyn(s))).to_cf()?, - I8x16Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v as i8).to_ne_bytes())).to_cf()?, - I16x8Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v as i16).to_ne_bytes())).to_cf()?, - I32x4Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v).to_ne_bytes())).to_cf()?, - I64x2Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v).to_ne_bytes())).to_cf()?, - F32x4Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v).to_ne_bytes())).to_cf()?, - F64x2Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v).to_ne_bytes())).to_cf()?, - - I8x16Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int().to_ne_bytes())).to_cf()?, - I16x8Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int().to_ne_bytes())).to_cf()?, - I32x4Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int().to_ne_bytes())).to_cf()?, - F32x4Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int().to_ne_bytes())).to_cf()?, - F64x2Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int().to_ne_bytes())).to_cf()?, - - I8x16Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int().to_ne_bytes())).to_cf()?, - I16x8Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int().to_ne_bytes())).to_cf()?, - I32x4Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int().to_ne_bytes())).to_cf()?, - F32x4Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int().to_ne_bytes())).to_cf()?, - F64x2Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int().to_ne_bytes())).to_cf()?, - - I8x16LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int().to_ne_bytes())).to_cf()?, - I16x8LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int().to_ne_bytes())).to_cf()?, - I32x4LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int().to_ne_bytes())).to_cf()?, - I64x2LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int().to_ne_bytes())).to_cf()?, - F32x4Lt => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int().to_ne_bytes())).to_cf()?, - F64x2Lt => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int().to_ne_bytes())).to_cf()?, - - I8x16LtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int().to_ne_bytes())).to_cf()?, - I16x8LtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int().to_ne_bytes())).to_cf()?, - I32x4LtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int().to_ne_bytes())).to_cf()?, - I64x2GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int().to_ne_bytes())).to_cf()?, - F32x4Gt => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int().to_ne_bytes())).to_cf()?, - F64x2Gt => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int().to_ne_bytes())).to_cf()?, - - I8x16GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int().to_ne_bytes())).to_cf()?, - I16x8GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int().to_ne_bytes())).to_cf()?, - I32x4GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int().to_ne_bytes())).to_cf()?, - I64x2LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int().to_ne_bytes())).to_cf()?, - F32x4Le => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int().to_ne_bytes())).to_cf()?, - F64x2Le => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int().to_ne_bytes())).to_cf()?, - - I8x16GtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int().to_ne_bytes())).to_cf()?, - I16x8GtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int().to_ne_bytes())).to_cf()?, - I32x4GtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int().to_ne_bytes())).to_cf()?, - I64x2GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int().to_ne_bytes())).to_cf()?, - F32x4Ge => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int().to_ne_bytes())).to_cf()?, - F64x2Ge => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int().to_ne_bytes())).to_cf()?, - - I8x16LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int().to_ne_bytes())).to_cf()?, - I16x8LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int().to_ne_bytes())).to_cf()?, - I32x4LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int().to_ne_bytes())).to_cf()?, - - I8x16LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int().to_ne_bytes())).to_cf()?, - I16x8LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int().to_ne_bytes())).to_cf()?, - I32x4LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int().to_ne_bytes())).to_cf()?, - - I8x16GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int().to_ne_bytes())).to_cf()?, - I16x8GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int().to_ne_bytes())).to_cf()?, - I32x4GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int().to_ne_bytes())).to_cf()?, + I8x16Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v as i8))).to_cf()?, + I16x8Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v as i16))).to_cf()?, + I32x4Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v))).to_cf()?, + I64x2Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v))).to_cf()?, + F32x4Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v))).to_cf()?, + F64x2Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v))).to_cf()?, + + I8x16Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, + I16x8Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, + I32x4Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, + F32x4Eq => self.stack.values.calculate::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, + F64x2Eq => self.stack.values.calculate::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, + + I8x16Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, + I16x8Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, + I32x4Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, + F32x4Ne => self.stack.values.calculate::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, + F64x2Ne => self.stack.values.calculate::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, + + I8x16LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + I16x8LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + I32x4LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + I64x2LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + I8x16LtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + I16x8LtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + I32x4LtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + F32x4Lt => self.stack.values.calculate::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + F64x2Lt => self.stack.values.calculate::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + + I64x2GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + F32x4Gt => self.stack.values.calculate::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + F64x2Gt => self.stack.values.calculate::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + + I8x16GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + I16x8GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + I32x4GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + I64x2LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + F32x4Le => self.stack.values.calculate::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + F64x2Le => self.stack.values.calculate::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + + I8x16GtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + I16x8GtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + I32x4GtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + I64x2GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + F32x4Ge => self.stack.values.calculate::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + F64x2Ge => self.stack.values.calculate::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + + I8x16LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + I16x8LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + I32x4LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + + I8x16LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + I16x8LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + I32x4LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + + I8x16GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + I16x8GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + I32x4GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + + I8x16Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, + I16x8Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, + I32x4Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, + I64x2Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, i => return ControlFlow::Break(Some(Error::UnsupportedFeature(format!("unimplemented opcode: {i:?}")))), }; diff --git a/crates/tinywasm/src/interpreter/simd.rs b/crates/tinywasm/src/interpreter/simd.rs index 53c64e3..2042bc6 100644 --- a/crates/tinywasm/src/interpreter/simd.rs +++ b/crates/tinywasm/src/interpreter/simd.rs @@ -1,18 +1,3 @@ -pub(super) use core::ops::Neg; - -pub(super) use core::simd::Simd; -pub(super) use core::simd::ToBytes; pub(super) use core::simd::num::SimdFloat; pub(super) use core::simd::num::SimdInt; - -macro_rules! impl_wasm_simd_val { - ($($v:ident),*) => { - $( - pub(super) fn $v(f: core::simd::u8x16) -> core::simd::$v { - core::simd::$v::from_ne_bytes(f) - } - )* - }; -} - -impl_wasm_simd_val!(i8x16, i16x8, i32x4, i64x2, f32x4, f64x2); +pub(super) use core::simd::*; diff --git a/crates/tinywasm/src/interpreter/values.rs b/crates/tinywasm/src/interpreter/values.rs index 7a2a916..98d40af 100644 --- a/crates/tinywasm/src/interpreter/values.rs +++ b/crates/tinywasm/src/interpreter/values.rs @@ -1,7 +1,7 @@ use crate::Result; -use tinywasm_types::{ExternRef, FuncRef, LocalAddr, ValType, WasmValue}; use super::stack::{Locals, ValueStack}; +use tinywasm_types::{ExternRef, FuncRef, LocalAddr, ValType, WasmValue}; pub(crate) type Value32 = u32; pub(crate) type Value64 = u64; @@ -272,3 +272,21 @@ impl_internalvalue! { Value128, stack_128, locals_128, Value128, Value128, |v| v, |v| v ValueRef, stack_ref, locals_ref, ValueRef, ValueRef, |v| v, |v| v } + +#[cfg(feature = "simd")] +use core::simd::{num::SimdUint, *}; + +#[cfg(feature = "simd")] +impl_internalvalue! { + Value128, stack_128, locals_128, u8x16, u128, |v: u128| v.to_ne_bytes().into(), |v: u8x16| u128::from_ne_bytes(v.into()) + Value128, stack_128, locals_128, u8x16, i8x16, |v: i8x16| v.to_ne_bytes(), |v: u8x16| v.cast() + Value128, stack_128, locals_128, u8x16, i16x8, |v: i16x8| v.to_ne_bytes(), |v: u8x16| i16x8::from_ne_bytes(v) + Value128, stack_128, locals_128, u8x16, i32x4, |v: i32x4| v.to_ne_bytes(), |v: u8x16| i32x4::from_ne_bytes(v) + Value128, stack_128, locals_128, u8x16, i64x2, |v: i64x2| v.to_ne_bytes(), |v: u8x16| i64x2::from_ne_bytes(v) + Value128, stack_128, locals_128, u8x16, f32x4, |v: f32x4| v.to_ne_bytes(), |v: u8x16| f32x4::from_ne_bytes(v) + Value128, stack_128, locals_128, u8x16, f64x2, |v: f64x2| v.to_ne_bytes(), |v: u8x16| f64x2::from_ne_bytes(v) + + Value128, stack_128, locals_128, u8x16, u16x8, |v: u16x8| v.to_ne_bytes(), |v: u8x16| u16x8::from_ne_bytes(v) + Value128, stack_128, locals_128, u8x16, u32x4, |v: u32x4| v.to_ne_bytes(), |v: u8x16| u32x4::from_ne_bytes(v) + Value128, stack_128, locals_128, u8x16, u64x2, |v: u64x2| v.to_ne_bytes(), |v: u8x16| u64x2::from_ne_bytes(v) +} diff --git a/crates/tinywasm/tests/generated/wasm-simd.csv b/crates/tinywasm/tests/generated/wasm-simd.csv index d695dfa..210564b 100644 --- a/crates/tinywasm/tests/generated/wasm-simd.csv +++ b/crates/tinywasm/tests/generated/wasm-simd.csv @@ -1,2 +1,2 @@ 0.8.0,1300,24679,[{"name":"simd_address.wast","passed":4,"failed":45},{"name":"simd_align.wast","passed":46,"failed":54},{"name":"simd_bit_shift.wast","passed":39,"failed":213},{"name":"simd_bitwise.wast","passed":28,"failed":141},{"name":"simd_boolean.wast","passed":16,"failed":261},{"name":"simd_const.wast","passed":301,"failed":456},{"name":"simd_conversions.wast","passed":48,"failed":234},{"name":"simd_f32x4.wast","passed":16,"failed":774},{"name":"simd_f32x4_arith.wast","passed":16,"failed":1806},{"name":"simd_f32x4_cmp.wast","passed":24,"failed":2583},{"name":"simd_f32x4_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f32x4_rounding.wast","passed":24,"failed":177},{"name":"simd_f64x2.wast","passed":8,"failed":795},{"name":"simd_f64x2_arith.wast","passed":16,"failed":1809},{"name":"simd_f64x2_cmp.wast","passed":24,"failed":2661},{"name":"simd_f64x2_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f64x2_rounding.wast","passed":24,"failed":177},{"name":"simd_i16x8_arith.wast","passed":11,"failed":183},{"name":"simd_i16x8_arith2.wast","passed":19,"failed":153},{"name":"simd_i16x8_cmp.wast","passed":30,"failed":435},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":4,"failed":17},{"name":"simd_i16x8_extmul_i8x16.wast","passed":12,"failed":105},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":3,"failed":27},{"name":"simd_i16x8_sat_arith.wast","passed":16,"failed":206},{"name":"simd_i32x4_arith.wast","passed":11,"failed":183},{"name":"simd_i32x4_arith2.wast","passed":26,"failed":123},{"name":"simd_i32x4_cmp.wast","passed":40,"failed":435},{"name":"simd_i32x4_dot_i16x8.wast","passed":3,"failed":27},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":4,"failed":17},{"name":"simd_i32x4_extmul_i16x8.wast","passed":12,"failed":105},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":4,"failed":103},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":4,"failed":103},{"name":"simd_i64x2_arith.wast","passed":11,"failed":189},{"name":"simd_i64x2_arith2.wast","passed":2,"failed":23},{"name":"simd_i64x2_cmp.wast","passed":10,"failed":103},{"name":"simd_i64x2_extmul_i32x4.wast","passed":12,"failed":105},{"name":"simd_i8x16_arith.wast","passed":8,"failed":123},{"name":"simd_i8x16_arith2.wast","passed":25,"failed":186},{"name":"simd_i8x16_cmp.wast","passed":30,"failed":415},{"name":"simd_i8x16_sat_arith.wast","passed":24,"failed":190},{"name":"simd_int_to_int_extend.wast","passed":24,"failed":229},{"name":"simd_lane.wast","passed":189,"failed":286},{"name":"simd_linking.wast","passed":0,"failed":3},{"name":"simd_load.wast","passed":8,"failed":31},{"name":"simd_load16_lane.wast","passed":3,"failed":33},{"name":"simd_load32_lane.wast","passed":3,"failed":21},{"name":"simd_load64_lane.wast","passed":3,"failed":13},{"name":"simd_load8_lane.wast","passed":3,"failed":49},{"name":"simd_load_extend.wast","passed":18,"failed":86},{"name":"simd_load_splat.wast","passed":12,"failed":114},{"name":"simd_load_zero.wast","passed":10,"failed":29},{"name":"simd_splat.wast","passed":23,"failed":162},{"name":"simd_store.wast","passed":9,"failed":19},{"name":"simd_store16_lane.wast","passed":3,"failed":33},{"name":"simd_store32_lane.wast","passed":3,"failed":21},{"name":"simd_store64_lane.wast","passed":3,"failed":13},{"name":"simd_store8_lane.wast","passed":3,"failed":49}] -0.9.0-alpha.0,1741,24238,[{"name":"simd_address.wast","passed":7,"failed":42},{"name":"simd_align.wast","passed":93,"failed":7},{"name":"simd_bit_shift.wast","passed":41,"failed":211},{"name":"simd_bitwise.wast","passed":30,"failed":139},{"name":"simd_boolean.wast","passed":18,"failed":259},{"name":"simd_const.wast","passed":551,"failed":206},{"name":"simd_conversions.wast","passed":50,"failed":232},{"name":"simd_f32x4.wast","passed":18,"failed":772},{"name":"simd_f32x4_arith.wast","passed":19,"failed":1803},{"name":"simd_f32x4_cmp.wast","passed":26,"failed":2581},{"name":"simd_f32x4_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f32x4_rounding.wast","passed":25,"failed":176},{"name":"simd_f64x2.wast","passed":10,"failed":793},{"name":"simd_f64x2_arith.wast","passed":19,"failed":1806},{"name":"simd_f64x2_cmp.wast","passed":26,"failed":2659},{"name":"simd_f64x2_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f64x2_rounding.wast","passed":25,"failed":176},{"name":"simd_i16x8_arith.wast","passed":13,"failed":181},{"name":"simd_i16x8_arith2.wast","passed":21,"failed":151},{"name":"simd_i16x8_cmp.wast","passed":32,"failed":433},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":5,"failed":16},{"name":"simd_i16x8_extmul_i8x16.wast","passed":13,"failed":104},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":4,"failed":26},{"name":"simd_i16x8_sat_arith.wast","passed":18,"failed":204},{"name":"simd_i32x4_arith.wast","passed":13,"failed":181},{"name":"simd_i32x4_arith2.wast","passed":28,"failed":121},{"name":"simd_i32x4_cmp.wast","passed":42,"failed":433},{"name":"simd_i32x4_dot_i16x8.wast","passed":4,"failed":26},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":5,"failed":16},{"name":"simd_i32x4_extmul_i16x8.wast","passed":13,"failed":104},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":5,"failed":102},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":5,"failed":102},{"name":"simd_i64x2_arith.wast","passed":13,"failed":187},{"name":"simd_i64x2_arith2.wast","passed":4,"failed":21},{"name":"simd_i64x2_cmp.wast","passed":11,"failed":102},{"name":"simd_i64x2_extmul_i32x4.wast","passed":13,"failed":104},{"name":"simd_i8x16_arith.wast","passed":10,"failed":121},{"name":"simd_i8x16_arith2.wast","passed":27,"failed":184},{"name":"simd_i8x16_cmp.wast","passed":32,"failed":413},{"name":"simd_i8x16_sat_arith.wast","passed":26,"failed":188},{"name":"simd_int_to_int_extend.wast","passed":25,"failed":228},{"name":"simd_lane.wast","passed":209,"failed":266},{"name":"simd_linking.wast","passed":0,"failed":3},{"name":"simd_load.wast","passed":24,"failed":15},{"name":"simd_load16_lane.wast","passed":4,"failed":32},{"name":"simd_load32_lane.wast","passed":4,"failed":20},{"name":"simd_load64_lane.wast","passed":4,"failed":12},{"name":"simd_load8_lane.wast","passed":4,"failed":48},{"name":"simd_load_extend.wast","passed":24,"failed":80},{"name":"simd_load_splat.wast","passed":17,"failed":109},{"name":"simd_load_zero.wast","passed":12,"failed":27},{"name":"simd_splat.wast","passed":37,"failed":148},{"name":"simd_store.wast","passed":20,"failed":8},{"name":"simd_store16_lane.wast","passed":3,"failed":33},{"name":"simd_store32_lane.wast","passed":3,"failed":21},{"name":"simd_store64_lane.wast","passed":3,"failed":13},{"name":"simd_store8_lane.wast","passed":3,"failed":49}] +0.9.0-alpha.0,1808,24172,[{"name":"simd_address.wast","passed":7,"failed":42},{"name":"simd_align.wast","passed":92,"failed":8},{"name":"simd_bit_shift.wast","passed":41,"failed":211},{"name":"simd_bitwise.wast","passed":30,"failed":139},{"name":"simd_boolean.wast","passed":123,"failed":154},{"name":"simd_const.wast","passed":551,"failed":206},{"name":"simd_conversions.wast","passed":50,"failed":232},{"name":"simd_f32x4.wast","passed":18,"failed":772},{"name":"simd_f32x4_arith.wast","passed":19,"failed":1803},{"name":"simd_f32x4_cmp.wast","passed":26,"failed":2581},{"name":"simd_f32x4_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f32x4_rounding.wast","passed":25,"failed":176},{"name":"simd_f64x2.wast","passed":10,"failed":793},{"name":"simd_f64x2_arith.wast","passed":19,"failed":1806},{"name":"simd_f64x2_cmp.wast","passed":26,"failed":2659},{"name":"simd_f64x2_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f64x2_rounding.wast","passed":25,"failed":176},{"name":"simd_i16x8_arith.wast","passed":13,"failed":181},{"name":"simd_i16x8_arith2.wast","passed":21,"failed":151},{"name":"simd_i16x8_cmp.wast","passed":32,"failed":433},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":5,"failed":16},{"name":"simd_i16x8_extmul_i8x16.wast","passed":13,"failed":104},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":4,"failed":26},{"name":"simd_i16x8_sat_arith.wast","passed":18,"failed":204},{"name":"simd_i32x4_arith.wast","passed":13,"failed":181},{"name":"simd_i32x4_arith2.wast","passed":28,"failed":121},{"name":"simd_i32x4_cmp.wast","passed":42,"failed":433},{"name":"simd_i32x4_dot_i16x8.wast","passed":4,"failed":26},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":5,"failed":16},{"name":"simd_i32x4_extmul_i16x8.wast","passed":13,"failed":104},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":5,"failed":102},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":5,"failed":102},{"name":"simd_i64x2_arith.wast","passed":13,"failed":187},{"name":"simd_i64x2_arith2.wast","passed":4,"failed":21},{"name":"simd_i64x2_cmp.wast","passed":11,"failed":102},{"name":"simd_i64x2_extmul_i32x4.wast","passed":13,"failed":104},{"name":"simd_i8x16_arith.wast","passed":10,"failed":121},{"name":"simd_i8x16_arith2.wast","passed":27,"failed":184},{"name":"simd_i8x16_cmp.wast","passed":32,"failed":413},{"name":"simd_i8x16_sat_arith.wast","passed":26,"failed":188},{"name":"simd_int_to_int_extend.wast","passed":25,"failed":228},{"name":"simd_lane.wast","passed":200,"failed":275},{"name":"simd_linking.wast","passed":0,"failed":3},{"name":"simd_load.wast","passed":22,"failed":17},{"name":"simd_load16_lane.wast","passed":4,"failed":32},{"name":"simd_load32_lane.wast","passed":4,"failed":20},{"name":"simd_load64_lane.wast","passed":4,"failed":12},{"name":"simd_load8_lane.wast","passed":4,"failed":48},{"name":"simd_load_extend.wast","passed":20,"failed":84},{"name":"simd_load_splat.wast","passed":14,"failed":112},{"name":"simd_load_zero.wast","passed":12,"failed":27},{"name":"simd_memory-multi.wast","passed":1,"failed":0},{"name":"simd_splat.wast","passed":26,"failed":159},{"name":"simd_store.wast","passed":11,"failed":17},{"name":"simd_store16_lane.wast","passed":3,"failed":33},{"name":"simd_store32_lane.wast","passed":3,"failed":21},{"name":"simd_store64_lane.wast","passed":3,"failed":13},{"name":"simd_store8_lane.wast","passed":3,"failed":49}] diff --git a/crates/tinywasm/tests/test-wasm-simd.rs b/crates/tinywasm/tests/test-wasm-simd.rs new file mode 100644 index 0000000..d8f15ea --- /dev/null +++ b/crates/tinywasm/tests/test-wasm-simd.rs @@ -0,0 +1,13 @@ +mod testsuite; +use eyre::Result; +use testsuite::TestSuite; +use wasm_testsuite::data::{Proposal, proposal}; + +fn main() -> Result<()> { + TestSuite::set_log_level(log::LevelFilter::Off); + + let mut test_suite = TestSuite::new(); + test_suite.run_files(proposal(&Proposal::Simd))?; + test_suite.save_csv("./tests/generated/wasm-simd.csv", env!("CARGO_PKG_VERSION"))?; + test_suite.report_status() +} diff --git a/crates/types/src/instructions.rs b/crates/types/src/instructions.rs index e3e30f6..24116e8 100644 --- a/crates/types/src/instructions.rs +++ b/crates/types/src/instructions.rs @@ -216,7 +216,7 @@ pub enum Instruction { I8x16Abs, I8x16Neg, I8x16AllTrue, I8x16Bitmask, I8x16Shl, I8x16ShrS, I8x16ShrU, I8x16Add, I8x16Sub, I8x16MinS, I8x16MinU, I8x16MaxS, I8x16MaxU, I16x8Abs, I16x8Neg, I16x8AllTrue, I16x8Bitmask, I16x8Shl, I16x8ShrS, I16x8ShrU, I16x8Add, I16x8Sub, I16x8MinS, I16x8MinU, I16x8MaxS, I16x8MaxU, - I32x4Abs, I32x4Neg, I32x4AllTrue, I32x4Bitmask, I32x4Shl, I32x4ShrS, I32x4ShrU, I32x4Add, I32x4Sub, I32x4MinS, I32x4MinU, I32x4MaxS, I32x4MaxU, + I32x4Abs, I32x4Neg, I32x4AllTrue, I32x4Bitmask, I32x4Shl, I32x4ShrS, I32x4ShrU, I32x4Add, I32x4Sub, I32x4MinS, I32x4MinU, I32x4MaxS, I32x4MaxU, I64x2Abs, I64x2Neg, I64x2AllTrue, I64x2Bitmask, I64x2Shl, I64x2ShrS, I64x2ShrU, I64x2Add, I64x2Sub, I64x2Mul, I8x16NarrowI16x8S, I8x16NarrowI16x8U, I8x16AddSatS, I8x16AddSatU, I8x16SubSatS, I8x16SubSatU, I8x16AvgrU, From afc76e44457975e3d20b3a490c5029dec6f4983a Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sat, 1 Mar 2025 19:49:41 +0100 Subject: [PATCH 44/54] feat: add most basic simd instructions Signed-off-by: Henry Gressmann --- crates/cli/src/args.rs | 2 +- crates/parser/src/conversion.rs | 1 + crates/parser/src/visit.rs | 10 +- crates/tinywasm/src/interpreter/executor.rs | 162 +++++++++++++++++- crates/tinywasm/src/interpreter/mod.rs | 3 - crates/tinywasm/src/interpreter/simd.rs | 3 - .../src/interpreter/stack/call_stack.rs | 7 +- .../src/interpreter/stack/value_stack.rs | 2 +- crates/tinywasm/src/interpreter/values.rs | 31 ++-- crates/tinywasm/src/store/memory.rs | 45 +++-- crates/tinywasm/tests/generated/wasm-simd.csv | 2 +- crates/tinywasm/tests/testsuite/util.rs | 28 +-- crates/types/src/instructions.rs | 1 + crates/types/src/lib.rs | 2 +- crates/types/src/value.rs | 8 +- 15 files changed, 245 insertions(+), 62 deletions(-) delete mode 100644 crates/tinywasm/src/interpreter/simd.rs diff --git a/crates/cli/src/args.rs b/crates/cli/src/args.rs index a23f1f4..1fec2d5 100644 --- a/crates/cli/src/args.rs +++ b/crates/cli/src/args.rs @@ -25,7 +25,7 @@ impl FromStr for WasmArg { "i64" => val.parse::().map_err(|e| format!("invalid argument value for i64: {e:?}"))?.into(), "f32" => val.parse::().map_err(|e| format!("invalid argument value for f32: {e:?}"))?.into(), "f64" => val.parse::().map_err(|e| format!("invalid argument value for f64: {e:?}"))?.into(), - "v128" => val.parse::().map_err(|e| format!("invalid argument value for v128: {e:?}"))?.into(), + "v128" => val.parse::().map_err(|e| format!("invalid argument value for v128: {e:?}"))?.into(), t => return Err(format!("Invalid arg type: {t}")), }; diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs index 86548d6..a4e3b35 100644 --- a/crates/parser/src/conversion.rs +++ b/crates/parser/src/conversion.rs @@ -261,6 +261,7 @@ pub(crate) fn process_const_operators(ops: OperatorsReader<'_>) -> Result Ok(ConstInstruction::I64Const(*value)), wasmparser::Operator::F32Const { value } => Ok(ConstInstruction::F32Const(f32::from_bits(value.bits()))), wasmparser::Operator::F64Const { value } => Ok(ConstInstruction::F64Const(f64::from_bits(value.bits()))), + wasmparser::Operator::V128Const { value } => Ok(ConstInstruction::V128Const(value.i128())), wasmparser::Operator::GlobalGet { global_index } => Ok(ConstInstruction::GlobalGet(*global_index)), op => Err(crate::ParseError::UnsupportedOperator(format!("Unsupported const instruction: {op:?}"))), } diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs index 2830d3a..270f6c6 100644 --- a/crates/parser/src/visit.rs +++ b/crates/parser/src/visit.rs @@ -111,7 +111,7 @@ macro_rules! define_mem_operands_simd_lane { pub(crate) struct FunctionBuilder { validator: FuncValidator, instructions: Vec, - v128_constants: Vec, + v128_constants: Vec, label_ptrs: Vec, local_addr_map: Vec, errors: Vec, @@ -530,12 +530,12 @@ impl wasmparser::VisitSimdOperator<'_> for FunctionBuild } fn visit_i8x16_shuffle(&mut self, lanes: [u8; 16]) -> Self::Output { - self.v128_constants.push(u128::from_le_bytes(lanes)); - self.instructions.push(Instruction::I8x16Shuffle(self.v128_constants.len() as u32 - 1)); + self.instructions.push(Instruction::I8x16Shuffle(self.v128_constants.len() as u32)); + self.v128_constants.push(i128::from_le_bytes(lanes)); } fn visit_v128_const(&mut self, value: wasmparser::V128) -> Self::Output { - self.v128_constants.push(value.i128() as u128); - self.instructions.push(Instruction::V128Const(self.v128_constants.len() as u32 - 1)); + self.instructions.push(Instruction::V128Const(self.v128_constants.len() as u32)); + self.v128_constants.push(value.i128()); } } diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index 100075b..932fad9 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -3,14 +3,21 @@ use super::no_std_floats::NoStdFloatExt; use alloc::{format, rc::Rc, string::ToString}; -use core::ops::ControlFlow; -use core::simd::cmp::{SimdPartialEq, SimdPartialOrd}; -use core::simd::num::SimdUint; +use core::ops::{ControlFlow, IndexMut, Shl, Shr}; + use interpreter::stack::CallFrame; use tinywasm_types::*; #[cfg(feature = "simd")] -use super::simd::*; +mod simd { + #[cfg(feature = "std")] + pub(super) use crate::std::simd::StdFloat; + pub(super) use core::simd::cmp::{SimdOrd, SimdPartialEq, SimdPartialOrd}; + pub(super) use core::simd::num::{SimdFloat, SimdInt, SimdUint}; + pub(super) use core::simd::*; +} +#[cfg(feature = "simd")] +use simd::*; use super::num_helpers::*; use super::stack::{BlockFrame, BlockType, Stack}; @@ -315,8 +322,16 @@ impl<'store, 'stack> Executor<'store, 'stack> { V128Or => self.stack.values.calculate_same::(|a, b| Ok(a | b)).to_cf()?, V128Xor => self.stack.values.calculate_same::(|a, b| Ok(a ^ b)).to_cf()?, V128Bitselect => self.stack.values.calculate_same_3::(|v1, v2, c| Ok((v1 & c) | (v2 & !c))).to_cf()?, - V128AnyTrue => self.stack.values.replace_top::(|v| Ok((v.reduce_sum() != 0) as i32)).to_cf()?, + V128AnyTrue => self.stack.values.replace_top::(|v| Ok((v.reduce_or() != 0) as i32)).to_cf()?, I8x16Swizzle => self.stack.values.calculate_same::(|a, s| Ok(a.swizzle_dyn(s))).to_cf()?, + V128Load(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| v)?, + V128Store(arg) => self.exec_mem_store::(arg.mem_addr(), arg.offset(), |v| v)?, + V128Const(arg) => self.exec_const::( self.cf.data().v128_constants[*arg as usize].to_le_bytes().into()), + + V128Load8Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, + V128Load16Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, + V128Load32Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, + V128Load64Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, I8x16Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v as i8))).to_cf()?, I16x8Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v as i16))).to_cf()?, @@ -373,6 +388,10 @@ impl<'store, 'stack> Executor<'store, 'stack> { I16x8LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, I32x4LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + I8x16GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + I16x8GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + I32x4GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + I8x16GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, I16x8GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, I32x4GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, @@ -382,6 +401,98 @@ impl<'store, 'stack> Executor<'store, 'stack> { I32x4Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, I64x2Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, + I8x16Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, + I16x8Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, + I32x4Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, + I64x2Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, + + I8x16AllTrue => self.stack.values.replace_top::(|v| Ok((v != Simd::splat(0)) as i32)).to_cf()?, + I16x8AllTrue => self.stack.values.replace_top::(|v| Ok((v != Simd::splat(0)) as i32)).to_cf()?, + I32x4AllTrue => self.stack.values.replace_top::(|v| Ok((v != Simd::splat(0)) as i32)).to_cf()?, + I64x2AllTrue => self.stack.values.replace_top::(|v| Ok((v != Simd::splat(0)) as i32)).to_cf()?, + + I8x16Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, + I16x8Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, + I32x4Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, + I64x2Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, + + I8x16Shl => self.stack.values.calculate_same::(|a, b| Ok(a.shl(b))).to_cf()?, + I16x8Shl => self.stack.values.calculate_same::(|a, b| Ok(a.shl(b))).to_cf()?, + I32x4Shl => self.stack.values.calculate_same::(|a, b| Ok(a.shl(b))).to_cf()?, + I64x2Shl => self.stack.values.calculate_same::(|a, b| Ok(a.shl(b))).to_cf()?, + + I8x16ShrS => self.stack.values.calculate_same::(|a, b| Ok(a.shr(b))).to_cf()?, + I16x8ShrS => self.stack.values.calculate_same::(|a, b| Ok(a.shr(b))).to_cf()?, + I32x4ShrS => self.stack.values.calculate_same::(|a, b| Ok(a.shr(b))).to_cf()?, + I64x2ShrS => self.stack.values.calculate_same::(|a, b| Ok(a.shr(b))).to_cf()?, + + I8x16ShrU => self.stack.values.calculate_same::(|a, b| Ok(a.shr(b))).to_cf()?, + I16x8ShrU => self.stack.values.calculate_same::(|a, b| Ok(a.shr(b))).to_cf()?, + I32x4ShrU => self.stack.values.calculate_same::(|a, b| Ok(a.shr(b))).to_cf()?, + I64x2ShrU => self.stack.values.calculate_same::(|a, b| Ok(a.shr(b))).to_cf()?, + + I8x16Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, + I16x8Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, + I32x4Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, + I64x2Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, + + I8x16Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, + I16x8Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, + I32x4Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, + I64x2Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, + + I8x16MinS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, + I16x8MinS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, + I32x4MinS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, + + I8x16MinU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, + I16x8MinU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, + I32x4MinU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, + + I8x16MaxS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + I16x8MaxS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + I32x4MaxS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + + I8x16MaxU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + I16x8MaxU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + I32x4MaxU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + + I64x2Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, + + I8x16AddSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, + I16x8AddSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, + I8x16AddSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, + I16x8AddSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, + I8x16SubSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, + I16x8SubSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, + I8x16SubSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, + I16x8SubSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, + + F32x4Ceil => self.stack.values.replace_top_same::(|v| Ok(v.ceil())).to_cf()?, + F64x2Ceil => self.stack.values.replace_top_same::(|v| Ok(v.ceil())).to_cf()?, + F32x4Floor => self.stack.values.replace_top_same::(|v| Ok(v.floor())).to_cf()?, + F64x2Floor => self.stack.values.replace_top_same::(|v| Ok(v.floor())).to_cf()?, + F32x4Trunc => self.stack.values.replace_top_same::(|v| Ok(v.trunc())).to_cf()?, + F64x2Trunc => self.stack.values.replace_top_same::(|v| Ok(v.trunc())).to_cf()?, + F32x4Abs => self.stack.values.replace_top_same::(|v| Ok(v.abs())).to_cf()?, + F64x2Abs => self.stack.values.replace_top_same::(|v| Ok(v.abs())).to_cf()?, + F32x4Neg => self.stack.values.replace_top_same::(|v| Ok(-v)).to_cf()?, + F64x2Neg => self.stack.values.replace_top_same::(|v| Ok(-v)).to_cf()?, + F32x4Sqrt => self.stack.values.replace_top_same::(|v| Ok(v.sqrt())).to_cf()?, + F64x2Sqrt => self.stack.values.replace_top_same::(|v| Ok(v.sqrt())).to_cf()?, + F32x4Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, + F64x2Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, + F32x4Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, + F64x2Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, + F32x4Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, + F64x2Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, + F32x4Div => self.stack.values.calculate_same::(|a, b| Ok(a / b)).to_cf()?, + F64x2Div => self.stack.values.calculate_same::(|a, b| Ok(a / b)).to_cf()?, + F32x4Min => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, + F64x2Min => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, + F32x4Max => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + F64x2Max => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + i => return ControlFlow::Break(Some(Error::UnsupportedFeature(format!("unimplemented opcode: {i:?}")))), }; @@ -689,6 +800,47 @@ impl<'store, 'stack> Executor<'store, 'stack> { Ok(()) } + fn exec_mem_load_lane< + LOAD: MemLoadable, + INTO: InternalValue + IndexMut, + const LOAD_SIZE: usize, + >( + &mut self, + mem_addr: tinywasm_types::MemAddr, + offset: u64, + lanes: u8, + ) -> ControlFlow> { + let mem = self.store.get_mem(self.module.resolve_mem_addr(mem_addr)); + let mut imm = self.stack.values.pop::(); + let val = self.stack.values.pop::() as u64; + let Some(Ok(addr)) = offset.checked_add(val).map(TryInto::try_into) else { + cold(); + return ControlFlow::Break(Some(Error::Trap(Trap::MemoryOutOfBounds { + offset: val as usize, + len: LOAD_SIZE, + max: 0, + }))); + }; + let val = mem.load_as::(addr).to_cf()?; + imm[lanes as usize] = val; + self.stack.values.push(imm); + ControlFlow::Continue(()) + } + + // fn mem_load, const LOAD_SIZE: usize, TARGET: InternalValue>( + // &mut self, + // mem_addr: tinywasm_types::MemAddr, + // offset: u64, + // ) -> Result { + // let mem = self.store.get_mem(self.module.resolve_mem_addr(mem_addr)); + // let val = self.stack.values.pop::() as u64; + // let Some(Ok(addr)) = offset.checked_add(val).map(TryInto::try_into) else { + // cold(); + // return Err(Error::Trap(Trap::MemoryOutOfBounds { offset: val as usize, len: LOAD_SIZE, max: 0 })); + // }; + // mem.load_as::(addr) + // } + fn exec_mem_load, const LOAD_SIZE: usize, TARGET: InternalValue>( &mut self, mem_addr: tinywasm_types::MemAddr, diff --git a/crates/tinywasm/src/interpreter/mod.rs b/crates/tinywasm/src/interpreter/mod.rs index 269bcfb..0b7df2f 100644 --- a/crates/tinywasm/src/interpreter/mod.rs +++ b/crates/tinywasm/src/interpreter/mod.rs @@ -6,9 +6,6 @@ mod values; #[cfg(not(feature = "std"))] mod no_std_floats; -#[cfg(feature = "simd")] -mod simd; - use crate::{Result, Store}; pub use values::*; diff --git a/crates/tinywasm/src/interpreter/simd.rs b/crates/tinywasm/src/interpreter/simd.rs deleted file mode 100644 index 2042bc6..0000000 --- a/crates/tinywasm/src/interpreter/simd.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub(super) use core::simd::num::SimdFloat; -pub(super) use core::simd::num::SimdInt; -pub(super) use core::simd::*; diff --git a/crates/tinywasm/src/interpreter/stack/call_stack.rs b/crates/tinywasm/src/interpreter/stack/call_stack.rs index 9b6c3fd..25ad81f 100644 --- a/crates/tinywasm/src/interpreter/stack/call_stack.rs +++ b/crates/tinywasm/src/interpreter/stack/call_stack.rs @@ -7,7 +7,7 @@ use crate::{Error, unlikely}; use alloc::boxed::Box; use alloc::{rc::Rc, vec, vec::Vec}; -use tinywasm_types::{Instruction, LocalAddr, ModuleInstanceAddr, WasmFunction, WasmValue}; +use tinywasm_types::{Instruction, LocalAddr, ModuleInstanceAddr, WasmFunction, WasmFunctionData, WasmValue}; pub(crate) const MAX_CALL_STACK_SIZE: usize = 1024; @@ -70,6 +70,11 @@ impl CallFrame { self.instr_ptr } + #[inline] + pub(crate) fn data(&self) -> &WasmFunctionData { + &self.func_instance.data + } + #[inline] pub(crate) fn incr_instr_ptr(&mut self) { self.instr_ptr += 1; diff --git a/crates/tinywasm/src/interpreter/stack/value_stack.rs b/crates/tinywasm/src/interpreter/stack/value_stack.rs index 843723a..bb5b2ea 100644 --- a/crates/tinywasm/src/interpreter/stack/value_stack.rs +++ b/crates/tinywasm/src/interpreter/stack/value_stack.rs @@ -184,7 +184,7 @@ impl ValueStack { ValType::V128 => WasmValue::V128(self.pop()), #[cfg(feature = "simd")] - ValType::V128 => WasmValue::V128(u128::from_ne_bytes(self.pop::().to_array())), + ValType::V128 => WasmValue::V128(i128::from_le_bytes(self.pop::().to_array())), } } diff --git a/crates/tinywasm/src/interpreter/values.rs b/crates/tinywasm/src/interpreter/values.rs index 98d40af..335da59 100644 --- a/crates/tinywasm/src/interpreter/values.rs +++ b/crates/tinywasm/src/interpreter/values.rs @@ -10,7 +10,7 @@ pub(crate) type ValueRef = Option; #[cfg(feature = "simd")] pub(crate) type Value128 = core::simd::u8x16; #[cfg(not(feature = "simd"))] -pub(crate) type Value128 = u128; +pub(crate) type Value128 = i128; #[derive(Debug, Clone, Copy, PartialEq)] /// A untyped WebAssembly value @@ -114,7 +114,7 @@ impl TinyWasmValue { ValType::RefFunc => WasmValue::RefFunc(FuncRef::new(self.unwrap_ref())), #[cfg(feature = "simd")] - ValType::V128 => WasmValue::V128(u128::from_ne_bytes(self.unwrap_128().to_array())), + ValType::V128 => WasmValue::V128(i128::from_le_bytes(self.unwrap_128().to_array())), #[cfg(not(feature = "simd"))] ValType::V128 => WasmValue::V128(self.unwrap_128()), @@ -136,7 +136,7 @@ impl From<&WasmValue> for TinyWasmValue { WasmValue::V128(v) => TinyWasmValue::Value128(*v), #[cfg(feature = "simd")] - WasmValue::V128(v) => TinyWasmValue::Value128(v.to_ne_bytes().into()), + WasmValue::V128(v) => TinyWasmValue::Value128(v.to_le_bytes().into()), } } } @@ -269,8 +269,8 @@ impl_internalvalue! { Value64, stack_64, locals_64, u64, i64, |v| v as u64, |v| v as i64 Value32, stack_32, locals_32, u32, f32, f32::to_bits, f32::from_bits Value64, stack_64, locals_64, u64, f64, f64::to_bits, f64::from_bits - Value128, stack_128, locals_128, Value128, Value128, |v| v, |v| v ValueRef, stack_ref, locals_ref, ValueRef, ValueRef, |v| v, |v| v + Value128, stack_128, locals_128, Value128, Value128, |v| v, |v| v } #[cfg(feature = "simd")] @@ -278,15 +278,16 @@ use core::simd::{num::SimdUint, *}; #[cfg(feature = "simd")] impl_internalvalue! { - Value128, stack_128, locals_128, u8x16, u128, |v: u128| v.to_ne_bytes().into(), |v: u8x16| u128::from_ne_bytes(v.into()) - Value128, stack_128, locals_128, u8x16, i8x16, |v: i8x16| v.to_ne_bytes(), |v: u8x16| v.cast() - Value128, stack_128, locals_128, u8x16, i16x8, |v: i16x8| v.to_ne_bytes(), |v: u8x16| i16x8::from_ne_bytes(v) - Value128, stack_128, locals_128, u8x16, i32x4, |v: i32x4| v.to_ne_bytes(), |v: u8x16| i32x4::from_ne_bytes(v) - Value128, stack_128, locals_128, u8x16, i64x2, |v: i64x2| v.to_ne_bytes(), |v: u8x16| i64x2::from_ne_bytes(v) - Value128, stack_128, locals_128, u8x16, f32x4, |v: f32x4| v.to_ne_bytes(), |v: u8x16| f32x4::from_ne_bytes(v) - Value128, stack_128, locals_128, u8x16, f64x2, |v: f64x2| v.to_ne_bytes(), |v: u8x16| f64x2::from_ne_bytes(v) - - Value128, stack_128, locals_128, u8x16, u16x8, |v: u16x8| v.to_ne_bytes(), |v: u8x16| u16x8::from_ne_bytes(v) - Value128, stack_128, locals_128, u8x16, u32x4, |v: u32x4| v.to_ne_bytes(), |v: u8x16| u32x4::from_ne_bytes(v) - Value128, stack_128, locals_128, u8x16, u64x2, |v: u64x2| v.to_ne_bytes(), |v: u8x16| u64x2::from_ne_bytes(v) + Value128, stack_128, locals_128, u8x16, i128, |v: i128| v.to_le_bytes().into(), |v: u8x16| i128::from_le_bytes(v.into()) + Value128, stack_128, locals_128, u8x16, u128, |v: u128| v.to_le_bytes().into(), |v: u8x16| u128::from_le_bytes(v.into()) + Value128, stack_128, locals_128, u8x16, i8x16, |v: i8x16| v.to_le_bytes(), |v: u8x16| v.cast() + Value128, stack_128, locals_128, u8x16, i16x8, |v: i16x8| v.to_le_bytes(), |v: u8x16| i16x8::from_le_bytes(v) + Value128, stack_128, locals_128, u8x16, i32x4, |v: i32x4| v.to_le_bytes(), |v: u8x16| i32x4::from_le_bytes(v) + Value128, stack_128, locals_128, u8x16, i64x2, |v: i64x2| v.to_le_bytes(), |v: u8x16| i64x2::from_le_bytes(v) + Value128, stack_128, locals_128, u8x16, f32x4, |v: f32x4| v.to_le_bytes(), |v: u8x16| f32x4::from_le_bytes(v) + Value128, stack_128, locals_128, u8x16, f64x2, |v: f64x2| v.to_le_bytes(), |v: u8x16| f64x2::from_le_bytes(v) + + Value128, stack_128, locals_128, u8x16, u16x8, |v: u16x8| v.to_le_bytes(), |v: u8x16| u16x8::from_le_bytes(v) + Value128, stack_128, locals_128, u8x16, u32x4, |v: u32x4| v.to_le_bytes(), |v: u8x16| u32x4::from_le_bytes(v) + Value128, stack_128, locals_128, u8x16, u64x2, |v: u64x2| v.to_le_bytes(), |v: u8x16| u64x2::from_le_bytes(v) } diff --git a/crates/tinywasm/src/store/memory.rs b/crates/tinywasm/src/store/memory.rs index d204c67..a1c7994 100644 --- a/crates/tinywasm/src/store/memory.rs +++ b/crates/tinywasm/src/store/memory.rs @@ -2,7 +2,10 @@ use alloc::vec; use alloc::vec::Vec; use tinywasm_types::{MemoryType, ModuleInstanceAddr}; -use crate::{Error, Result, cold, log}; +use crate::{Error, Result, cold, interpreter::Value128, log}; + +#[cfg(feature = "simd")] +use core::simd::ToBytes; /// A WebAssembly Memory Instance /// @@ -80,7 +83,7 @@ impl MemoryInstance { return Err(self.trap_oob(addr, SIZE)); } - Ok(T::from_le_bytes(match self.data[addr..end].try_into() { + Ok(T::from_mem_bytes(match self.data[addr..end].try_into() { Ok(bytes) => bytes, Err(_) => return Err(self.trap_oob(addr, SIZE)), })) @@ -158,30 +161,52 @@ pub(crate) trait MemStorable { /// A trait for types that can be loaded from memory pub(crate) trait MemLoadable: Sized + Copy { /// Load a value from memory - fn from_le_bytes(bytes: [u8; N]) -> Self; + fn from_mem_bytes(bytes: [u8; N]) -> Self; } macro_rules! impl_mem_traits { - ($($type:ty, $size:expr),*) => { + ($($ty:ty, $size:expr),*) => { $( - impl MemLoadable<$size> for $type { + impl MemLoadable<$size> for $ty { #[inline(always)] - fn from_le_bytes(bytes: [u8; $size]) -> Self { - <$type>::from_le_bytes(bytes) + fn from_mem_bytes(bytes: [u8; $size]) -> Self { + <$ty>::from_le_bytes(bytes.into()) } } - impl MemStorable<$size> for $type { + impl MemStorable<$size> for $ty { #[inline(always)] fn to_mem_bytes(self) -> [u8; $size] { - self.to_ne_bytes() + self.to_le_bytes().into() } } )* } } -impl_mem_traits!(u8, 1, i8, 1, u16, 2, i16, 2, u32, 4, i32, 4, f32, 4, u64, 8, i64, 8, f64, 8, u128, 16, i128, 16); +impl_mem_traits!(u8, 1, i8, 1, u16, 2, i16, 2, u32, 4, i32, 4, f32, 4, u64, 8, i64, 8, f64, 8, Value128, 16); + +#[cfg(feature = "simd")] +impl_mem_traits!( + core::simd::i8x16, + 16, + core::simd::i16x8, + 16, + core::simd::i32x4, + 16, + core::simd::i64x2, + 16, + core::simd::u16x8, + 16, + core::simd::u32x4, + 16, + core::simd::u64x2, + 16, + core::simd::f32x4, + 16, + core::simd::f64x2, + 16 +); #[cfg(test)] mod memory_instance_tests { diff --git a/crates/tinywasm/tests/generated/wasm-simd.csv b/crates/tinywasm/tests/generated/wasm-simd.csv index 210564b..6f37f4d 100644 --- a/crates/tinywasm/tests/generated/wasm-simd.csv +++ b/crates/tinywasm/tests/generated/wasm-simd.csv @@ -1,2 +1,2 @@ 0.8.0,1300,24679,[{"name":"simd_address.wast","passed":4,"failed":45},{"name":"simd_align.wast","passed":46,"failed":54},{"name":"simd_bit_shift.wast","passed":39,"failed":213},{"name":"simd_bitwise.wast","passed":28,"failed":141},{"name":"simd_boolean.wast","passed":16,"failed":261},{"name":"simd_const.wast","passed":301,"failed":456},{"name":"simd_conversions.wast","passed":48,"failed":234},{"name":"simd_f32x4.wast","passed":16,"failed":774},{"name":"simd_f32x4_arith.wast","passed":16,"failed":1806},{"name":"simd_f32x4_cmp.wast","passed":24,"failed":2583},{"name":"simd_f32x4_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f32x4_rounding.wast","passed":24,"failed":177},{"name":"simd_f64x2.wast","passed":8,"failed":795},{"name":"simd_f64x2_arith.wast","passed":16,"failed":1809},{"name":"simd_f64x2_cmp.wast","passed":24,"failed":2661},{"name":"simd_f64x2_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f64x2_rounding.wast","passed":24,"failed":177},{"name":"simd_i16x8_arith.wast","passed":11,"failed":183},{"name":"simd_i16x8_arith2.wast","passed":19,"failed":153},{"name":"simd_i16x8_cmp.wast","passed":30,"failed":435},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":4,"failed":17},{"name":"simd_i16x8_extmul_i8x16.wast","passed":12,"failed":105},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":3,"failed":27},{"name":"simd_i16x8_sat_arith.wast","passed":16,"failed":206},{"name":"simd_i32x4_arith.wast","passed":11,"failed":183},{"name":"simd_i32x4_arith2.wast","passed":26,"failed":123},{"name":"simd_i32x4_cmp.wast","passed":40,"failed":435},{"name":"simd_i32x4_dot_i16x8.wast","passed":3,"failed":27},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":4,"failed":17},{"name":"simd_i32x4_extmul_i16x8.wast","passed":12,"failed":105},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":4,"failed":103},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":4,"failed":103},{"name":"simd_i64x2_arith.wast","passed":11,"failed":189},{"name":"simd_i64x2_arith2.wast","passed":2,"failed":23},{"name":"simd_i64x2_cmp.wast","passed":10,"failed":103},{"name":"simd_i64x2_extmul_i32x4.wast","passed":12,"failed":105},{"name":"simd_i8x16_arith.wast","passed":8,"failed":123},{"name":"simd_i8x16_arith2.wast","passed":25,"failed":186},{"name":"simd_i8x16_cmp.wast","passed":30,"failed":415},{"name":"simd_i8x16_sat_arith.wast","passed":24,"failed":190},{"name":"simd_int_to_int_extend.wast","passed":24,"failed":229},{"name":"simd_lane.wast","passed":189,"failed":286},{"name":"simd_linking.wast","passed":0,"failed":3},{"name":"simd_load.wast","passed":8,"failed":31},{"name":"simd_load16_lane.wast","passed":3,"failed":33},{"name":"simd_load32_lane.wast","passed":3,"failed":21},{"name":"simd_load64_lane.wast","passed":3,"failed":13},{"name":"simd_load8_lane.wast","passed":3,"failed":49},{"name":"simd_load_extend.wast","passed":18,"failed":86},{"name":"simd_load_splat.wast","passed":12,"failed":114},{"name":"simd_load_zero.wast","passed":10,"failed":29},{"name":"simd_splat.wast","passed":23,"failed":162},{"name":"simd_store.wast","passed":9,"failed":19},{"name":"simd_store16_lane.wast","passed":3,"failed":33},{"name":"simd_store32_lane.wast","passed":3,"failed":21},{"name":"simd_store64_lane.wast","passed":3,"failed":13},{"name":"simd_store8_lane.wast","passed":3,"failed":49}] -0.9.0-alpha.0,1808,24172,[{"name":"simd_address.wast","passed":7,"failed":42},{"name":"simd_align.wast","passed":92,"failed":8},{"name":"simd_bit_shift.wast","passed":41,"failed":211},{"name":"simd_bitwise.wast","passed":30,"failed":139},{"name":"simd_boolean.wast","passed":123,"failed":154},{"name":"simd_const.wast","passed":551,"failed":206},{"name":"simd_conversions.wast","passed":50,"failed":232},{"name":"simd_f32x4.wast","passed":18,"failed":772},{"name":"simd_f32x4_arith.wast","passed":19,"failed":1803},{"name":"simd_f32x4_cmp.wast","passed":26,"failed":2581},{"name":"simd_f32x4_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f32x4_rounding.wast","passed":25,"failed":176},{"name":"simd_f64x2.wast","passed":10,"failed":793},{"name":"simd_f64x2_arith.wast","passed":19,"failed":1806},{"name":"simd_f64x2_cmp.wast","passed":26,"failed":2659},{"name":"simd_f64x2_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f64x2_rounding.wast","passed":25,"failed":176},{"name":"simd_i16x8_arith.wast","passed":13,"failed":181},{"name":"simd_i16x8_arith2.wast","passed":21,"failed":151},{"name":"simd_i16x8_cmp.wast","passed":32,"failed":433},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":5,"failed":16},{"name":"simd_i16x8_extmul_i8x16.wast","passed":13,"failed":104},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":4,"failed":26},{"name":"simd_i16x8_sat_arith.wast","passed":18,"failed":204},{"name":"simd_i32x4_arith.wast","passed":13,"failed":181},{"name":"simd_i32x4_arith2.wast","passed":28,"failed":121},{"name":"simd_i32x4_cmp.wast","passed":42,"failed":433},{"name":"simd_i32x4_dot_i16x8.wast","passed":4,"failed":26},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":5,"failed":16},{"name":"simd_i32x4_extmul_i16x8.wast","passed":13,"failed":104},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":5,"failed":102},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":5,"failed":102},{"name":"simd_i64x2_arith.wast","passed":13,"failed":187},{"name":"simd_i64x2_arith2.wast","passed":4,"failed":21},{"name":"simd_i64x2_cmp.wast","passed":11,"failed":102},{"name":"simd_i64x2_extmul_i32x4.wast","passed":13,"failed":104},{"name":"simd_i8x16_arith.wast","passed":10,"failed":121},{"name":"simd_i8x16_arith2.wast","passed":27,"failed":184},{"name":"simd_i8x16_cmp.wast","passed":32,"failed":413},{"name":"simd_i8x16_sat_arith.wast","passed":26,"failed":188},{"name":"simd_int_to_int_extend.wast","passed":25,"failed":228},{"name":"simd_lane.wast","passed":200,"failed":275},{"name":"simd_linking.wast","passed":0,"failed":3},{"name":"simd_load.wast","passed":22,"failed":17},{"name":"simd_load16_lane.wast","passed":4,"failed":32},{"name":"simd_load32_lane.wast","passed":4,"failed":20},{"name":"simd_load64_lane.wast","passed":4,"failed":12},{"name":"simd_load8_lane.wast","passed":4,"failed":48},{"name":"simd_load_extend.wast","passed":20,"failed":84},{"name":"simd_load_splat.wast","passed":14,"failed":112},{"name":"simd_load_zero.wast","passed":12,"failed":27},{"name":"simd_memory-multi.wast","passed":1,"failed":0},{"name":"simd_splat.wast","passed":26,"failed":159},{"name":"simd_store.wast","passed":11,"failed":17},{"name":"simd_store16_lane.wast","passed":3,"failed":33},{"name":"simd_store32_lane.wast","passed":3,"failed":21},{"name":"simd_store64_lane.wast","passed":3,"failed":13},{"name":"simd_store8_lane.wast","passed":3,"failed":49}] +0.9.0-alpha.0,14613,11367,[{"name":"simd_address.wast","passed":48,"failed":1},{"name":"simd_align.wast","passed":100,"failed":0},{"name":"simd_bit_shift.wast","passed":41,"failed":211},{"name":"simd_bitwise.wast","passed":169,"failed":0},{"name":"simd_boolean.wast","passed":241,"failed":36},{"name":"simd_const.wast","passed":751,"failed":6},{"name":"simd_conversions.wast","passed":50,"failed":232},{"name":"simd_f32x4.wast","passed":629,"failed":161},{"name":"simd_f32x4_arith.wast","passed":1357,"failed":465},{"name":"simd_f32x4_cmp.wast","passed":2607,"failed":0},{"name":"simd_f32x4_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f32x4_rounding.wast","passed":148,"failed":53},{"name":"simd_f64x2.wast","passed":639,"failed":164},{"name":"simd_f64x2_arith.wast","passed":1360,"failed":465},{"name":"simd_f64x2_cmp.wast","passed":2685,"failed":0},{"name":"simd_f64x2_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f64x2_rounding.wast","passed":148,"failed":53},{"name":"simd_i16x8_arith.wast","passed":138,"failed":56},{"name":"simd_i16x8_arith2.wast","passed":142,"failed":30},{"name":"simd_i16x8_cmp.wast","passed":436,"failed":29},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":5,"failed":16},{"name":"simd_i16x8_extmul_i8x16.wast","passed":13,"failed":104},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":4,"failed":26},{"name":"simd_i16x8_sat_arith.wast","passed":222,"failed":0},{"name":"simd_i32x4_arith.wast","passed":138,"failed":56},{"name":"simd_i32x4_arith2.wast","passed":149,"failed":0},{"name":"simd_i32x4_cmp.wast","passed":450,"failed":25},{"name":"simd_i32x4_dot_i16x8.wast","passed":4,"failed":26},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":5,"failed":16},{"name":"simd_i32x4_extmul_i16x8.wast","passed":13,"failed":104},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":5,"failed":102},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":5,"failed":102},{"name":"simd_i64x2_arith.wast","passed":200,"failed":0},{"name":"simd_i64x2_arith2.wast","passed":25,"failed":0},{"name":"simd_i64x2_cmp.wast","passed":97,"failed":16},{"name":"simd_i64x2_extmul_i32x4.wast","passed":13,"failed":104},{"name":"simd_i8x16_arith.wast","passed":131,"failed":0},{"name":"simd_i8x16_arith2.wast","passed":148,"failed":63},{"name":"simd_i8x16_cmp.wast","passed":409,"failed":36},{"name":"simd_i8x16_sat_arith.wast","passed":214,"failed":0},{"name":"simd_int_to_int_extend.wast","passed":25,"failed":228},{"name":"simd_lane.wast","passed":213,"failed":262},{"name":"simd_linking.wast","passed":0,"failed":3},{"name":"simd_load.wast","passed":34,"failed":5},{"name":"simd_load16_lane.wast","passed":36,"failed":0},{"name":"simd_load32_lane.wast","passed":24,"failed":0},{"name":"simd_load64_lane.wast","passed":16,"failed":0},{"name":"simd_load8_lane.wast","passed":52,"failed":0},{"name":"simd_load_extend.wast","passed":20,"failed":84},{"name":"simd_load_splat.wast","passed":14,"failed":112},{"name":"simd_load_zero.wast","passed":12,"failed":27},{"name":"simd_memory-multi.wast","passed":1,"failed":0},{"name":"simd_splat.wast","passed":157,"failed":28},{"name":"simd_store.wast","passed":28,"failed":0},{"name":"simd_store16_lane.wast","passed":3,"failed":33},{"name":"simd_store32_lane.wast","passed":3,"failed":21},{"name":"simd_store64_lane.wast","passed":3,"failed":13},{"name":"simd_store8_lane.wast","passed":3,"failed":49}] diff --git a/crates/tinywasm/tests/testsuite/util.rs b/crates/tinywasm/tests/testsuite/util.rs index f8f862b..91a1e41 100644 --- a/crates/tinywasm/tests/testsuite/util.rs +++ b/crates/tinywasm/tests/testsuite/util.rs @@ -1,9 +1,9 @@ use std::panic::{self, AssertUnwindSafe}; -use eyre::{bail, eyre, Result}; +use eyre::{Result, bail, eyre}; use tinywasm_types::{ExternRef, FuncRef, ModuleInstanceAddr, TinyWasmModule, ValType, WasmValue}; use wasm_testsuite::wast; -use wasm_testsuite::wast::{core::AbstractHeapType, QuoteWat}; +use wasm_testsuite::wast::{QuoteWat, core::AbstractHeapType}; pub fn try_downcast_panic(panic: Box) -> String { let info = panic.downcast_ref::().or(None).map(ToString::to_string).clone(); @@ -96,7 +96,7 @@ fn wastarg2tinywasmvalue(arg: wast::WastArg) -> Result WasmValue::F32(f32::from_bits(f.bits)), F64(f) => WasmValue::F64(f64::from_bits(f.bits)), @@ -117,19 +117,21 @@ fn wastarg2tinywasmvalue(arg: wast::WastArg) -> Result u128 { - match i { +fn wast_i128_to_i128(i: wast::core::V128Pattern) -> i128 { + let res: Vec = match i { wast::core::V128Pattern::F32x4(f) => { - f.iter().fold(0, |acc, &f| (acc << 32) | nanpattern2tinywasmvalue(f).unwrap().as_f32().unwrap() as u128) + f.iter().map(|v| nanpattern2tinywasmvalue(*v).unwrap().as_f32().unwrap().to_le_bytes()).flatten().collect() } wast::core::V128Pattern::F64x2(f) => { - f.iter().fold(0, |acc, &f| (acc << 64) | nanpattern2tinywasmvalue(f).unwrap().as_f64().unwrap() as u128) + f.iter().map(|v| nanpattern2tinywasmvalue(*v).unwrap().as_f64().unwrap().to_le_bytes()).flatten().collect() } - wast::core::V128Pattern::I16x8(f) => f.iter().fold(0, |acc, &f| (acc << 16) | f as u128), - wast::core::V128Pattern::I32x4(f) => f.iter().fold(0, |acc, &f| (acc << 32) | f as u128), - wast::core::V128Pattern::I64x2(f) => f.iter().fold(0, |acc, &f| (acc << 64) | f as u128), - wast::core::V128Pattern::I8x16(f) => f.iter().fold(0, |acc, &f| (acc << 8) | f as u128), - } + wast::core::V128Pattern::I16x8(f) => f.iter().map(|v| v.to_le_bytes()).flatten().collect(), + wast::core::V128Pattern::I32x4(f) => f.iter().map(|v| v.to_le_bytes()).flatten().collect(), + wast::core::V128Pattern::I64x2(f) => f.iter().map(|v| v.to_le_bytes()).flatten().collect(), + wast::core::V128Pattern::I8x16(f) => f.iter().map(|v| v.to_le_bytes()).flatten().collect(), + }; + + i128::from_le_bytes(res.try_into().unwrap()) } fn wastret2tinywasmvalue(ret: wast::WastRet) -> Result { @@ -137,7 +139,7 @@ fn wastret2tinywasmvalue(ret: wast::WastRet) -> Result nanpattern2tinywasmvalue(f)?, F64(f) => nanpattern2tinywasmvalue(f)?, diff --git a/crates/types/src/instructions.rs b/crates/types/src/instructions.rs index 24116e8..593af2f 100644 --- a/crates/types/src/instructions.rs +++ b/crates/types/src/instructions.rs @@ -36,6 +36,7 @@ pub enum ConstInstruction { I64Const(i64), F32Const(f32), F64Const(f64), + V128Const(i128), GlobalGet(GlobalAddr), RefFunc(Option), RefExtern(Option), diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index d9f2234..470c631 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -259,7 +259,7 @@ pub struct WasmFunction { #[derive(Debug, Clone, PartialEq, Default)] #[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct WasmFunctionData { - pub v128_constants: Box<[u128]>, + pub v128_constants: Box<[i128]>, } /// A WebAssembly Module Export diff --git a/crates/types/src/value.rs b/crates/types/src/value.rs index 01a31d5..a9498cc 100644 --- a/crates/types/src/value.rs +++ b/crates/types/src/value.rs @@ -17,7 +17,7 @@ pub enum WasmValue { /// A 64-bit float. F64(f64), // /// A 128-bit vector - V128(u128), + V128(i128), RefExtern(ExternRef), RefFunc(FuncRef), @@ -112,6 +112,7 @@ impl WasmValue { Self::I64(i) => ConstInstruction::I64Const(*i), Self::F32(i) => ConstInstruction::F32Const(*i), Self::F64(i) => ConstInstruction::F64Const(*i), + Self::V128(i) => ConstInstruction::V128Const(*i), Self::RefFunc(i) => ConstInstruction::RefFunc(i.addr()), _ => unimplemented!("no const_instr for {:?}", self), } @@ -137,6 +138,7 @@ impl WasmValue { match (self, other) { (Self::I32(a), Self::I32(b)) => a == b, (Self::I64(a), Self::I64(b)) => a == b, + (Self::V128(a), Self::V128(b)) => a == b, (Self::RefExtern(addr), Self::RefExtern(addr2)) => addr == addr2, (Self::RefFunc(addr), Self::RefFunc(addr2)) => addr == addr2, (Self::F32(a), Self::F32(b)) => { @@ -190,7 +192,7 @@ impl WasmValue { } #[doc(hidden)] - pub fn as_v128(&self) -> Option { + pub fn as_v128(&self) -> Option { match self { Self::V128(i) => Some(*i), _ => None, @@ -309,4 +311,4 @@ macro_rules! impl_conversion_for_wasmvalue { } } -impl_conversion_for_wasmvalue! { i32 => I32, i64 => I64, f32 => F32, f64 => F64, u128 => V128, ExternRef => RefExtern, FuncRef => RefFunc } +impl_conversion_for_wasmvalue! { i32 => I32, i64 => I64, f32 => F32, f64 => F64, i128 => V128, ExternRef => RefExtern, FuncRef => RefFunc } From 569e0b42bde426f83ad0329d4d6ec7a4c0793b36 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sat, 1 Mar 2025 22:01:02 +0100 Subject: [PATCH 45/54] feat: support the tail call proposal (#37) Signed-off-by: Henry Gressmann --- CHANGELOG.md | 1 + README.md | 3 +- crates/parser/src/visit.rs | 6 +- crates/tinywasm/Cargo.toml | 4 + crates/tinywasm/src/interpreter/executor.rs | 110 +++++++++--------- .../src/interpreter/stack/call_stack.rs | 14 +++ crates/tinywasm/tests/generated/wasm-3.csv | 2 +- .../generated/wasm-custom-page-sizes.csv | 2 +- .../tests/generated/wasm-tail-call.csv | 1 + .../tests/test-wasm-custom-page-sizes.rs | 10 +- crates/tinywasm/tests/test-wasm-tail-call.rs | 13 +++ crates/types/src/instructions.rs | 4 +- 12 files changed, 110 insertions(+), 60 deletions(-) create mode 100644 crates/tinywasm/tests/generated/wasm-tail-call.csv create mode 100644 crates/tinywasm/tests/test-wasm-tail-call.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index c01787f..e63ff2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Support for the custom memory page sizes proposal ([#22](https://github.com/explodingcamera/tinywasm/pull/22) by [@danielstuart14](https://github.com/danielstuart14)) +- Support for the `tail_call` proposal ### Breaking Changes diff --git a/README.md b/README.md index 8db5a84..6b72448 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,9 @@ TinyWasm passes all WebAssembly MVP tests from the [WebAssembly core testsuite]( | [**Reference Types**](https://github.com/WebAssembly/reference-types/blob/master/proposals/reference-types/Overview.md) | 🟢 | 0.7.0 | | [**Multiple Memories**](https://github.com/WebAssembly/multi-memory/blob/master/proposals/multi-memory/Overview.md) | 🟢 | 0.8.0 | | [**Custom Page Sizes**](https://github.com/WebAssembly/custom-page-sizes/blob/main/proposals/custom-page-sizes/Overview.md) | 🟢 | `next` | +| [**Tail Call**](https://github.com/WebAssembly/tail-call/blob/main/proposals/tail-call/Overview.md) | 🟢 | `next` | | [**Memory64**](https://github.com/WebAssembly/memory64/blob/master/proposals/memory64/Overview.md) | 🚧 | N/A | -| [**Fixed-Width SIMD**](https://github.com/webassembly/simd) | 🌑 | N/A | +| [**Fixed-Width SIMD**](https://github.com/webassembly/simd) | 🚧 | N/A | ## Usage diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs index 2830d3a..8ed44be 100644 --- a/crates/parser/src/visit.rs +++ b/crates/parser/src/visit.rs @@ -158,6 +158,7 @@ macro_rules! impl_visit_operator { (@@saturating_float_to_int $($rest:tt)* ) => {}; (@@bulk_memory $($rest:tt)* ) => {}; (@@simd $($rest:tt)* ) => {}; + (@@tail_call $($rest:tt)* ) => {}; (@@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*)) => { #[cold] @@ -181,7 +182,7 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild define_operands! { // basic instructions - visit_br(Br, u32), visit_br_if(BrIf, u32), visit_global_get(GlobalGet, u32), visit_i32_const(I32Const, i32), visit_i64_const(I64Const, i64), visit_call(Call, u32), visit_memory_size(MemorySize, u32), visit_memory_grow(MemoryGrow, u32), visit_unreachable(Unreachable), visit_nop(Nop), visit_return(Return), visit_i32_eqz(I32Eqz), visit_i32_eq(I32Eq), visit_i32_ne(I32Ne), visit_i32_lt_s(I32LtS), visit_i32_lt_u(I32LtU), visit_i32_gt_s(I32GtS), visit_i32_gt_u(I32GtU), visit_i32_le_s(I32LeS), visit_i32_le_u(I32LeU), visit_i32_ge_s(I32GeS), visit_i32_ge_u(I32GeU), visit_i64_eqz(I64Eqz), visit_i64_eq(I64Eq), visit_i64_ne(I64Ne), visit_i64_lt_s(I64LtS), visit_i64_lt_u(I64LtU), visit_i64_gt_s(I64GtS), visit_i64_gt_u(I64GtU), visit_i64_le_s(I64LeS), visit_i64_le_u(I64LeU), visit_i64_ge_s(I64GeS), visit_i64_ge_u(I64GeU), visit_f32_eq(F32Eq), visit_f32_ne(F32Ne), visit_f32_lt(F32Lt), visit_f32_gt(F32Gt), visit_f32_le(F32Le), visit_f32_ge(F32Ge), visit_f64_eq(F64Eq), visit_f64_ne(F64Ne), visit_f64_lt(F64Lt), visit_f64_gt(F64Gt), visit_f64_le(F64Le), visit_f64_ge(F64Ge), visit_i32_clz(I32Clz), visit_i32_ctz(I32Ctz), visit_i32_popcnt(I32Popcnt), visit_i32_add(I32Add), visit_i32_sub(I32Sub), visit_i32_mul(I32Mul), visit_i32_div_s(I32DivS), visit_i32_div_u(I32DivU), visit_i32_rem_s(I32RemS), visit_i32_rem_u(I32RemU), visit_i32_and(I32And), visit_i32_or(I32Or), visit_i32_xor(I32Xor), visit_i32_shl(I32Shl), visit_i32_shr_s(I32ShrS), visit_i32_shr_u(I32ShrU), visit_i32_rotl(I32Rotl), visit_i32_rotr(I32Rotr), visit_i64_clz(I64Clz), visit_i64_ctz(I64Ctz), visit_i64_popcnt(I64Popcnt), visit_i64_add(I64Add), visit_i64_sub(I64Sub), visit_i64_mul(I64Mul), visit_i64_div_s(I64DivS), visit_i64_div_u(I64DivU), visit_i64_rem_s(I64RemS), visit_i64_rem_u(I64RemU), visit_i64_and(I64And), visit_i64_or(I64Or), visit_i64_xor(I64Xor), visit_i64_shl(I64Shl), visit_i64_shr_s(I64ShrS), visit_i64_shr_u(I64ShrU), visit_i64_rotl(I64Rotl), visit_i64_rotr(I64Rotr), visit_f32_abs(F32Abs), visit_f32_neg(F32Neg), visit_f32_ceil(F32Ceil), visit_f32_floor(F32Floor), visit_f32_trunc(F32Trunc), visit_f32_nearest(F32Nearest), visit_f32_sqrt(F32Sqrt), visit_f32_add(F32Add), visit_f32_sub(F32Sub), visit_f32_mul(F32Mul), visit_f32_div(F32Div), visit_f32_min(F32Min), visit_f32_max(F32Max), visit_f32_copysign(F32Copysign), visit_f64_abs(F64Abs), visit_f64_neg(F64Neg), visit_f64_ceil(F64Ceil), visit_f64_floor(F64Floor), visit_f64_trunc(F64Trunc), visit_f64_nearest(F64Nearest), visit_f64_sqrt(F64Sqrt), visit_f64_add(F64Add), visit_f64_sub(F64Sub), visit_f64_mul(F64Mul), visit_f64_div(F64Div), visit_f64_min(F64Min), visit_f64_max(F64Max), visit_f64_copysign(F64Copysign), visit_i32_wrap_i64(I32WrapI64), visit_i32_trunc_f32_s(I32TruncF32S), visit_i32_trunc_f32_u(I32TruncF32U), visit_i32_trunc_f64_s(I32TruncF64S), visit_i32_trunc_f64_u(I32TruncF64U), visit_i64_extend_i32_s(I64ExtendI32S), visit_i64_extend_i32_u(I64ExtendI32U), visit_i64_trunc_f32_s(I64TruncF32S), visit_i64_trunc_f32_u(I64TruncF32U), visit_i64_trunc_f64_s(I64TruncF64S), visit_i64_trunc_f64_u(I64TruncF64U), visit_f32_convert_i32_s(F32ConvertI32S), visit_f32_convert_i32_u(F32ConvertI32U), visit_f32_convert_i64_s(F32ConvertI64S), visit_f32_convert_i64_u(F32ConvertI64U), visit_f32_demote_f64(F32DemoteF64), visit_f64_convert_i32_s(F64ConvertI32S), visit_f64_convert_i32_u(F64ConvertI32U), visit_f64_convert_i64_s(F64ConvertI64S), visit_f64_convert_i64_u(F64ConvertI64U), visit_f64_promote_f32(F64PromoteF32), visit_i32_reinterpret_f32(I32ReinterpretF32), visit_i64_reinterpret_f64(I64ReinterpretF64), visit_f32_reinterpret_i32(F32ReinterpretI32), visit_f64_reinterpret_i64(F64ReinterpretI64), + visit_br(Br, u32), visit_br_if(BrIf, u32), visit_global_get(GlobalGet, u32), visit_i32_const(I32Const, i32), visit_i64_const(I64Const, i64), visit_call(Call, u32), visit_return_call(ReturnCall, u32), visit_memory_size(MemorySize, u32), visit_memory_grow(MemoryGrow, u32), visit_unreachable(Unreachable), visit_nop(Nop), visit_return(Return), visit_i32_eqz(I32Eqz), visit_i32_eq(I32Eq), visit_i32_ne(I32Ne), visit_i32_lt_s(I32LtS), visit_i32_lt_u(I32LtU), visit_i32_gt_s(I32GtS), visit_i32_gt_u(I32GtU), visit_i32_le_s(I32LeS), visit_i32_le_u(I32LeU), visit_i32_ge_s(I32GeS), visit_i32_ge_u(I32GeU), visit_i64_eqz(I64Eqz), visit_i64_eq(I64Eq), visit_i64_ne(I64Ne), visit_i64_lt_s(I64LtS), visit_i64_lt_u(I64LtU), visit_i64_gt_s(I64GtS), visit_i64_gt_u(I64GtU), visit_i64_le_s(I64LeS), visit_i64_le_u(I64LeU), visit_i64_ge_s(I64GeS), visit_i64_ge_u(I64GeU), visit_f32_eq(F32Eq), visit_f32_ne(F32Ne), visit_f32_lt(F32Lt), visit_f32_gt(F32Gt), visit_f32_le(F32Le), visit_f32_ge(F32Ge), visit_f64_eq(F64Eq), visit_f64_ne(F64Ne), visit_f64_lt(F64Lt), visit_f64_gt(F64Gt), visit_f64_le(F64Le), visit_f64_ge(F64Ge), visit_i32_clz(I32Clz), visit_i32_ctz(I32Ctz), visit_i32_popcnt(I32Popcnt), visit_i32_add(I32Add), visit_i32_sub(I32Sub), visit_i32_mul(I32Mul), visit_i32_div_s(I32DivS), visit_i32_div_u(I32DivU), visit_i32_rem_s(I32RemS), visit_i32_rem_u(I32RemU), visit_i32_and(I32And), visit_i32_or(I32Or), visit_i32_xor(I32Xor), visit_i32_shl(I32Shl), visit_i32_shr_s(I32ShrS), visit_i32_shr_u(I32ShrU), visit_i32_rotl(I32Rotl), visit_i32_rotr(I32Rotr), visit_i64_clz(I64Clz), visit_i64_ctz(I64Ctz), visit_i64_popcnt(I64Popcnt), visit_i64_add(I64Add), visit_i64_sub(I64Sub), visit_i64_mul(I64Mul), visit_i64_div_s(I64DivS), visit_i64_div_u(I64DivU), visit_i64_rem_s(I64RemS), visit_i64_rem_u(I64RemU), visit_i64_and(I64And), visit_i64_or(I64Or), visit_i64_xor(I64Xor), visit_i64_shl(I64Shl), visit_i64_shr_s(I64ShrS), visit_i64_shr_u(I64ShrU), visit_i64_rotl(I64Rotl), visit_i64_rotr(I64Rotr), visit_f32_abs(F32Abs), visit_f32_neg(F32Neg), visit_f32_ceil(F32Ceil), visit_f32_floor(F32Floor), visit_f32_trunc(F32Trunc), visit_f32_nearest(F32Nearest), visit_f32_sqrt(F32Sqrt), visit_f32_add(F32Add), visit_f32_sub(F32Sub), visit_f32_mul(F32Mul), visit_f32_div(F32Div), visit_f32_min(F32Min), visit_f32_max(F32Max), visit_f32_copysign(F32Copysign), visit_f64_abs(F64Abs), visit_f64_neg(F64Neg), visit_f64_ceil(F64Ceil), visit_f64_floor(F64Floor), visit_f64_trunc(F64Trunc), visit_f64_nearest(F64Nearest), visit_f64_sqrt(F64Sqrt), visit_f64_add(F64Add), visit_f64_sub(F64Sub), visit_f64_mul(F64Mul), visit_f64_div(F64Div), visit_f64_min(F64Min), visit_f64_max(F64Max), visit_f64_copysign(F64Copysign), visit_i32_wrap_i64(I32WrapI64), visit_i32_trunc_f32_s(I32TruncF32S), visit_i32_trunc_f32_u(I32TruncF32U), visit_i32_trunc_f64_s(I32TruncF64S), visit_i32_trunc_f64_u(I32TruncF64U), visit_i64_extend_i32_s(I64ExtendI32S), visit_i64_extend_i32_u(I64ExtendI32U), visit_i64_trunc_f32_s(I64TruncF32S), visit_i64_trunc_f32_u(I64TruncF32U), visit_i64_trunc_f64_s(I64TruncF64S), visit_i64_trunc_f64_u(I64TruncF64U), visit_f32_convert_i32_s(F32ConvertI32S), visit_f32_convert_i32_u(F32ConvertI32U), visit_f32_convert_i64_s(F32ConvertI64S), visit_f32_convert_i64_u(F32ConvertI64U), visit_f32_demote_f64(F32DemoteF64), visit_f64_convert_i32_s(F64ConvertI32S), visit_f64_convert_i32_u(F64ConvertI32U), visit_f64_convert_i64_s(F64ConvertI64S), visit_f64_convert_i64_u(F64ConvertI64U), visit_f64_promote_f32(F64PromoteF32), visit_i32_reinterpret_f32(I32ReinterpretF32), visit_i64_reinterpret_f64(I64ReinterpretF64), visit_f32_reinterpret_i32(F32ReinterpretI32), visit_f64_reinterpret_i64(F64ReinterpretI64), // sign_extension visit_i32_extend8_s(I32Extend8S), visit_i32_extend16_s(I32Extend16S), visit_i64_extend8_s(I64Extend8S), visit_i64_extend16_s(I64Extend16S), visit_i64_extend32_s(I64Extend32S), @@ -431,6 +432,9 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild fn visit_call_indirect(&mut self, ty: u32, table: u32) -> Self::Output { self.instructions.push(Instruction::CallIndirect(ty, table)); } + fn visit_return_call_indirect(&mut self, ty: u32, table: u32) -> Self::Output { + self.instructions.push(Instruction::ReturnCallIndirect(ty, table)); + } fn visit_f32_const(&mut self, val: wasmparser::Ieee32) -> Self::Output { self.instructions.push(Instruction::F32Const(f32::from_bits(val.bits()))); diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index 2cad2e4..d004760 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -62,6 +62,10 @@ harness=false name="test-wasm-custom-page-sizes" harness=false +[[test]] +name="test-wasm-tail-call" +harness=false + [[test]] name="test-wasm-memory64" harness=false diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index 3c579c1..c776710 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -55,8 +55,11 @@ impl<'store, 'stack> Executor<'store, 'stack> { Select128 => self.stack.values.select::(), SelectRef => self.stack.values.select::(), - Call(v) => return self.exec_call_direct(*v), - CallIndirect(ty, table) => return self.exec_call_indirect(*ty, *table), + Call(v) => return self.exec_call_direct::(*v), + CallIndirect(ty, table) => return self.exec_call_indirect::(*ty, *table), + + ReturnCall(v) => return self.exec_call_direct::(*v), + ReturnCallIndirect(ty, table) => return self.exec_call_indirect::(*ty, *table), If(end, el) => self.exec_if(*end, *el, (StackHeight::default(), StackHeight::default())), IfWithType(ty, end, el) => self.exec_if(*end, *el, (StackHeight::default(), (*ty).into())), @@ -314,50 +317,71 @@ impl<'store, 'stack> Executor<'store, 'stack> { ControlFlow::Break(Some(Trap::Unreachable.into())) } - fn exec_call(&mut self, wasm_func: Rc, owner: ModuleInstanceAddr) -> ControlFlow> { - let locals = self.stack.values.pop_locals(wasm_func.params, wasm_func.locals); - let new_call_frame = CallFrame::new_raw(wasm_func, owner, locals, self.stack.blocks.len() as u32); - self.cf.incr_instr_ptr(); // skip the call instruction - self.stack.call_stack.push(core::mem::replace(&mut self.cf, new_call_frame))?; - self.module.swap_with(self.cf.module_addr(), self.store); + fn exec_call( + &mut self, + wasm_func: Rc, + owner: ModuleInstanceAddr, + ) -> ControlFlow> { + if !IS_RETURN_CALL { + let locals = self.stack.values.pop_locals(wasm_func.params, wasm_func.locals); + let new_call_frame = CallFrame::new_raw(wasm_func, owner, locals, self.stack.blocks.len() as u32); + self.cf.incr_instr_ptr(); // skip the call instruction + self.stack.call_stack.push(core::mem::replace(&mut self.cf, new_call_frame))?; + self.module.swap_with(self.cf.module_addr(), self.store); + } else { + let locals = self.stack.values.pop_locals(wasm_func.params, wasm_func.locals); + self.cf.reuse_for(wasm_func, locals, self.stack.blocks.len() as u32, owner); + self.module.swap_with(self.cf.module_addr(), self.store); + } + ControlFlow::Continue(()) } - fn exec_call_direct(&mut self, v: u32) -> ControlFlow> { + fn exec_call_host(&mut self, host_func: Rc) -> ControlFlow> { + let params = self.stack.values.pop_params(&host_func.ty.params); + let res = host_func + .clone() + .call(FuncContext { store: self.store, module_addr: self.module.id() }, ¶ms) + .to_cf()?; + self.stack.values.extend_from_wasmvalues(&res); + self.cf.incr_instr_ptr(); + ControlFlow::Continue(()) + } + fn exec_call_direct(&mut self, v: u32) -> ControlFlow> { let func_inst = self.store.get_func(self.module.resolve_func_addr(v)); - let wasm_func = match &func_inst.func { - crate::Function::Wasm(wasm_func) => wasm_func, - crate::Function::Host(host_func) => { - let func = &host_func.clone(); - let params = self.stack.values.pop_params(&host_func.ty.params); - let res = - func.call(FuncContext { store: self.store, module_addr: self.module.id() }, ¶ms).to_cf()?; - self.stack.values.extend_from_wasmvalues(&res); - self.cf.incr_instr_ptr(); - return ControlFlow::Continue(()); - } - }; - - self.exec_call(wasm_func.clone(), func_inst.owner) + match func_inst.func.clone() { + crate::Function::Wasm(wasm_func) => self.exec_call::(wasm_func, func_inst.owner), + crate::Function::Host(host_func) => self.exec_call_host(host_func), + } } - fn exec_call_indirect(&mut self, type_addr: u32, table_addr: u32) -> ControlFlow> { + fn exec_call_indirect( + &mut self, + type_addr: u32, + table_addr: u32, + ) -> ControlFlow> { // verify that the table is of the right type, this should be validated by the parser already let func_ref = { let table = self.store.get_table(self.module.resolve_table_addr(table_addr)); let table_idx: u32 = self.stack.values.pop::() as u32; assert!(table.kind.element_type == ValType::RefFunc, "table is not of type funcref"); - table - .get(table_idx) - .map_err(|_| Error::Trap(Trap::UndefinedElement { index: table_idx as usize })) - .to_cf()? - .addr() - .ok_or(Error::Trap(Trap::UninitializedElement { index: table_idx as usize })) - .to_cf()? + let table = table.get(table_idx).map_err(|_| Trap::UndefinedElement { index: table_idx as usize }.into()); + let table = table.to_cf()?; + table.addr().ok_or(Trap::UninitializedElement { index: table_idx as usize }.into()).to_cf()? }; let func_inst = self.store.get_func(func_ref); let call_ty = self.module.func_ty(type_addr); - let wasm_func = match &func_inst.func { - crate::Function::Wasm(f) => f, + + match func_inst.func.clone() { + crate::Function::Wasm(wasm_func) => { + if unlikely(wasm_func.ty != *call_ty) { + return ControlFlow::Break(Some( + Trap::IndirectCallTypeMismatch { actual: wasm_func.ty.clone(), expected: call_ty.clone() } + .into(), + )); + } + + self.exec_call::(wasm_func, func_inst.owner) + } crate::Function::Host(host_func) => { if unlikely(host_func.ty != *call_ty) { return ControlFlow::Break(Some( @@ -366,27 +390,9 @@ impl<'store, 'stack> Executor<'store, 'stack> { )); } - let host_func = host_func.clone(); - let params = self.stack.values.pop_params(&host_func.ty.params); - let res = - match host_func.call(FuncContext { store: self.store, module_addr: self.module.id() }, ¶ms) { - Ok(res) => res, - Err(e) => return ControlFlow::Break(Some(e)), - }; - - self.stack.values.extend_from_wasmvalues(&res); - self.cf.incr_instr_ptr(); - return ControlFlow::Continue(()); + self.exec_call_host(host_func) } - }; - - if unlikely(wasm_func.ty != *call_ty) { - return ControlFlow::Break(Some( - Trap::IndirectCallTypeMismatch { actual: wasm_func.ty.clone(), expected: call_ty.clone() }.into(), - )); } - - self.exec_call(wasm_func.clone(), func_inst.owner) } fn exec_if(&mut self, else_offset: u32, end_offset: u32, (params, results): (StackHeight, StackHeight)) { diff --git a/crates/tinywasm/src/interpreter/stack/call_stack.rs b/crates/tinywasm/src/interpreter/stack/call_stack.rs index 9b6c3fd..11bbe29 100644 --- a/crates/tinywasm/src/interpreter/stack/call_stack.rs +++ b/crates/tinywasm/src/interpreter/stack/call_stack.rs @@ -98,6 +98,20 @@ impl CallFrame { } } + pub(crate) fn reuse_for( + &mut self, + func: Rc, + locals: Locals, + block_depth: u32, + module_addr: ModuleInstanceAddr, + ) { + self.func_instance = func; + self.module_addr = module_addr; + self.locals = locals; + self.block_ptr = block_depth; + self.instr_ptr = 0; // Reset to function entry + } + /// Break to a block at the given index (relative to the current frame) /// Returns `None` if there is no block at the given index (e.g. if we need to return, this is handled by the caller) #[inline] diff --git a/crates/tinywasm/tests/generated/wasm-3.csv b/crates/tinywasm/tests/generated/wasm-3.csv index ed301e4..a1df609 100644 --- a/crates/tinywasm/tests/generated/wasm-3.csv +++ b/crates/tinywasm/tests/generated/wasm-3.csv @@ -1 +1 @@ -0.9.0-alpha.0,32305,2591,[{"name":"address.wast","passed":260,"failed":0},{"name":"address64.wast","passed":0,"failed":242},{"name":"align.wast","passed":161,"failed":0},{"name":"align64.wast","passed":83,"failed":73},{"name":"annotations.wast","passed":74,"failed":0},{"name":"binary-leb128.wast","passed":92,"failed":1},{"name":"binary.wast","passed":126,"failed":0},{"name":"block.wast","passed":223,"failed":0},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":119,"failed":0},{"name":"br_on_non_null.wast","passed":1,"failed":9},{"name":"br_on_null.wast","passed":1,"failed":9},{"name":"br_table.wast","passed":24,"failed":162},{"name":"bulk.wast","passed":117,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":49,"failed":124},{"name":"call_ref.wast","passed":4,"failed":31},{"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":59,"failed":6},{"name":"elem.wast","passed":137,"failed":14},{"name":"endianness.wast","passed":69,"failed":0},{"name":"endianness64.wast","passed":0,"failed":69},{"name":"exports.wast","passed":97,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_memory64.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":471,"failed":0},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":175,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"global.wast","passed":53,"failed":71},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":169,"failed":90},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"instance.wast","passed":0,"failed":23},{"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":142,"failed":21},{"name":"load.wast","passed":118,"failed":0},{"name":"load64.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_init.wast","passed":10,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":98,"failed":0},{"name":"loop.wast","passed":120,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":89,"failed":0},{"name":"memory64.wast","passed":14,"failed":53},{"name":"memory_copy.wast","passed":8385,"failed":515},{"name":"memory_fill.wast","passed":164,"failed":36},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_grow64.wast","passed":0,"failed":49},{"name":"memory_init.wast","passed":307,"failed":173},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_redundancy64.wast","passed":0,"failed":8},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"memory_trap64.wast","passed":0,"failed":172},{"name":"names.wast","passed":486,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref.wast","passed":12,"failed":1},{"name":"ref_as_non_null.wast","passed":1,"failed":6},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":2,"failed":20},{"name":"ref_null.wast","passed":0,"failed":34},{"name":"return.wast","passed":84,"failed":0},{"name":"return_call.wast","passed":11,"failed":34},{"name":"return_call_indirect.wast","passed":26,"failed":50},{"name":"return_call_ref.wast","passed":11,"failed":40},{"name":"select.wast","passed":155,"failed":2},{"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":111,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"table-sub.wast","passed":2,"failed":1},{"name":"table.wast","passed":47,"failed":9},{"name":"table_copy.wast","passed":1742,"failed":30},{"name":"table_copy_mixed.wast","passed":4,"failed":0},{"name":"table_fill.wast","passed":45,"failed":35},{"name":"table_get.wast","passed":16,"failed":1},{"name":"table_grow.wast","passed":58,"failed":21},{"name":"table_init.wast","passed":780,"failed":96},{"name":"table_set.wast","passed":26,"failed":2},{"name":"table_size.wast","passed":39,"failed":1},{"name":"tag.wast","passed":1,"failed":8},{"name":"throw.wast","passed":3,"failed":10},{"name":"throw_ref.wast","passed":2,"failed":13},{"name":"token.wast","passed":61,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"try_table.wast","passed":11,"failed":51},{"name":"type-canon.wast","passed":0,"failed":2},{"name":"type-equivalence.wast","passed":12,"failed":20},{"name":"type-rec.wast","passed":6,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":121,"failed":0},{"name":"unreached-valid.wast","passed":2,"failed":11},{"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.9.0-alpha.0,32377,2526,[{"name":"address.wast","passed":260,"failed":0},{"name":"address64.wast","passed":0,"failed":242},{"name":"align.wast","passed":161,"failed":0},{"name":"align64.wast","passed":83,"failed":73},{"name":"annotations.wast","passed":74,"failed":0},{"name":"binary-leb128.wast","passed":92,"failed":1},{"name":"binary.wast","passed":126,"failed":0},{"name":"block.wast","passed":223,"failed":0},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":119,"failed":0},{"name":"br_on_non_null.wast","passed":1,"failed":9},{"name":"br_on_null.wast","passed":1,"failed":9},{"name":"br_table.wast","passed":24,"failed":162},{"name":"bulk.wast","passed":117,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":49,"failed":124},{"name":"call_ref.wast","passed":4,"failed":31},{"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":59,"failed":6},{"name":"elem.wast","passed":137,"failed":14},{"name":"endianness.wast","passed":69,"failed":0},{"name":"endianness64.wast","passed":0,"failed":69},{"name":"exports.wast","passed":97,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_memory64.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":471,"failed":0},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":175,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"global.wast","passed":53,"failed":71},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":169,"failed":90},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"instance.wast","passed":0,"failed":23},{"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":142,"failed":21},{"name":"load.wast","passed":118,"failed":0},{"name":"load64.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_init.wast","passed":10,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":98,"failed":0},{"name":"loop.wast","passed":120,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":89,"failed":1},{"name":"memory64.wast","passed":14,"failed":55},{"name":"memory_copy.wast","passed":8385,"failed":515},{"name":"memory_fill.wast","passed":164,"failed":36},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_grow64.wast","passed":0,"failed":49},{"name":"memory_init.wast","passed":307,"failed":173},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_redundancy64.wast","passed":0,"failed":8},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"memory_trap64.wast","passed":0,"failed":172},{"name":"names.wast","passed":486,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref.wast","passed":12,"failed":1},{"name":"ref_as_non_null.wast","passed":1,"failed":6},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":2,"failed":20},{"name":"ref_null.wast","passed":0,"failed":34},{"name":"return.wast","passed":84,"failed":0},{"name":"return_call.wast","passed":40,"failed":5},{"name":"return_call_indirect.wast","passed":69,"failed":7},{"name":"return_call_ref.wast","passed":11,"failed":40},{"name":"select.wast","passed":155,"failed":2},{"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":111,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"table-sub.wast","passed":2,"failed":1},{"name":"table.wast","passed":47,"failed":13},{"name":"table_copy.wast","passed":1742,"failed":30},{"name":"table_copy_mixed.wast","passed":4,"failed":0},{"name":"table_fill.wast","passed":45,"failed":35},{"name":"table_get.wast","passed":16,"failed":1},{"name":"table_grow.wast","passed":58,"failed":21},{"name":"table_init.wast","passed":780,"failed":96},{"name":"table_set.wast","passed":26,"failed":2},{"name":"table_size.wast","passed":39,"failed":1},{"name":"tag.wast","passed":1,"failed":8},{"name":"throw.wast","passed":3,"failed":10},{"name":"throw_ref.wast","passed":2,"failed":13},{"name":"token.wast","passed":61,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"try_table.wast","passed":11,"failed":51},{"name":"type-canon.wast","passed":0,"failed":2},{"name":"type-equivalence.wast","passed":12,"failed":20},{"name":"type-rec.wast","passed":6,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":121,"failed":0},{"name":"unreached-valid.wast","passed":2,"failed":11},{"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/wasm-custom-page-sizes.csv b/crates/tinywasm/tests/generated/wasm-custom-page-sizes.csv index 7f168a1..5ba121e 100644 --- a/crates/tinywasm/tests/generated/wasm-custom-page-sizes.csv +++ b/crates/tinywasm/tests/generated/wasm-custom-page-sizes.csv @@ -1,2 +1,2 @@ 0.8.0,57,0,[{"name":"custom-page-sizes-invalid.wast","passed":22,"failed":0},{"name":"custom-page-sizes.wast","passed":35,"failed":0}] -0.9.0-alpha.0,57,0,[{"name":"custom-page-sizes-invalid.wast","passed":22,"failed":0},{"name":"custom-page-sizes.wast","passed":35,"failed":0}] +0.9.0-alpha.0,76,0,[{"name":"custom-page-sizes-invalid.wast","passed":23,"failed":0},{"name":"custom-page-sizes.wast","passed":45,"failed":0},{"name":"memory_max.wast","passed":4,"failed":0},{"name":"memory_max_i64.wast","passed":4,"failed":0}] diff --git a/crates/tinywasm/tests/generated/wasm-tail-call.csv b/crates/tinywasm/tests/generated/wasm-tail-call.csv new file mode 100644 index 0000000..c9f0910 --- /dev/null +++ b/crates/tinywasm/tests/generated/wasm-tail-call.csv @@ -0,0 +1 @@ +0.9.0-alpha.0,119,0,[{"name":"return_call.wast","passed":44,"failed":0},{"name":"return_call_indirect.wast","passed":75,"failed":0}] diff --git a/crates/tinywasm/tests/test-wasm-custom-page-sizes.rs b/crates/tinywasm/tests/test-wasm-custom-page-sizes.rs index d49d89a..e4aacfc 100644 --- a/crates/tinywasm/tests/test-wasm-custom-page-sizes.rs +++ b/crates/tinywasm/tests/test-wasm-custom-page-sizes.rs @@ -1,7 +1,13 @@ mod testsuite; use eyre::Result; +use testsuite::TestSuite; +use wasm_testsuite::data::{Proposal, proposal}; fn main() -> Result<()> { - println!("Skipping Wasm Custom Page Sizes tests (Wast doesn't support the syntax yet)"); - Ok(()) + TestSuite::set_log_level(log::LevelFilter::Off); + + let mut test_suite = TestSuite::new(); + test_suite.run_files(proposal(&Proposal::CustomPageSizes))?; + test_suite.save_csv("./tests/generated/wasm-custom-page-sizes.csv", env!("CARGO_PKG_VERSION"))?; + test_suite.report_status() } diff --git a/crates/tinywasm/tests/test-wasm-tail-call.rs b/crates/tinywasm/tests/test-wasm-tail-call.rs new file mode 100644 index 0000000..f888f38 --- /dev/null +++ b/crates/tinywasm/tests/test-wasm-tail-call.rs @@ -0,0 +1,13 @@ +mod testsuite; +use eyre::Result; +use testsuite::TestSuite; +use wasm_testsuite::data::{Proposal, proposal}; + +fn main() -> Result<()> { + TestSuite::set_log_level(log::LevelFilter::Off); + + let mut test_suite = TestSuite::new(); + test_suite.run_files(proposal(&Proposal::TailCall))?; + test_suite.save_csv("./tests/generated/wasm-tail-call.csv", env!("CARGO_PKG_VERSION"))?; + test_suite.report_status() +} diff --git a/crates/types/src/instructions.rs b/crates/types/src/instructions.rs index c61a02f..899be65 100644 --- a/crates/types/src/instructions.rs +++ b/crates/types/src/instructions.rs @@ -86,8 +86,8 @@ pub enum Instruction { Return, Call(FuncAddr), CallIndirect(TypeAddr, TableAddr), - // ReturnCall(FuncAddr), - // ReturnCallIndirect(TypeAddr, TableAddr), + ReturnCall(FuncAddr), + ReturnCallIndirect(TypeAddr, TableAddr), // > Parametric Instructions // See From 1252a8936eb2a69496efc849f3eb59e72b964920 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sun, 2 Mar 2025 14:43:02 +0100 Subject: [PATCH 46/54] feat: memory64 support (#38) Signed-off-by: Henry Gressmann --- Cargo.lock | 6 +- README.md | 12 ++-- crates/tinywasm/Cargo.toml | 2 +- crates/tinywasm/src/interpreter/executor.rs | 55 ++++++++++++++----- crates/tinywasm/src/reference.rs | 2 +- crates/tinywasm/src/store/memory.rs | 19 ++++--- crates/tinywasm/src/store/mod.rs | 28 +++++----- crates/tinywasm/src/store/table.rs | 2 +- crates/tinywasm/tests/generated/wasm-3.csv | 2 +- .../tests/generated/wasm-memory64.csv | 2 +- crates/tinywasm/tests/test-wasm-memory64.rs | 15 +---- 11 files changed, 83 insertions(+), 62 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1178a8a..8bdb809 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -674,9 +674,9 @@ dependencies = [ [[package]] name = "wasm-testsuite" -version = "0.4.4" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea6edc2d1ffad1d673091e3e3e98961e7c1a8c0f24cbf2431fa02d861e071bd" +checksum = "e01c897a970135c086793fa320de6632534ad7b4a519a3ca51c7ef40e6a567d7" dependencies = [ "include_dir", "wast", diff --git a/README.md b/README.md index 6b72448..27eb8f5 100644 --- a/README.md +++ b/README.md @@ -14,11 +14,15 @@ - **Tiny**: TinyWasm is designed to be as small as possible without significantly compromising performance or functionality (< 4000 LLOC). - **Portable**: TinyWasm runs on any platform that Rust can target, including `no_std`, with minimal external dependencies. -- **Safe**: No unsafe code is used in the runtime (`rkyv`, which uses unsafe code, can be used for serialization but is optional). +- **Safe**: No unsafe code is used in the runtime -## Status +## Current Status -TinyWasm passes all WebAssembly MVP tests from the [WebAssembly core testsuite](https://github.com/WebAssembly/testsuite) and is able to run most WebAssembly programs. Additionally, the current 2.0 Draft is mostly supported, with the exception of Fixed-Width SIMD and Memory64/Multiple Memories. See the [Supported Proposals](#supported-proposals) section for more information. +TinyWasm passes all WebAssembly MVP tests from the [WebAssembly core testsuite](https://github.com/WebAssembly/testsuite) and is able to run most WebAssembly programs. Additionally, the current 2.0 WebAssembly is mostly supported, with the exception of the SIMD and Memory64 proposals. See the [Supported Proposals](#supported-proposals) section for more information. + +## Safety + +Safety wise, TinyWasm doesn't use any unsafe code and is designed to be completly memory-safe. Untrusted WebAssembly code should not be able to crash the runtime or access memory outside of its sandbox, however currently there is no protection against infinite loops or excessive memory usage. Unvalidated Wasm and untrusted, precompilled twasm bytecode is safe to run too but can crash the runtime. ## Supported Proposals @@ -38,7 +42,7 @@ TinyWasm passes all WebAssembly MVP tests from the [WebAssembly core testsuite]( | [**Multiple Memories**](https://github.com/WebAssembly/multi-memory/blob/master/proposals/multi-memory/Overview.md) | 🟢 | 0.8.0 | | [**Custom Page Sizes**](https://github.com/WebAssembly/custom-page-sizes/blob/main/proposals/custom-page-sizes/Overview.md) | 🟢 | `next` | | [**Tail Call**](https://github.com/WebAssembly/tail-call/blob/main/proposals/tail-call/Overview.md) | 🟢 | `next` | -| [**Memory64**](https://github.com/WebAssembly/memory64/blob/master/proposals/memory64/Overview.md) | 🚧 | N/A | +| [**Memory64**](https://github.com/WebAssembly/memory64/blob/master/proposals/memory64/Overview.md) | 🟢 | `next` | | [**Fixed-Width SIMD**](https://github.com/webassembly/simd) | 🚧 | N/A | ## Usage diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index d004760..9be8233 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -20,7 +20,7 @@ tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false libm={version="0.2", default-features=false} [dev-dependencies] -wasm-testsuite={version="0.4.4"} +wasm-testsuite={version="0.5.0"} indexmap="2.7" wast={workspace=true} wat={workspace=true} diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index c776710..4ba4556 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -518,16 +518,31 @@ impl<'store, 'stack> Executor<'store, 'stack> { fn exec_memory_size(&mut self, addr: u32) { let mem = self.store.get_mem(self.module.resolve_mem_addr(addr)); - self.stack.values.push::(mem.page_count as i32); + + match mem.is_64bit() { + true => self.stack.values.push::(mem.page_count as i64), + false => self.stack.values.push::(mem.page_count as i32), + } } fn exec_memory_grow(&mut self, addr: u32) { let mem = self.store.get_mem_mut(self.module.resolve_mem_addr(addr)); - let prev_size = mem.page_count as i32; - let pages_delta = self.stack.values.pop::(); - self.stack.values.push::(match mem.grow(pages_delta) { - Some(_) => prev_size, - None => -1, - }); + let prev_size = mem.page_count; + + let pages_delta = match mem.is_64bit() { + true => self.stack.values.pop::(), + false => self.stack.values.pop::() as i64, + }; + + match ( + mem.is_64bit(), + match mem.grow(pages_delta) { + Some(_) => prev_size as i64, + None => -1_i64, + }, + ) { + (true, size) => self.stack.values.push::(size), + (false, size) => self.stack.values.push::(size as i32), + }; } fn exec_memory_copy(&mut self, from: u32, to: u32) -> Result<()> { @@ -605,14 +620,13 @@ impl<'store, 'stack> Executor<'store, 'stack> { dst as usize, src as usize, size as usize, - )?; + ) } else { // copy between two memories let (table_from, table_to) = self.store.get_tables_mut(self.module.resolve_table_addr(from), self.module.resolve_table_addr(to))?; - table_to.copy_from_slice(dst as usize, table_from.load(src as usize, size as usize)?)?; + table_to.copy_from_slice(dst as usize, table_from.load(src as usize, size as usize)?) } - Ok(()) } fn exec_mem_load, const LOAD_SIZE: usize, TARGET: InternalValue>( @@ -622,11 +636,16 @@ impl<'store, 'stack> Executor<'store, 'stack> { cast: fn(LOAD) -> TARGET, ) -> ControlFlow> { let mem = self.store.get_mem(self.module.resolve_mem_addr(mem_addr)); - let val = self.stack.values.pop::() as u64; - let Some(Ok(addr)) = offset.checked_add(val).map(TryInto::try_into) else { + + let addr = match mem.is_64bit() { + true => self.stack.values.pop::() as u64, + false => self.stack.values.pop::() as u32 as u64, + }; + + let Some(Ok(addr)) = offset.checked_add(addr).map(TryInto::try_into) else { cold(); return ControlFlow::Break(Some(Error::Trap(Trap::MemoryOutOfBounds { - offset: val as usize, + offset: addr as usize, len: LOAD_SIZE, max: 0, }))); @@ -644,10 +663,16 @@ impl<'store, 'stack> Executor<'store, 'stack> { let mem = self.store.get_mem_mut(self.module.resolve_mem_addr(mem_addr)); let val = self.stack.values.pop::(); let val = (cast(val)).to_mem_bytes(); - let addr = self.stack.values.pop::() as u64; + + let addr = match mem.is_64bit() { + true => self.stack.values.pop::() as u64, + false => self.stack.values.pop::() as u32 as u64, + }; + if let Err(e) = mem.store((offset + addr) as usize, val.len(), &val) { return ControlFlow::Break(Some(e)); } + ControlFlow::Continue(()) } @@ -707,7 +732,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { return Err(Trap::TableOutOfBounds { offset: 0, len: 0, max: 0 }.into()); }; - table.init(dst, &items[offset as usize..(offset + size) as usize]) + table.init(dst as i64, &items[offset as usize..(offset + size) as usize]) } fn exec_table_grow(&mut self, table_index: u32) -> Result<()> { let table = self.store.get_table_mut(self.module.resolve_table_addr(table_index)); diff --git a/crates/tinywasm/src/reference.rs b/crates/tinywasm/src/reference.rs index e151c87..e32a2f3 100644 --- a/crates/tinywasm/src/reference.rs +++ b/crates/tinywasm/src/reference.rs @@ -54,7 +54,7 @@ impl MemoryRefMut<'_> { } /// Grow the memory by the given number of pages - pub fn grow(&mut self, delta_pages: i32) -> Option { + pub fn grow(&mut self, delta_pages: i64) -> Option { self.0.grow(delta_pages) } diff --git a/crates/tinywasm/src/store/memory.rs b/crates/tinywasm/src/store/memory.rs index d204c67..53c1133 100644 --- a/crates/tinywasm/src/store/memory.rs +++ b/crates/tinywasm/src/store/memory.rs @@ -1,6 +1,6 @@ use alloc::vec; use alloc::vec::Vec; -use tinywasm_types::{MemoryType, ModuleInstanceAddr}; +use tinywasm_types::{MemoryArch, MemoryType, ModuleInstanceAddr}; use crate::{Error, Result, cold, log}; @@ -28,6 +28,11 @@ impl MemoryInstance { } } + #[inline] + pub(crate) fn is_64bit(&self) -> bool { + matches!(self.kind.arch(), MemoryArch::I64) + } + #[inline(always)] pub(crate) fn len(&self) -> usize { self.data.len() @@ -124,15 +129,13 @@ impl MemoryInstance { } #[inline] - pub(crate) fn grow(&mut self, pages_delta: i32) -> Option { + pub(crate) fn grow(&mut self, pages_delta: i64) -> Option { let current_pages = self.page_count; - let new_pages = current_pages as i64 + pages_delta as i64; - debug_assert!(new_pages <= i32::MAX as i64, "page count should never be greater than i32::MAX"); + let new_pages = current_pages as i64 + pages_delta; if new_pages < 0 || new_pages as usize > self.max_pages() { log::debug!("memory.grow failed: new_pages={}, max_pages={}", new_pages, self.max_pages()); log::debug!("{} {}", self.kind.page_count_max(), self.kind.page_size()); - return None; } @@ -145,7 +148,7 @@ impl MemoryInstance { self.data.reserve_exact(new_size); self.data.resize_with(new_size, Default::default); self.page_count = new_pages as usize; - Some(current_pages as i32) + Some(current_pages as i64) } } @@ -241,14 +244,14 @@ mod memory_instance_tests { fn test_memory_grow() { let mut memory = create_test_memory(); let original_pages = memory.page_count; - assert_eq!(memory.grow(1), Some(original_pages as i32)); + assert_eq!(memory.grow(1), Some(original_pages as i64)); assert_eq!(memory.page_count, original_pages + 1); } #[test] fn test_memory_grow_out_of_bounds() { let mut memory = create_test_memory(); - assert!(memory.grow(memory.kind.max_size() as i32 + 1).is_none()); + assert!(memory.grow(memory.kind.max_size() as i64 + 1).is_none()); } #[test] diff --git a/crates/tinywasm/src/store/mod.rs b/crates/tinywasm/src/store/mod.rs index 5730631..358cbef 100644 --- a/crates/tinywasm/src/store/mod.rs +++ b/crates/tinywasm/src/store/mod.rs @@ -243,9 +243,6 @@ impl Store { let mem_count = self.data.memories.len(); let mut mem_addrs = Vec::with_capacity(mem_count); for (i, mem) in memories.into_iter().enumerate() { - if let MemoryArch::I64 = mem.arch() { - return Err(Error::UnsupportedFeature("64-bit memories".to_string())); - } self.data.memories.push(MemoryInstance::new(mem, idx)); mem_addrs.push((i + mem_count) as MemAddr); } @@ -325,7 +322,7 @@ impl Store { // this one is active, so we need to initialize it (essentially a `table.init` instruction) ElementKind::Active { offset, table } => { - let offset = self.eval_i32_const(offset)?; + let offset = self.eval_size_const(offset)?; let table_addr = table_addrs .get(table as usize) .copied() @@ -373,7 +370,7 @@ impl Store { return Err(Error::Other(format!("memory {mem_addr} not found for data segment {i}"))); }; - let offset = self.eval_i32_const(offset)?; + let offset = self.eval_size_const(offset)?; let Some(mem) = self.data.memories.get_mut(*mem_addr as usize) else { return Err(Error::Other(format!("memory {mem_addr} not found for data segment {i}"))); }; @@ -418,15 +415,18 @@ impl Store { Ok(self.data.funcs.len() as FuncAddr - 1) } - /// Evaluate a constant expression, only supporting i32 globals and i32.const - pub(crate) fn eval_i32_const(&self, const_instr: tinywasm_types::ConstInstruction) -> Result { - use tinywasm_types::ConstInstruction::*; - let val = match const_instr { - I32Const(i) => i, - GlobalGet(addr) => self.data.globals[addr as usize].value.get().unwrap_32() as i32, - _ => return Err(Error::Other("expected i32".to_string())), - }; - Ok(val) + /// Evaluate a constant expression that's either a i32 or a i64 as a global or a const instruction + pub(crate) fn eval_size_const(&self, const_instr: tinywasm_types::ConstInstruction) -> Result { + Ok(match const_instr { + ConstInstruction::I32Const(i) => i as i64, + ConstInstruction::I64Const(i) => i, + ConstInstruction::GlobalGet(addr) => match self.data.globals[addr as usize].value.get() { + TinyWasmValue::Value32(i) => i as i64, + TinyWasmValue::Value64(i) => i as i64, + o => return Err(Error::Other(format!("expected i32 or i64, got {o:?}"))), + }, + o => return Err(Error::Other(format!("expected i32, got {o:?}"))), + }) } /// Evaluate a constant expression diff --git a/crates/tinywasm/src/store/table.rs b/crates/tinywasm/src/store/table.rs index 0cbd054..f83de9b 100644 --- a/crates/tinywasm/src/store/table.rs +++ b/crates/tinywasm/src/store/table.rs @@ -134,7 +134,7 @@ impl TableInstance { .expect("error initializing table: function not found. This should have been caught by the validator") } - pub(crate) fn init(&mut self, offset: i32, init: &[TableElement]) -> Result<()> { + pub(crate) fn init(&mut self, offset: i64, init: &[TableElement]) -> Result<()> { let offset = offset as usize; let end = offset.checked_add(init.len()).ok_or({ Error::Trap(crate::Trap::TableOutOfBounds { offset, len: init.len(), max: self.elements.len() }) diff --git a/crates/tinywasm/tests/generated/wasm-3.csv b/crates/tinywasm/tests/generated/wasm-3.csv index a1df609..5d4d068 100644 --- a/crates/tinywasm/tests/generated/wasm-3.csv +++ b/crates/tinywasm/tests/generated/wasm-3.csv @@ -1 +1 @@ -0.9.0-alpha.0,32377,2526,[{"name":"address.wast","passed":260,"failed":0},{"name":"address64.wast","passed":0,"failed":242},{"name":"align.wast","passed":161,"failed":0},{"name":"align64.wast","passed":83,"failed":73},{"name":"annotations.wast","passed":74,"failed":0},{"name":"binary-leb128.wast","passed":92,"failed":1},{"name":"binary.wast","passed":126,"failed":0},{"name":"block.wast","passed":223,"failed":0},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":119,"failed":0},{"name":"br_on_non_null.wast","passed":1,"failed":9},{"name":"br_on_null.wast","passed":1,"failed":9},{"name":"br_table.wast","passed":24,"failed":162},{"name":"bulk.wast","passed":117,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":49,"failed":124},{"name":"call_ref.wast","passed":4,"failed":31},{"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":59,"failed":6},{"name":"elem.wast","passed":137,"failed":14},{"name":"endianness.wast","passed":69,"failed":0},{"name":"endianness64.wast","passed":0,"failed":69},{"name":"exports.wast","passed":97,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_memory64.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":471,"failed":0},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":175,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"global.wast","passed":53,"failed":71},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":169,"failed":90},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"instance.wast","passed":0,"failed":23},{"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":142,"failed":21},{"name":"load.wast","passed":118,"failed":0},{"name":"load64.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_init.wast","passed":10,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":98,"failed":0},{"name":"loop.wast","passed":120,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":89,"failed":1},{"name":"memory64.wast","passed":14,"failed":55},{"name":"memory_copy.wast","passed":8385,"failed":515},{"name":"memory_fill.wast","passed":164,"failed":36},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_grow64.wast","passed":0,"failed":49},{"name":"memory_init.wast","passed":307,"failed":173},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_redundancy64.wast","passed":0,"failed":8},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"memory_trap64.wast","passed":0,"failed":172},{"name":"names.wast","passed":486,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref.wast","passed":12,"failed":1},{"name":"ref_as_non_null.wast","passed":1,"failed":6},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":2,"failed":20},{"name":"ref_null.wast","passed":0,"failed":34},{"name":"return.wast","passed":84,"failed":0},{"name":"return_call.wast","passed":40,"failed":5},{"name":"return_call_indirect.wast","passed":69,"failed":7},{"name":"return_call_ref.wast","passed":11,"failed":40},{"name":"select.wast","passed":155,"failed":2},{"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":111,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"table-sub.wast","passed":2,"failed":1},{"name":"table.wast","passed":47,"failed":13},{"name":"table_copy.wast","passed":1742,"failed":30},{"name":"table_copy_mixed.wast","passed":4,"failed":0},{"name":"table_fill.wast","passed":45,"failed":35},{"name":"table_get.wast","passed":16,"failed":1},{"name":"table_grow.wast","passed":58,"failed":21},{"name":"table_init.wast","passed":780,"failed":96},{"name":"table_set.wast","passed":26,"failed":2},{"name":"table_size.wast","passed":39,"failed":1},{"name":"tag.wast","passed":1,"failed":8},{"name":"throw.wast","passed":3,"failed":10},{"name":"throw_ref.wast","passed":2,"failed":13},{"name":"token.wast","passed":61,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"try_table.wast","passed":11,"failed":51},{"name":"type-canon.wast","passed":0,"failed":2},{"name":"type-equivalence.wast","passed":12,"failed":20},{"name":"type-rec.wast","passed":6,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":121,"failed":0},{"name":"unreached-valid.wast","passed":2,"failed":11},{"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.9.0-alpha.0,33714,1189,[{"name":"address.wast","passed":260,"failed":0},{"name":"address64.wast","passed":242,"failed":0},{"name":"align.wast","passed":161,"failed":0},{"name":"align64.wast","passed":156,"failed":0},{"name":"annotations.wast","passed":74,"failed":0},{"name":"binary-leb128.wast","passed":93,"failed":0},{"name":"binary.wast","passed":126,"failed":0},{"name":"block.wast","passed":223,"failed":0},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":119,"failed":0},{"name":"br_on_non_null.wast","passed":1,"failed":9},{"name":"br_on_null.wast","passed":1,"failed":9},{"name":"br_table.wast","passed":24,"failed":162},{"name":"bulk.wast","passed":117,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":172,"failed":1},{"name":"call_ref.wast","passed":4,"failed":31},{"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":59,"failed":6},{"name":"elem.wast","passed":137,"failed":14},{"name":"endianness.wast","passed":69,"failed":0},{"name":"endianness64.wast","passed":69,"failed":0},{"name":"exports.wast","passed":97,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_memory64.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"failed":0},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":175,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"global.wast","passed":53,"failed":71},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":169,"failed":90},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"instance.wast","passed":0,"failed":23},{"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":142,"failed":21},{"name":"load.wast","passed":118,"failed":0},{"name":"load64.wast","passed":97,"failed":0},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_init.wast","passed":10,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":98,"failed":0},{"name":"loop.wast","passed":120,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":89,"failed":1},{"name":"memory64.wast","passed":68,"failed":1},{"name":"memory_copy.wast","passed":8628,"failed":272},{"name":"memory_fill.wast","passed":184,"failed":16},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_grow64.wast","passed":49,"failed":0},{"name":"memory_init.wast","passed":439,"failed":41},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_redundancy64.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"memory_trap64.wast","passed":172,"failed":0},{"name":"names.wast","passed":486,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref.wast","passed":12,"failed":1},{"name":"ref_as_non_null.wast","passed":1,"failed":6},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":2,"failed":20},{"name":"ref_null.wast","passed":0,"failed":34},{"name":"return.wast","passed":84,"failed":0},{"name":"return_call.wast","passed":45,"failed":0},{"name":"return_call_indirect.wast","passed":76,"failed":0},{"name":"return_call_ref.wast","passed":11,"failed":40},{"name":"select.wast","passed":155,"failed":2},{"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":111,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"table-sub.wast","passed":2,"failed":1},{"name":"table.wast","passed":47,"failed":13},{"name":"table_copy.wast","passed":1750,"failed":22},{"name":"table_copy_mixed.wast","passed":4,"failed":0},{"name":"table_fill.wast","passed":45,"failed":35},{"name":"table_get.wast","passed":16,"failed":1},{"name":"table_grow.wast","passed":58,"failed":21},{"name":"table_init.wast","passed":783,"failed":93},{"name":"table_set.wast","passed":26,"failed":2},{"name":"table_size.wast","passed":39,"failed":1},{"name":"tag.wast","passed":1,"failed":8},{"name":"throw.wast","passed":3,"failed":10},{"name":"throw_ref.wast","passed":2,"failed":13},{"name":"token.wast","passed":61,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"try_table.wast","passed":11,"failed":51},{"name":"type-canon.wast","passed":0,"failed":2},{"name":"type-equivalence.wast","passed":12,"failed":20},{"name":"type-rec.wast","passed":6,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":121,"failed":0},{"name":"unreached-valid.wast","passed":2,"failed":11},{"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/wasm-memory64.csv b/crates/tinywasm/tests/generated/wasm-memory64.csv index 6638c85..039fe8c 100644 --- a/crates/tinywasm/tests/generated/wasm-memory64.csv +++ b/crates/tinywasm/tests/generated/wasm-memory64.csv @@ -1,2 +1,2 @@ 0.8.0,15081,3214,[{"name":"address.wast","passed":260,"failed":0},{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"address64.wast","passed":0,"failed":242},{"name":"align.wast","passed":161,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"align64.wast","passed":83,"failed":73},{"name":"annotations.wast","passed":74,"failed":0},{"name":"array_copy.wast","passed":4,"failed":31},{"name":"array_fill.wast","passed":3,"failed":14},{"name":"array_init_data.wast","passed":2,"failed":31},{"name":"array_init_elem.wast","passed":3,"failed":20},{"name":"binary-gc.wast","passed":1,"failed":0},{"name":"binary-leb128.wast","passed":92,"failed":1},{"name":"binary.wast","passed":124,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"br_if.wast","passed":119,"failed":0},{"name":"br_on_cast.wast","passed":6,"failed":31},{"name":"br_on_cast_fail.wast","passed":6,"failed":31},{"name":"br_on_non_null.wast","passed":1,"failed":9},{"name":"br_on_null.wast","passed":1,"failed":9},{"name":"br_table.wast","passed":24,"failed":162},{"name":"call_indirect.wast","passed":47,"failed":124},{"name":"call_ref.wast","passed":4,"failed":31},{"name":"data.wast","passed":59,"failed":6},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"elem.wast","passed":137,"failed":14},{"name":"endianness64.wast","passed":0,"failed":69},{"name":"exports.wast","passed":97,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"float_memory64.wast","passed":0,"failed":90},{"name":"func.wast","passed":175,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":99,"failed":82},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking.wast","passed":122,"failed":41},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"load64.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_init.wast","passed":10,"failed":0},{"name":"local_tee.wast","passed":98,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory64.wast","passed":10,"failed":53},{"name":"memory64/array.wast (skipped)","passed":0,"failed":0},{"name":"memory64/extern.wast (skipped)","passed":0,"failed":0},{"name":"memory64/global.wast (skipped)","passed":0,"failed":0},{"name":"memory64/i31.wast (skipped)","passed":0,"failed":0},{"name":"memory64/ref_null.wast (skipped)","passed":0,"failed":0},{"name":"memory64/select.wast (skipped)","passed":0,"failed":0},{"name":"memory64/simd_address.wast (skipped)","passed":0,"failed":0},{"name":"memory64/simd_lane.wast (skipped)","passed":0,"failed":0},{"name":"memory64/struct.wast (skipped)","passed":0,"failed":0},{"name":"memory64/table.wast (skipped)","passed":0,"failed":0},{"name":"memory_copy.wast","passed":8385,"failed":515},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill.wast","passed":164,"failed":36},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_grow64.wast","passed":0,"failed":49},{"name":"memory_init.wast","passed":307,"failed":173},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_redundancy64.wast","passed":0,"failed":8},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"memory_trap64.wast","passed":0,"failed":172},{"name":"ref.wast","passed":12,"failed":1},{"name":"ref_as_non_null.wast","passed":1,"failed":6},{"name":"ref_cast.wast","passed":0,"failed":45},{"name":"ref_eq.wast","passed":6,"failed":83},{"name":"ref_is_null.wast","passed":2,"failed":20},{"name":"ref_test.wast","passed":0,"failed":71},{"name":"return_call.wast","passed":18,"failed":27},{"name":"return_call_indirect.wast","passed":31,"failed":45},{"name":"return_call_ref.wast","passed":11,"failed":40},{"name":"simd_memory-multi.wast","passed":0,"failed":1},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"table-sub.wast","passed":2,"failed":1},{"name":"table_copy.wast","passed":1742,"failed":30},{"name":"table_copy_mixed.wast","passed":3,"failed":1},{"name":"table_fill.wast","passed":9,"failed":71},{"name":"table_get.wast","passed":5,"failed":12},{"name":"table_grow.wast","passed":36,"failed":43},{"name":"table_init.wast","passed":588,"failed":288},{"name":"table_set.wast","passed":7,"failed":21},{"name":"table_size.wast","passed":2,"failed":38},{"name":"tag.wast","passed":1,"failed":8},{"name":"throw.wast","passed":3,"failed":10},{"name":"throw_ref.wast","passed":2,"failed":13},{"name":"token.wast","passed":61,"failed":0},{"name":"traps0.wast","passed":15,"failed":0},{"name":"try_table.wast","passed":11,"failed":51},{"name":"type-canon.wast","passed":0,"failed":2},{"name":"type-equivalence.wast","passed":12,"failed":20},{"name":"type-rec.wast","passed":6,"failed":14},{"name":"type-subtyping.wast","passed":16,"failed":86},{"name":"unreached-invalid.wast","passed":121,"failed":0},{"name":"unreached-valid.wast","passed":2,"failed":11}] -0.9.0-alpha.0,12505,1919,[{"name":"address.wast","passed":260,"failed":0},{"name":"address64.wast","passed":0,"failed":242},{"name":"align64.wast","passed":83,"failed":73},{"name":"binary-leb128.wast","passed":92,"failed":1},{"name":"binary.wast","passed":126,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"call_indirect.wast","passed":47,"failed":124},{"name":"endianness64.wast","passed":0,"failed":69},{"name":"float_memory64.wast","passed":0,"failed":90},{"name":"imports.wast","passed":169,"failed":90},{"name":"load64.wast","passed":59,"failed":38},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory64.wast","passed":10,"failed":53},{"name":"memory64/simd_address.wast (skipped)","passed":0,"failed":0},{"name":"memory64/table.wast (skipped)","passed":0,"failed":0},{"name":"memory_copy.wast","passed":8385,"failed":515},{"name":"memory_fill.wast","passed":164,"failed":36},{"name":"memory_grow64.wast","passed":0,"failed":49},{"name":"memory_init.wast","passed":307,"failed":173},{"name":"memory_redundancy64.wast","passed":0,"failed":8},{"name":"memory_trap64.wast","passed":0,"failed":172},{"name":"table_copy.wast","passed":1742,"failed":30},{"name":"table_copy_mixed.wast","passed":4,"failed":0},{"name":"table_fill.wast","passed":45,"failed":35},{"name":"table_get.wast","passed":16,"failed":1},{"name":"table_grow.wast","passed":58,"failed":21},{"name":"table_init.wast","passed":780,"failed":96},{"name":"table_set.wast","passed":26,"failed":2},{"name":"table_size.wast","passed":39,"failed":1}] +0.9.0-alpha.0,1556,42,[{"name":"address.wast","passed":260,"failed":0},{"name":"address64.wast","passed":242,"failed":0},{"name":"align64.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":93,"failed":0},{"name":"binary.wast","passed":169,"failed":0},{"name":"endianness64.wast","passed":69,"failed":0},{"name":"float_memory64.wast","passed":90,"failed":0},{"name":"load64.wast","passed":97,"failed":0},{"name":"memory.wast","passed":79,"failed":0},{"name":"memory64.wast","passed":65,"failed":0},{"name":"memory_grow64.wast","passed":49,"failed":0},{"name":"memory_redundancy64.wast","passed":8,"failed":0},{"name":"memory_trap64.wast","passed":172,"failed":0},{"name":"simd_address.wast","passed":7,"failed":42}] diff --git a/crates/tinywasm/tests/test-wasm-memory64.rs b/crates/tinywasm/tests/test-wasm-memory64.rs index 391a1ef..447bbfc 100644 --- a/crates/tinywasm/tests/test-wasm-memory64.rs +++ b/crates/tinywasm/tests/test-wasm-memory64.rs @@ -1,22 +1,11 @@ mod testsuite; -use eyre::{eyre, Result}; -use owo_colors::OwoColorize; +use eyre::Result; use testsuite::TestSuite; +use wasm_testsuite::data::{Proposal, proposal}; fn main() -> Result<()> { TestSuite::set_log_level(log::LevelFilter::Off); - let mut test_suite = TestSuite::new(); - test_suite.skip("memory64/array.wast"); - test_suite.skip("memory64/extern.wast"); - test_suite.skip("memory64/global.wast"); - test_suite.skip("memory64/i31.wast"); - test_suite.skip("memory64/ref_null.wast"); - test_suite.skip("memory64/select.wast"); - test_suite.skip("memory64/simd_address.wast"); - test_suite.skip("memory64/simd_lane.wast"); - test_suite.skip("memory64/struct.wast"); - test_suite.skip("memory64/table.wast"); test_suite.run_files(proposal(&Proposal::Memory64))?; test_suite.save_csv("./tests/generated/wasm-memory64.csv", env!("CARGO_PKG_VERSION"))?; From 374db44a6b7666353875df17f44ec4da7ff317d5 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Thu, 6 Mar 2025 23:40:16 +0100 Subject: [PATCH 47/54] chore: update wasmparser Signed-off-by: Henry Gressmann --- Cargo.lock | 6 +++--- Cargo.toml | 6 +++--- crates/tinywasm/tests/generated/wasm-memory64.csv | 2 +- crates/tinywasm/tests/generated/wasm-relaxed-simd.csv | 1 + 4 files changed, 8 insertions(+), 7 deletions(-) create mode 100644 crates/tinywasm/tests/generated/wasm-relaxed-simd.csv diff --git a/Cargo.lock b/Cargo.lock index e2c5d3f..00d3aaa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -596,7 +596,7 @@ dependencies = [ "tinywasm-parser", "tinywasm-types", "wasm-testsuite", - "wast 226.0.0", + "wast 227.0.0", "wat", ] @@ -609,7 +609,7 @@ dependencies = [ "log", "pretty_env_logger", "tinywasm", - "wast 226.0.0", + "wast 227.0.0", ] [[package]] @@ -618,7 +618,7 @@ version = "0.9.0-alpha.0" dependencies = [ "log", "tinywasm-types", - "wasmparser 0.226.0", + "wasmparser 0.227.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index e433260..74ad676 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,9 +4,9 @@ default-members=[".", "crates/tinywasm", "crates/types", "crates/parser"] resolver="2" [workspace.dependencies] -wast="226" -wat="1.226" -wasmparser={version="0.226", default-features=false} +wast="227" +wat="1.227" +wasmparser={version="0.227", default-features=false} eyre="0.6" log="0.4" pretty_env_logger="0.5" diff --git a/crates/tinywasm/tests/generated/wasm-memory64.csv b/crates/tinywasm/tests/generated/wasm-memory64.csv index 039fe8c..20afc3b 100644 --- a/crates/tinywasm/tests/generated/wasm-memory64.csv +++ b/crates/tinywasm/tests/generated/wasm-memory64.csv @@ -1,2 +1,2 @@ 0.8.0,15081,3214,[{"name":"address.wast","passed":260,"failed":0},{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"address64.wast","passed":0,"failed":242},{"name":"align.wast","passed":161,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"align64.wast","passed":83,"failed":73},{"name":"annotations.wast","passed":74,"failed":0},{"name":"array_copy.wast","passed":4,"failed":31},{"name":"array_fill.wast","passed":3,"failed":14},{"name":"array_init_data.wast","passed":2,"failed":31},{"name":"array_init_elem.wast","passed":3,"failed":20},{"name":"binary-gc.wast","passed":1,"failed":0},{"name":"binary-leb128.wast","passed":92,"failed":1},{"name":"binary.wast","passed":124,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"br_if.wast","passed":119,"failed":0},{"name":"br_on_cast.wast","passed":6,"failed":31},{"name":"br_on_cast_fail.wast","passed":6,"failed":31},{"name":"br_on_non_null.wast","passed":1,"failed":9},{"name":"br_on_null.wast","passed":1,"failed":9},{"name":"br_table.wast","passed":24,"failed":162},{"name":"call_indirect.wast","passed":47,"failed":124},{"name":"call_ref.wast","passed":4,"failed":31},{"name":"data.wast","passed":59,"failed":6},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"elem.wast","passed":137,"failed":14},{"name":"endianness64.wast","passed":0,"failed":69},{"name":"exports.wast","passed":97,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"float_memory64.wast","passed":0,"failed":90},{"name":"func.wast","passed":175,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":99,"failed":82},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking.wast","passed":122,"failed":41},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"load64.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_init.wast","passed":10,"failed":0},{"name":"local_tee.wast","passed":98,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory64.wast","passed":10,"failed":53},{"name":"memory64/array.wast (skipped)","passed":0,"failed":0},{"name":"memory64/extern.wast (skipped)","passed":0,"failed":0},{"name":"memory64/global.wast (skipped)","passed":0,"failed":0},{"name":"memory64/i31.wast (skipped)","passed":0,"failed":0},{"name":"memory64/ref_null.wast (skipped)","passed":0,"failed":0},{"name":"memory64/select.wast (skipped)","passed":0,"failed":0},{"name":"memory64/simd_address.wast (skipped)","passed":0,"failed":0},{"name":"memory64/simd_lane.wast (skipped)","passed":0,"failed":0},{"name":"memory64/struct.wast (skipped)","passed":0,"failed":0},{"name":"memory64/table.wast (skipped)","passed":0,"failed":0},{"name":"memory_copy.wast","passed":8385,"failed":515},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill.wast","passed":164,"failed":36},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_grow64.wast","passed":0,"failed":49},{"name":"memory_init.wast","passed":307,"failed":173},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_redundancy64.wast","passed":0,"failed":8},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"memory_trap64.wast","passed":0,"failed":172},{"name":"ref.wast","passed":12,"failed":1},{"name":"ref_as_non_null.wast","passed":1,"failed":6},{"name":"ref_cast.wast","passed":0,"failed":45},{"name":"ref_eq.wast","passed":6,"failed":83},{"name":"ref_is_null.wast","passed":2,"failed":20},{"name":"ref_test.wast","passed":0,"failed":71},{"name":"return_call.wast","passed":18,"failed":27},{"name":"return_call_indirect.wast","passed":31,"failed":45},{"name":"return_call_ref.wast","passed":11,"failed":40},{"name":"simd_memory-multi.wast","passed":0,"failed":1},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"table-sub.wast","passed":2,"failed":1},{"name":"table_copy.wast","passed":1742,"failed":30},{"name":"table_copy_mixed.wast","passed":3,"failed":1},{"name":"table_fill.wast","passed":9,"failed":71},{"name":"table_get.wast","passed":5,"failed":12},{"name":"table_grow.wast","passed":36,"failed":43},{"name":"table_init.wast","passed":588,"failed":288},{"name":"table_set.wast","passed":7,"failed":21},{"name":"table_size.wast","passed":2,"failed":38},{"name":"tag.wast","passed":1,"failed":8},{"name":"throw.wast","passed":3,"failed":10},{"name":"throw_ref.wast","passed":2,"failed":13},{"name":"token.wast","passed":61,"failed":0},{"name":"traps0.wast","passed":15,"failed":0},{"name":"try_table.wast","passed":11,"failed":51},{"name":"type-canon.wast","passed":0,"failed":2},{"name":"type-equivalence.wast","passed":12,"failed":20},{"name":"type-rec.wast","passed":6,"failed":14},{"name":"type-subtyping.wast","passed":16,"failed":86},{"name":"unreached-invalid.wast","passed":121,"failed":0},{"name":"unreached-valid.wast","passed":2,"failed":11}] -0.9.0-alpha.0,1556,42,[{"name":"address.wast","passed":260,"failed":0},{"name":"address64.wast","passed":242,"failed":0},{"name":"align64.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":93,"failed":0},{"name":"binary.wast","passed":169,"failed":0},{"name":"endianness64.wast","passed":69,"failed":0},{"name":"float_memory64.wast","passed":90,"failed":0},{"name":"load64.wast","passed":97,"failed":0},{"name":"memory.wast","passed":79,"failed":0},{"name":"memory64.wast","passed":65,"failed":0},{"name":"memory_grow64.wast","passed":49,"failed":0},{"name":"memory_redundancy64.wast","passed":8,"failed":0},{"name":"memory_trap64.wast","passed":172,"failed":0},{"name":"simd_address.wast","passed":7,"failed":42}] +0.9.0-alpha.0,1598,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"address64.wast","passed":242,"failed":0},{"name":"align64.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":93,"failed":0},{"name":"binary.wast","passed":169,"failed":0},{"name":"endianness64.wast","passed":69,"failed":0},{"name":"float_memory64.wast","passed":90,"failed":0},{"name":"load64.wast","passed":97,"failed":0},{"name":"memory.wast","passed":79,"failed":0},{"name":"memory64.wast","passed":65,"failed":0},{"name":"memory_grow64.wast","passed":49,"failed":0},{"name":"memory_redundancy64.wast","passed":8,"failed":0},{"name":"memory_trap64.wast","passed":172,"failed":0},{"name":"simd_address.wast","passed":49,"failed":0}] diff --git a/crates/tinywasm/tests/generated/wasm-relaxed-simd.csv b/crates/tinywasm/tests/generated/wasm-relaxed-simd.csv new file mode 100644 index 0000000..a6e6228 --- /dev/null +++ b/crates/tinywasm/tests/generated/wasm-relaxed-simd.csv @@ -0,0 +1 @@ +0.9.0-alpha.0,0,93,[{"name":"i16x8_relaxed_q15mulr_s.wast","passed":0,"failed":3},{"name":"i32x4_relaxed_trunc.wast","passed":0,"failed":17},{"name":"i8x16_relaxed_swizzle.wast","passed":0,"failed":6},{"name":"relaxed_dot_product.wast","passed":0,"failed":11},{"name":"relaxed_laneselect.wast","passed":0,"failed":12},{"name":"relaxed_madd_nmadd.wast","passed":0,"failed":19},{"name":"relaxed_min_max.wast","passed":0,"failed":25}] From 904aa393a7c1f50d247d8af778244a7e76fa665d Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sun, 9 Mar 2025 18:26:50 +0100 Subject: [PATCH 48/54] chore: progress on more simd instructions Signed-off-by: Henry Gressmann --- crates/tinywasm/src/interpreter/executor.rs | 61 ++++++++++++++----- .../src/interpreter/stack/value_stack.rs | 11 ++++ crates/tinywasm/src/store/mod.rs | 1 + crates/tinywasm/tests/generated/wasm-simd.csv | 2 +- 4 files changed, 58 insertions(+), 17 deletions(-) diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index 70c3d97..aff1696 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -331,6 +331,15 @@ impl<'store, 'stack> Executor<'store, 'stack> { V128Store(arg) => self.exec_mem_store::(arg.mem_addr(), arg.offset(), |v| v)?, V128Const(arg) => self.exec_const::( self.cf.data().v128_constants[*arg as usize].to_le_bytes().into()), + I8x16ExtractLaneS(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, + I8x16ExtractLaneU(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, + I16x8ExtractLaneS(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, + I16x8ExtractLaneU(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, + I32x4ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, + I64x2ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, + F32x4ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, + F64x2ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, + V128Load8Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, V128Load16Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, V128Load32Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, @@ -409,30 +418,30 @@ impl<'store, 'stack> Executor<'store, 'stack> { I32x4Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, I64x2Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, - I8x16AllTrue => self.stack.values.replace_top::(|v| Ok((v != Simd::splat(0)) as i32)).to_cf()?, - I16x8AllTrue => self.stack.values.replace_top::(|v| Ok((v != Simd::splat(0)) as i32)).to_cf()?, - I32x4AllTrue => self.stack.values.replace_top::(|v| Ok((v != Simd::splat(0)) as i32)).to_cf()?, - I64x2AllTrue => self.stack.values.replace_top::(|v| Ok((v != Simd::splat(0)) as i32)).to_cf()?, + I8x16AllTrue => self.stack.values.replace_top::(|v| Ok((v.simd_ne(Simd::splat(0)).all()) as i32)).to_cf()?, + I16x8AllTrue => self.stack.values.replace_top::(|v| Ok((v.simd_ne(Simd::splat(0)).all()) as i32)).to_cf()?, + I32x4AllTrue => self.stack.values.replace_top::(|v| Ok((v.simd_ne(Simd::splat(0)).all()) as i32)).to_cf()?, + I64x2AllTrue => self.stack.values.replace_top::(|v| Ok((v.simd_ne(Simd::splat(0)).all()) as i32)).to_cf()?, I8x16Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, I16x8Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, I32x4Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, I64x2Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, - I8x16Shl => self.stack.values.calculate_same::(|a, b| Ok(a.shl(b))).to_cf()?, - I16x8Shl => self.stack.values.calculate_same::(|a, b| Ok(a.shl(b))).to_cf()?, - I32x4Shl => self.stack.values.calculate_same::(|a, b| Ok(a.shl(b))).to_cf()?, - I64x2Shl => self.stack.values.calculate_same::(|a, b| Ok(a.shl(b))).to_cf()?, + I8x16Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a as i8))).to_cf()?, + I16x8Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a as i16))).to_cf()?, + I32x4Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a as i32))).to_cf()?, + I64x2Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a as i64))).to_cf()?, - I8x16ShrS => self.stack.values.calculate_same::(|a, b| Ok(a.shr(b))).to_cf()?, - I16x8ShrS => self.stack.values.calculate_same::(|a, b| Ok(a.shr(b))).to_cf()?, - I32x4ShrS => self.stack.values.calculate_same::(|a, b| Ok(a.shr(b))).to_cf()?, - I64x2ShrS => self.stack.values.calculate_same::(|a, b| Ok(a.shr(b))).to_cf()?, + I8x16ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as i8))).to_cf()?, + I16x8ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as i16))).to_cf()?, + I32x4ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as i32))).to_cf()?, + I64x2ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as i64))).to_cf()?, - I8x16ShrU => self.stack.values.calculate_same::(|a, b| Ok(a.shr(b))).to_cf()?, - I16x8ShrU => self.stack.values.calculate_same::(|a, b| Ok(a.shr(b))).to_cf()?, - I32x4ShrU => self.stack.values.calculate_same::(|a, b| Ok(a.shr(b))).to_cf()?, - I64x2ShrU => self.stack.values.calculate_same::(|a, b| Ok(a.shr(b))).to_cf()?, + I8x16ShrU => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as u8))).to_cf()?, + I16x8ShrU => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as u16))).to_cf()?, + I32x4ShrU => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as u32))).to_cf()?, + I64x2ShrU => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as u64))).to_cf()?, I8x16Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, I16x8Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, @@ -471,6 +480,9 @@ impl<'store, 'stack> Executor<'store, 'stack> { I8x16SubSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, I16x8SubSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, + I16x8Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, + I32x4Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, + F32x4Ceil => self.stack.values.replace_top_same::(|v| Ok(v.ceil())).to_cf()?, F64x2Ceil => self.stack.values.replace_top_same::(|v| Ok(v.ceil())).to_cf()?, F32x4Floor => self.stack.values.replace_top_same::(|v| Ok(v.floor())).to_cf()?, @@ -496,6 +508,23 @@ impl<'store, 'stack> Executor<'store, 'stack> { F32x4Max => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, F64x2Max => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + F32x4PMin => unimplemented!(), + F32x4PMax => unimplemented!(), + F64x2PMin => unimplemented!(), + F64x2PMax => unimplemented!(), + + // not correct + I32x4TruncSatF32x4S => self.stack.values.replace_top::(|v| Ok(v.trunc())).to_cf()?, + I32x4TruncSatF32x4U => self.stack.values.replace_top::(|v| Ok(v.trunc())).to_cf()?, + F32x4ConvertI32x4S => {}, + F32x4ConvertI32x4U => {}, + F64x2ConvertLowI32x4S => {}, + F64x2ConvertLowI32x4U => {}, + F32x4DemoteF64x2Zero => {}, + F64x2PromoteLowF32x4 => {}, + I32x4TruncSatF64x2SZero => unimplemented!(), + I32x4TruncSatF64x2UZero => unimplemented!(), + i => return ControlFlow::Break(Some(Error::UnsupportedFeature(format!("unimplemented opcode: {i:?}")))), }; diff --git a/crates/tinywasm/src/interpreter/stack/value_stack.rs b/crates/tinywasm/src/interpreter/stack/value_stack.rs index bb5b2ea..01cea1c 100644 --- a/crates/tinywasm/src/interpreter/stack/value_stack.rs +++ b/crates/tinywasm/src/interpreter/stack/value_stack.rs @@ -87,6 +87,17 @@ impl ValueStack { Ok(()) } + #[inline] + pub(crate) fn calculate_diff( + &mut self, + func: impl FnOnce(A, B) -> Result, + ) -> Result<()> { + let v2 = B::stack_pop(self); + let v1 = A::stack_pop(self); + RES::stack_push(self, func(v1, v2)?); + Ok(()) + } + #[inline] pub(crate) fn replace_top( &mut self, diff --git a/crates/tinywasm/src/store/mod.rs b/crates/tinywasm/src/store/mod.rs index 358cbef..d53654e 100644 --- a/crates/tinywasm/src/store/mod.rs +++ b/crates/tinywasm/src/store/mod.rs @@ -442,6 +442,7 @@ impl Store { F64Const(f) => (*f).into(), I32Const(i) => (*i).into(), I64Const(i) => (*i).into(), + V128Const(i) => (*i).into(), GlobalGet(addr) => { let addr = module_global_addrs.get(*addr as usize).ok_or_else(|| { Error::Other(format!("global {addr} not found. This should have been caught by the validator")) diff --git a/crates/tinywasm/tests/generated/wasm-simd.csv b/crates/tinywasm/tests/generated/wasm-simd.csv index 6f37f4d..79adc36 100644 --- a/crates/tinywasm/tests/generated/wasm-simd.csv +++ b/crates/tinywasm/tests/generated/wasm-simd.csv @@ -1,2 +1,2 @@ 0.8.0,1300,24679,[{"name":"simd_address.wast","passed":4,"failed":45},{"name":"simd_align.wast","passed":46,"failed":54},{"name":"simd_bit_shift.wast","passed":39,"failed":213},{"name":"simd_bitwise.wast","passed":28,"failed":141},{"name":"simd_boolean.wast","passed":16,"failed":261},{"name":"simd_const.wast","passed":301,"failed":456},{"name":"simd_conversions.wast","passed":48,"failed":234},{"name":"simd_f32x4.wast","passed":16,"failed":774},{"name":"simd_f32x4_arith.wast","passed":16,"failed":1806},{"name":"simd_f32x4_cmp.wast","passed":24,"failed":2583},{"name":"simd_f32x4_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f32x4_rounding.wast","passed":24,"failed":177},{"name":"simd_f64x2.wast","passed":8,"failed":795},{"name":"simd_f64x2_arith.wast","passed":16,"failed":1809},{"name":"simd_f64x2_cmp.wast","passed":24,"failed":2661},{"name":"simd_f64x2_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f64x2_rounding.wast","passed":24,"failed":177},{"name":"simd_i16x8_arith.wast","passed":11,"failed":183},{"name":"simd_i16x8_arith2.wast","passed":19,"failed":153},{"name":"simd_i16x8_cmp.wast","passed":30,"failed":435},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":4,"failed":17},{"name":"simd_i16x8_extmul_i8x16.wast","passed":12,"failed":105},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":3,"failed":27},{"name":"simd_i16x8_sat_arith.wast","passed":16,"failed":206},{"name":"simd_i32x4_arith.wast","passed":11,"failed":183},{"name":"simd_i32x4_arith2.wast","passed":26,"failed":123},{"name":"simd_i32x4_cmp.wast","passed":40,"failed":435},{"name":"simd_i32x4_dot_i16x8.wast","passed":3,"failed":27},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":4,"failed":17},{"name":"simd_i32x4_extmul_i16x8.wast","passed":12,"failed":105},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":4,"failed":103},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":4,"failed":103},{"name":"simd_i64x2_arith.wast","passed":11,"failed":189},{"name":"simd_i64x2_arith2.wast","passed":2,"failed":23},{"name":"simd_i64x2_cmp.wast","passed":10,"failed":103},{"name":"simd_i64x2_extmul_i32x4.wast","passed":12,"failed":105},{"name":"simd_i8x16_arith.wast","passed":8,"failed":123},{"name":"simd_i8x16_arith2.wast","passed":25,"failed":186},{"name":"simd_i8x16_cmp.wast","passed":30,"failed":415},{"name":"simd_i8x16_sat_arith.wast","passed":24,"failed":190},{"name":"simd_int_to_int_extend.wast","passed":24,"failed":229},{"name":"simd_lane.wast","passed":189,"failed":286},{"name":"simd_linking.wast","passed":0,"failed":3},{"name":"simd_load.wast","passed":8,"failed":31},{"name":"simd_load16_lane.wast","passed":3,"failed":33},{"name":"simd_load32_lane.wast","passed":3,"failed":21},{"name":"simd_load64_lane.wast","passed":3,"failed":13},{"name":"simd_load8_lane.wast","passed":3,"failed":49},{"name":"simd_load_extend.wast","passed":18,"failed":86},{"name":"simd_load_splat.wast","passed":12,"failed":114},{"name":"simd_load_zero.wast","passed":10,"failed":29},{"name":"simd_splat.wast","passed":23,"failed":162},{"name":"simd_store.wast","passed":9,"failed":19},{"name":"simd_store16_lane.wast","passed":3,"failed":33},{"name":"simd_store32_lane.wast","passed":3,"failed":21},{"name":"simd_store64_lane.wast","passed":3,"failed":13},{"name":"simd_store8_lane.wast","passed":3,"failed":49}] -0.9.0-alpha.0,14613,11367,[{"name":"simd_address.wast","passed":48,"failed":1},{"name":"simd_align.wast","passed":100,"failed":0},{"name":"simd_bit_shift.wast","passed":41,"failed":211},{"name":"simd_bitwise.wast","passed":169,"failed":0},{"name":"simd_boolean.wast","passed":241,"failed":36},{"name":"simd_const.wast","passed":751,"failed":6},{"name":"simd_conversions.wast","passed":50,"failed":232},{"name":"simd_f32x4.wast","passed":629,"failed":161},{"name":"simd_f32x4_arith.wast","passed":1357,"failed":465},{"name":"simd_f32x4_cmp.wast","passed":2607,"failed":0},{"name":"simd_f32x4_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f32x4_rounding.wast","passed":148,"failed":53},{"name":"simd_f64x2.wast","passed":639,"failed":164},{"name":"simd_f64x2_arith.wast","passed":1360,"failed":465},{"name":"simd_f64x2_cmp.wast","passed":2685,"failed":0},{"name":"simd_f64x2_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f64x2_rounding.wast","passed":148,"failed":53},{"name":"simd_i16x8_arith.wast","passed":138,"failed":56},{"name":"simd_i16x8_arith2.wast","passed":142,"failed":30},{"name":"simd_i16x8_cmp.wast","passed":436,"failed":29},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":5,"failed":16},{"name":"simd_i16x8_extmul_i8x16.wast","passed":13,"failed":104},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":4,"failed":26},{"name":"simd_i16x8_sat_arith.wast","passed":222,"failed":0},{"name":"simd_i32x4_arith.wast","passed":138,"failed":56},{"name":"simd_i32x4_arith2.wast","passed":149,"failed":0},{"name":"simd_i32x4_cmp.wast","passed":450,"failed":25},{"name":"simd_i32x4_dot_i16x8.wast","passed":4,"failed":26},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":5,"failed":16},{"name":"simd_i32x4_extmul_i16x8.wast","passed":13,"failed":104},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":5,"failed":102},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":5,"failed":102},{"name":"simd_i64x2_arith.wast","passed":200,"failed":0},{"name":"simd_i64x2_arith2.wast","passed":25,"failed":0},{"name":"simd_i64x2_cmp.wast","passed":97,"failed":16},{"name":"simd_i64x2_extmul_i32x4.wast","passed":13,"failed":104},{"name":"simd_i8x16_arith.wast","passed":131,"failed":0},{"name":"simd_i8x16_arith2.wast","passed":148,"failed":63},{"name":"simd_i8x16_cmp.wast","passed":409,"failed":36},{"name":"simd_i8x16_sat_arith.wast","passed":214,"failed":0},{"name":"simd_int_to_int_extend.wast","passed":25,"failed":228},{"name":"simd_lane.wast","passed":213,"failed":262},{"name":"simd_linking.wast","passed":0,"failed":3},{"name":"simd_load.wast","passed":34,"failed":5},{"name":"simd_load16_lane.wast","passed":36,"failed":0},{"name":"simd_load32_lane.wast","passed":24,"failed":0},{"name":"simd_load64_lane.wast","passed":16,"failed":0},{"name":"simd_load8_lane.wast","passed":52,"failed":0},{"name":"simd_load_extend.wast","passed":20,"failed":84},{"name":"simd_load_splat.wast","passed":14,"failed":112},{"name":"simd_load_zero.wast","passed":12,"failed":27},{"name":"simd_memory-multi.wast","passed":1,"failed":0},{"name":"simd_splat.wast","passed":157,"failed":28},{"name":"simd_store.wast","passed":28,"failed":0},{"name":"simd_store16_lane.wast","passed":3,"failed":33},{"name":"simd_store32_lane.wast","passed":3,"failed":21},{"name":"simd_store64_lane.wast","passed":3,"failed":13},{"name":"simd_store8_lane.wast","passed":3,"failed":49}] +0.9.0-alpha.0,15151,10829,[{"name":"simd_address.wast","passed":49,"failed":0},{"name":"simd_align.wast","passed":100,"failed":0},{"name":"simd_bit_shift.wast","passed":252,"failed":0},{"name":"simd_bitwise.wast","passed":169,"failed":0},{"name":"simd_boolean.wast","passed":277,"failed":0},{"name":"simd_const.wast","passed":757,"failed":0},{"name":"simd_conversions.wast","passed":56,"failed":226},{"name":"simd_f32x4.wast","passed":629,"failed":161},{"name":"simd_f32x4_arith.wast","passed":1357,"failed":465},{"name":"simd_f32x4_cmp.wast","passed":2607,"failed":0},{"name":"simd_f32x4_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f32x4_rounding.wast","passed":148,"failed":53},{"name":"simd_f64x2.wast","passed":639,"failed":164},{"name":"simd_f64x2_arith.wast","passed":1360,"failed":465},{"name":"simd_f64x2_cmp.wast","passed":2685,"failed":0},{"name":"simd_f64x2_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f64x2_rounding.wast","passed":148,"failed":53},{"name":"simd_i16x8_arith.wast","passed":194,"failed":0},{"name":"simd_i16x8_arith2.wast","passed":142,"failed":30},{"name":"simd_i16x8_cmp.wast","passed":436,"failed":29},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":5,"failed":16},{"name":"simd_i16x8_extmul_i8x16.wast","passed":13,"failed":104},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":4,"failed":26},{"name":"simd_i16x8_sat_arith.wast","passed":222,"failed":0},{"name":"simd_i32x4_arith.wast","passed":194,"failed":0},{"name":"simd_i32x4_arith2.wast","passed":149,"failed":0},{"name":"simd_i32x4_cmp.wast","passed":450,"failed":25},{"name":"simd_i32x4_dot_i16x8.wast","passed":4,"failed":26},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":5,"failed":16},{"name":"simd_i32x4_extmul_i16x8.wast","passed":13,"failed":104},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":17,"failed":90},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":5,"failed":102},{"name":"simd_i64x2_arith.wast","passed":200,"failed":0},{"name":"simd_i64x2_arith2.wast","passed":25,"failed":0},{"name":"simd_i64x2_cmp.wast","passed":97,"failed":16},{"name":"simd_i64x2_extmul_i32x4.wast","passed":13,"failed":104},{"name":"simd_i8x16_arith.wast","passed":131,"failed":0},{"name":"simd_i8x16_arith2.wast","passed":148,"failed":63},{"name":"simd_i8x16_cmp.wast","passed":409,"failed":36},{"name":"simd_i8x16_sat_arith.wast","passed":214,"failed":0},{"name":"simd_int_to_int_extend.wast","passed":25,"failed":228},{"name":"simd_lane.wast","passed":331,"failed":144},{"name":"simd_linking.wast","passed":3,"failed":0},{"name":"simd_load.wast","passed":37,"failed":2},{"name":"simd_load16_lane.wast","passed":36,"failed":0},{"name":"simd_load32_lane.wast","passed":24,"failed":0},{"name":"simd_load64_lane.wast","passed":16,"failed":0},{"name":"simd_load8_lane.wast","passed":52,"failed":0},{"name":"simd_load_extend.wast","passed":20,"failed":84},{"name":"simd_load_splat.wast","passed":14,"failed":112},{"name":"simd_load_zero.wast","passed":12,"failed":27},{"name":"simd_memory-multi.wast","passed":1,"failed":0},{"name":"simd_splat.wast","passed":183,"failed":2},{"name":"simd_store.wast","passed":28,"failed":0},{"name":"simd_store16_lane.wast","passed":4,"failed":32},{"name":"simd_store32_lane.wast","passed":4,"failed":20},{"name":"simd_store64_lane.wast","passed":4,"failed":12},{"name":"simd_store8_lane.wast","passed":4,"failed":48}] From 7806d394d645af9d9d830d4b3662d4abef4df347 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sun, 9 Mar 2025 19:02:35 +0100 Subject: [PATCH 49/54] chore: progress on more simd instructions Signed-off-by: Henry Gressmann --- crates/tinywasm/src/interpreter/executor.rs | 107 +++++++++++++++++- crates/tinywasm/tests/generated/wasm-simd.csv | 2 +- 2 files changed, 102 insertions(+), 7 deletions(-) diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index aff1696..a00b693 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -470,6 +470,13 @@ impl<'store, 'stack> Executor<'store, 'stack> { I32x4MaxU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, I64x2Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, + I16x8Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, + I32x4Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, + + I8x16NarrowI16x8S => unimplemented!(), + I8x16NarrowI16x8U => unimplemented!(), + I16x8NarrowI32x4S => unimplemented!(), + I16x8NarrowI32x4U => unimplemented!(), I8x16AddSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, I16x8AddSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, @@ -480,8 +487,72 @@ impl<'store, 'stack> Executor<'store, 'stack> { I8x16SubSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, I16x8SubSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, - I16x8Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, - I32x4Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, + I16x8ExtAddPairwiseI8x16S => unimplemented!(), + I16x8ExtAddPairwiseI8x16U => unimplemented!(), + I32x4ExtAddPairwiseI16x8S => unimplemented!(), + I32x4ExtAddPairwiseI16x8U => unimplemented!(), + + I16x8ExtMulLowI8x16S => unimplemented!(), + I16x8ExtMulLowI8x16U => unimplemented!(), + I16x8ExtMulHighI8x16S => unimplemented!(), + I16x8ExtMulHighI8x16U => unimplemented!(), + I32x4ExtMulLowI16x8S => unimplemented!(), + I32x4ExtMulLowI16x8U => unimplemented!(), + I32x4ExtMulHighI16x8S => unimplemented!(), + I32x4ExtMulHighI16x8U => unimplemented!(), + I64x2ExtMulLowI32x4S => unimplemented!(), + I64x2ExtMulLowI32x4U => unimplemented!(), + I64x2ExtMulHighI32x4S => unimplemented!(), + I64x2ExtMulHighI32x4U => unimplemented!(), + + I16x8ExtendLowI8x16S => unimplemented!(), + I16x8ExtendLowI8x16U => unimplemented!(), + I16x8ExtendHighI8x16S => unimplemented!(), + I16x8ExtendHighI8x16U => unimplemented!(), + I32x4ExtendLowI16x8S => unimplemented!(), + I32x4ExtendLowI16x8U => unimplemented!(), + I32x4ExtendHighI16x8S => unimplemented!(), + I32x4ExtendHighI16x8U => unimplemented!(), + I64x2ExtendLowI32x4S => unimplemented!(), + I64x2ExtendLowI32x4U => unimplemented!(), + I64x2ExtendHighI32x4S => unimplemented!(), + I64x2ExtendHighI32x4U => unimplemented!(), + + I8x16Popcnt => self.stack.values.replace_top::(|v| Ok(v.count_ones())).to_cf()?, + + I16x8Q15MulrSatS => self.stack.values.calculate_same::(|a, b| { + let subq15mulr = |a,b| { + let a = a as i32; + let b = b as i32; + let r = (a * b + 0x4000) >> 15; + if r > i16::MAX as i32 { + i16::MAX + } else if r < i16::MIN as i32 { + i16::MIN + } else { + r as i16 + } + }; + Ok(Simd::::from_array([ + subq15mulr(a[0], b[0]), + subq15mulr(a[1], b[1]), + subq15mulr(a[2], b[2]), + subq15mulr(a[3], b[3]), + subq15mulr(a[4], b[4]), + subq15mulr(a[5], b[5]), + subq15mulr(a[6], b[6]), + subq15mulr(a[7], b[7]), + ])) + }).to_cf()?, + + I32x4DotI16x8S => self.stack.values.calculate::(|a, b| { + Ok(Simd::::from_array([ + i32::from(a[0] * b[0] + a[1] * b[1]), + i32::from(a[2] * b[2] + a[3] * b[3]), + i32::from(a[4] * b[4] + a[5] * b[5]), + i32::from(a[6] * b[6] + a[7] * b[7]), + ])) + }).to_cf()?, F32x4Ceil => self.stack.values.replace_top_same::(|v| Ok(v.ceil())).to_cf()?, F64x2Ceil => self.stack.values.replace_top_same::(|v| Ok(v.ceil())).to_cf()?, @@ -508,10 +579,34 @@ impl<'store, 'stack> Executor<'store, 'stack> { F32x4Max => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, F64x2Max => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, - F32x4PMin => unimplemented!(), - F32x4PMax => unimplemented!(), - F64x2PMin => unimplemented!(), - F64x2PMax => unimplemented!(), + F32x4PMin => self.stack.values.calculate_same::(|a, b| { + Ok(Simd::::from_array([ + if b[0] < a[0] { b[0] } else { a[0]}, + if b[1] < a[1] { b[1] } else { a[1]}, + if b[2] < a[2] { b[2] } else { a[2]}, + if b[3] < a[3] { b[3] } else { a[3]}, + ])) + }).to_cf()?, + F32x4PMax => self.stack.values.calculate_same::(|a, b| { + Ok(Simd::::from_array([ + if b[0] > a[0] { b[0] } else { a[0]}, + if b[1] > a[1] { b[1] } else { a[1]}, + if b[2] > a[2] { b[2] } else { a[2]}, + if b[3] > a[3] { b[3] } else { a[3]}, + ])) + }).to_cf()?, + F64x2PMin => self.stack.values.calculate_same::(|a, b| { + Ok(Simd::::from_array([ + if b[0] < a[0] { b[0] } else { a[0]}, + if b[1] < a[1] { b[1] } else { a[1]}, + ])) + }).to_cf()?, + F64x2PMax => self.stack.values.calculate_same::(|a, b| { + Ok(Simd::::from_array([ + if b[0] > a[0] { b[0] } else { a[0]}, + if b[1] > a[1] { b[1] } else { a[1]}, + ])) + }).to_cf()?, // not correct I32x4TruncSatF32x4S => self.stack.values.replace_top::(|v| Ok(v.trunc())).to_cf()?, diff --git a/crates/tinywasm/tests/generated/wasm-simd.csv b/crates/tinywasm/tests/generated/wasm-simd.csv index 79adc36..6a25709 100644 --- a/crates/tinywasm/tests/generated/wasm-simd.csv +++ b/crates/tinywasm/tests/generated/wasm-simd.csv @@ -1,2 +1,2 @@ 0.8.0,1300,24679,[{"name":"simd_address.wast","passed":4,"failed":45},{"name":"simd_align.wast","passed":46,"failed":54},{"name":"simd_bit_shift.wast","passed":39,"failed":213},{"name":"simd_bitwise.wast","passed":28,"failed":141},{"name":"simd_boolean.wast","passed":16,"failed":261},{"name":"simd_const.wast","passed":301,"failed":456},{"name":"simd_conversions.wast","passed":48,"failed":234},{"name":"simd_f32x4.wast","passed":16,"failed":774},{"name":"simd_f32x4_arith.wast","passed":16,"failed":1806},{"name":"simd_f32x4_cmp.wast","passed":24,"failed":2583},{"name":"simd_f32x4_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f32x4_rounding.wast","passed":24,"failed":177},{"name":"simd_f64x2.wast","passed":8,"failed":795},{"name":"simd_f64x2_arith.wast","passed":16,"failed":1809},{"name":"simd_f64x2_cmp.wast","passed":24,"failed":2661},{"name":"simd_f64x2_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f64x2_rounding.wast","passed":24,"failed":177},{"name":"simd_i16x8_arith.wast","passed":11,"failed":183},{"name":"simd_i16x8_arith2.wast","passed":19,"failed":153},{"name":"simd_i16x8_cmp.wast","passed":30,"failed":435},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":4,"failed":17},{"name":"simd_i16x8_extmul_i8x16.wast","passed":12,"failed":105},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":3,"failed":27},{"name":"simd_i16x8_sat_arith.wast","passed":16,"failed":206},{"name":"simd_i32x4_arith.wast","passed":11,"failed":183},{"name":"simd_i32x4_arith2.wast","passed":26,"failed":123},{"name":"simd_i32x4_cmp.wast","passed":40,"failed":435},{"name":"simd_i32x4_dot_i16x8.wast","passed":3,"failed":27},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":4,"failed":17},{"name":"simd_i32x4_extmul_i16x8.wast","passed":12,"failed":105},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":4,"failed":103},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":4,"failed":103},{"name":"simd_i64x2_arith.wast","passed":11,"failed":189},{"name":"simd_i64x2_arith2.wast","passed":2,"failed":23},{"name":"simd_i64x2_cmp.wast","passed":10,"failed":103},{"name":"simd_i64x2_extmul_i32x4.wast","passed":12,"failed":105},{"name":"simd_i8x16_arith.wast","passed":8,"failed":123},{"name":"simd_i8x16_arith2.wast","passed":25,"failed":186},{"name":"simd_i8x16_cmp.wast","passed":30,"failed":415},{"name":"simd_i8x16_sat_arith.wast","passed":24,"failed":190},{"name":"simd_int_to_int_extend.wast","passed":24,"failed":229},{"name":"simd_lane.wast","passed":189,"failed":286},{"name":"simd_linking.wast","passed":0,"failed":3},{"name":"simd_load.wast","passed":8,"failed":31},{"name":"simd_load16_lane.wast","passed":3,"failed":33},{"name":"simd_load32_lane.wast","passed":3,"failed":21},{"name":"simd_load64_lane.wast","passed":3,"failed":13},{"name":"simd_load8_lane.wast","passed":3,"failed":49},{"name":"simd_load_extend.wast","passed":18,"failed":86},{"name":"simd_load_splat.wast","passed":12,"failed":114},{"name":"simd_load_zero.wast","passed":10,"failed":29},{"name":"simd_splat.wast","passed":23,"failed":162},{"name":"simd_store.wast","passed":9,"failed":19},{"name":"simd_store16_lane.wast","passed":3,"failed":33},{"name":"simd_store32_lane.wast","passed":3,"failed":21},{"name":"simd_store64_lane.wast","passed":3,"failed":13},{"name":"simd_store8_lane.wast","passed":3,"failed":49}] -0.9.0-alpha.0,15151,10829,[{"name":"simd_address.wast","passed":49,"failed":0},{"name":"simd_align.wast","passed":100,"failed":0},{"name":"simd_bit_shift.wast","passed":252,"failed":0},{"name":"simd_bitwise.wast","passed":169,"failed":0},{"name":"simd_boolean.wast","passed":277,"failed":0},{"name":"simd_const.wast","passed":757,"failed":0},{"name":"simd_conversions.wast","passed":56,"failed":226},{"name":"simd_f32x4.wast","passed":629,"failed":161},{"name":"simd_f32x4_arith.wast","passed":1357,"failed":465},{"name":"simd_f32x4_cmp.wast","passed":2607,"failed":0},{"name":"simd_f32x4_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f32x4_rounding.wast","passed":148,"failed":53},{"name":"simd_f64x2.wast","passed":639,"failed":164},{"name":"simd_f64x2_arith.wast","passed":1360,"failed":465},{"name":"simd_f64x2_cmp.wast","passed":2685,"failed":0},{"name":"simd_f64x2_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f64x2_rounding.wast","passed":148,"failed":53},{"name":"simd_i16x8_arith.wast","passed":194,"failed":0},{"name":"simd_i16x8_arith2.wast","passed":142,"failed":30},{"name":"simd_i16x8_cmp.wast","passed":436,"failed":29},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":5,"failed":16},{"name":"simd_i16x8_extmul_i8x16.wast","passed":13,"failed":104},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":4,"failed":26},{"name":"simd_i16x8_sat_arith.wast","passed":222,"failed":0},{"name":"simd_i32x4_arith.wast","passed":194,"failed":0},{"name":"simd_i32x4_arith2.wast","passed":149,"failed":0},{"name":"simd_i32x4_cmp.wast","passed":450,"failed":25},{"name":"simd_i32x4_dot_i16x8.wast","passed":4,"failed":26},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":5,"failed":16},{"name":"simd_i32x4_extmul_i16x8.wast","passed":13,"failed":104},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":17,"failed":90},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":5,"failed":102},{"name":"simd_i64x2_arith.wast","passed":200,"failed":0},{"name":"simd_i64x2_arith2.wast","passed":25,"failed":0},{"name":"simd_i64x2_cmp.wast","passed":97,"failed":16},{"name":"simd_i64x2_extmul_i32x4.wast","passed":13,"failed":104},{"name":"simd_i8x16_arith.wast","passed":131,"failed":0},{"name":"simd_i8x16_arith2.wast","passed":148,"failed":63},{"name":"simd_i8x16_cmp.wast","passed":409,"failed":36},{"name":"simd_i8x16_sat_arith.wast","passed":214,"failed":0},{"name":"simd_int_to_int_extend.wast","passed":25,"failed":228},{"name":"simd_lane.wast","passed":331,"failed":144},{"name":"simd_linking.wast","passed":3,"failed":0},{"name":"simd_load.wast","passed":37,"failed":2},{"name":"simd_load16_lane.wast","passed":36,"failed":0},{"name":"simd_load32_lane.wast","passed":24,"failed":0},{"name":"simd_load64_lane.wast","passed":16,"failed":0},{"name":"simd_load8_lane.wast","passed":52,"failed":0},{"name":"simd_load_extend.wast","passed":20,"failed":84},{"name":"simd_load_splat.wast","passed":14,"failed":112},{"name":"simd_load_zero.wast","passed":12,"failed":27},{"name":"simd_memory-multi.wast","passed":1,"failed":0},{"name":"simd_splat.wast","passed":183,"failed":2},{"name":"simd_store.wast","passed":28,"failed":0},{"name":"simd_store16_lane.wast","passed":4,"failed":32},{"name":"simd_store32_lane.wast","passed":4,"failed":20},{"name":"simd_store64_lane.wast","passed":4,"failed":12},{"name":"simd_store8_lane.wast","passed":4,"failed":48}] +0.9.0-alpha.0,22962,3018,[{"name":"simd_address.wast","passed":49,"failed":0},{"name":"simd_align.wast","passed":100,"failed":0},{"name":"simd_bit_shift.wast","passed":252,"failed":0},{"name":"simd_bitwise.wast","passed":169,"failed":0},{"name":"simd_boolean.wast","passed":277,"failed":0},{"name":"simd_const.wast","passed":757,"failed":0},{"name":"simd_conversions.wast","passed":56,"failed":226},{"name":"simd_f32x4.wast","passed":629,"failed":161},{"name":"simd_f32x4_arith.wast","passed":1357,"failed":465},{"name":"simd_f32x4_cmp.wast","passed":2607,"failed":0},{"name":"simd_f32x4_pmin_pmax.wast","passed":3887,"failed":0},{"name":"simd_f32x4_rounding.wast","passed":148,"failed":53},{"name":"simd_f64x2.wast","passed":639,"failed":164},{"name":"simd_f64x2_arith.wast","passed":1360,"failed":465},{"name":"simd_f64x2_cmp.wast","passed":2685,"failed":0},{"name":"simd_f64x2_pmin_pmax.wast","passed":3887,"failed":0},{"name":"simd_f64x2_rounding.wast","passed":148,"failed":53},{"name":"simd_i16x8_arith.wast","passed":194,"failed":0},{"name":"simd_i16x8_arith2.wast","passed":142,"failed":30},{"name":"simd_i16x8_cmp.wast","passed":436,"failed":29},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":5,"failed":16},{"name":"simd_i16x8_extmul_i8x16.wast","passed":13,"failed":104},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":30,"failed":0},{"name":"simd_i16x8_sat_arith.wast","passed":222,"failed":0},{"name":"simd_i32x4_arith.wast","passed":194,"failed":0},{"name":"simd_i32x4_arith2.wast","passed":149,"failed":0},{"name":"simd_i32x4_cmp.wast","passed":450,"failed":25},{"name":"simd_i32x4_dot_i16x8.wast","passed":14,"failed":16},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":5,"failed":16},{"name":"simd_i32x4_extmul_i16x8.wast","passed":13,"failed":104},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":17,"failed":90},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":5,"failed":102},{"name":"simd_i64x2_arith.wast","passed":200,"failed":0},{"name":"simd_i64x2_arith2.wast","passed":25,"failed":0},{"name":"simd_i64x2_cmp.wast","passed":97,"failed":16},{"name":"simd_i64x2_extmul_i32x4.wast","passed":13,"failed":104},{"name":"simd_i8x16_arith.wast","passed":131,"failed":0},{"name":"simd_i8x16_arith2.wast","passed":179,"failed":32},{"name":"simd_i8x16_cmp.wast","passed":409,"failed":36},{"name":"simd_i8x16_sat_arith.wast","passed":214,"failed":0},{"name":"simd_int_to_int_extend.wast","passed":25,"failed":228},{"name":"simd_lane.wast","passed":331,"failed":144},{"name":"simd_linking.wast","passed":3,"failed":0},{"name":"simd_load.wast","passed":37,"failed":2},{"name":"simd_load16_lane.wast","passed":36,"failed":0},{"name":"simd_load32_lane.wast","passed":24,"failed":0},{"name":"simd_load64_lane.wast","passed":16,"failed":0},{"name":"simd_load8_lane.wast","passed":52,"failed":0},{"name":"simd_load_extend.wast","passed":20,"failed":84},{"name":"simd_load_splat.wast","passed":14,"failed":112},{"name":"simd_load_zero.wast","passed":12,"failed":27},{"name":"simd_memory-multi.wast","passed":1,"failed":0},{"name":"simd_splat.wast","passed":183,"failed":2},{"name":"simd_store.wast","passed":28,"failed":0},{"name":"simd_store16_lane.wast","passed":4,"failed":32},{"name":"simd_store32_lane.wast","passed":4,"failed":20},{"name":"simd_store64_lane.wast","passed":4,"failed":12},{"name":"simd_store8_lane.wast","passed":4,"failed":48}] From 353a676cc58473a6a0292d48b32335d8f6c75504 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sun, 9 Mar 2025 20:05:17 +0100 Subject: [PATCH 50/54] chore: progress on more simd instructions Signed-off-by: Henry Gressmann --- crates/tinywasm/src/interpreter/executor.rs | 91 +++++++++++-------- .../tinywasm/src/interpreter/num_helpers.rs | 18 ++++ crates/tinywasm/tests/generated/wasm-simd.csv | 2 +- 3 files changed, 74 insertions(+), 37 deletions(-) diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index a00b693..b5521e7 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -3,21 +3,15 @@ use super::no_std_floats::NoStdFloatExt; use alloc::{format, rc::Rc, string::ToString}; -use core::ops::{ControlFlow, IndexMut, Shl, Shr}; +use core::ops::{ControlFlow, Index, IndexMut, Shl, Shr}; use interpreter::stack::CallFrame; use tinywasm_types::*; +#[cfg(all(feature = "std", feature = "simd"))] +use crate::std::simd::StdFloat; #[cfg(feature = "simd")] -mod simd { - #[cfg(feature = "std")] - pub(super) use crate::std::simd::StdFloat; - pub(super) use core::simd::cmp::{SimdOrd, SimdPartialEq, SimdPartialOrd}; - pub(super) use core::simd::num::{SimdFloat, SimdInt, SimdUint}; - pub(super) use core::simd::*; -} -#[cfg(feature = "simd")] -use simd::*; +use core::simd::{cmp::*, num::*, *}; use super::num_helpers::*; use super::stack::{BlockFrame, BlockType, Stack}; @@ -329,6 +323,22 @@ impl<'store, 'stack> Executor<'store, 'stack> { I8x16Swizzle => self.stack.values.calculate_same::(|a, s| Ok(a.swizzle_dyn(s))).to_cf()?, V128Load(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| v)?, V128Store(arg) => self.exec_mem_store::(arg.mem_addr(), arg.offset(), |v| v)?, + + V128Store8Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, + V128Store16Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, + V128Store32Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, + V128Store64Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, + + // Load a single 32-bit or 64-bit element into the lowest bits of a v128 vector, and initialize all other bits of the v128 vector to zero. + V128Load32Zero(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| { + let bytes = v.to_le_bytes(); + u8x16::from_array([bytes[0], bytes[1], bytes[2], bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + })?, + V128Load64Zero(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| { + let bytes = v.to_le_bytes(); + u8x16::from_array([bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], 0, 0, 0, 0, 0, 0, 0, 0]) + })?, + V128Const(arg) => self.exec_const::( self.cf.data().v128_constants[*arg as usize].to_le_bytes().into()), I8x16ExtractLaneS(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, @@ -564,16 +574,16 @@ impl<'store, 'stack> Executor<'store, 'stack> { F64x2Abs => self.stack.values.replace_top_same::(|v| Ok(v.abs())).to_cf()?, F32x4Neg => self.stack.values.replace_top_same::(|v| Ok(-v)).to_cf()?, F64x2Neg => self.stack.values.replace_top_same::(|v| Ok(-v)).to_cf()?, - F32x4Sqrt => self.stack.values.replace_top_same::(|v| Ok(v.sqrt())).to_cf()?, - F64x2Sqrt => self.stack.values.replace_top_same::(|v| Ok(v.sqrt())).to_cf()?, - F32x4Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, - F64x2Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, - F32x4Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, - F64x2Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, - F32x4Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, - F64x2Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, - F32x4Div => self.stack.values.calculate_same::(|a, b| Ok(a / b)).to_cf()?, - F64x2Div => self.stack.values.calculate_same::(|a, b| Ok(a / b)).to_cf()?, + F32x4Sqrt => self.stack.values.replace_top_same::(|v| Ok(canonicalize_f32x4(v.sqrt()))).to_cf()?, + F64x2Sqrt => self.stack.values.replace_top_same::(|v| Ok(canonicalize_f64x2(v.sqrt()))).to_cf()?, + F32x4Add => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f32x4(a + b))).to_cf()?, + F64x2Add => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a + b))).to_cf()?, + F32x4Sub => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f32x4(a - b))).to_cf()?, + F64x2Sub => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a - b))).to_cf()?, + F32x4Mul => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f32x4(a * b))).to_cf()?, + F64x2Mul => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a * b))).to_cf()?, + F32x4Div => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f32x4(a / b))).to_cf()?, + F64x2Div => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a / b))).to_cf()?, F32x4Min => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, F64x2Min => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, F32x4Max => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, @@ -952,7 +962,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { &mut self, mem_addr: tinywasm_types::MemAddr, offset: u64, - lanes: u8, + lane: u8, ) -> ControlFlow> { let mem = self.store.get_mem(self.module.resolve_mem_addr(mem_addr)); let mut imm = self.stack.values.pop::(); @@ -966,25 +976,11 @@ impl<'store, 'stack> Executor<'store, 'stack> { }))); }; let val = mem.load_as::(addr).to_cf()?; - imm[lanes as usize] = val; + imm[lane as usize] = val; self.stack.values.push(imm); ControlFlow::Continue(()) } - // fn mem_load, const LOAD_SIZE: usize, TARGET: InternalValue>( - // &mut self, - // mem_addr: tinywasm_types::MemAddr, - // offset: u64, - // ) -> Result { - // let mem = self.store.get_mem(self.module.resolve_mem_addr(mem_addr)); - // let val = self.stack.values.pop::() as u64; - // let Some(Ok(addr)) = offset.checked_add(val).map(TryInto::try_into) else { - // cold(); - // return Err(Error::Trap(Trap::MemoryOutOfBounds { offset: val as usize, len: LOAD_SIZE, max: 0 })); - // }; - // mem.load_as::(addr) - // } - fn exec_mem_load, const LOAD_SIZE: usize, TARGET: InternalValue>( &mut self, mem_addr: tinywasm_types::MemAddr, @@ -1010,6 +1006,29 @@ impl<'store, 'stack> Executor<'store, 'stack> { self.stack.values.push(cast(val)); ControlFlow::Continue(()) } + + fn exec_mem_store_lane, U: MemStorable + Copy, const N: usize>( + &mut self, + mem_addr: tinywasm_types::MemAddr, + offset: u64, + lane: u8, + ) -> ControlFlow> { + let mem = self.store.get_mem_mut(self.module.resolve_mem_addr(mem_addr)); + let val = self.stack.values.pop::(); + let val = val[lane as usize].to_mem_bytes(); + + let addr = match mem.is_64bit() { + true => self.stack.values.pop::() as u64, + false => self.stack.values.pop::() as u32 as u64, + }; + + if let Err(e) = mem.store((offset + addr) as usize, val.len(), &val) { + return ControlFlow::Break(Some(e)); + } + + ControlFlow::Continue(()) + } + fn exec_mem_store, const N: usize>( &mut self, mem_addr: tinywasm_types::MemAddr, diff --git a/crates/tinywasm/src/interpreter/num_helpers.rs b/crates/tinywasm/src/interpreter/num_helpers.rs index 02fbc24..9b6345c 100644 --- a/crates/tinywasm/src/interpreter/num_helpers.rs +++ b/crates/tinywasm/src/interpreter/num_helpers.rs @@ -180,3 +180,21 @@ macro_rules! impl_checked_wrapping_rem { } impl_checked_wrapping_rem! { i32 i64 u32 u64 } + +#[cfg(feature = "simd")] +/// replace all NaNs in a f32x4 with f32::NAN +pub(crate) fn canonicalize_f32x4(x: core::simd::f32x4) -> core::simd::f32x4 { + use core::simd::{Simd, num::SimdFloat}; + let nan = Simd::splat(f32::NAN); + let mask = x.is_nan(); + mask.select(nan, x) +} + +#[cfg(feature = "simd")] +/// replace all NaNs in a f64x2 with f64::NAN +pub(crate) fn canonicalize_f64x2(x: core::simd::f64x2) -> core::simd::f64x2 { + use core::simd::{Simd, num::SimdFloat}; + let nan = Simd::splat(f64::NAN); + let mask = x.is_nan(); + mask.select(nan, x) +} diff --git a/crates/tinywasm/tests/generated/wasm-simd.csv b/crates/tinywasm/tests/generated/wasm-simd.csv index 6a25709..c3f307c 100644 --- a/crates/tinywasm/tests/generated/wasm-simd.csv +++ b/crates/tinywasm/tests/generated/wasm-simd.csv @@ -1,2 +1,2 @@ 0.8.0,1300,24679,[{"name":"simd_address.wast","passed":4,"failed":45},{"name":"simd_align.wast","passed":46,"failed":54},{"name":"simd_bit_shift.wast","passed":39,"failed":213},{"name":"simd_bitwise.wast","passed":28,"failed":141},{"name":"simd_boolean.wast","passed":16,"failed":261},{"name":"simd_const.wast","passed":301,"failed":456},{"name":"simd_conversions.wast","passed":48,"failed":234},{"name":"simd_f32x4.wast","passed":16,"failed":774},{"name":"simd_f32x4_arith.wast","passed":16,"failed":1806},{"name":"simd_f32x4_cmp.wast","passed":24,"failed":2583},{"name":"simd_f32x4_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f32x4_rounding.wast","passed":24,"failed":177},{"name":"simd_f64x2.wast","passed":8,"failed":795},{"name":"simd_f64x2_arith.wast","passed":16,"failed":1809},{"name":"simd_f64x2_cmp.wast","passed":24,"failed":2661},{"name":"simd_f64x2_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f64x2_rounding.wast","passed":24,"failed":177},{"name":"simd_i16x8_arith.wast","passed":11,"failed":183},{"name":"simd_i16x8_arith2.wast","passed":19,"failed":153},{"name":"simd_i16x8_cmp.wast","passed":30,"failed":435},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":4,"failed":17},{"name":"simd_i16x8_extmul_i8x16.wast","passed":12,"failed":105},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":3,"failed":27},{"name":"simd_i16x8_sat_arith.wast","passed":16,"failed":206},{"name":"simd_i32x4_arith.wast","passed":11,"failed":183},{"name":"simd_i32x4_arith2.wast","passed":26,"failed":123},{"name":"simd_i32x4_cmp.wast","passed":40,"failed":435},{"name":"simd_i32x4_dot_i16x8.wast","passed":3,"failed":27},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":4,"failed":17},{"name":"simd_i32x4_extmul_i16x8.wast","passed":12,"failed":105},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":4,"failed":103},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":4,"failed":103},{"name":"simd_i64x2_arith.wast","passed":11,"failed":189},{"name":"simd_i64x2_arith2.wast","passed":2,"failed":23},{"name":"simd_i64x2_cmp.wast","passed":10,"failed":103},{"name":"simd_i64x2_extmul_i32x4.wast","passed":12,"failed":105},{"name":"simd_i8x16_arith.wast","passed":8,"failed":123},{"name":"simd_i8x16_arith2.wast","passed":25,"failed":186},{"name":"simd_i8x16_cmp.wast","passed":30,"failed":415},{"name":"simd_i8x16_sat_arith.wast","passed":24,"failed":190},{"name":"simd_int_to_int_extend.wast","passed":24,"failed":229},{"name":"simd_lane.wast","passed":189,"failed":286},{"name":"simd_linking.wast","passed":0,"failed":3},{"name":"simd_load.wast","passed":8,"failed":31},{"name":"simd_load16_lane.wast","passed":3,"failed":33},{"name":"simd_load32_lane.wast","passed":3,"failed":21},{"name":"simd_load64_lane.wast","passed":3,"failed":13},{"name":"simd_load8_lane.wast","passed":3,"failed":49},{"name":"simd_load_extend.wast","passed":18,"failed":86},{"name":"simd_load_splat.wast","passed":12,"failed":114},{"name":"simd_load_zero.wast","passed":10,"failed":29},{"name":"simd_splat.wast","passed":23,"failed":162},{"name":"simd_store.wast","passed":9,"failed":19},{"name":"simd_store16_lane.wast","passed":3,"failed":33},{"name":"simd_store32_lane.wast","passed":3,"failed":21},{"name":"simd_store64_lane.wast","passed":3,"failed":13},{"name":"simd_store8_lane.wast","passed":3,"failed":49}] -0.9.0-alpha.0,22962,3018,[{"name":"simd_address.wast","passed":49,"failed":0},{"name":"simd_align.wast","passed":100,"failed":0},{"name":"simd_bit_shift.wast","passed":252,"failed":0},{"name":"simd_bitwise.wast","passed":169,"failed":0},{"name":"simd_boolean.wast","passed":277,"failed":0},{"name":"simd_const.wast","passed":757,"failed":0},{"name":"simd_conversions.wast","passed":56,"failed":226},{"name":"simd_f32x4.wast","passed":629,"failed":161},{"name":"simd_f32x4_arith.wast","passed":1357,"failed":465},{"name":"simd_f32x4_cmp.wast","passed":2607,"failed":0},{"name":"simd_f32x4_pmin_pmax.wast","passed":3887,"failed":0},{"name":"simd_f32x4_rounding.wast","passed":148,"failed":53},{"name":"simd_f64x2.wast","passed":639,"failed":164},{"name":"simd_f64x2_arith.wast","passed":1360,"failed":465},{"name":"simd_f64x2_cmp.wast","passed":2685,"failed":0},{"name":"simd_f64x2_pmin_pmax.wast","passed":3887,"failed":0},{"name":"simd_f64x2_rounding.wast","passed":148,"failed":53},{"name":"simd_i16x8_arith.wast","passed":194,"failed":0},{"name":"simd_i16x8_arith2.wast","passed":142,"failed":30},{"name":"simd_i16x8_cmp.wast","passed":436,"failed":29},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":5,"failed":16},{"name":"simd_i16x8_extmul_i8x16.wast","passed":13,"failed":104},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":30,"failed":0},{"name":"simd_i16x8_sat_arith.wast","passed":222,"failed":0},{"name":"simd_i32x4_arith.wast","passed":194,"failed":0},{"name":"simd_i32x4_arith2.wast","passed":149,"failed":0},{"name":"simd_i32x4_cmp.wast","passed":450,"failed":25},{"name":"simd_i32x4_dot_i16x8.wast","passed":14,"failed":16},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":5,"failed":16},{"name":"simd_i32x4_extmul_i16x8.wast","passed":13,"failed":104},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":17,"failed":90},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":5,"failed":102},{"name":"simd_i64x2_arith.wast","passed":200,"failed":0},{"name":"simd_i64x2_arith2.wast","passed":25,"failed":0},{"name":"simd_i64x2_cmp.wast","passed":97,"failed":16},{"name":"simd_i64x2_extmul_i32x4.wast","passed":13,"failed":104},{"name":"simd_i8x16_arith.wast","passed":131,"failed":0},{"name":"simd_i8x16_arith2.wast","passed":179,"failed":32},{"name":"simd_i8x16_cmp.wast","passed":409,"failed":36},{"name":"simd_i8x16_sat_arith.wast","passed":214,"failed":0},{"name":"simd_int_to_int_extend.wast","passed":25,"failed":228},{"name":"simd_lane.wast","passed":331,"failed":144},{"name":"simd_linking.wast","passed":3,"failed":0},{"name":"simd_load.wast","passed":37,"failed":2},{"name":"simd_load16_lane.wast","passed":36,"failed":0},{"name":"simd_load32_lane.wast","passed":24,"failed":0},{"name":"simd_load64_lane.wast","passed":16,"failed":0},{"name":"simd_load8_lane.wast","passed":52,"failed":0},{"name":"simd_load_extend.wast","passed":20,"failed":84},{"name":"simd_load_splat.wast","passed":14,"failed":112},{"name":"simd_load_zero.wast","passed":12,"failed":27},{"name":"simd_memory-multi.wast","passed":1,"failed":0},{"name":"simd_splat.wast","passed":183,"failed":2},{"name":"simd_store.wast","passed":28,"failed":0},{"name":"simd_store16_lane.wast","passed":4,"failed":32},{"name":"simd_store32_lane.wast","passed":4,"failed":20},{"name":"simd_store64_lane.wast","passed":4,"failed":12},{"name":"simd_store8_lane.wast","passed":4,"failed":48}] +0.9.0-alpha.0,24030,1950,[{"name":"simd_address.wast","passed":49,"failed":0},{"name":"simd_align.wast","passed":100,"failed":0},{"name":"simd_bit_shift.wast","passed":252,"failed":0},{"name":"simd_bitwise.wast","passed":169,"failed":0},{"name":"simd_boolean.wast","passed":277,"failed":0},{"name":"simd_const.wast","passed":757,"failed":0},{"name":"simd_conversions.wast","passed":56,"failed":226},{"name":"simd_f32x4.wast","passed":629,"failed":161},{"name":"simd_f32x4_arith.wast","passed":1822,"failed":0},{"name":"simd_f32x4_cmp.wast","passed":2607,"failed":0},{"name":"simd_f32x4_pmin_pmax.wast","passed":3887,"failed":0},{"name":"simd_f32x4_rounding.wast","passed":148,"failed":53},{"name":"simd_f64x2.wast","passed":639,"failed":164},{"name":"simd_f64x2_arith.wast","passed":1824,"failed":1},{"name":"simd_f64x2_cmp.wast","passed":2685,"failed":0},{"name":"simd_f64x2_pmin_pmax.wast","passed":3887,"failed":0},{"name":"simd_f64x2_rounding.wast","passed":148,"failed":53},{"name":"simd_i16x8_arith.wast","passed":194,"failed":0},{"name":"simd_i16x8_arith2.wast","passed":142,"failed":30},{"name":"simd_i16x8_cmp.wast","passed":436,"failed":29},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":5,"failed":16},{"name":"simd_i16x8_extmul_i8x16.wast","passed":13,"failed":104},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":30,"failed":0},{"name":"simd_i16x8_sat_arith.wast","passed":222,"failed":0},{"name":"simd_i32x4_arith.wast","passed":194,"failed":0},{"name":"simd_i32x4_arith2.wast","passed":149,"failed":0},{"name":"simd_i32x4_cmp.wast","passed":450,"failed":25},{"name":"simd_i32x4_dot_i16x8.wast","passed":14,"failed":16},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":5,"failed":16},{"name":"simd_i32x4_extmul_i16x8.wast","passed":13,"failed":104},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":17,"failed":90},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":5,"failed":102},{"name":"simd_i64x2_arith.wast","passed":200,"failed":0},{"name":"simd_i64x2_arith2.wast","passed":25,"failed":0},{"name":"simd_i64x2_cmp.wast","passed":97,"failed":16},{"name":"simd_i64x2_extmul_i32x4.wast","passed":13,"failed":104},{"name":"simd_i8x16_arith.wast","passed":131,"failed":0},{"name":"simd_i8x16_arith2.wast","passed":179,"failed":32},{"name":"simd_i8x16_cmp.wast","passed":409,"failed":36},{"name":"simd_i8x16_sat_arith.wast","passed":214,"failed":0},{"name":"simd_int_to_int_extend.wast","passed":25,"failed":228},{"name":"simd_lane.wast","passed":331,"failed":144},{"name":"simd_linking.wast","passed":3,"failed":0},{"name":"simd_load.wast","passed":37,"failed":2},{"name":"simd_load16_lane.wast","passed":36,"failed":0},{"name":"simd_load32_lane.wast","passed":24,"failed":0},{"name":"simd_load64_lane.wast","passed":16,"failed":0},{"name":"simd_load8_lane.wast","passed":52,"failed":0},{"name":"simd_load_extend.wast","passed":20,"failed":84},{"name":"simd_load_splat.wast","passed":14,"failed":112},{"name":"simd_load_zero.wast","passed":39,"failed":0},{"name":"simd_memory-multi.wast","passed":1,"failed":0},{"name":"simd_splat.wast","passed":183,"failed":2},{"name":"simd_store.wast","passed":28,"failed":0},{"name":"simd_store16_lane.wast","passed":36,"failed":0},{"name":"simd_store32_lane.wast","passed":24,"failed":0},{"name":"simd_store64_lane.wast","passed":16,"failed":0},{"name":"simd_store8_lane.wast","passed":52,"failed":0}] From 9b3e8fee9731d1f21fd573b562775a841f7d1209 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Tue, 11 Mar 2025 20:11:35 +0100 Subject: [PATCH 51/54] fix: canonicalize simd nan values Signed-off-by: Henry Gressmann --- crates/tinywasm/src/interpreter/executor.rs | 32 ++++++++++++++++--- .../tinywasm/src/interpreter/num_helpers.rs | 9 ++++-- crates/tinywasm/tests/generated/wasm-simd.csv | 2 +- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index b5521e7..d6d8089 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -584,10 +584,34 @@ impl<'store, 'stack> Executor<'store, 'stack> { F64x2Mul => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a * b))).to_cf()?, F32x4Div => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f32x4(a / b))).to_cf()?, F64x2Div => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a / b))).to_cf()?, - F32x4Min => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, - F64x2Min => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, - F32x4Max => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, - F64x2Max => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + F32x4Min => self.stack.values.calculate_same::(|a, b| { + Ok(Simd::::from_array([ + b[0].tw_minimum(a[0]), + b[1].tw_minimum(a[1]), + b[2].tw_minimum(a[2]), + b[3].tw_minimum(a[3]), + ])) + }).to_cf()?, + F64x2Min => self.stack.values.calculate_same::(|a, b| { + Ok(Simd::::from_array([ + b[0].tw_minimum(a[0]), + b[1].tw_minimum(a[1]), + ])) + }).to_cf()?, + F32x4Max => self.stack.values.calculate_same::(|a, b| { + Ok(Simd::::from_array([ + b[0].tw_maximum(a[0]), + b[1].tw_maximum(a[1]), + b[2].tw_maximum(a[2]), + b[3].tw_maximum(a[3]), + ])) + }).to_cf()?, + F64x2Max => self.stack.values.calculate_same::(|a, b| { + Ok(Simd::::from_array([ + b[0].tw_maximum(a[0]), + b[1].tw_maximum(a[1]), + ])) + }).to_cf()?, F32x4PMin => self.stack.values.calculate_same::(|a, b| { Ok(Simd::::from_array([ diff --git a/crates/tinywasm/src/interpreter/num_helpers.rs b/crates/tinywasm/src/interpreter/num_helpers.rs index 9b6345c..bba35cb 100644 --- a/crates/tinywasm/src/interpreter/num_helpers.rs +++ b/crates/tinywasm/src/interpreter/num_helpers.rs @@ -74,7 +74,8 @@ macro_rules! impl_wasm_float_ops { // https://webassembly.github.io/spec/core/exec/numerics.html#op-fnearest fn tw_nearest(self) -> Self { match self { - x if x.is_nan() => x, // preserve NaN + // x if x.is_nan() => x, // preserve NaN + x if x.is_nan() => Self::NAN, // Do not preserve NaN x if x.is_infinite() || x == 0.0 => x, // preserve infinities and zeros x if (0.0..=0.5).contains(&x) => 0.0, x if (-0.5..0.0).contains(&x) => -0.0, @@ -99,7 +100,8 @@ macro_rules! impl_wasm_float_ops { Some(core::cmp::Ordering::Less) => self, Some(core::cmp::Ordering::Greater) => other, Some(core::cmp::Ordering::Equal) => if self.is_sign_negative() && other.is_sign_positive() { self } else { other }, - None => self + other, // At least one input is NaN. Use `+` to perform NaN propagation and quieting. + // None => self + other, // At least one input is NaN. Use `+` to perform NaN propagation and quieting. + None => Self::NAN, // Do not preserve NaN } } @@ -111,7 +113,8 @@ macro_rules! impl_wasm_float_ops { Some(core::cmp::Ordering::Greater) => self, Some(core::cmp::Ordering::Less) => other, Some(core::cmp::Ordering::Equal) => if self.is_sign_negative() && other.is_sign_positive() { other } else { self }, - None => self + other, // At least one input is NaN. Use `+` to perform NaN propagation and quieting. + // None => self + other, // At least one input is NaN. Use `+` to perform NaN propagation and quieting. + None => Self::NAN, // Do not preserve NaN } } } diff --git a/crates/tinywasm/tests/generated/wasm-simd.csv b/crates/tinywasm/tests/generated/wasm-simd.csv index c3f307c..86b7780 100644 --- a/crates/tinywasm/tests/generated/wasm-simd.csv +++ b/crates/tinywasm/tests/generated/wasm-simd.csv @@ -1,2 +1,2 @@ 0.8.0,1300,24679,[{"name":"simd_address.wast","passed":4,"failed":45},{"name":"simd_align.wast","passed":46,"failed":54},{"name":"simd_bit_shift.wast","passed":39,"failed":213},{"name":"simd_bitwise.wast","passed":28,"failed":141},{"name":"simd_boolean.wast","passed":16,"failed":261},{"name":"simd_const.wast","passed":301,"failed":456},{"name":"simd_conversions.wast","passed":48,"failed":234},{"name":"simd_f32x4.wast","passed":16,"failed":774},{"name":"simd_f32x4_arith.wast","passed":16,"failed":1806},{"name":"simd_f32x4_cmp.wast","passed":24,"failed":2583},{"name":"simd_f32x4_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f32x4_rounding.wast","passed":24,"failed":177},{"name":"simd_f64x2.wast","passed":8,"failed":795},{"name":"simd_f64x2_arith.wast","passed":16,"failed":1809},{"name":"simd_f64x2_cmp.wast","passed":24,"failed":2661},{"name":"simd_f64x2_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f64x2_rounding.wast","passed":24,"failed":177},{"name":"simd_i16x8_arith.wast","passed":11,"failed":183},{"name":"simd_i16x8_arith2.wast","passed":19,"failed":153},{"name":"simd_i16x8_cmp.wast","passed":30,"failed":435},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":4,"failed":17},{"name":"simd_i16x8_extmul_i8x16.wast","passed":12,"failed":105},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":3,"failed":27},{"name":"simd_i16x8_sat_arith.wast","passed":16,"failed":206},{"name":"simd_i32x4_arith.wast","passed":11,"failed":183},{"name":"simd_i32x4_arith2.wast","passed":26,"failed":123},{"name":"simd_i32x4_cmp.wast","passed":40,"failed":435},{"name":"simd_i32x4_dot_i16x8.wast","passed":3,"failed":27},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":4,"failed":17},{"name":"simd_i32x4_extmul_i16x8.wast","passed":12,"failed":105},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":4,"failed":103},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":4,"failed":103},{"name":"simd_i64x2_arith.wast","passed":11,"failed":189},{"name":"simd_i64x2_arith2.wast","passed":2,"failed":23},{"name":"simd_i64x2_cmp.wast","passed":10,"failed":103},{"name":"simd_i64x2_extmul_i32x4.wast","passed":12,"failed":105},{"name":"simd_i8x16_arith.wast","passed":8,"failed":123},{"name":"simd_i8x16_arith2.wast","passed":25,"failed":186},{"name":"simd_i8x16_cmp.wast","passed":30,"failed":415},{"name":"simd_i8x16_sat_arith.wast","passed":24,"failed":190},{"name":"simd_int_to_int_extend.wast","passed":24,"failed":229},{"name":"simd_lane.wast","passed":189,"failed":286},{"name":"simd_linking.wast","passed":0,"failed":3},{"name":"simd_load.wast","passed":8,"failed":31},{"name":"simd_load16_lane.wast","passed":3,"failed":33},{"name":"simd_load32_lane.wast","passed":3,"failed":21},{"name":"simd_load64_lane.wast","passed":3,"failed":13},{"name":"simd_load8_lane.wast","passed":3,"failed":49},{"name":"simd_load_extend.wast","passed":18,"failed":86},{"name":"simd_load_splat.wast","passed":12,"failed":114},{"name":"simd_load_zero.wast","passed":10,"failed":29},{"name":"simd_splat.wast","passed":23,"failed":162},{"name":"simd_store.wast","passed":9,"failed":19},{"name":"simd_store16_lane.wast","passed":3,"failed":33},{"name":"simd_store32_lane.wast","passed":3,"failed":21},{"name":"simd_store64_lane.wast","passed":3,"failed":13},{"name":"simd_store8_lane.wast","passed":3,"failed":49}] -0.9.0-alpha.0,24030,1950,[{"name":"simd_address.wast","passed":49,"failed":0},{"name":"simd_align.wast","passed":100,"failed":0},{"name":"simd_bit_shift.wast","passed":252,"failed":0},{"name":"simd_bitwise.wast","passed":169,"failed":0},{"name":"simd_boolean.wast","passed":277,"failed":0},{"name":"simd_const.wast","passed":757,"failed":0},{"name":"simd_conversions.wast","passed":56,"failed":226},{"name":"simd_f32x4.wast","passed":629,"failed":161},{"name":"simd_f32x4_arith.wast","passed":1822,"failed":0},{"name":"simd_f32x4_cmp.wast","passed":2607,"failed":0},{"name":"simd_f32x4_pmin_pmax.wast","passed":3887,"failed":0},{"name":"simd_f32x4_rounding.wast","passed":148,"failed":53},{"name":"simd_f64x2.wast","passed":639,"failed":164},{"name":"simd_f64x2_arith.wast","passed":1824,"failed":1},{"name":"simd_f64x2_cmp.wast","passed":2685,"failed":0},{"name":"simd_f64x2_pmin_pmax.wast","passed":3887,"failed":0},{"name":"simd_f64x2_rounding.wast","passed":148,"failed":53},{"name":"simd_i16x8_arith.wast","passed":194,"failed":0},{"name":"simd_i16x8_arith2.wast","passed":142,"failed":30},{"name":"simd_i16x8_cmp.wast","passed":436,"failed":29},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":5,"failed":16},{"name":"simd_i16x8_extmul_i8x16.wast","passed":13,"failed":104},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":30,"failed":0},{"name":"simd_i16x8_sat_arith.wast","passed":222,"failed":0},{"name":"simd_i32x4_arith.wast","passed":194,"failed":0},{"name":"simd_i32x4_arith2.wast","passed":149,"failed":0},{"name":"simd_i32x4_cmp.wast","passed":450,"failed":25},{"name":"simd_i32x4_dot_i16x8.wast","passed":14,"failed":16},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":5,"failed":16},{"name":"simd_i32x4_extmul_i16x8.wast","passed":13,"failed":104},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":17,"failed":90},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":5,"failed":102},{"name":"simd_i64x2_arith.wast","passed":200,"failed":0},{"name":"simd_i64x2_arith2.wast","passed":25,"failed":0},{"name":"simd_i64x2_cmp.wast","passed":97,"failed":16},{"name":"simd_i64x2_extmul_i32x4.wast","passed":13,"failed":104},{"name":"simd_i8x16_arith.wast","passed":131,"failed":0},{"name":"simd_i8x16_arith2.wast","passed":179,"failed":32},{"name":"simd_i8x16_cmp.wast","passed":409,"failed":36},{"name":"simd_i8x16_sat_arith.wast","passed":214,"failed":0},{"name":"simd_int_to_int_extend.wast","passed":25,"failed":228},{"name":"simd_lane.wast","passed":331,"failed":144},{"name":"simd_linking.wast","passed":3,"failed":0},{"name":"simd_load.wast","passed":37,"failed":2},{"name":"simd_load16_lane.wast","passed":36,"failed":0},{"name":"simd_load32_lane.wast","passed":24,"failed":0},{"name":"simd_load64_lane.wast","passed":16,"failed":0},{"name":"simd_load8_lane.wast","passed":52,"failed":0},{"name":"simd_load_extend.wast","passed":20,"failed":84},{"name":"simd_load_splat.wast","passed":14,"failed":112},{"name":"simd_load_zero.wast","passed":39,"failed":0},{"name":"simd_memory-multi.wast","passed":1,"failed":0},{"name":"simd_splat.wast","passed":183,"failed":2},{"name":"simd_store.wast","passed":28,"failed":0},{"name":"simd_store16_lane.wast","passed":36,"failed":0},{"name":"simd_store32_lane.wast","passed":24,"failed":0},{"name":"simd_store64_lane.wast","passed":16,"failed":0},{"name":"simd_store8_lane.wast","passed":52,"failed":0}] +0.9.0-alpha.0,24355,1625,[{"name":"simd_address.wast","passed":49,"failed":0},{"name":"simd_align.wast","passed":100,"failed":0},{"name":"simd_bit_shift.wast","passed":252,"failed":0},{"name":"simd_bitwise.wast","passed":169,"failed":0},{"name":"simd_boolean.wast","passed":277,"failed":0},{"name":"simd_const.wast","passed":757,"failed":0},{"name":"simd_conversions.wast","passed":56,"failed":226},{"name":"simd_f32x4.wast","passed":790,"failed":0},{"name":"simd_f32x4_arith.wast","passed":1822,"failed":0},{"name":"simd_f32x4_cmp.wast","passed":2607,"failed":0},{"name":"simd_f32x4_pmin_pmax.wast","passed":3887,"failed":0},{"name":"simd_f32x4_rounding.wast","passed":148,"failed":53},{"name":"simd_f64x2.wast","passed":803,"failed":0},{"name":"simd_f64x2_arith.wast","passed":1824,"failed":1},{"name":"simd_f64x2_cmp.wast","passed":2685,"failed":0},{"name":"simd_f64x2_pmin_pmax.wast","passed":3887,"failed":0},{"name":"simd_f64x2_rounding.wast","passed":148,"failed":53},{"name":"simd_i16x8_arith.wast","passed":194,"failed":0},{"name":"simd_i16x8_arith2.wast","passed":142,"failed":30},{"name":"simd_i16x8_cmp.wast","passed":436,"failed":29},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":5,"failed":16},{"name":"simd_i16x8_extmul_i8x16.wast","passed":13,"failed":104},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":30,"failed":0},{"name":"simd_i16x8_sat_arith.wast","passed":222,"failed":0},{"name":"simd_i32x4_arith.wast","passed":194,"failed":0},{"name":"simd_i32x4_arith2.wast","passed":149,"failed":0},{"name":"simd_i32x4_cmp.wast","passed":450,"failed":25},{"name":"simd_i32x4_dot_i16x8.wast","passed":14,"failed":16},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":5,"failed":16},{"name":"simd_i32x4_extmul_i16x8.wast","passed":13,"failed":104},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":17,"failed":90},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":5,"failed":102},{"name":"simd_i64x2_arith.wast","passed":200,"failed":0},{"name":"simd_i64x2_arith2.wast","passed":25,"failed":0},{"name":"simd_i64x2_cmp.wast","passed":97,"failed":16},{"name":"simd_i64x2_extmul_i32x4.wast","passed":13,"failed":104},{"name":"simd_i8x16_arith.wast","passed":131,"failed":0},{"name":"simd_i8x16_arith2.wast","passed":179,"failed":32},{"name":"simd_i8x16_cmp.wast","passed":409,"failed":36},{"name":"simd_i8x16_sat_arith.wast","passed":214,"failed":0},{"name":"simd_int_to_int_extend.wast","passed":25,"failed":228},{"name":"simd_lane.wast","passed":331,"failed":144},{"name":"simd_linking.wast","passed":3,"failed":0},{"name":"simd_load.wast","passed":37,"failed":2},{"name":"simd_load16_lane.wast","passed":36,"failed":0},{"name":"simd_load32_lane.wast","passed":24,"failed":0},{"name":"simd_load64_lane.wast","passed":16,"failed":0},{"name":"simd_load8_lane.wast","passed":52,"failed":0},{"name":"simd_load_extend.wast","passed":20,"failed":84},{"name":"simd_load_splat.wast","passed":14,"failed":112},{"name":"simd_load_zero.wast","passed":39,"failed":0},{"name":"simd_memory-multi.wast","passed":1,"failed":0},{"name":"simd_splat.wast","passed":183,"failed":2},{"name":"simd_store.wast","passed":28,"failed":0},{"name":"simd_store16_lane.wast","passed":36,"failed":0},{"name":"simd_store32_lane.wast","passed":24,"failed":0},{"name":"simd_store64_lane.wast","passed":16,"failed":0},{"name":"simd_store8_lane.wast","passed":52,"failed":0}] From cdc0015b7752b5404f6edd2777ad62a9eb2e6244 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Thu, 3 Apr 2025 00:52:27 +0200 Subject: [PATCH 52/54] chore: update deps, cargo fmt Signed-off-by: Henry Gressmann --- Cargo.lock | 128 +++++++----------- Cargo.toml | 6 +- crates/cli/src/bin.rs | 2 +- crates/cli/src/wat.rs | 2 +- crates/parser/src/lib.rs | 8 +- crates/tinywasm/Cargo.toml | 2 +- crates/tinywasm/src/interpreter/executor.rs | 4 +- .../tests/host_func_signature_check.rs | 2 +- crates/tinywasm/tests/test-wasm-1.rs | 2 +- crates/tinywasm/tests/test-wasm-2.rs | 2 +- crates/tinywasm/tests/test-wasm-3.rs | 2 +- .../tinywasm/tests/test-wasm-annotations.rs | 2 +- .../tests/test-wasm-extended-const.rs | 2 +- .../tinywasm/tests/test-wasm-multi-memory.rs | 2 +- .../tinywasm/tests/test-wasm-relaxed-simd.rs | 2 +- crates/tinywasm/tests/test-wast.rs | 2 +- crates/tinywasm/tests/testsuite/mod.rs | 2 +- crates/tinywasm/tests/testsuite/run.rs | 4 +- crates/tinywasm/tests/testsuite/util.rs | 14 +- examples/archive.rs | 2 +- examples/funcref_callbacks.rs | 2 +- examples/wasm-rust.rs | 2 +- 22 files changed, 82 insertions(+), 114 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 00d3aaa..48bfcf9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -114,18 +114,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.31" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "027bb0d98429ae334a8698531da7077bdf906419543a35a55c2cb1b66437d767" +checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.31" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5589e0cba072e0f3d23791efac0fd8627b49c829c196a492e88168e6a669d863" +checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" dependencies = [ "anstyle", "clap_lex", @@ -258,9 +258,9 @@ dependencies = [ [[package]] name = "half" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1" dependencies = [ "cfg-if", "crunchy", @@ -274,15 +274,15 @@ checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "hermit-abi" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" +checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e" [[package]] name = "humantime" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" [[package]] name = "include_dir" @@ -311,9 +311,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "2.7.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" +checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" dependencies = [ "equivalent", "hashbrown", @@ -321,9 +321,9 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.15" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e19b23d53f35ce9f56aebc7d1bb4e6ac1e9c0db7ac85c8d1760c04379edced37" +checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ "hermit-abi", "libc", @@ -353,9 +353,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.170" +version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" [[package]] name = "libm" @@ -365,9 +365,9 @@ checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "log" -version = "0.4.26" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "memchr" @@ -386,15 +386,15 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.3" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "oorandom" -version = "11.1.4" +version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "owo-colors" @@ -435,9 +435,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.39" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -520,18 +520,18 @@ checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" [[package]] name = "serde" -version = "1.0.218" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.218" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -552,9 +552,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.99" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02e925281e18ffd9d640e234264753c43edc62d64b2d4cf898f1bc5e75f3fc2" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -596,7 +596,7 @@ dependencies = [ "tinywasm-parser", "tinywasm-types", "wasm-testsuite", - "wast 227.0.0", + "wast", "wat", ] @@ -609,7 +609,7 @@ dependencies = [ "log", "pretty_env_logger", "tinywasm", - "wast 227.0.0", + "wast", ] [[package]] @@ -618,7 +618,7 @@ version = "0.9.0-alpha.0" dependencies = [ "log", "tinywasm-types", - "wasmparser 0.227.0", + "wasmparser", ] [[package]] @@ -664,50 +664,29 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.226.0" +version = "0.228.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d81b727619aec227dce83e7f7420d4e56c79acd044642a356ea045b98d4e13" +checksum = "05d30290541f2d4242a162bbda76b8f2d8b1ac59eab3568ed6f2327d52c9b2c4" dependencies = [ "leb128fmt", - "wasmparser 0.226.0", -] - -[[package]] -name = "wasm-encoder" -version = "0.227.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829806010c17fa417fa56a42b76efadb35d70dbd972de9f07373b87d2729b698" -dependencies = [ - "leb128fmt", - "wasmparser 0.227.0", + "wasmparser", ] [[package]] name = "wasm-testsuite" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01c897a970135c086793fa320de6632534ad7b4a519a3ca51c7ef40e6a567d7" +checksum = "ec81df5b65371f919b41f3682861d98f1c90d081cfd8cb68784eb5d942dc1e36" dependencies = [ "include_dir", - "wast 226.0.0", -] - -[[package]] -name = "wasmparser" -version = "0.226.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc28600dcb2ba68d7e5f1c3ba4195c2bddc918c0243fd702d0b6dbd05689b681" -dependencies = [ - "bitflags", - "indexmap", - "semver", + "wast", ] [[package]] name = "wasmparser" -version = "0.227.0" +version = "0.228.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c15e32b1ab55e5e112f7c1dabd0d3f57c61992bfb0c4d4a6f141fe65c10ba750" +checksum = "4abf1132c1fdf747d56bbc1bb52152400c70f336870f968b85e89ea422198ae3" dependencies = [ "bitflags", "indexmap", @@ -716,37 +695,24 @@ dependencies = [ [[package]] name = "wast" -version = "226.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb903956d0151eabb6c30a2304dd61e5c8d7182805226120c2b6d611fb09a26" -dependencies = [ - "bumpalo", - "leb128fmt", - "memchr", - "unicode-width", - "wasm-encoder 0.226.0", -] - -[[package]] -name = "wast" -version = "227.0.0" +version = "228.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9ba0f7fe54ce2895314110aac579043d43175f66201153a0549badfa0fb04e" +checksum = "9e5aae124478cb51439f6587f074a3a5e835afd22751c59a87b2e2a882727c97" dependencies = [ "bumpalo", "leb128fmt", "memchr", "unicode-width", - "wasm-encoder 0.227.0", + "wasm-encoder", ] [[package]] name = "wat" -version = "1.227.0" +version = "1.228.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc4d0762d835bf25be727f4320a8b08ce4451fb1e5868940ad7708503c6a6c9" +checksum = "7ec29c89a8d055df988de7236483bf569988ac3d6905899f6af5ef920f9385ad" dependencies = [ - "wast 227.0.0", + "wast", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 74ad676..56e0be1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,9 +4,9 @@ default-members=[".", "crates/tinywasm", "crates/types", "crates/parser"] resolver="2" [workspace.dependencies] -wast="227" -wat="1.227" -wasmparser={version="0.227", default-features=false} +wast="228" +wat="1.228" +wasmparser={version="0.228", default-features=false} eyre="0.6" log="0.4" pretty_env_logger="0.5" diff --git a/crates/cli/src/bin.rs b/crates/cli/src/bin.rs index 6efbba1..8c0fe93 100644 --- a/crates/cli/src/bin.rs +++ b/crates/cli/src/bin.rs @@ -4,7 +4,7 @@ use argh::FromArgs; use args::WasmArg; use eyre::Result; use log::{debug, info}; -use tinywasm::{types::WasmValue, Module}; +use tinywasm::{Module, types::WasmValue}; use crate::args::to_wasm_args; mod args; diff --git a/crates/cli/src/wat.rs b/crates/cli/src/wat.rs index fd00a8e..8d2998d 100644 --- a/crates/cli/src/wat.rs +++ b/crates/cli/src/wat.rs @@ -1,6 +1,6 @@ use wast::{ - parser::{self, ParseBuffer}, Wat, + parser::{self, ParseBuffer}, }; pub fn wat2wasm(wat: &str) -> Vec { diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index e5022c5..1292fa6 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -70,8 +70,6 @@ impl Parser { gc_types: true, stack_switching: false, component_model: false, - component_model_nested_names: false, - component_model_values: false, exceptions: false, gc: false, memory_control: false, @@ -79,7 +77,11 @@ impl Parser { threads: false, shared_everything_threads: false, legacy_exceptions: false, - component_model_async: false, + cm_async: false, + cm_async_builtins: false, + cm_async_stackful: false, + cm_nested_names: false, + cm_values: false, }; Validator::new_with_features(features.into()) } diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index 8af013d..5810f0e 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -20,7 +20,7 @@ tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false libm={version="0.2", default-features=false} [dev-dependencies] -wasm-testsuite={version="0.5.0"} +wasm-testsuite={version="0.5.2"} indexmap="2.7" wast={workspace=true} wat={workspace=true} diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index d6d8089..a0153af 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -440,12 +440,12 @@ impl<'store, 'stack> Executor<'store, 'stack> { I8x16Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a as i8))).to_cf()?, I16x8Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a as i16))).to_cf()?, - I32x4Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a as i32))).to_cf()?, + I32x4Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a))).to_cf()?, I64x2Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a as i64))).to_cf()?, I8x16ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as i8))).to_cf()?, I16x8ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as i16))).to_cf()?, - I32x4ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as i32))).to_cf()?, + I32x4ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a))).to_cf()?, I64x2ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as i64))).to_cf()?, I8x16ShrU => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as u8))).to_cf()?, diff --git a/crates/tinywasm/tests/host_func_signature_check.rs b/crates/tinywasm/tests/host_func_signature_check.rs index c60ade2..698ad61 100644 --- a/crates/tinywasm/tests/host_func_signature_check.rs +++ b/crates/tinywasm/tests/host_func_signature_check.rs @@ -1,8 +1,8 @@ use eyre::Result; use std::fmt::Write; use tinywasm::{ - types::{FuncType, ValType, WasmValue}, Extern, FuncContext, Imports, Module, Store, + types::{FuncType, ValType, WasmValue}, }; use tinywasm_types::ExternRef; diff --git a/crates/tinywasm/tests/test-wasm-1.rs b/crates/tinywasm/tests/test-wasm-1.rs index 94c83f9..be235ae 100644 --- a/crates/tinywasm/tests/test-wasm-1.rs +++ b/crates/tinywasm/tests/test-wasm-1.rs @@ -1,7 +1,7 @@ mod testsuite; use eyre::Result; use testsuite::TestSuite; -use wasm_testsuite::data::{spec, SpecVersion}; +use wasm_testsuite::data::{SpecVersion, spec}; fn main() -> Result<()> { TestSuite::set_log_level(log::LevelFilter::Off); diff --git a/crates/tinywasm/tests/test-wasm-2.rs b/crates/tinywasm/tests/test-wasm-2.rs index 9b30ac0..0379ca6 100644 --- a/crates/tinywasm/tests/test-wasm-2.rs +++ b/crates/tinywasm/tests/test-wasm-2.rs @@ -1,7 +1,7 @@ mod testsuite; use eyre::Result; use testsuite::TestSuite; -use wasm_testsuite::data::{spec, SpecVersion}; +use wasm_testsuite::data::{SpecVersion, spec}; fn main() -> Result<()> { TestSuite::set_log_level(log::LevelFilter::Off); diff --git a/crates/tinywasm/tests/test-wasm-3.rs b/crates/tinywasm/tests/test-wasm-3.rs index a0e2543..3e63dc5 100644 --- a/crates/tinywasm/tests/test-wasm-3.rs +++ b/crates/tinywasm/tests/test-wasm-3.rs @@ -1,7 +1,7 @@ mod testsuite; use eyre::Result; use testsuite::TestSuite; -use wasm_testsuite::data::{spec, SpecVersion}; +use wasm_testsuite::data::{SpecVersion, spec}; fn main() -> Result<()> { if !std::env::args().any(|x| &x == "--enable") { diff --git a/crates/tinywasm/tests/test-wasm-annotations.rs b/crates/tinywasm/tests/test-wasm-annotations.rs index 3170241..beac9eb 100644 --- a/crates/tinywasm/tests/test-wasm-annotations.rs +++ b/crates/tinywasm/tests/test-wasm-annotations.rs @@ -1,7 +1,7 @@ mod testsuite; use eyre::Result; use testsuite::TestSuite; -use wasm_testsuite::data::{proposal, Proposal}; +use wasm_testsuite::data::{Proposal, proposal}; fn main() -> Result<()> { TestSuite::set_log_level(log::LevelFilter::Off); diff --git a/crates/tinywasm/tests/test-wasm-extended-const.rs b/crates/tinywasm/tests/test-wasm-extended-const.rs index 7c9a304..888a49f 100644 --- a/crates/tinywasm/tests/test-wasm-extended-const.rs +++ b/crates/tinywasm/tests/test-wasm-extended-const.rs @@ -1,7 +1,7 @@ mod testsuite; use eyre::Result; use testsuite::TestSuite; -use wasm_testsuite::data::{proposal, Proposal}; +use wasm_testsuite::data::{Proposal, proposal}; fn main() -> Result<()> { TestSuite::set_log_level(log::LevelFilter::Off); diff --git a/crates/tinywasm/tests/test-wasm-multi-memory.rs b/crates/tinywasm/tests/test-wasm-multi-memory.rs index d491fb1..30052b0 100644 --- a/crates/tinywasm/tests/test-wasm-multi-memory.rs +++ b/crates/tinywasm/tests/test-wasm-multi-memory.rs @@ -1,7 +1,7 @@ mod testsuite; use eyre::Result; use testsuite::TestSuite; -use wasm_testsuite::data::{proposal, Proposal}; +use wasm_testsuite::data::{Proposal, proposal}; fn main() -> Result<()> { TestSuite::set_log_level(log::LevelFilter::Off); diff --git a/crates/tinywasm/tests/test-wasm-relaxed-simd.rs b/crates/tinywasm/tests/test-wasm-relaxed-simd.rs index 7af830a..0851d18 100644 --- a/crates/tinywasm/tests/test-wasm-relaxed-simd.rs +++ b/crates/tinywasm/tests/test-wasm-relaxed-simd.rs @@ -1,7 +1,7 @@ mod testsuite; use eyre::Result; use testsuite::TestSuite; -use wasm_testsuite::data::{proposal, Proposal}; +use wasm_testsuite::data::{Proposal, proposal}; fn main() -> Result<()> { TestSuite::set_log_level(log::LevelFilter::Off); diff --git a/crates/tinywasm/tests/test-wast.rs b/crates/tinywasm/tests/test-wast.rs index 33c716c..40b0e04 100644 --- a/crates/tinywasm/tests/test-wast.rs +++ b/crates/tinywasm/tests/test-wast.rs @@ -1,6 +1,6 @@ use std::path::PathBuf; -use eyre::{bail, eyre, Result}; +use eyre::{Result, bail, eyre}; use owo_colors::OwoColorize; use testsuite::TestSuite; diff --git a/crates/tinywasm/tests/testsuite/mod.rs b/crates/tinywasm/tests/testsuite/mod.rs index ee0336e..c1ba46e 100644 --- a/crates/tinywasm/tests/testsuite/mod.rs +++ b/crates/tinywasm/tests/testsuite/mod.rs @@ -1,5 +1,5 @@ #![allow(unused)] -use eyre::{eyre, Result}; +use eyre::{Result, eyre}; use indexmap::IndexMap; use owo_colors::OwoColorize; use std::io::{BufRead, Seek, SeekFrom}; diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index 0804266..d09efdb 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -2,14 +2,14 @@ use crate::testsuite::util::*; use std::{borrow::Cow, collections::HashMap, fs::canonicalize, path::PathBuf}; use super::TestSuite; -use eyre::{eyre, Result}; +use eyre::{Result, eyre}; use indexmap::IndexMap; use log::{debug, error, info}; use tinywasm::{Extern, Imports, ModuleInstance}; use tinywasm_types::{ExternVal, MemoryType, ModuleInstanceAddr, TableType, ValType, WasmValue}; use wasm_testsuite::data::TestFile; use wasm_testsuite::wast; -use wasm_testsuite::wast::{lexer::Lexer, parser::ParseBuffer, Wast}; +use wasm_testsuite::wast::{Wast, lexer::Lexer, parser::ParseBuffer}; #[derive(Default)] struct ModuleRegistry { diff --git a/crates/tinywasm/tests/testsuite/util.rs b/crates/tinywasm/tests/testsuite/util.rs index 91a1e41..5e8558a 100644 --- a/crates/tinywasm/tests/testsuite/util.rs +++ b/crates/tinywasm/tests/testsuite/util.rs @@ -102,7 +102,7 @@ fn wastarg2tinywasmvalue(arg: wast::WastArg) -> Result WasmValue::F64(f64::from_bits(f.bits)), I32(i) => WasmValue::I32(i), I64(i) => WasmValue::I64(i), - V128(i) => WasmValue::V128(i128::from_le_bytes(i.to_le_bytes()).try_into().unwrap()), + V128(i) => WasmValue::V128(i128::from_le_bytes(i.to_le_bytes())), RefExtern(v) => WasmValue::RefExtern(ExternRef::new(Some(v))), RefNull(t) => match t { wast::core::HeapType::Abstract { shared: false, ty: AbstractHeapType::Func } => { @@ -120,15 +120,15 @@ fn wastarg2tinywasmvalue(arg: wast::WastArg) -> Result i128 { let res: Vec = match i { wast::core::V128Pattern::F32x4(f) => { - f.iter().map(|v| nanpattern2tinywasmvalue(*v).unwrap().as_f32().unwrap().to_le_bytes()).flatten().collect() + f.iter().flat_map(|v| nanpattern2tinywasmvalue(*v).unwrap().as_f32().unwrap().to_le_bytes()).collect() } wast::core::V128Pattern::F64x2(f) => { - f.iter().map(|v| nanpattern2tinywasmvalue(*v).unwrap().as_f64().unwrap().to_le_bytes()).flatten().collect() + f.iter().flat_map(|v| nanpattern2tinywasmvalue(*v).unwrap().as_f64().unwrap().to_le_bytes()).collect() } - wast::core::V128Pattern::I16x8(f) => f.iter().map(|v| v.to_le_bytes()).flatten().collect(), - wast::core::V128Pattern::I32x4(f) => f.iter().map(|v| v.to_le_bytes()).flatten().collect(), - wast::core::V128Pattern::I64x2(f) => f.iter().map(|v| v.to_le_bytes()).flatten().collect(), - wast::core::V128Pattern::I8x16(f) => f.iter().map(|v| v.to_le_bytes()).flatten().collect(), + wast::core::V128Pattern::I16x8(f) => f.iter().flat_map(|v| v.to_le_bytes()).collect(), + wast::core::V128Pattern::I32x4(f) => f.iter().flat_map(|v| v.to_le_bytes()).collect(), + wast::core::V128Pattern::I64x2(f) => f.iter().flat_map(|v| v.to_le_bytes()).collect(), + wast::core::V128Pattern::I8x16(f) => f.iter().flat_map(|v| v.to_le_bytes()).collect(), }; i128::from_le_bytes(res.try_into().unwrap()) diff --git a/examples/archive.rs b/examples/archive.rs index 6a3d54e..7a1021b 100644 --- a/examples/archive.rs +++ b/examples/archive.rs @@ -1,5 +1,5 @@ use eyre::Result; -use tinywasm::{parser::Parser, types::TinyWasmModule, Module, Store}; +use tinywasm::{Module, Store, parser::Parser, types::TinyWasmModule}; const WASM: &str = r#" (module diff --git a/examples/funcref_callbacks.rs b/examples/funcref_callbacks.rs index df50e75..01f833c 100644 --- a/examples/funcref_callbacks.rs +++ b/examples/funcref_callbacks.rs @@ -1,5 +1,5 @@ use eyre::Result; -use tinywasm::{types::FuncRef, Extern, FuncContext, Imports, Module, Store}; +use tinywasm::{Extern, FuncContext, Imports, Module, Store, types::FuncRef}; fn main() -> Result<()> { by_func_ref_passed()?; diff --git a/examples/wasm-rust.rs b/examples/wasm-rust.rs index 95769f4..d5a6b2a 100644 --- a/examples/wasm-rust.rs +++ b/examples/wasm-rust.rs @@ -1,6 +1,6 @@ use std::hint::black_box; -use eyre::{eyre, Result}; +use eyre::{Result, eyre}; use tinywasm::{Extern, FuncContext, Imports, MemoryStringExt, Module, Store}; /// Examples of using WebAssembly compiled from Rust with tinywasm. From 3664c8b79918ffad109ccec32336d38c299f1351 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Wed, 23 Apr 2025 20:46:50 +0200 Subject: [PATCH 53/54] chore: update deps, properly feature gate simd Signed-off-by: Henry Gressmann --- Cargo.lock | 36 +- Cargo.toml | 6 +- crates/parser/src/lib.rs | 1 + crates/parser/src/module.rs | 2 +- crates/parser/src/visit.rs | 6 +- crates/tinywasm/Cargo.toml | 8 +- crates/tinywasm/src/interpreter/executor.rs | 511 +++++++++--------- .../tinywasm/src/interpreter/num_helpers.rs | 4 +- .../src/interpreter/stack/call_stack.rs | 1 + .../src/interpreter/stack/value_stack.rs | 6 +- crates/tinywasm/src/interpreter/values.rs | 17 +- crates/tinywasm/src/lib.rs | 2 +- crates/tinywasm/src/store/memory.rs | 4 +- crates/tinywasm/tests/generated/wasm-1.csv | 2 +- crates/tinywasm/tests/generated/wasm-2.csv | 2 +- .../tests/generated/wasm-multi-memory.csv | 2 +- crates/types/src/instructions.rs | 1 - 17 files changed, 317 insertions(+), 294 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 48bfcf9..acdc41b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -114,18 +114,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.35" +version = "4.5.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" +checksum = "2df961d8c8a0d08aa9945718ccf584145eee3f3aa06cddbeac12933781102e04" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.35" +version = "4.5.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" +checksum = "132dbda40fb6753878316a489d5a1242a8ef2f0d9e47ba01c951ea8aa7d013a5" dependencies = [ "anstyle", "clap_lex", @@ -258,9 +258,9 @@ dependencies = [ [[package]] name = "half" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" dependencies = [ "cfg-if", "crunchy", @@ -311,9 +311,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", "hashbrown", @@ -664,9 +664,9 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.228.0" +version = "0.229.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d30290541f2d4242a162bbda76b8f2d8b1ac59eab3568ed6f2327d52c9b2c4" +checksum = "38ba1d491ecacb085a2552025c10a675a6fddcbd03b1fc9b36c536010ce265d2" dependencies = [ "leb128fmt", "wasmparser", @@ -674,9 +674,9 @@ dependencies = [ [[package]] name = "wasm-testsuite" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec81df5b65371f919b41f3682861d98f1c90d081cfd8cb68784eb5d942dc1e36" +checksum = "735333508bfc70a3cc7a7ed86b3cd53e4a775cbf78511eaec8ac4926ed3a0bf7" dependencies = [ "include_dir", "wast", @@ -684,9 +684,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.228.0" +version = "0.229.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4abf1132c1fdf747d56bbc1bb52152400c70f336870f968b85e89ea422198ae3" +checksum = "0cc3b1f053f5d41aa55640a1fa9b6d1b8a9e4418d118ce308d20e24ff3575a8c" dependencies = [ "bitflags", "indexmap", @@ -695,9 +695,9 @@ dependencies = [ [[package]] name = "wast" -version = "228.0.0" +version = "229.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5aae124478cb51439f6587f074a3a5e835afd22751c59a87b2e2a882727c97" +checksum = "63fcaff613c12225696bb163f79ca38ffb40e9300eff0ff4b8aa8b2f7eadf0d9" dependencies = [ "bumpalo", "leb128fmt", @@ -708,9 +708,9 @@ dependencies = [ [[package]] name = "wat" -version = "1.228.0" +version = "1.229.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ec29c89a8d055df988de7236483bf569988ac3d6905899f6af5ef920f9385ad" +checksum = "4189bad08b70455a9e9e67dc126d2dcf91fac143a80f1046747a5dde6d4c33e0" dependencies = [ "wast", ] diff --git a/Cargo.toml b/Cargo.toml index 56e0be1..1f645cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,9 +4,9 @@ default-members=[".", "crates/tinywasm", "crates/types", "crates/parser"] resolver="2" [workspace.dependencies] -wast="228" -wat="1.228" -wasmparser={version="0.228", default-features=false} +wast="229" +wat="1.229" +wasmparser={version="0.229", default-features=false} eyre="0.6" log="0.4" pretty_env_logger="0.5" diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index 1292fa6..aa33995 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -82,6 +82,7 @@ impl Parser { cm_async_stackful: false, cm_nested_names: false, cm_values: false, + cm_error_context: false, }; Validator::new_with_features(features.into()) } diff --git a/crates/parser/src/module.rs b/crates/parser/src/module.rs index ff6b22b..0e17ad9 100644 --- a/crates/parser/src/module.rs +++ b/crates/parser/src/module.rs @@ -130,7 +130,7 @@ impl ModuleReader { return Err(ParseError::DuplicateSection("Code section".into())); } self.code.reserve(count as usize); - validator.code_section_start(count, &range)?; + validator.code_section_start(&range)?; } CodeSectionEntry(function) => { debug!("Found code section entry"); diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs index 3e6fa4b..10005c0 100644 --- a/crates/parser/src/visit.rs +++ b/crates/parser/src/visit.rs @@ -46,7 +46,7 @@ pub(crate) fn process_operators_and_validate( reader.visit_operator(&mut ValidateThenVisit(reader.original_position(), &mut builder))??; } - builder.validator_finish(reader.original_position())?; + reader.finish()?; if !builder.errors.is_empty() { return Err(builder.errors.remove(0)); } @@ -124,10 +124,6 @@ impl FunctionBuilder { ) -> impl VisitOperator<'_, Output = Result<(), wasmparser::BinaryReaderError>> + VisitSimdOperator<'_> { self.validator.simd_visitor(offset) } - - pub(crate) fn validator_finish(&mut self, offset: usize) -> Result<(), wasmparser::BinaryReaderError> { - self.validator.finish(offset) - } } impl FunctionBuilder { diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index 5810f0e..3281476 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -20,7 +20,7 @@ tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false libm={version="0.2", default-features=false} [dev-dependencies] -wasm-testsuite={version="0.5.2"} +wasm-testsuite={version="0.5.3"} indexmap="2.7" wast={workspace=true} wat={workspace=true} @@ -32,12 +32,14 @@ serde_json={version="1.0"} serde={version="1.0", features=["derive"]} [features] -default=["std", "parser", "logging", "archive", "simd"] +default=["std", "parser", "logging", "archive"] logging=["log", "tinywasm-parser?/logging", "tinywasm-types/logging"] std=["tinywasm-parser?/std", "tinywasm-types/std"] parser=["dep:tinywasm-parser"] archive=["tinywasm-types/archive"] -simd=[] + +# enable simd support (unstable / unfinished) +__simd=[] [[test]] name="test-wasm-1" diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index a0153af..4bf4f5d 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -3,16 +3,19 @@ use super::no_std_floats::NoStdFloatExt; use alloc::{format, rc::Rc, string::ToString}; -use core::ops::{ControlFlow, Index, IndexMut, Shl, Shr}; +use core::ops::ControlFlow; use interpreter::stack::CallFrame; use tinywasm_types::*; -#[cfg(all(feature = "std", feature = "simd"))] +#[cfg(all(feature = "std", feature = "__simd"))] use crate::std::simd::StdFloat; -#[cfg(feature = "simd")] +#[cfg(feature = "__simd")] use core::simd::{cmp::*, num::*, *}; +#[cfg(feature = "__simd")] +use core::ops::{Index, IndexMut, Shl, Shr}; + use super::num_helpers::*; use super::stack::{BlockFrame, BlockType, Stack}; use super::values::*; @@ -313,234 +316,235 @@ impl<'store, 'stack> Executor<'store, 'stack> { LocalCopy128(from, to) => self.exec_local_copy::(*from, *to), LocalCopyRef(from, to) => self.exec_local_copy::(*from, *to), - V128Not => self.stack.values.replace_top_same::(|v| Ok(!v)).to_cf()?, - V128And => self.stack.values.calculate_same::(|a, b| Ok(a & b)).to_cf()?, - V128AndNot => self.stack.values.calculate_same::(|a, b| Ok(a & (!b))).to_cf()?, - V128Or => self.stack.values.calculate_same::(|a, b| Ok(a | b)).to_cf()?, - V128Xor => self.stack.values.calculate_same::(|a, b| Ok(a ^ b)).to_cf()?, - V128Bitselect => self.stack.values.calculate_same_3::(|v1, v2, c| Ok((v1 & c) | (v2 & !c))).to_cf()?, - V128AnyTrue => self.stack.values.replace_top::(|v| Ok((v.reduce_or() != 0) as i32)).to_cf()?, - I8x16Swizzle => self.stack.values.calculate_same::(|a, s| Ok(a.swizzle_dyn(s))).to_cf()?, - V128Load(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| v)?, - V128Store(arg) => self.exec_mem_store::(arg.mem_addr(), arg.offset(), |v| v)?, - - V128Store8Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, - V128Store16Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, - V128Store32Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, - V128Store64Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, + #[cfg(feature = "__simd")] V128Not => self.stack.values.replace_top_same::(|v| Ok(!v)).to_cf()?, + #[cfg(feature = "__simd")] V128And => self.stack.values.calculate_same::(|a, b| Ok(a & b)).to_cf()?, + #[cfg(feature = "__simd")] V128AndNot => self.stack.values.calculate_same::(|a, b| Ok(a & (!b))).to_cf()?, + #[cfg(feature = "__simd")] V128Or => self.stack.values.calculate_same::(|a, b| Ok(a | b)).to_cf()?, + #[cfg(feature = "__simd")] V128Xor => self.stack.values.calculate_same::(|a, b| Ok(a ^ b)).to_cf()?, + #[cfg(feature = "__simd")] V128Bitselect => self.stack.values.calculate_same_3::(|v1, v2, c| Ok((v1 & c) | (v2 & !c))).to_cf()?, + #[cfg(feature = "__simd")] V128AnyTrue => self.stack.values.replace_top::(|v| Ok((v.reduce_or() != 0) as i32)).to_cf()?, + #[cfg(feature = "__simd")] I8x16Swizzle => self.stack.values.calculate_same::(|a, s| Ok(a.swizzle_dyn(s))).to_cf()?, + #[cfg(feature = "__simd")] V128Load(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| v)?, + #[cfg(feature = "__simd")] V128Store(arg) => self.exec_mem_store::(arg.mem_addr(), arg.offset(), |v| v)?, + + #[cfg(feature = "__simd")] V128Store8Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, + #[cfg(feature = "__simd")] V128Store16Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, + #[cfg(feature = "__simd")] V128Store32Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, + #[cfg(feature = "__simd")] V128Store64Lane(arg, lane) => self.exec_mem_store_lane::(arg.mem_addr(), arg.offset(), *lane)?, // Load a single 32-bit or 64-bit element into the lowest bits of a v128 vector, and initialize all other bits of the v128 vector to zero. - V128Load32Zero(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| { + #[cfg(feature = "__simd")] V128Load32Zero(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| { let bytes = v.to_le_bytes(); u8x16::from_array([bytes[0], bytes[1], bytes[2], bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) })?, - V128Load64Zero(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| { + #[cfg(feature = "__simd")] V128Load64Zero(arg) => self.exec_mem_load::(arg.mem_addr(), arg.offset(), |v| { let bytes = v.to_le_bytes(); u8x16::from_array([bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], 0, 0, 0, 0, 0, 0, 0, 0]) })?, - V128Const(arg) => self.exec_const::( self.cf.data().v128_constants[*arg as usize].to_le_bytes().into()), - - I8x16ExtractLaneS(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, - I8x16ExtractLaneU(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, - I16x8ExtractLaneS(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, - I16x8ExtractLaneU(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, - I32x4ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, - I64x2ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, - F32x4ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, - F64x2ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, - - V128Load8Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, - V128Load16Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, - V128Load32Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, - V128Load64Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, - - I8x16Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v as i8))).to_cf()?, - I16x8Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v as i16))).to_cf()?, - I32x4Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v))).to_cf()?, - I64x2Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v))).to_cf()?, - F32x4Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v))).to_cf()?, - F64x2Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v))).to_cf()?, - - I8x16Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, - I16x8Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, - I32x4Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, - F32x4Eq => self.stack.values.calculate::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, - F64x2Eq => self.stack.values.calculate::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, - - I8x16Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, - I16x8Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, - I32x4Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, - F32x4Ne => self.stack.values.calculate::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, - F64x2Ne => self.stack.values.calculate::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, - - I8x16LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, - I16x8LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, - I32x4LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, - I64x2LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, - I8x16LtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, - I16x8LtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, - I32x4LtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, - F32x4Lt => self.stack.values.calculate::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, - F64x2Lt => self.stack.values.calculate::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, - - I64x2GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, - F32x4Gt => self.stack.values.calculate::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, - F64x2Gt => self.stack.values.calculate::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, - - I8x16GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, - I16x8GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, - I32x4GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, - I64x2LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, - F32x4Le => self.stack.values.calculate::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, - F64x2Le => self.stack.values.calculate::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, - - I8x16GtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, - I16x8GtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, - I32x4GtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, - I64x2GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, - F32x4Ge => self.stack.values.calculate::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, - F64x2Ge => self.stack.values.calculate::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, - - I8x16LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, - I16x8LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, - I32x4LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, - - I8x16LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, - I16x8LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, - I32x4LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, - - I8x16GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, - I16x8GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, - I32x4GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, - - I8x16GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, - I16x8GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, - I32x4GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, - - I8x16Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, - I16x8Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, - I32x4Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, - I64x2Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, - - I8x16Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, - I16x8Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, - I32x4Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, - I64x2Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, - - I8x16AllTrue => self.stack.values.replace_top::(|v| Ok((v.simd_ne(Simd::splat(0)).all()) as i32)).to_cf()?, - I16x8AllTrue => self.stack.values.replace_top::(|v| Ok((v.simd_ne(Simd::splat(0)).all()) as i32)).to_cf()?, - I32x4AllTrue => self.stack.values.replace_top::(|v| Ok((v.simd_ne(Simd::splat(0)).all()) as i32)).to_cf()?, - I64x2AllTrue => self.stack.values.replace_top::(|v| Ok((v.simd_ne(Simd::splat(0)).all()) as i32)).to_cf()?, - - I8x16Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, - I16x8Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, - I32x4Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, - I64x2Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, - - I8x16Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a as i8))).to_cf()?, - I16x8Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a as i16))).to_cf()?, - I32x4Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a))).to_cf()?, - I64x2Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a as i64))).to_cf()?, - - I8x16ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as i8))).to_cf()?, - I16x8ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as i16))).to_cf()?, - I32x4ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a))).to_cf()?, - I64x2ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as i64))).to_cf()?, - - I8x16ShrU => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as u8))).to_cf()?, - I16x8ShrU => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as u16))).to_cf()?, - I32x4ShrU => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as u32))).to_cf()?, - I64x2ShrU => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as u64))).to_cf()?, - - I8x16Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, - I16x8Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, - I32x4Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, - I64x2Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, - - I8x16Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, - I16x8Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, - I32x4Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, - I64x2Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, - - I8x16MinS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, - I16x8MinS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, - I32x4MinS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, - - I8x16MinU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, - I16x8MinU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, - I32x4MinU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, - - I8x16MaxS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, - I16x8MaxS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, - I32x4MaxS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, - - I8x16MaxU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, - I16x8MaxU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, - I32x4MaxU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, - - I64x2Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, - I16x8Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, - I32x4Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, - - I8x16NarrowI16x8S => unimplemented!(), - I8x16NarrowI16x8U => unimplemented!(), - I16x8NarrowI32x4S => unimplemented!(), - I16x8NarrowI32x4U => unimplemented!(), - - I8x16AddSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, - I16x8AddSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, - I8x16AddSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, - I16x8AddSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, - I8x16SubSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, - I16x8SubSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, - I8x16SubSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, - I16x8SubSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, - - I16x8ExtAddPairwiseI8x16S => unimplemented!(), - I16x8ExtAddPairwiseI8x16U => unimplemented!(), - I32x4ExtAddPairwiseI16x8S => unimplemented!(), - I32x4ExtAddPairwiseI16x8U => unimplemented!(), - - I16x8ExtMulLowI8x16S => unimplemented!(), - I16x8ExtMulLowI8x16U => unimplemented!(), - I16x8ExtMulHighI8x16S => unimplemented!(), - I16x8ExtMulHighI8x16U => unimplemented!(), - I32x4ExtMulLowI16x8S => unimplemented!(), - I32x4ExtMulLowI16x8U => unimplemented!(), - I32x4ExtMulHighI16x8S => unimplemented!(), - I32x4ExtMulHighI16x8U => unimplemented!(), - I64x2ExtMulLowI32x4S => unimplemented!(), - I64x2ExtMulLowI32x4U => unimplemented!(), - I64x2ExtMulHighI32x4S => unimplemented!(), - I64x2ExtMulHighI32x4U => unimplemented!(), - - I16x8ExtendLowI8x16S => unimplemented!(), - I16x8ExtendLowI8x16U => unimplemented!(), - I16x8ExtendHighI8x16S => unimplemented!(), - I16x8ExtendHighI8x16U => unimplemented!(), - I32x4ExtendLowI16x8S => unimplemented!(), - I32x4ExtendLowI16x8U => unimplemented!(), - I32x4ExtendHighI16x8S => unimplemented!(), - I32x4ExtendHighI16x8U => unimplemented!(), - I64x2ExtendLowI32x4S => unimplemented!(), - I64x2ExtendLowI32x4U => unimplemented!(), - I64x2ExtendHighI32x4S => unimplemented!(), - I64x2ExtendHighI32x4U => unimplemented!(), - - I8x16Popcnt => self.stack.values.replace_top::(|v| Ok(v.count_ones())).to_cf()?, - + #[cfg(feature = "__simd")] V128Const(arg) => self.exec_const::( self.cf.data().v128_constants[*arg as usize].to_le_bytes().into()), + + #[cfg(feature = "__simd")] I8x16ExtractLaneS(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, + #[cfg(feature = "__simd")] I8x16ExtractLaneU(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, + #[cfg(feature = "__simd")] I16x8ExtractLaneS(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, + #[cfg(feature = "__simd")] I16x8ExtractLaneU(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize] as i32)).to_cf()?, + #[cfg(feature = "__simd")] I32x4ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, + #[cfg(feature = "__simd")] I64x2ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, + #[cfg(feature = "__simd")] F32x4ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, + #[cfg(feature = "__simd")] F64x2ExtractLane(lane) => self.stack.values.replace_top::(|v| Ok(v[*lane as usize])).to_cf()?, + + #[cfg(feature = "__simd")] V128Load8Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, + #[cfg(feature = "__simd")] V128Load16Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, + #[cfg(feature = "__simd")] V128Load32Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, + #[cfg(feature = "__simd")] V128Load64Lane(arg, lane) => self.exec_mem_load_lane::(arg.mem_addr(), arg.offset(), *lane)?, + + #[cfg(feature = "__simd")] I8x16Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v as i8))).to_cf()?, + #[cfg(feature = "__simd")] I16x8Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v as i16))).to_cf()?, + #[cfg(feature = "__simd")] I32x4Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v))).to_cf()?, + #[cfg(feature = "__simd")] I64x2Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v))).to_cf()?, + #[cfg(feature = "__simd")] F32x4Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v))).to_cf()?, + #[cfg(feature = "__simd")] F64x2Splat => self.stack.values.replace_top::(|v| Ok(Simd::::splat(v))).to_cf()?, + + #[cfg(feature = "__simd")] I8x16Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I16x8Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I32x4Eq => self.stack.values.calculate_same::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] F32x4Eq => self.stack.values.calculate::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] F64x2Eq => self.stack.values.calculate::(|a, b| Ok(a.simd_eq(b).to_int())).to_cf()?, + + #[cfg(feature = "__simd")] I8x16Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I16x8Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I32x4Ne => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] F32x4Ne => self.stack.values.calculate::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] F64x2Ne => self.stack.values.calculate::(|a, b| Ok(a.simd_ne(b).to_int())).to_cf()?, + + #[cfg(feature = "__simd")] I8x16LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I16x8LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I32x4LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I64x2LtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I8x16LtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I16x8LtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I32x4LtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] F32x4Lt => self.stack.values.calculate::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] F64x2Lt => self.stack.values.calculate::(|a, b| Ok(a.simd_lt(b).to_int())).to_cf()?, + + #[cfg(feature = "__simd")] I64x2GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] F32x4Gt => self.stack.values.calculate::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] F64x2Gt => self.stack.values.calculate::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + + #[cfg(feature = "__simd")] I8x16GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I16x8GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I32x4GtS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I64x2LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] F32x4Le => self.stack.values.calculate::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] F64x2Le => self.stack.values.calculate::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + + #[cfg(feature = "__simd")] I8x16GtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I16x8GtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I32x4GtU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_gt(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I64x2GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] F32x4Ge => self.stack.values.calculate::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] F64x2Ge => self.stack.values.calculate::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + + #[cfg(feature = "__simd")] I8x16LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I16x8LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I32x4LeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + + #[cfg(feature = "__simd")] I8x16LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I16x8LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I32x4LeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_le(b).to_int())).to_cf()?, + + #[cfg(feature = "__simd")] I8x16GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I16x8GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I32x4GeS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + + #[cfg(feature = "__simd")] I8x16GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I16x8GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + #[cfg(feature = "__simd")] I32x4GeU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_ge(b).to_int())).to_cf()?, + + #[cfg(feature = "__simd")] I8x16Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, + #[cfg(feature = "__simd")] I16x8Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, + #[cfg(feature = "__simd")] I32x4Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, + #[cfg(feature = "__simd")] I64x2Abs => self.stack.values.replace_top_same::(|a| Ok(a.abs())).to_cf()?, + + #[cfg(feature = "__simd")] I8x16Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, + #[cfg(feature = "__simd")] I16x8Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, + #[cfg(feature = "__simd")] I32x4Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, + #[cfg(feature = "__simd")] I64x2Neg => self.stack.values.replace_top_same::(|a| Ok(-a)).to_cf()?, + + #[cfg(feature = "__simd")] I8x16AllTrue => self.stack.values.replace_top::(|v| Ok((v.simd_ne(Simd::splat(0)).all()) as i32)).to_cf()?, + #[cfg(feature = "__simd")] I16x8AllTrue => self.stack.values.replace_top::(|v| Ok((v.simd_ne(Simd::splat(0)).all()) as i32)).to_cf()?, + #[cfg(feature = "__simd")] I32x4AllTrue => self.stack.values.replace_top::(|v| Ok((v.simd_ne(Simd::splat(0)).all()) as i32)).to_cf()?, + #[cfg(feature = "__simd")] I64x2AllTrue => self.stack.values.replace_top::(|v| Ok((v.simd_ne(Simd::splat(0)).all()) as i32)).to_cf()?, + + #[cfg(feature = "__simd")] I8x16Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, + #[cfg(feature = "__simd")] I16x8Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, + #[cfg(feature = "__simd")] I32x4Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, + #[cfg(feature = "__simd")] I64x2Bitmask => self.stack.values.replace_top::(|v| Ok(v.simd_lt(Simd::splat(0)).to_bitmask() as i32)).to_cf()?, + + #[cfg(feature = "__simd")] I8x16Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a as i8))).to_cf()?, + #[cfg(feature = "__simd")] I16x8Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a as i16))).to_cf()?, + #[cfg(feature = "__simd")] I32x4Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a))).to_cf()?, + #[cfg(feature = "__simd")] I64x2Shl => self.stack.values.calculate_diff::(|a, b| Ok(b.shl(a as i64))).to_cf()?, + + #[cfg(feature = "__simd")] I8x16ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as i8))).to_cf()?, + #[cfg(feature = "__simd")] I16x8ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as i16))).to_cf()?, + #[cfg(feature = "__simd")] I32x4ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a))).to_cf()?, + #[cfg(feature = "__simd")] I64x2ShrS => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as i64))).to_cf()?, + + #[cfg(feature = "__simd")] I8x16ShrU => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as u8))).to_cf()?, + #[cfg(feature = "__simd")] I16x8ShrU => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as u16))).to_cf()?, + #[cfg(feature = "__simd")] I32x4ShrU => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as u32))).to_cf()?, + #[cfg(feature = "__simd")] I64x2ShrU => self.stack.values.calculate_diff::(|a, b| Ok(b.shr(a as u64))).to_cf()?, + + #[cfg(feature = "__simd")] I8x16Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, + #[cfg(feature = "__simd")] I16x8Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, + #[cfg(feature = "__simd")] I32x4Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, + #[cfg(feature = "__simd")] I64x2Add => self.stack.values.calculate_same::(|a, b| Ok(a + b)).to_cf()?, + + #[cfg(feature = "__simd")] I8x16Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, + #[cfg(feature = "__simd")] I16x8Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, + #[cfg(feature = "__simd")] I32x4Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, + #[cfg(feature = "__simd")] I64x2Sub => self.stack.values.calculate_same::(|a, b| Ok(a - b)).to_cf()?, + + #[cfg(feature = "__simd")] I8x16MinS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, + #[cfg(feature = "__simd")] I16x8MinS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, + #[cfg(feature = "__simd")] I32x4MinS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, + + #[cfg(feature = "__simd")] I8x16MinU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, + #[cfg(feature = "__simd")] I16x8MinU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, + #[cfg(feature = "__simd")] I32x4MinU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_min(b))).to_cf()?, + + #[cfg(feature = "__simd")] I8x16MaxS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + #[cfg(feature = "__simd")] I16x8MaxS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + #[cfg(feature = "__simd")] I32x4MaxS => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + + #[cfg(feature = "__simd")] I8x16MaxU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + #[cfg(feature = "__simd")] I16x8MaxU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + #[cfg(feature = "__simd")] I32x4MaxU => self.stack.values.calculate_same::(|a, b| Ok(a.simd_max(b))).to_cf()?, + + #[cfg(feature = "__simd")] I64x2Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, + #[cfg(feature = "__simd")] I16x8Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, + #[cfg(feature = "__simd")] I32x4Mul => self.stack.values.calculate_same::(|a, b| Ok(a * b)).to_cf()?, + + #[cfg(feature = "__simd")] I8x16NarrowI16x8S => unimplemented!(), + #[cfg(feature = "__simd")] I8x16NarrowI16x8U => unimplemented!(), + #[cfg(feature = "__simd")] I16x8NarrowI32x4S => unimplemented!(), + #[cfg(feature = "__simd")] I16x8NarrowI32x4U => unimplemented!(), + + #[cfg(feature = "__simd")] I8x16AddSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, + #[cfg(feature = "__simd")] I16x8AddSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, + #[cfg(feature = "__simd")] I8x16AddSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, + #[cfg(feature = "__simd")] I16x8AddSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_add(b))).to_cf()?, + #[cfg(feature = "__simd")] I8x16SubSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, + #[cfg(feature = "__simd")] I16x8SubSatS => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, + #[cfg(feature = "__simd")] I8x16SubSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, + #[cfg(feature = "__simd")] I16x8SubSatU => self.stack.values.calculate_same::(|a, b| Ok(a.saturating_sub(b))).to_cf()?, + + #[cfg(feature = "__simd")] I16x8ExtAddPairwiseI8x16S => unimplemented!(), + #[cfg(feature = "__simd")] I16x8ExtAddPairwiseI8x16U => unimplemented!(), + #[cfg(feature = "__simd")] I32x4ExtAddPairwiseI16x8S => unimplemented!(), + #[cfg(feature = "__simd")] I32x4ExtAddPairwiseI16x8U => unimplemented!(), + + #[cfg(feature = "__simd")] I16x8ExtMulLowI8x16S => unimplemented!(), + #[cfg(feature = "__simd")] I16x8ExtMulLowI8x16U => unimplemented!(), + #[cfg(feature = "__simd")] I16x8ExtMulHighI8x16S => unimplemented!(), + #[cfg(feature = "__simd")] I16x8ExtMulHighI8x16U => unimplemented!(), + #[cfg(feature = "__simd")] I32x4ExtMulLowI16x8S => unimplemented!(), + #[cfg(feature = "__simd")] I32x4ExtMulLowI16x8U => unimplemented!(), + #[cfg(feature = "__simd")] I32x4ExtMulHighI16x8S => unimplemented!(), + #[cfg(feature = "__simd")] I32x4ExtMulHighI16x8U => unimplemented!(), + #[cfg(feature = "__simd")] I64x2ExtMulLowI32x4S => unimplemented!(), + #[cfg(feature = "__simd")] I64x2ExtMulLowI32x4U => unimplemented!(), + #[cfg(feature = "__simd")] I64x2ExtMulHighI32x4S => unimplemented!(), + #[cfg(feature = "__simd")] I64x2ExtMulHighI32x4U => unimplemented!(), + + #[cfg(feature = "__simd")] I16x8ExtendLowI8x16S => unimplemented!(), + #[cfg(feature = "__simd")] I16x8ExtendLowI8x16U => unimplemented!(), + #[cfg(feature = "__simd")] I16x8ExtendHighI8x16S => unimplemented!(), + #[cfg(feature = "__simd")] I16x8ExtendHighI8x16U => unimplemented!(), + #[cfg(feature = "__simd")] I32x4ExtendLowI16x8S => unimplemented!(), + #[cfg(feature = "__simd")] I32x4ExtendLowI16x8U => unimplemented!(), + #[cfg(feature = "__simd")] I32x4ExtendHighI16x8S => unimplemented!(), + #[cfg(feature = "__simd")] I32x4ExtendHighI16x8U => unimplemented!(), + #[cfg(feature = "__simd")] I64x2ExtendLowI32x4S => unimplemented!(), + #[cfg(feature = "__simd")] I64x2ExtendLowI32x4U => unimplemented!(), + #[cfg(feature = "__simd")] I64x2ExtendHighI32x4S => unimplemented!(), + #[cfg(feature = "__simd")] I64x2ExtendHighI32x4U => unimplemented!(), + + #[cfg(feature = "__simd")] I8x16Popcnt => self.stack.values.replace_top::(|v| Ok(v.count_ones())).to_cf()?, + + #[cfg(feature = "__simd")] I16x8Q15MulrSatS => self.stack.values.calculate_same::(|a, b| { let subq15mulr = |a,b| { let a = a as i32; let b = b as i32; let r = (a * b + 0x4000) >> 15; if r > i16::MAX as i32 { - i16::MAX + i16::MAX } else if r < i16::MIN as i32 { - i16::MIN + i16::MIN } else { - r as i16 + r as i16 } }; Ok(Simd::::from_array([ @@ -555,6 +559,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { ])) }).to_cf()?, + #[cfg(feature = "__simd")] I32x4DotI16x8S => self.stack.values.calculate::(|a, b| { Ok(Simd::::from_array([ i32::from(a[0] * b[0] + a[1] * b[1]), @@ -564,26 +569,27 @@ impl<'store, 'stack> Executor<'store, 'stack> { ])) }).to_cf()?, - F32x4Ceil => self.stack.values.replace_top_same::(|v| Ok(v.ceil())).to_cf()?, - F64x2Ceil => self.stack.values.replace_top_same::(|v| Ok(v.ceil())).to_cf()?, - F32x4Floor => self.stack.values.replace_top_same::(|v| Ok(v.floor())).to_cf()?, - F64x2Floor => self.stack.values.replace_top_same::(|v| Ok(v.floor())).to_cf()?, - F32x4Trunc => self.stack.values.replace_top_same::(|v| Ok(v.trunc())).to_cf()?, - F64x2Trunc => self.stack.values.replace_top_same::(|v| Ok(v.trunc())).to_cf()?, - F32x4Abs => self.stack.values.replace_top_same::(|v| Ok(v.abs())).to_cf()?, - F64x2Abs => self.stack.values.replace_top_same::(|v| Ok(v.abs())).to_cf()?, - F32x4Neg => self.stack.values.replace_top_same::(|v| Ok(-v)).to_cf()?, - F64x2Neg => self.stack.values.replace_top_same::(|v| Ok(-v)).to_cf()?, - F32x4Sqrt => self.stack.values.replace_top_same::(|v| Ok(canonicalize_f32x4(v.sqrt()))).to_cf()?, - F64x2Sqrt => self.stack.values.replace_top_same::(|v| Ok(canonicalize_f64x2(v.sqrt()))).to_cf()?, - F32x4Add => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f32x4(a + b))).to_cf()?, - F64x2Add => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a + b))).to_cf()?, - F32x4Sub => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f32x4(a - b))).to_cf()?, - F64x2Sub => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a - b))).to_cf()?, - F32x4Mul => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f32x4(a * b))).to_cf()?, - F64x2Mul => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a * b))).to_cf()?, - F32x4Div => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f32x4(a / b))).to_cf()?, - F64x2Div => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a / b))).to_cf()?, + #[cfg(feature = "__simd")] F32x4Ceil => self.stack.values.replace_top_same::(|v| Ok(v.ceil())).to_cf()?, + #[cfg(feature = "__simd")] F64x2Ceil => self.stack.values.replace_top_same::(|v| Ok(v.ceil())).to_cf()?, + #[cfg(feature = "__simd")] F32x4Floor => self.stack.values.replace_top_same::(|v| Ok(v.floor())).to_cf()?, + #[cfg(feature = "__simd")] F64x2Floor => self.stack.values.replace_top_same::(|v| Ok(v.floor())).to_cf()?, + #[cfg(feature = "__simd")] F32x4Trunc => self.stack.values.replace_top_same::(|v| Ok(v.trunc())).to_cf()?, + #[cfg(feature = "__simd")] F64x2Trunc => self.stack.values.replace_top_same::(|v| Ok(v.trunc())).to_cf()?, + #[cfg(feature = "__simd")] F32x4Abs => self.stack.values.replace_top_same::(|v| Ok(v.abs())).to_cf()?, + #[cfg(feature = "__simd")] F64x2Abs => self.stack.values.replace_top_same::(|v| Ok(v.abs())).to_cf()?, + #[cfg(feature = "__simd")] F32x4Neg => self.stack.values.replace_top_same::(|v| Ok(-v)).to_cf()?, + #[cfg(feature = "__simd")] F64x2Neg => self.stack.values.replace_top_same::(|v| Ok(-v)).to_cf()?, + #[cfg(feature = "__simd")] F32x4Sqrt => self.stack.values.replace_top_same::(|v| Ok(canonicalize_f32x4(v.sqrt()))).to_cf()?, + #[cfg(feature = "__simd")] F64x2Sqrt => self.stack.values.replace_top_same::(|v| Ok(canonicalize_f64x2(v.sqrt()))).to_cf()?, + #[cfg(feature = "__simd")] F32x4Add => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f32x4(a + b))).to_cf()?, + #[cfg(feature = "__simd")] F64x2Add => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a + b))).to_cf()?, + #[cfg(feature = "__simd")] F32x4Sub => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f32x4(a - b))).to_cf()?, + #[cfg(feature = "__simd")] F64x2Sub => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a - b))).to_cf()?, + #[cfg(feature = "__simd")] F32x4Mul => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f32x4(a * b))).to_cf()?, + #[cfg(feature = "__simd")] F64x2Mul => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a * b))).to_cf()?, + #[cfg(feature = "__simd")] F32x4Div => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f32x4(a / b))).to_cf()?, + #[cfg(feature = "__simd")] F64x2Div => self.stack.values.calculate_same::(|a, b| Ok(canonicalize_f64x2(a / b))).to_cf()?, + #[cfg(feature = "__simd")] F32x4Min => self.stack.values.calculate_same::(|a, b| { Ok(Simd::::from_array([ b[0].tw_minimum(a[0]), @@ -592,12 +598,16 @@ impl<'store, 'stack> Executor<'store, 'stack> { b[3].tw_minimum(a[3]), ])) }).to_cf()?, + + #[cfg(feature = "__simd")] F64x2Min => self.stack.values.calculate_same::(|a, b| { Ok(Simd::::from_array([ b[0].tw_minimum(a[0]), b[1].tw_minimum(a[1]), ])) }).to_cf()?, + + #[cfg(feature = "__simd")] F32x4Max => self.stack.values.calculate_same::(|a, b| { Ok(Simd::::from_array([ b[0].tw_maximum(a[0]), @@ -606,6 +616,8 @@ impl<'store, 'stack> Executor<'store, 'stack> { b[3].tw_maximum(a[3]), ])) }).to_cf()?, + + #[cfg(feature = "__simd")] F64x2Max => self.stack.values.calculate_same::(|a, b| { Ok(Simd::::from_array([ b[0].tw_maximum(a[0]), @@ -613,6 +625,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { ])) }).to_cf()?, + #[cfg(feature = "__simd")] F32x4PMin => self.stack.values.calculate_same::(|a, b| { Ok(Simd::::from_array([ if b[0] < a[0] { b[0] } else { a[0]}, @@ -621,6 +634,8 @@ impl<'store, 'stack> Executor<'store, 'stack> { if b[3] < a[3] { b[3] } else { a[3]}, ])) }).to_cf()?, + + #[cfg(feature = "__simd")] F32x4PMax => self.stack.values.calculate_same::(|a, b| { Ok(Simd::::from_array([ if b[0] > a[0] { b[0] } else { a[0]}, @@ -629,12 +644,16 @@ impl<'store, 'stack> Executor<'store, 'stack> { if b[3] > a[3] { b[3] } else { a[3]}, ])) }).to_cf()?, + + #[cfg(feature = "__simd")] F64x2PMin => self.stack.values.calculate_same::(|a, b| { Ok(Simd::::from_array([ if b[0] < a[0] { b[0] } else { a[0]}, if b[1] < a[1] { b[1] } else { a[1]}, ])) }).to_cf()?, + + #[cfg(feature = "__simd")] F64x2PMax => self.stack.values.calculate_same::(|a, b| { Ok(Simd::::from_array([ if b[0] > a[0] { b[0] } else { a[0]}, @@ -643,16 +662,16 @@ impl<'store, 'stack> Executor<'store, 'stack> { }).to_cf()?, // not correct - I32x4TruncSatF32x4S => self.stack.values.replace_top::(|v| Ok(v.trunc())).to_cf()?, - I32x4TruncSatF32x4U => self.stack.values.replace_top::(|v| Ok(v.trunc())).to_cf()?, - F32x4ConvertI32x4S => {}, - F32x4ConvertI32x4U => {}, - F64x2ConvertLowI32x4S => {}, - F64x2ConvertLowI32x4U => {}, - F32x4DemoteF64x2Zero => {}, - F64x2PromoteLowF32x4 => {}, - I32x4TruncSatF64x2SZero => unimplemented!(), - I32x4TruncSatF64x2UZero => unimplemented!(), + #[cfg(feature = "__simd")] I32x4TruncSatF32x4S => self.stack.values.replace_top::(|v| Ok(v.trunc())).to_cf()?, + #[cfg(feature = "__simd")] I32x4TruncSatF32x4U => self.stack.values.replace_top::(|v| Ok(v.trunc())).to_cf()?, + #[cfg(feature = "__simd")] F32x4ConvertI32x4S => {}, + #[cfg(feature = "__simd")] F32x4ConvertI32x4U => {}, + #[cfg(feature = "__simd")] F64x2ConvertLowI32x4S => {}, + #[cfg(feature = "__simd")] F64x2ConvertLowI32x4U => {}, + #[cfg(feature = "__simd")] F32x4DemoteF64x2Zero => {}, + #[cfg(feature = "__simd")] F64x2PromoteLowF32x4 => {}, + #[cfg(feature = "__simd")] I32x4TruncSatF64x2SZero => unimplemented!(), + #[cfg(feature = "__simd")] I32x4TruncSatF64x2UZero => unimplemented!(), i => return ControlFlow::Break(Some(Error::UnsupportedFeature(format!("unimplemented opcode: {i:?}")))), }; @@ -978,6 +997,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { } } + #[cfg(feature = "__simd")] fn exec_mem_load_lane< LOAD: MemLoadable, INTO: InternalValue + IndexMut, @@ -1018,7 +1038,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { false => self.stack.values.pop::() as u32 as u64, }; - let Some(Ok(addr)) = offset.checked_add(addr).map(TryInto::try_into) else { + let Some(Ok(addr)) = offset.checked_add(addr).map(|a| a.try_into()) else { cold(); return ControlFlow::Break(Some(Error::Trap(Trap::MemoryOutOfBounds { offset: addr as usize, @@ -1031,6 +1051,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { ControlFlow::Continue(()) } + #[cfg(feature = "__simd")] fn exec_mem_store_lane, U: MemStorable + Copy, const N: usize>( &mut self, mem_addr: tinywasm_types::MemAddr, diff --git a/crates/tinywasm/src/interpreter/num_helpers.rs b/crates/tinywasm/src/interpreter/num_helpers.rs index bba35cb..678c32e 100644 --- a/crates/tinywasm/src/interpreter/num_helpers.rs +++ b/crates/tinywasm/src/interpreter/num_helpers.rs @@ -184,7 +184,7 @@ macro_rules! impl_checked_wrapping_rem { impl_checked_wrapping_rem! { i32 i64 u32 u64 } -#[cfg(feature = "simd")] +#[cfg(feature = "__simd")] /// replace all NaNs in a f32x4 with f32::NAN pub(crate) fn canonicalize_f32x4(x: core::simd::f32x4) -> core::simd::f32x4 { use core::simd::{Simd, num::SimdFloat}; @@ -193,7 +193,7 @@ pub(crate) fn canonicalize_f32x4(x: core::simd::f32x4) -> core::simd::f32x4 { mask.select(nan, x) } -#[cfg(feature = "simd")] +#[cfg(feature = "__simd")] /// replace all NaNs in a f64x2 with f64::NAN pub(crate) fn canonicalize_f64x2(x: core::simd::f64x2) -> core::simd::f64x2 { use core::simd::{Simd, num::SimdFloat}; diff --git a/crates/tinywasm/src/interpreter/stack/call_stack.rs b/crates/tinywasm/src/interpreter/stack/call_stack.rs index e94e401..c7f02b6 100644 --- a/crates/tinywasm/src/interpreter/stack/call_stack.rs +++ b/crates/tinywasm/src/interpreter/stack/call_stack.rs @@ -71,6 +71,7 @@ impl CallFrame { } #[inline] + #[allow(dead_code)] pub(crate) fn data(&self) -> &WasmFunctionData { &self.func_instance.data } diff --git a/crates/tinywasm/src/interpreter/stack/value_stack.rs b/crates/tinywasm/src/interpreter/stack/value_stack.rs index 01cea1c..481a88c 100644 --- a/crates/tinywasm/src/interpreter/stack/value_stack.rs +++ b/crates/tinywasm/src/interpreter/stack/value_stack.rs @@ -72,6 +72,7 @@ impl ValueStack { } #[inline] + #[allow(dead_code)] pub(crate) fn calculate_same_3(&mut self, func: impl FnOnce(T, T, T) -> Result) -> Result<()> { T::stack_calculate3(self, func) } @@ -88,6 +89,7 @@ impl ValueStack { } #[inline] + #[allow(dead_code)] pub(crate) fn calculate_diff( &mut self, func: impl FnOnce(A, B) -> Result, @@ -191,10 +193,10 @@ impl ValueStack { ValType::RefExtern => WasmValue::RefExtern(ExternRef::new(self.pop())), ValType::RefFunc => WasmValue::RefFunc(FuncRef::new(self.pop())), - #[cfg(not(feature = "simd"))] + #[cfg(not(feature = "__simd"))] ValType::V128 => WasmValue::V128(self.pop()), - #[cfg(feature = "simd")] + #[cfg(feature = "__simd")] ValType::V128 => WasmValue::V128(i128::from_le_bytes(self.pop::().to_array())), } } diff --git a/crates/tinywasm/src/interpreter/values.rs b/crates/tinywasm/src/interpreter/values.rs index 335da59..779fc60 100644 --- a/crates/tinywasm/src/interpreter/values.rs +++ b/crates/tinywasm/src/interpreter/values.rs @@ -7,9 +7,9 @@ pub(crate) type Value32 = u32; pub(crate) type Value64 = u64; pub(crate) type ValueRef = Option; -#[cfg(feature = "simd")] +#[cfg(feature = "__simd")] pub(crate) type Value128 = core::simd::u8x16; -#[cfg(not(feature = "simd"))] +#[cfg(not(feature = "__simd"))] pub(crate) type Value128 = i128; #[derive(Debug, Clone, Copy, PartialEq)] @@ -113,10 +113,10 @@ impl TinyWasmValue { ValType::RefExtern => WasmValue::RefExtern(ExternRef::new(self.unwrap_ref())), ValType::RefFunc => WasmValue::RefFunc(FuncRef::new(self.unwrap_ref())), - #[cfg(feature = "simd")] + #[cfg(feature = "__simd")] ValType::V128 => WasmValue::V128(i128::from_le_bytes(self.unwrap_128().to_array())), - #[cfg(not(feature = "simd"))] + #[cfg(not(feature = "__simd"))] ValType::V128 => WasmValue::V128(self.unwrap_128()), } } @@ -132,10 +132,10 @@ impl From<&WasmValue> for TinyWasmValue { WasmValue::RefExtern(v) => TinyWasmValue::ValueRef(v.addr()), WasmValue::RefFunc(v) => TinyWasmValue::ValueRef(v.addr()), - #[cfg(not(feature = "simd"))] + #[cfg(not(feature = "__simd"))] WasmValue::V128(v) => TinyWasmValue::Value128(*v), - #[cfg(feature = "simd")] + #[cfg(feature = "__simd")] WasmValue::V128(v) => TinyWasmValue::Value128(v.to_le_bytes().into()), } } @@ -160,6 +160,7 @@ pub(crate) trait InternalValue: sealed::Sealed + Into { fn stack_calculate(stack: &mut ValueStack, func: impl FnOnce(Self, Self) -> Result) -> Result<()> where Self: Sized; + #[allow(dead_code)] fn stack_calculate3(stack: &mut ValueStack, func: impl FnOnce(Self, Self, Self) -> Result) -> Result<()> where Self: Sized; @@ -273,10 +274,10 @@ impl_internalvalue! { Value128, stack_128, locals_128, Value128, Value128, |v| v, |v| v } -#[cfg(feature = "simd")] +#[cfg(feature = "__simd")] use core::simd::{num::SimdUint, *}; -#[cfg(feature = "simd")] +#[cfg(feature = "__simd")] impl_internalvalue! { Value128, stack_128, locals_128, u8x16, i128, |v: i128| v.to_le_bytes().into(), |v: u8x16| i128::from_le_bytes(v.into()) Value128, stack_128, locals_128, u8x16, u128, |v: u128| v.to_le_bytes().into(), |v: u8x16| u128::from_le_bytes(v.into()) diff --git a/crates/tinywasm/src/lib.rs b/crates/tinywasm/src/lib.rs index 72c38cd..9cb6c0a 100644 --- a/crates/tinywasm/src/lib.rs +++ b/crates/tinywasm/src/lib.rs @@ -5,7 +5,7 @@ ))] #![warn(missing_docs, missing_debug_implementations, rust_2018_idioms, unreachable_pub)] #![forbid(unsafe_code)] -#![cfg_attr(feature = "simd", feature(portable_simd))] +#![cfg_attr(feature = "__simd", feature(portable_simd))] //! A tiny WebAssembly Runtime written in Rust //! diff --git a/crates/tinywasm/src/store/memory.rs b/crates/tinywasm/src/store/memory.rs index df3d49e..7abd7b9 100644 --- a/crates/tinywasm/src/store/memory.rs +++ b/crates/tinywasm/src/store/memory.rs @@ -4,7 +4,7 @@ use tinywasm_types::{MemoryArch, MemoryType, ModuleInstanceAddr}; use crate::{Error, Result, cold, interpreter::Value128, log}; -#[cfg(feature = "simd")] +#[cfg(feature = "__simd")] use core::simd::ToBytes; /// A WebAssembly Memory Instance @@ -189,7 +189,7 @@ macro_rules! impl_mem_traits { impl_mem_traits!(u8, 1, i8, 1, u16, 2, i16, 2, u32, 4, i32, 4, f32, 4, u64, 8, i64, 8, f64, 8, Value128, 16); -#[cfg(feature = "simd")] +#[cfg(feature = "__simd")] impl_mem_traits!( core::simd::i8x16, 16, diff --git a/crates/tinywasm/tests/generated/wasm-1.csv b/crates/tinywasm/tests/generated/wasm-1.csv index d403e3b..ebb511b 100644 --- a/crates/tinywasm/tests/generated/wasm-1.csv +++ b/crates/tinywasm/tests/generated/wasm-1.csv @@ -5,4 +5,4 @@ 0.6.1,27572,335,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.7.0,27572,335,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.8.0,20360,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":128,"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":98,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_grow.wast","passed":104,"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.9.0-alpha.0,19243,0,[{"name":"address.wast","passed":243,"failed":0},{"name":"align.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":79,"failed":0},{"name":"binary.wast","passed":67,"failed":0},{"name":"block.wast","passed":171,"failed":0},{"name":"br.wast","passed":84,"failed":0},{"name":"br_if.wast","passed":118,"failed":0},{"name":"br_table.wast","passed":168,"failed":0},{"name":"break-drop.wast","passed":4,"failed":0},{"name":"call.wast","passed":82,"failed":0},{"name":"call_indirect.wast","passed":152,"failed":0},{"name":"comments.wast","passed":4,"failed":0},{"name":"const.wast","passed":668,"failed":0},{"name":"conversions.wast","passed":435,"failed":0},{"name":"custom.wast","passed":10,"failed":0},{"name":"data.wast","passed":45,"failed":0},{"name":"elem.wast","passed":55,"failed":0},{"name":"endianness.wast","passed":69,"failed":0},{"name":"exports.wast","passed":82,"failed":0},{"name":"f32.wast","passed":2512,"failed":0},{"name":"f32_bitwise.wast","passed":364,"failed":0},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":2512,"failed":0},{"name":"f64_bitwise.wast","passed":364,"failed":0},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":7,"failed":0},{"name":"float_exprs.wast","passed":900,"failed":0},{"name":"float_literals.wast","passed":161,"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":121,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"globals.wast","passed":78,"failed":0},{"name":"i32.wast","passed":443,"failed":0},{"name":"i64.wast","passed":389,"failed":0},{"name":"if.wast","passed":151,"failed":0},{"name":"imports.wast","passed":146,"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":116,"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":81,"failed":0},{"name":"memory.wast","passed":71,"failed":0},{"name":"memory_grow.wast","passed":94,"failed":0},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":42,"failed":0},{"name":"memory_trap.wast","passed":173,"failed":0},{"name":"names.wast","passed":483,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":111,"failed":0},{"name":"skip-stack-guard-page.wast","passed":11,"failed":0},{"name":"stack.wast","passed":5,"failed":0},{"name":"start.wast","passed":19,"failed":0},{"name":"store.wast","passed":68,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"token.wast","passed":2,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":62,"failed":0},{"name":"unreached-invalid.wast","passed":110,"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.9.0-alpha.0,19241,0,[{"name":"address.wast","passed":243,"failed":0},{"name":"align.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":77,"failed":0},{"name":"binary.wast","passed":67,"failed":0},{"name":"block.wast","passed":171,"failed":0},{"name":"br.wast","passed":84,"failed":0},{"name":"br_if.wast","passed":118,"failed":0},{"name":"br_table.wast","passed":168,"failed":0},{"name":"break-drop.wast","passed":4,"failed":0},{"name":"call.wast","passed":82,"failed":0},{"name":"call_indirect.wast","passed":152,"failed":0},{"name":"comments.wast","passed":4,"failed":0},{"name":"const.wast","passed":668,"failed":0},{"name":"conversions.wast","passed":435,"failed":0},{"name":"custom.wast","passed":10,"failed":0},{"name":"data.wast","passed":45,"failed":0},{"name":"elem.wast","passed":55,"failed":0},{"name":"endianness.wast","passed":69,"failed":0},{"name":"exports.wast","passed":82,"failed":0},{"name":"f32.wast","passed":2512,"failed":0},{"name":"f32_bitwise.wast","passed":364,"failed":0},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":2512,"failed":0},{"name":"f64_bitwise.wast","passed":364,"failed":0},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":7,"failed":0},{"name":"float_exprs.wast","passed":900,"failed":0},{"name":"float_literals.wast","passed":161,"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":121,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"globals.wast","passed":78,"failed":0},{"name":"i32.wast","passed":443,"failed":0},{"name":"i64.wast","passed":389,"failed":0},{"name":"if.wast","passed":151,"failed":0},{"name":"imports.wast","passed":146,"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":116,"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":81,"failed":0},{"name":"memory.wast","passed":71,"failed":0},{"name":"memory_grow.wast","passed":94,"failed":0},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":42,"failed":0},{"name":"memory_trap.wast","passed":173,"failed":0},{"name":"names.wast","passed":483,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":111,"failed":0},{"name":"skip-stack-guard-page.wast","passed":11,"failed":0},{"name":"stack.wast","passed":5,"failed":0},{"name":"start.wast","passed":19,"failed":0},{"name":"store.wast","passed":68,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"token.wast","passed":2,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":62,"failed":0},{"name":"unreached-invalid.wast","passed":110,"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/wasm-2.csv b/crates/tinywasm/tests/generated/wasm-2.csv index b0949ec..8e228b4 100644 --- a/crates/tinywasm/tests/generated/wasm-2.csv +++ b/crates/tinywasm/tests/generated/wasm-2.csv @@ -10,4 +10,4 @@ 0.6.1,20278,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.7.0,20278,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"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":98,"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":179,"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.8.0,28008,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":128,"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":117,"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":98,"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":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"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":178,"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":88,"failed":0},{"name":"memory_copy.wast","passed":4450,"failed":0},{"name":"memory_fill.wast","passed":100,"failed":0},{"name":"memory_grow.wast","passed":104,"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":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":16,"failed":0},{"name":"ref_null.wast","passed":3,"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-sub.wast","passed":2,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"table_copy.wast","passed":1728,"failed":0},{"name":"table_fill.wast","passed":45,"failed":0},{"name":"table_get.wast","passed":16,"failed":0},{"name":"table_grow.wast","passed":58,"failed":0},{"name":"table_init.wast","passed":780,"failed":0},{"name":"table_set.wast","passed":26,"failed":0},{"name":"table_size.wast","passed":39,"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.9.0-alpha.0,27826,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":81,"failed":0},{"name":"binary.wast","passed":162,"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":117,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":169,"failed":0},{"name":"comments.wast","passed":4,"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":58,"failed":0},{"name":"elem.wast","passed":74,"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":161,"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":108,"failed":0},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":239,"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":17,"failed":0},{"name":"ref_is_null.wast","passed":16,"failed":0},{"name":"ref_null.wast","passed":3,"failed":0},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":147,"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":1728,"failed":0},{"name":"table_fill.wast","passed":45,"failed":0},{"name":"table_get.wast","passed":16,"failed":0},{"name":"table_grow.wast","passed":50,"failed":0},{"name":"table_init.wast","passed":780,"failed":0},{"name":"table_set.wast","passed":26,"failed":0},{"name":"table_size.wast","passed":39,"failed":0},{"name":"token.wast","passed":2,"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":6,"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.9.0-alpha.0,27822,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":79,"failed":0},{"name":"binary.wast","passed":160,"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":117,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":169,"failed":0},{"name":"comments.wast","passed":4,"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":58,"failed":0},{"name":"elem.wast","passed":74,"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":161,"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":108,"failed":0},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":239,"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":17,"failed":0},{"name":"ref_is_null.wast","passed":16,"failed":0},{"name":"ref_null.wast","passed":3,"failed":0},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":147,"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":1728,"failed":0},{"name":"table_fill.wast","passed":45,"failed":0},{"name":"table_get.wast","passed":16,"failed":0},{"name":"table_grow.wast","passed":50,"failed":0},{"name":"table_init.wast","passed":780,"failed":0},{"name":"table_set.wast","passed":26,"failed":0},{"name":"table_size.wast","passed":39,"failed":0},{"name":"token.wast","passed":2,"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":6,"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/wasm-multi-memory.csv b/crates/tinywasm/tests/generated/wasm-multi-memory.csv index ae9ba03..33debd6 100644 --- a/crates/tinywasm/tests/generated/wasm-multi-memory.csv +++ b/crates/tinywasm/tests/generated/wasm-multi-memory.csv @@ -1,2 +1,2 @@ 0.8.0,1872,0,[{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"align.wast","passed":160,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"binary.wast","passed":126,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"imports.wast","passed":175,"failed":0},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"multi-memory/simd_memory-multi.wast (skipped)","passed":0,"failed":0},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"traps0.wast","passed":15,"failed":0}] -0.9.0-alpha.0,1872,0,[{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"align.wast","passed":160,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"binary.wast","passed":126,"failed":0},{"name":"binary0.wast","passed":7,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"imports.wast","passed":175,"failed":0},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"simd_memory-multi.wast (skipped)","passed":0,"failed":0},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"traps0.wast","passed":15,"failed":0}] +0.9.0-alpha.0,1871,0,[{"name":"address0.wast","passed":92,"failed":0},{"name":"address1.wast","passed":127,"failed":0},{"name":"align.wast","passed":160,"failed":0},{"name":"align0.wast","passed":5,"failed":0},{"name":"binary.wast","passed":126,"failed":0},{"name":"binary0.wast","passed":6,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"data0.wast","passed":7,"failed":0},{"name":"data1.wast","passed":14,"failed":0},{"name":"data_drop0.wast","passed":11,"failed":0},{"name":"exports0.wast","passed":8,"failed":0},{"name":"float_exprs0.wast","passed":14,"failed":0},{"name":"float_exprs1.wast","passed":3,"failed":0},{"name":"float_memory0.wast","passed":30,"failed":0},{"name":"imports.wast","passed":175,"failed":0},{"name":"imports0.wast","passed":8,"failed":0},{"name":"imports1.wast","passed":5,"failed":0},{"name":"imports2.wast","passed":20,"failed":0},{"name":"imports3.wast","passed":10,"failed":0},{"name":"imports4.wast","passed":16,"failed":0},{"name":"linking0.wast","passed":6,"failed":0},{"name":"linking1.wast","passed":14,"failed":0},{"name":"linking2.wast","passed":11,"failed":0},{"name":"linking3.wast","passed":14,"failed":0},{"name":"load.wast","passed":118,"failed":0},{"name":"load0.wast","passed":3,"failed":0},{"name":"load1.wast","passed":18,"failed":0},{"name":"load2.wast","passed":38,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":86,"failed":0},{"name":"memory_copy0.wast","passed":29,"failed":0},{"name":"memory_copy1.wast","passed":14,"failed":0},{"name":"memory_fill0.wast","passed":16,"failed":0},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_init0.wast","passed":13,"failed":0},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_size0.wast","passed":8,"failed":0},{"name":"memory_size1.wast","passed":15,"failed":0},{"name":"memory_size2.wast","passed":21,"failed":0},{"name":"memory_size3.wast","passed":2,"failed":0},{"name":"memory_trap0.wast","passed":14,"failed":0},{"name":"memory_trap1.wast","passed":168,"failed":0},{"name":"simd_memory-multi.wast (skipped)","passed":0,"failed":0},{"name":"start0.wast","passed":9,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"store0.wast","passed":5,"failed":0},{"name":"store1.wast","passed":13,"failed":0},{"name":"traps0.wast","passed":15,"failed":0}] diff --git a/crates/types/src/instructions.rs b/crates/types/src/instructions.rs index bf4f6fb..9db5ed5 100644 --- a/crates/types/src/instructions.rs +++ b/crates/types/src/instructions.rs @@ -4,7 +4,6 @@ use crate::{ConstIdx, DataAddr, ElemAddr, ExternAddr, MemAddr}; /// Represents a memory immediate in a WebAssembly memory instruction. #[derive(Debug, Copy, Clone, PartialEq)] #[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] - pub struct MemoryArg([u8; 12]); impl MemoryArg { From e1b76386b7e323054d5e8844366ebad86bba693e Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sat, 26 Apr 2025 17:43:23 +0200 Subject: [PATCH 54/54] feat: add canonicalize_nans feature Signed-off-by: Henry Gressmann --- CHANGELOG.md | 3 ++ Cargo.lock | 20 ++++++------- crates/tinywasm/Cargo.toml | 10 ++++++- .../tinywasm/src/interpreter/num_helpers.rs | 29 ++++++++++++++++--- 4 files changed, 47 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e63ff2b..8c47dea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for the custom memory page sizes proposal ([#22](https://github.com/explodingcamera/tinywasm/pull/22) by [@danielstuart14](https://github.com/danielstuart14)) - Support for the `tail_call` proposal +- Support for the `memory64` proposal +- Groundwork for the `simd` proposal +- New `canonicalize_nans` feature flag to enable canonicalizing NaN values in the `f32`, `f64`, and `v128` types ### Breaking Changes diff --git a/Cargo.lock b/Cargo.lock index acdc41b..f194530 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -114,18 +114,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.36" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2df961d8c8a0d08aa9945718ccf584145eee3f3aa06cddbeac12933781102e04" +checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.36" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "132dbda40fb6753878316a489d5a1242a8ef2f0d9e47ba01c951ea8aa7d013a5" +checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2" dependencies = [ "anstyle", "clap_lex", @@ -353,15 +353,15 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.171" +version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libm" -version = "0.2.11" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" +checksum = "c9627da5196e5d8ed0b0495e61e518847578da83483c37288316d9b2e03a7f72" [[package]] name = "log" @@ -426,9 +426,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index 3281476..10a3099 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -32,12 +32,20 @@ serde_json={version="1.0"} serde={version="1.0", features=["derive"]} [features] -default=["std", "parser", "logging", "archive"] +default=["std", "parser", "logging", "archive", "canonicalize_nans"] + logging=["log", "tinywasm-parser?/logging", "tinywasm-types/logging"] std=["tinywasm-parser?/std", "tinywasm-types/std"] + +# support for parsing WebAssembly parser=["dep:tinywasm-parser"] + +# support for "archiving" tinywasm bytecode archive=["tinywasm-types/archive"] +# canonicalize all NaN values to a single representation +canonicalize_nans=[] + # enable simd support (unstable / unfinished) __simd=[] diff --git a/crates/tinywasm/src/interpreter/num_helpers.rs b/crates/tinywasm/src/interpreter/num_helpers.rs index 678c32e..7e8a461 100644 --- a/crates/tinywasm/src/interpreter/num_helpers.rs +++ b/crates/tinywasm/src/interpreter/num_helpers.rs @@ -72,9 +72,12 @@ macro_rules! impl_wasm_float_ops { ($($t:ty)*) => ($( impl TinywasmFloatExt for $t { // https://webassembly.github.io/spec/core/exec/numerics.html#op-fnearest + #[inline] fn tw_nearest(self) -> Self { match self { - // x if x.is_nan() => x, // preserve NaN + #[cfg(not(feature = "canonicalize_nans"))] + x if x.is_nan() => x, // preserve NaN + #[cfg(feature = "canonicalize_nans")] x if x.is_nan() => Self::NAN, // Do not preserve NaN x if x.is_infinite() || x == 0.0 => x, // preserve infinities and zeros x if (0.0..=0.5).contains(&x) => 0.0, @@ -100,7 +103,9 @@ macro_rules! impl_wasm_float_ops { Some(core::cmp::Ordering::Less) => self, Some(core::cmp::Ordering::Greater) => other, Some(core::cmp::Ordering::Equal) => if self.is_sign_negative() && other.is_sign_positive() { self } else { other }, - // None => self + other, // At least one input is NaN. Use `+` to perform NaN propagation and quieting. + #[cfg(not(feature = "canonicalize_nans"))] + None => self + other, // At least one input is NaN. Use `+` to perform NaN propagation and quieting. + #[cfg(feature = "canonicalize_nans")] None => Self::NAN, // Do not preserve NaN } } @@ -113,7 +118,9 @@ macro_rules! impl_wasm_float_ops { Some(core::cmp::Ordering::Greater) => self, Some(core::cmp::Ordering::Less) => other, Some(core::cmp::Ordering::Equal) => if self.is_sign_negative() && other.is_sign_positive() { other } else { self }, - // None => self + other, // At least one input is NaN. Use `+` to perform NaN propagation and quieting. + #[cfg(not(feature = "canonicalize_nans"))] + None => self + other, // At least one input is NaN. Use `+` to perform NaN propagation and quieting. + #[cfg(feature = "canonicalize_nans")] None => Self::NAN, // Do not preserve NaN } } @@ -184,8 +191,15 @@ macro_rules! impl_checked_wrapping_rem { impl_checked_wrapping_rem! { i32 i64 u32 u64 } -#[cfg(feature = "__simd")] +#[cfg(all(feature = "__simd", not(feature = "canonicalize_nans")))] +#[inline] +pub(crate) fn canonicalize_f32x4(x: core::simd::f32x4) -> core::simd::f32x4 { + x // No need to do anything, as we are not replacing NaNs +} + +#[cfg(all(feature = "__simd", feature = "canonicalize_nans"))] /// replace all NaNs in a f32x4 with f32::NAN +#[inline] pub(crate) fn canonicalize_f32x4(x: core::simd::f32x4) -> core::simd::f32x4 { use core::simd::{Simd, num::SimdFloat}; let nan = Simd::splat(f32::NAN); @@ -193,8 +207,15 @@ pub(crate) fn canonicalize_f32x4(x: core::simd::f32x4) -> core::simd::f32x4 { mask.select(nan, x) } +#[cfg(all(feature = "__simd", not(feature = "canonicalize_nans")))] +#[inline] +pub(crate) fn canonicalize_f64x2(x: core::simd::f64x2) -> core::simd::f64x2 { + x // No need to do anything, as we are not replacing NaNs +} + #[cfg(feature = "__simd")] /// replace all NaNs in a f64x2 with f64::NAN +#[inline] pub(crate) fn canonicalize_f64x2(x: core::simd::f64x2) -> core::simd::f64x2 { use core::simd::{Simd, num::SimdFloat}; let nan = Simd::splat(f64::NAN);