From 1041182f6ed3376eb62f4269c41cb16a47ab8ad0 Mon Sep 17 00:00:00 2001 From: Henry Date: Wed, 27 Dec 2023 22:45:02 +0100 Subject: [PATCH 01/31] chore: bump version Signed-off-by: Henry --- Cargo.lock | 8 ++--- Cargo.toml | 2 +- crates/cli/Cargo.toml | 2 +- crates/parser/Cargo.toml | 2 +- crates/tinywasm/Cargo.toml | 4 +-- crates/tinywasm/tests/generated/mvp.csv | 3 +- .../tinywasm/tests/generated/progress-mvp.svg | 31 +++++++++++-------- 7 files changed, 29 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index acee43d..3b17097 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1233,7 +1233,7 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tinywasm" -version = "0.1.0" +version = "0.2.0-alpha.0" dependencies = [ "eyre", "log", @@ -1250,7 +1250,7 @@ dependencies = [ [[package]] name = "tinywasm-cli" -version = "0.1.0" +version = "0.2.0-alpha.0" dependencies = [ "argh", "color-eyre", @@ -1262,7 +1262,7 @@ dependencies = [ [[package]] name = "tinywasm-parser" -version = "0.1.0" +version = "0.2.0-alpha.0" dependencies = [ "log", "tinywasm-types", @@ -1271,7 +1271,7 @@ dependencies = [ [[package]] name = "tinywasm-types" -version = "0.1.0" +version = "0.2.0-alpha.0" dependencies = [ "log", "rkyv", diff --git a/Cargo.toml b/Cargo.toml index bf078c5..ae4fd11 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ default-members=["crates/cli"] resolver="2" [workspace.package] -version="0.1.0" +version="0.2.0-alpha.0" edition="2021" license="MIT OR Apache-2.0" authors=["Henry Gressmann "] diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 1a23d16..571dfc0 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -14,7 +14,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.1.0", path="../tinywasm", features=["std", "parser"]} +tinywasm={version="0.2.0-alpha.0", path="../tinywasm", features=["std", "parser"]} argh="0.1" color-eyre={version="0.6", default-features=false} log="0.4" diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index 29908b6..1bd4ea3 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -12,7 +12,7 @@ repository.workspace=true # TODO: create dependency free parser wasmparser={version="0.100", package="wasmparser-nostd", default-features=false} log={version="0.4", optional=true} -tinywasm-types={version="0.1.0", path="../types"} +tinywasm-types={version="0.2.0-alpha.0", path="../types"} [features] default=["std", "logging"] diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index 3f97364..d04a227 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -14,8 +14,8 @@ path="src/lib.rs" [dependencies] log={version="0.4", optional=true} -tinywasm-parser={version="0.1.0", path="../parser", default-features=false, optional=true} -tinywasm-types={version="0.1.0", path="../types", default-features=false} +tinywasm-parser={version="0.2.0-alpha.0", path="../parser", default-features=false, optional=true} +tinywasm-types={version="0.2.0-alpha.0", path="../types", default-features=false} [dev-dependencies] wasm-testsuite={path="../wasm-testsuite"} diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index c18acc5..9bb7d0a 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -1,4 +1,5 @@ 0.0.3,9258,7567,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.4,9258,10909,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"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.0.6-alpha.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index 331b0f8..c482202 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -36,24 +36,29 @@ TinyWasm Version - + v0.0.3 (9258) - - + + v0.0.4 (9258) - - + + v0.0.5 (11135) - - -v0.0.6-alpha.0 (17630) + + +v0.1.0 (17630) - - - - - + + +v0.2.0-alpha.0 (17630) + + + + + + + From 28b8a556b51aecf9eaed92c1fc3e648e4efe7572 Mon Sep 17 00:00:00 2001 From: Henry Date: Thu, 28 Dec 2023 16:47:35 +0100 Subject: [PATCH 02/31] chore: add ref instructions Signed-off-by: Henry --- crates/parser/src/conversion.rs | 17 ++++++++++++----- crates/tinywasm/tests/generated/mvp.csv | 2 +- .../tinywasm/tests/generated/progress-mvp.svg | 4 ++-- crates/tinywasm/tests/test-mvp.rs | 2 +- crates/types/src/instructions.rs | 13 +++++++++++-- 5 files changed, 27 insertions(+), 11 deletions(-) diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs index b962ff4..1b22af8 100644 --- a/crates/parser/src/conversion.rs +++ b/crates/parser/src/conversion.rs @@ -296,6 +296,9 @@ pub(crate) fn process_const_operators(ops: OperatorsReader) -> Result Result { match op { + wasmparser::Operator::RefNull { ty } => Ok(ConstInstruction::RefNull(convert_valtype(&ty))), + wasmparser::Operator::RefFunc { function_index } => Ok(ConstInstruction::RefFunc(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()))), // TODO: check if this is correct @@ -414,12 +417,15 @@ pub fn process_operators<'a>( LocalTee { local_index } => Instruction::LocalTee(local_index), GlobalGet { global_index } => Instruction::GlobalGet(global_index), GlobalSet { global_index } => Instruction::GlobalSet(global_index), - MemorySize { .. } => Instruction::MemorySize, - MemoryGrow { .. } => Instruction::MemoryGrow, + MemorySize { mem, mem_byte } => Instruction::MemorySize(mem, mem_byte), + MemoryGrow { mem, mem_byte } => Instruction::MemoryGrow(mem, mem_byte), I32Const { value } => Instruction::I32Const(value), I64Const { value } => Instruction::I64Const(value), - F32Const { value } => Instruction::F32Const(f32::from_bits(value.bits())), // TODO: check if this is correct - F64Const { value } => Instruction::F64Const(f64::from_bits(value.bits())), // TODO: check if this is correct + F32Const { value } => Instruction::F32Const(f32::from_bits(value.bits())), + F64Const { value } => Instruction::F64Const(f64::from_bits(value.bits())), + RefNull { ty } => Instruction::RefNull(convert_valtype(&ty)), + RefIsNull => Instruction::RefIsNull, + RefFunc { function_index } => Instruction::RefFunc(function_index), I32Load { memarg } => Instruction::I32Load(convert_memarg(memarg)), I64Load { memarg } => Instruction::I64Load(convert_memarg(memarg)), F32Load { memarg } => Instruction::F32Load(convert_memarg(memarg)), @@ -580,10 +586,11 @@ pub fn process_operators<'a>( I64TruncSatF64S => Instruction::I64TruncSatF64S, I64TruncSatF64U => Instruction::I64TruncSatF64U, op => { + log::error!("Unsupported instruction: {:?}", op); return Err(crate::ParseError::UnsupportedOperator(format!( "Unsupported instruction: {:?}", op - ))) + ))); } }; diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index 9bb7d0a..275de67 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -2,4 +2,4 @@ 0.0.4,9258,10909,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"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.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17639,2589,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":55,"failed":44},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":52,"failed":58},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":22,"failed":110},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index c482202..8d954a1 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -53,12 +53,12 @@ v0.1.0 (17630) -v0.2.0-alpha.0 (17630) +v0.2.0-alpha.0 (17639) + - diff --git a/crates/tinywasm/tests/test-mvp.rs b/crates/tinywasm/tests/test-mvp.rs index fdd043d..cc04a3c 100644 --- a/crates/tinywasm/tests/test-mvp.rs +++ b/crates/tinywasm/tests/test-mvp.rs @@ -8,7 +8,7 @@ fn main() -> Result<()> { fn test_mvp() -> Result<()> { let mut test_suite = TestSuite::new(); - + TestSuite::set_log_level(log::LevelFilter::Off); test_suite.run_spec_group(wasm_testsuite::MVP_TESTS)?; test_suite.save_csv("./tests/generated/mvp.csv", env!("CARGO_PKG_VERSION"))?; diff --git a/crates/types/src/instructions.rs b/crates/types/src/instructions.rs index 95fddc5..535b727 100644 --- a/crates/types/src/instructions.rs +++ b/crates/types/src/instructions.rs @@ -1,3 +1,5 @@ +use crate::MemAddr; + use super::{FuncAddr, GlobalAddr, LabelAddr, LocalAddr, TableAddr, TypeAddr, ValType}; #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -26,6 +28,8 @@ pub enum ConstInstruction { F32Const(f32), F64Const(f64), GlobalGet(GlobalAddr), + RefNull(ValType), + RefFunc(FuncAddr), } /// A WebAssembly Instruction @@ -99,8 +103,8 @@ pub enum Instruction { I64Store8(MemArg), I64Store16(MemArg), I64Store32(MemArg), - MemorySize, - MemoryGrow, + MemorySize(MemAddr, u8), + MemoryGrow(MemAddr, u8), // Constants I32Const(i32), @@ -108,6 +112,11 @@ pub enum Instruction { F32Const(f32), F64Const(f64), + // Reference Types + RefNull(ValType), + RefFunc(FuncAddr), + RefIsNull, + // Numeric Instructions // See I32Eqz, From ba5e8d584fc608547d5fb3195d37142bae181a57 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Thu, 4 Jan 2024 13:21:56 +0100 Subject: [PATCH 03/31] test: improve test reporting Signed-off-by: Henry Gressmann --- crates/tinywasm/tests/generated/mvp.csv | 2 +- .../tinywasm/tests/generated/progress-mvp.svg | 4 +- crates/tinywasm/tests/test-mvp.rs | 9 +- crates/tinywasm/tests/test-wast.rs | 8 +- crates/tinywasm/tests/testsuite/mod.rs | 43 +++++++--- crates/tinywasm/tests/testsuite/run.rs | 83 ++++++++++--------- 6 files changed, 92 insertions(+), 57 deletions(-) diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index 275de67..b9cbcb4 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -2,4 +2,4 @@ 0.0.4,9258,10909,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"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.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17639,2589,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":55,"failed":44},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":52,"failed":58},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":22,"failed":110},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17639,2580,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":55,"failed":44},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":2},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":52,"failed":58},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":22,"failed":103},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index 8d954a1..48bd29f 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -56,9 +56,9 @@ v0.1.0 (17630) v0.2.0-alpha.0 (17639) - - + + diff --git a/crates/tinywasm/tests/test-mvp.rs b/crates/tinywasm/tests/test-mvp.rs index cc04a3c..0e5b02f 100644 --- a/crates/tinywasm/tests/test-mvp.rs +++ b/crates/tinywasm/tests/test-mvp.rs @@ -1,5 +1,6 @@ mod testsuite; use eyre::{eyre, Result}; +use owo_colors::OwoColorize; use testsuite::TestSuite; fn main() -> Result<()> { @@ -13,8 +14,12 @@ fn test_mvp() -> Result<()> { test_suite.save_csv("./tests/generated/mvp.csv", env!("CARGO_PKG_VERSION"))?; if test_suite.failed() { - eprintln!("\n\nfailed one or more tests:\n{:#?}", test_suite); - Err(eyre!("failed one or more tests")) + 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-wast.rs b/crates/tinywasm/tests/test-wast.rs index 68372a0..1efa85d 100644 --- a/crates/tinywasm/tests/test-wast.rs +++ b/crates/tinywasm/tests/test-wast.rs @@ -1,6 +1,7 @@ use std::path::PathBuf; -use eyre::{bail, Result}; +use eyre::{bail, eyre, Result}; +use owo_colors::OwoColorize; use testsuite::TestSuite; mod testsuite; @@ -40,9 +41,10 @@ fn test_wast(wast_file: &str) -> Result<()> { test_suite.run_paths(&[wast_file])?; if test_suite.failed() { - eprintln!("\n\nfailed one or more tests:\n{:#?}", test_suite); + println!(); test_suite.print_errors(); - bail!("failed one or more tests") + println!(); + Err(eyre!(format!("{}", "failed one or more tests".red().bold()))) } else { println!("\n\npassed all tests:\n{:#?}", test_suite); Ok(()) diff --git a/crates/tinywasm/tests/testsuite/mod.rs b/crates/tinywasm/tests/testsuite/mod.rs index fd3e39f..cfbe882 100644 --- a/crates/tinywasm/tests/testsuite/mod.rs +++ b/crates/tinywasm/tests/testsuite/mod.rs @@ -1,6 +1,7 @@ #![allow(dead_code)] // rust analyzer doesn't recognize that code is used by tests without harness use eyre::Result; +use owo_colors::OwoColorize; use std::io::{BufRead, Seek, SeekFrom}; use std::{ collections::BTreeMap, @@ -20,6 +21,10 @@ pub struct TestGroupResult { pub failed: usize, } +fn format_linecol(linecol: (usize, usize)) -> String { + format!("{}:{}", linecol.0 + 1, linecol.1 + 1) +} + pub struct TestSuite(BTreeMap); impl TestSuite { @@ -31,7 +36,15 @@ impl TestSuite { for (group_name, group) in &self.0 { for (test_name, test) in &group.tests { if let Err(e) = &test.result { - eprintln!("{}: {} failed: {:?}", group_name, test_name, e); + eprintln!( + "{} {} failed: {:?}", + link( + format!("{}:{}", group_name.red().underline(), test.linecol.0 + 1).as_str(), + format!("{}:{}", group.file, test.linecol.0 + 1).as_str() + ), + test_name.bold(), + e.to_string().bright_red() + ); } } } @@ -45,8 +58,8 @@ impl TestSuite { self.0.values().any(|group| group.stats().1 > 0) } - fn test_group(&mut self, name: &str) -> &mut TestGroup { - self.0.entry(name.to_string()).or_insert_with(TestGroup::new) + fn test_group(&mut self, name: &str, file: &str) -> &mut TestGroup { + self.0.entry(name.to_string()).or_insert_with(|| TestGroup::new(file)) } // create or add to a test result file @@ -93,9 +106,12 @@ impl TestSuite { } } +fn link(name: &str, file: &str) -> String { + format!("\x1b]8;;file://{}\x1b\\{}\x1b]8;;\x1b\\", file, name) +} + impl Debug for TestSuite { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - use owo_colors::OwoColorize; let mut total_passed = 0; let mut total_failed = 0; @@ -104,7 +120,7 @@ impl Debug for TestSuite { total_passed += group_passed; total_failed += group_failed; - writeln!(f, "{}", group_name.bold().underline())?; + writeln!(f, "{}", link(group_name, &group.file).bold().underline())?; writeln!(f, " Tests Passed: {}", group_passed.to_string().green())?; writeln!(f, " Tests Failed: {}", group_failed.to_string().red())?; @@ -133,14 +149,20 @@ impl Debug for TestSuite { struct TestGroup { tests: BTreeMap, + file: String, } impl TestGroup { - fn new() -> Self { - Self { tests: BTreeMap::new() } + fn new(file: &str) -> Self { + Self { + tests: BTreeMap::new(), + file: file.to_string(), + } } fn stats(&self) -> (usize, usize) { + log::error!("stats: {:?}", self.tests); + let mut passed_count = 0; let mut failed_count = 0; @@ -154,12 +176,13 @@ impl TestGroup { (passed_count, failed_count) } - fn add_result(&mut self, name: &str, span: wast::token::Span, result: Result<()>) { - self.tests.insert(name.to_string(), TestCase { result, _span: span }); + fn add_result(&mut self, name: &str, linecol: (usize, usize), result: Result<()>) { + self.tests.insert(name.to_string(), TestCase { result, linecol }); } } +#[derive(Debug)] struct TestCase { result: Result<()>, - _span: wast::token::Span, + linecol: (usize, usize), } diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index fc3d7bc..1473b17 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -12,7 +12,6 @@ impl TestSuite { tests.iter().for_each(|group| { let group_wast = std::fs::read(group).expect("failed to read test wast"); let group_wast = Cow::Owned(group_wast); - debug!("running group: {}", group); self.run_group(group, group_wast).expect("failed to run group"); }); @@ -29,7 +28,8 @@ impl TestSuite { } pub fn run_group(&mut self, group_name: &str, group_wast: Cow<'_, [u8]>) -> Result<()> { - let test_group = self.test_group(group_name); + 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); @@ -46,8 +46,6 @@ impl TestSuite { use wast::WastDirective::*; let name = format!("{}-{}", group_name, i); - debug!("directive: {:?}", directive); - match directive { Wat(mut module) => { debug!("got wat module"); @@ -65,7 +63,7 @@ impl TestSuite { debug!("failed to parse module: {:?}", err) } - test_group.add_result(&format!("{}-parse", name), span, result.map(|_| ())); + test_group.add_result(&format!("{}-parse", name), span.linecol_in(wast), result.map(|_| ())); } AssertMalformed { @@ -74,7 +72,7 @@ impl TestSuite { message: _, } => { let Ok(module) = module.encode() else { - test_group.add_result(&format!("{}-malformed", name), span, Ok(())); + test_group.add_result(&format!("{}-malformed", name), span.linecol_in(wast), Ok(())); continue; }; @@ -84,7 +82,7 @@ impl TestSuite { test_group.add_result( &format!("{}-malformed", name), - span, + span.linecol_in(wast), match res { Ok(_) => Err(eyre!("expected module to be malformed")), Err(_) => Ok(()), @@ -103,7 +101,7 @@ impl TestSuite { test_group.add_result( &format!("{}-invalid", name), - span, + span.linecol_in(wast), match res { Ok(_) => Err(eyre!("expected module to be invalid")), Err(_) => Ok(()), @@ -134,41 +132,46 @@ impl TestSuite { match res { Err(err) => test_group.add_result( &format!("{}-trap", name), - span, - Err(eyre!("test panicked: {:?}, span: {:?}", err, span.linecol_in(&wast))), + span.linecol_in(wast), + Err(eyre!("test panicked: {:?}", err)), ), Ok(Err(tinywasm::Error::Trap(_))) => { - test_group.add_result(&format!("{}-trap", name), span, Ok(())) + test_group.add_result(&format!("{}-trap", name), span.linecol_in(wast), Ok(())) } Ok(Err(err)) => test_group.add_result( &format!("{}-trap", name), - span, - Err(eyre!( - "expected trap, got error: {:?}, span: {:?}", - err, - span.linecol_in(&wast) - )), + span.linecol_in(wast), + Err(eyre!("expected trap, got error: {:?}", err,)), ), Ok(Ok(())) => test_group.add_result( &format!("{}-trap", name), - span, - Err(eyre!("expected trap, got ok, span: {:?}", span.linecol_in(&wast))), + span.linecol_in(wast), + Err(eyre!("expected trap, got ok")), ), } } AssertReturn { span, exec, results } => { info!("AssertReturn: {:?}", exec); - let res: Result, _> = catch_unwind_silent(|| { - let invoke = match exec { - wast::WastExecute::Wat(_) => { - error!("wat not supported"); - return Err(eyre!("wat not supported")); - } - wast::WastExecute::Get { module: _, global: _ } => return Err(eyre!("get not supported")), - wast::WastExecute::Invoke(invoke) => invoke, - }; + let invoke = match match exec { + wast::WastExecute::Wat(_) => Err(eyre!("wat not supported")), + wast::WastExecute::Get { module: _, global: _ } => Err(eyre!("get not supported")), + wast::WastExecute::Invoke(invoke) => Ok(invoke), + } { + Ok(invoke) => invoke, + Err(err) => { + test_group.add_result( + "AssertReturn(unknown)", + span.linecol_in(wast), + Err(eyre!("unsupported directive: {:?}", err)), + ); + continue; + } + }; + let invoke_name = invoke.name; + + let res: Result, _> = catch_unwind_silent(|| { debug!("invoke: {:?}", invoke); let args = invoke .args @@ -212,15 +215,9 @@ impl TestSuite { .zip(expected) .enumerate() .try_for_each(|(i, (outcome, exp))| { - (outcome.eq_loose(&exp)).then_some(()).ok_or_else(|| { - eyre!( - "span: {:?}: result {} did not match: {:?} != {:?}", - span.linecol_in(&wast), - i, - outcome, - exp - ) - }) + (outcome.eq_loose(&exp)) + .then_some(()) + .ok_or_else(|| eyre!(" result {} did not match: {:?} != {:?}", i, outcome, exp)) }) }); @@ -228,9 +225,17 @@ impl TestSuite { .map_err(|e| eyre!("test panicked: {:?}", e.downcast_ref::<&str>())) .and_then(|r| r); - test_group.add_result(&format!("{}-return", name), span, res); + test_group.add_result( + &format!("AssertReturn({}-{})", invoke_name, i), + span.linecol_in(wast), + res, + ); } - _ => test_group.add_result(&format!("{}-unknown", name), span, Err(eyre!("unsupported directive"))), + _ => test_group.add_result( + &format!("Unknown({})", i), + span.linecol_in(wast), + Err(eyre!("unsupported directive")), + ), } } From c0dbf46be1dece623946e3019350914d9161a157 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Thu, 4 Jan 2024 15:41:44 +0100 Subject: [PATCH 04/31] test: improve test case naming Signed-off-by: Henry Gressmann --- crates/tinywasm/tests/generated/mvp.csv | 2 +- .../tinywasm/tests/generated/progress-mvp.svg | 6 +++--- crates/tinywasm/tests/testsuite/run.rs | 20 +++++++++---------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index b9cbcb4..275de67 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -2,4 +2,4 @@ 0.0.4,9258,10909,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"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.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17639,2580,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":55,"failed":44},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":2},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":52,"failed":58},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":22,"failed":103},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17639,2589,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":55,"failed":44},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":52,"failed":58},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":22,"failed":110},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index 48bd29f..042b0c0 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -56,9 +56,9 @@ v0.1.0 (17630) v0.2.0-alpha.0 (17639) - - - + + + diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index 1473b17..93c33b9 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -44,7 +44,7 @@ impl TestSuite { for (i, directive) in wast_data.directives.into_iter().enumerate() { let span = directive.span(); use wast::WastDirective::*; - let name = format!("{}-{}", group_name, i); + // let name = format!("{}-{}", group_name, i); match directive { Wat(mut module) => { @@ -63,7 +63,7 @@ impl TestSuite { debug!("failed to parse module: {:?}", err) } - test_group.add_result(&format!("{}-parse", name), span.linecol_in(wast), result.map(|_| ())); + test_group.add_result(&format!("Wat({})", i), span.linecol_in(wast), result.map(|_| ())); } AssertMalformed { @@ -72,7 +72,7 @@ impl TestSuite { message: _, } => { let Ok(module) = module.encode() else { - test_group.add_result(&format!("{}-malformed", name), span.linecol_in(wast), Ok(())); + test_group.add_result(&format!("AssertMalformed({})", i), span.linecol_in(wast), Ok(())); continue; }; @@ -81,7 +81,7 @@ impl TestSuite { .and_then(|res| res); test_group.add_result( - &format!("{}-malformed", name), + &format!("AssertMalformed({})", i), span.linecol_in(wast), match res { Ok(_) => Err(eyre!("expected module to be malformed")), @@ -100,7 +100,7 @@ impl TestSuite { .and_then(|res| res); test_group.add_result( - &format!("{}-invalid", name), + &format!("AssertInvalid({})", i), span.linecol_in(wast), match res { Ok(_) => Err(eyre!("expected module to be invalid")), @@ -131,20 +131,20 @@ impl TestSuite { match res { Err(err) => test_group.add_result( - &format!("{}-trap", name), + &format!("AssertTrap({})", i), span.linecol_in(wast), Err(eyre!("test panicked: {:?}", err)), ), Ok(Err(tinywasm::Error::Trap(_))) => { - test_group.add_result(&format!("{}-trap", name), span.linecol_in(wast), Ok(())) + test_group.add_result(&format!("AssertTrap({})", i), span.linecol_in(wast), Ok(())) } Ok(Err(err)) => test_group.add_result( - &format!("{}-trap", name), + &format!("AssertTrap({})", i), span.linecol_in(wast), Err(eyre!("expected trap, got error: {:?}", err,)), ), Ok(Ok(())) => test_group.add_result( - &format!("{}-trap", name), + &format!("AssertTrap({})", i), span.linecol_in(wast), Err(eyre!("expected trap, got ok")), ), @@ -162,7 +162,7 @@ impl TestSuite { Ok(invoke) => invoke, Err(err) => { test_group.add_result( - "AssertReturn(unknown)", + &format!("AssertReturn(unsupported-{})", i), span.linecol_in(wast), Err(eyre!("unsupported directive: {:?}", err)), ); From ca1837be7414f8d7762e2b5c5529cde35facf890 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Thu, 4 Jan 2024 19:43:59 +0100 Subject: [PATCH 05/31] test: impprove panic reporting Signed-off-by: Henry Gressmann --- crates/cli/src/bin.rs | 2 +- crates/tinywasm/src/instance.rs | 13 +++++++++++-- crates/tinywasm/src/runtime/executor/mod.rs | 9 +++++++-- crates/tinywasm/src/store.rs | 7 +++++-- crates/tinywasm/tests/testsuite/mod.rs | 2 -- crates/tinywasm/tests/testsuite/run.rs | 10 +++++----- crates/tinywasm/tests/testsuite/util.rs | 18 +++++++++++++++++- 7 files changed, 46 insertions(+), 15 deletions(-) diff --git a/crates/cli/src/bin.rs b/crates/cli/src/bin.rs index 2712751..fc680b1 100644 --- a/crates/cli/src/bin.rs +++ b/crates/cli/src/bin.rs @@ -117,7 +117,7 @@ fn run(module: Module, func: Option, args: Vec) -> Result<()> let instance = module.instantiate(&mut store)?; if let Some(func) = func { - let func = instance.get_func(&store, &func)?; + let func = instance.exported_func_by_name(&store, &func)?; let res = func.call(&mut store, &args)?; info!("{res:?}"); } diff --git a/crates/tinywasm/src/instance.rs b/crates/tinywasm/src/instance.rs index 2fa9cf3..6ef303a 100644 --- a/crates/tinywasm/src/instance.rs +++ b/crates/tinywasm/src/instance.rs @@ -58,8 +58,17 @@ impl ModuleInstance { &self.0.types[addr as usize] } + // resolve a function address to the index of the function in the store + pub(crate) fn func_addr(&self, addr: FuncAddr) -> FuncAddr { + self.0.func_addrs[addr as usize] + } + + pub(crate) fn func_addrs(&self) -> &[FuncAddr] { + &self.0.func_addrs + } + /// Get an exported function by name - pub fn get_func(&self, store: &Store, name: &str) -> Result { + pub fn exported_func_by_name(&self, store: &Store, name: &str) -> Result { if self.0.store_id != store.id() { return Err(Error::InvalidStore); } @@ -90,7 +99,7 @@ impl ModuleInstance { P: IntoWasmValueTuple, R: FromWasmValueTuple, { - let func = self.get_func(store, name)?; + let func = self.exported_func_by_name(store, name)?; Ok(TypedFuncHandle { func, marker: core::marker::PhantomData, diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs index 6486b38..6f0e820 100644 --- a/crates/tinywasm/src/runtime/executor/mod.rs +++ b/crates/tinywasm/src/runtime/executor/mod.rs @@ -18,6 +18,10 @@ use traits::*; impl DefaultRuntime { pub(crate) fn exec(&self, store: &mut Store, stack: &mut Stack, module: ModuleInstance) -> Result<()> { + log::info!("exports: {:?}", module.exports()); + log::info!("func_addrs: {:?}", module.func_addrs()); + log::info!("store funcs: {:?}", store.data.funcs.len()); + // The current call frame, gets updated inside of exec_one let mut cf = stack.call_stack.pop()?; @@ -106,8 +110,9 @@ fn exec_one( Call(v) => { debug!("start call"); // prepare the call frame - let func = store.get_func(*v as usize)?; - let func_ty = module.func_ty(*v); + let func_idx = module.func_addr(*v); + let func = store.get_func(func_idx as usize)?; + let func_ty = module.func_ty(func_idx); debug!("params: {:?}", func_ty.params); debug!("stack: {:?}", stack.values); diff --git a/crates/tinywasm/src/store.rs b/crates/tinywasm/src/store.rs index ff44d0d..f28a6cb 100644 --- a/crates/tinywasm/src/store.rs +++ b/crates/tinywasm/src/store.rs @@ -124,18 +124,21 @@ impl Store { Ok(()) } + /// Add functions to the store, returning their addresses in the store pub(crate) fn add_funcs(&mut self, funcs: Vec, idx: ModuleInstanceAddr) -> Vec { - let mut func_addrs = Vec::with_capacity(funcs.len()); + let func_count = self.data.funcs.len(); + let mut func_addrs = Vec::with_capacity(func_count); for (i, func) in funcs.into_iter().enumerate() { self.data.funcs.push(Rc::new(FunctionInstance { func, _module_instance: idx, })); - func_addrs.push(i as FuncAddr); + func_addrs.push((i + func_count) as FuncAddr); } func_addrs } + /// Get the function at the actual index in the store pub(crate) fn get_func(&self, addr: usize) -> Result<&Rc> { self.data .funcs diff --git a/crates/tinywasm/tests/testsuite/mod.rs b/crates/tinywasm/tests/testsuite/mod.rs index cfbe882..d372af5 100644 --- a/crates/tinywasm/tests/testsuite/mod.rs +++ b/crates/tinywasm/tests/testsuite/mod.rs @@ -161,8 +161,6 @@ impl TestGroup { } fn stats(&self) -> (usize, usize) { - log::error!("stats: {:?}", self.tests); - let mut passed_count = 0; let mut failed_count = 0; diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index 93c33b9..33154bd 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -51,7 +51,7 @@ impl TestSuite { debug!("got wat module"); let result = catch_unwind_silent(move || parse_module_bytes(&module.encode().unwrap())) - .map_err(|e| eyre!("failed to parse module: {:?}", e)) + .map_err(|e| eyre!("failed to parse module: {:?}", try_downcast_panic(e))) .and_then(|res| res); match &result { @@ -77,7 +77,7 @@ impl TestSuite { }; let res = catch_unwind_silent(|| parse_module_bytes(&module)) - .map_err(|e| eyre!("failed to parse module: {:?}", e)) + .map_err(|e| eyre!("failed to parse module: {:?}", try_downcast_panic(e))) .and_then(|res| res); test_group.add_result( @@ -96,7 +96,7 @@ impl TestSuite { message: _, } => { let res = catch_unwind_silent(move || parse_module_bytes(&module.encode().unwrap())) - .map_err(|e| eyre!("failed to parse module: {:?}", e)) + .map_err(|e| eyre!("failed to parse module: {:?}", try_downcast_panic(e))) .and_then(|res| res); test_group.add_result( @@ -133,7 +133,7 @@ impl TestSuite { Err(err) => test_group.add_result( &format!("AssertTrap({})", i), span.linecol_in(wast), - Err(eyre!("test panicked: {:?}", err)), + Err(eyre!("test panicked: {:?}", try_downcast_panic(err))), ), Ok(Err(tinywasm::Error::Trap(_))) => { test_group.add_result(&format!("AssertTrap({})", i), span.linecol_in(wast), Ok(())) @@ -222,7 +222,7 @@ impl TestSuite { }); let res = res - .map_err(|e| eyre!("test panicked: {:?}", e.downcast_ref::<&str>())) + .map_err(|e| eyre!("test panicked: {:?}", try_downcast_panic(e))) .and_then(|r| r); test_group.add_result( diff --git a/crates/tinywasm/tests/testsuite/util.rs b/crates/tinywasm/tests/testsuite/util.rs index 85b2a06..82c2699 100644 --- a/crates/tinywasm/tests/testsuite/util.rs +++ b/crates/tinywasm/tests/testsuite/util.rs @@ -3,6 +3,22 @@ use std::panic; use eyre::{eyre, Result}; use tinywasm_types::{TinyWasmModule, WasmValue}; +pub fn try_downcast_panic(panic: Box) -> String { + let info = panic + .downcast_ref::() + .or(None) + .map(|p| p.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(), + ) +} + pub fn exec_fn( module: Option<&TinyWasmModule>, name: &str, @@ -15,7 +31,7 @@ pub fn exec_fn( let mut store = tinywasm::Store::new(); let module = tinywasm::Module::from(module); let instance = module.instantiate(&mut store)?; - instance.get_func(&store, name)?.call(&mut store, args) + instance.exported_func_by_name(&store, name)?.call(&mut store, args) } pub fn catch_unwind_silent R + panic::UnwindSafe, R>(f: F) -> std::thread::Result { From af3caca15123e06879c789a25b6254454cb1a756 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Thu, 4 Jan 2024 20:05:20 +0100 Subject: [PATCH 06/31] feat: improve func_addr resolution Signed-off-by: Henry Gressmann --- crates/tinywasm/src/instance.rs | 29 +++++++++------------ crates/tinywasm/src/runtime/executor/mod.rs | 5 ++-- crates/tinywasm/tests/generated/mvp.csv | 2 +- crates/tinywasm/tests/test-mvp.rs | 5 ++++ crates/tinywasm/tests/test-wast.rs | 6 ++++- crates/tinywasm/tests/testsuite/mod.rs | 8 ++++-- crates/tinywasm/tests/testsuite/run.rs | 8 +++++- 7 files changed, 40 insertions(+), 23 deletions(-) diff --git a/crates/tinywasm/src/instance.rs b/crates/tinywasm/src/instance.rs index 6ef303a..fb09249 100644 --- a/crates/tinywasm/src/instance.rs +++ b/crates/tinywasm/src/instance.rs @@ -36,6 +36,14 @@ impl ModuleInstance { &self.0.exports } + pub(crate) fn func_addrs(&self) -> &[FuncAddr] { + &self.0.func_addrs + } + + pub(crate) fn func_ty_addrs(&self) -> &[FuncType] { + &self.0.types + } + pub(crate) fn new( types: Box<[FuncType]>, func_start: Option, @@ -58,15 +66,11 @@ impl ModuleInstance { &self.0.types[addr as usize] } - // resolve a function address to the index of the function in the store - pub(crate) fn func_addr(&self, addr: FuncAddr) -> FuncAddr { + // resolve a function address to the global store address + pub(crate) fn resolve_func_addr(&self, addr: FuncAddr) -> FuncAddr { self.0.func_addrs[addr as usize] } - pub(crate) fn func_addrs(&self) -> &[FuncAddr] { - &self.0.func_addrs - } - /// Get an exported function by name pub fn exported_func_by_name(&self, store: &Store, name: &str) -> Result { if self.0.store_id != store.id() { @@ -74,16 +78,9 @@ impl ModuleInstance { } let export = self.0.exports.get(name, ExternalKind::Func)?; - log::debug!("get_func: export: {:?}", export); - - log::debug!("{:?}", self.0.func_addrs); let func_addr = self.0.func_addrs[export.index as usize]; - log::debug!("get_func: func index: {}", export.index); let func = store.get_func(func_addr as usize)?; - log::debug!("get_func: func_addr: {}, func: {:?}", func_addr, func); let ty = self.0.types[func.ty_addr() as usize].clone(); - log::debug!("get_func: ty: {:?}", ty); - log::debug!("types: {:?}", self.0.types); Ok(FuncHandle { addr: export.index, @@ -94,7 +91,7 @@ impl ModuleInstance { } /// Get a typed exported function by name - pub fn get_typed_func(&self, store: &Store, name: &str) -> Result> + pub fn typed_func(&self, store: &Store, name: &str) -> Result> where P: IntoWasmValueTuple, R: FromWasmValueTuple, @@ -113,7 +110,7 @@ impl ModuleInstance { /// (which is not part of the spec, but used by llvm) /// /// See - pub fn get_start_func(&mut self, store: &Store) -> Result> { + pub fn start_func(&mut self, store: &Store) -> Result> { if self.0.store_id != store.id() { return Err(Error::InvalidStore); } @@ -148,7 +145,7 @@ impl ModuleInstance { /// /// See pub fn start(&mut self, store: &mut Store) -> Result> { - let Some(func) = self.get_start_func(store)? else { + let Some(func) = self.start_func(store)? else { return Ok(None); }; diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs index 6f0e820..ca404fa 100644 --- a/crates/tinywasm/src/runtime/executor/mod.rs +++ b/crates/tinywasm/src/runtime/executor/mod.rs @@ -20,6 +20,7 @@ impl DefaultRuntime { pub(crate) fn exec(&self, store: &mut Store, stack: &mut Stack, module: ModuleInstance) -> Result<()> { log::info!("exports: {:?}", module.exports()); log::info!("func_addrs: {:?}", module.func_addrs()); + log::info!("func_ty_addrs: {:?}", module.func_ty_addrs().len()); log::info!("store funcs: {:?}", store.data.funcs.len()); // The current call frame, gets updated inside of exec_one @@ -110,9 +111,9 @@ fn exec_one( Call(v) => { debug!("start call"); // prepare the call frame - let func_idx = module.func_addr(*v); + let func_idx = module.resolve_func_addr(*v); let func = store.get_func(func_idx as usize)?; - let func_ty = module.func_ty(func_idx); + let func_ty = module.func_ty(func.ty_addr()); debug!("params: {:?}", func_ty.params); debug!("stack: {:?}", stack.values); diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index 275de67..7faedc8 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -2,4 +2,4 @@ 0.0.4,9258,10909,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"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.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17639,2589,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":55,"failed":44},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":52,"failed":58},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":22,"failed":110},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17747,2473,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":208,"failed":15},{"name":"br.wast","passed":89,"failed":8},{"name":"br_if.wast","passed":101,"failed":17},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":49,"failed":42},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":55,"failed":44},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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 (skipped)","passed":0,"failed":0},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":52,"failed":58},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":22,"failed":110},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":77,"failed":20},{"name":"loop.wast","passed":105,"failed":15},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":56,"failed":32},{"name":"return.wast","passed":81,"failed":3},{"name":"select.wast","passed":96,"failed":52},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":60,"failed":4},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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-mvp.rs b/crates/tinywasm/tests/test-mvp.rs index 0e5b02f..b9ae416 100644 --- a/crates/tinywasm/tests/test-mvp.rs +++ b/crates/tinywasm/tests/test-mvp.rs @@ -9,8 +9,13 @@ fn main() -> Result<()> { fn test_mvp() -> Result<()> { let mut test_suite = TestSuite::new(); + + // currently hangs, so skip it for now + test_suite.skip(&["fac.wast"]); + TestSuite::set_log_level(log::LevelFilter::Off); test_suite.run_spec_group(wasm_testsuite::MVP_TESTS)?; + test_suite.save_csv("./tests/generated/mvp.csv", env!("CARGO_PKG_VERSION"))?; if test_suite.failed() { diff --git a/crates/tinywasm/tests/test-wast.rs b/crates/tinywasm/tests/test-wast.rs index 1efa85d..8537956 100644 --- a/crates/tinywasm/tests/test-wast.rs +++ b/crates/tinywasm/tests/test-wast.rs @@ -44,7 +44,11 @@ fn test_wast(wast_file: &str) -> Result<()> { println!(); test_suite.print_errors(); println!(); - Err(eyre!(format!("{}", "failed one or more tests".red().bold()))) + 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/mod.rs b/crates/tinywasm/tests/testsuite/mod.rs index d372af5..a0b390a 100644 --- a/crates/tinywasm/tests/testsuite/mod.rs +++ b/crates/tinywasm/tests/testsuite/mod.rs @@ -25,9 +25,13 @@ fn format_linecol(linecol: (usize, usize)) -> String { format!("{}:{}", linecol.0 + 1, linecol.1 + 1) } -pub struct TestSuite(BTreeMap); +pub struct TestSuite(BTreeMap, Vec); impl TestSuite { + pub fn skip(&mut self, groups: &[&str]) { + self.1.extend(groups.iter().map(|s| s.to_string())); + } + pub fn set_log_level(level: log::LevelFilter) { pretty_env_logger::formatted_builder().filter_level(level).init(); } @@ -51,7 +55,7 @@ impl TestSuite { } pub fn new() -> Self { - Self(BTreeMap::new()) + Self(BTreeMap::new(), Vec::new()) } pub fn failed(&self) -> bool { diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index 33154bd..38f025a 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -21,6 +21,12 @@ impl TestSuite { pub fn run_spec_group(&mut self, tests: &[&str]) -> Result<()> { tests.iter().for_each(|group| { 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!("{} (skipped)", group), group); + return; + } + self.run_group(group, group_wast).expect("failed to run group"); }); @@ -40,7 +46,7 @@ impl TestSuite { let wast_data = wast::parser::parse::(&buf).expect("failed to parse wat"); let mut last_module: Option = None; - debug!("running {} tests for group: {}", wast_data.directives.len(), group_name); + println!("running {} tests for group: {}", wast_data.directives.len(), group_name); for (i, directive) in wast_data.directives.into_iter().enumerate() { let span = directive.span(); use wast::WastDirective::*; From 489abcda7b1e5aedcb12b6c6a768c9046542836c Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Thu, 4 Jan 2024 22:21:38 +0100 Subject: [PATCH 07/31] chore: add all instances Signed-off-by: Henry Gressmann --- crates/tinywasm/src/instance.rs | 45 ++-- crates/tinywasm/src/module.rs | 38 ++- crates/tinywasm/src/store.rs | 221 +++++++++++++++--- .../tinywasm/tests/generated/progress-mvp.svg | 6 +- 4 files changed, 233 insertions(+), 77 deletions(-) diff --git a/crates/tinywasm/src/instance.rs b/crates/tinywasm/src/instance.rs index fb09249..86a9296 100644 --- a/crates/tinywasm/src/instance.rs +++ b/crates/tinywasm/src/instance.rs @@ -1,5 +1,8 @@ use alloc::{boxed::Box, string::ToString, sync::Arc, vec::Vec}; -use tinywasm_types::{Export, ExternalKind, FuncAddr, FuncType, ModuleInstanceAddr}; +use tinywasm_types::{ + DataAddr, ElmAddr, Export, ExternalKind, FuncAddr, FuncType, GlobalAddr, Import, MemAddr, ModuleInstanceAddr, + TableAddr, +}; use crate::{ func::{FromWasmValueTuple, IntoWasmValueTuple}, @@ -15,19 +18,21 @@ use crate::{ pub struct ModuleInstance(Arc); #[derive(Debug)] -struct ModuleInstanceInner { +pub(crate) struct ModuleInstanceInner { pub(crate) store_id: usize, - pub(crate) _idx: ModuleInstanceAddr, - pub(crate) func_start: Option, - pub(crate) types: Box<[FuncType]>, - pub(crate) exports: ExportInstance, + pub(crate) idx: ModuleInstanceAddr, + pub(crate) types: Box<[FuncType]>, pub(crate) func_addrs: Vec, - // pub table_addrs: Vec, - // pub mem_addrs: Vec, - // pub global_addrs: Vec, - // pub elem_addrs: Vec, - // pub data_addrs: Vec, + pub(crate) table_addrs: Vec, + pub(crate) mem_addrs: Vec, + pub(crate) global_addrs: Vec, + pub(crate) elem_addrs: Vec, + pub(crate) data_addrs: Vec, + + pub(crate) func_start: Option, + pub(crate) imports: Box<[Import]>, + pub(crate) exports: ExportInstance, } impl ModuleInstance { @@ -44,22 +49,8 @@ impl ModuleInstance { &self.0.types } - pub(crate) fn new( - types: Box<[FuncType]>, - func_start: Option, - exports: Box<[Export]>, - func_addrs: Vec, - idx: ModuleInstanceAddr, - store_id: usize, - ) -> Self { - Self(Arc::new(ModuleInstanceInner { - store_id, - _idx: idx, - types, - func_start, - func_addrs, - exports: ExportInstance(exports), - })) + pub(crate) fn new(inner: ModuleInstanceInner) -> Self { + Self(Arc::new(inner)) } pub(crate) fn func_ty(&self, addr: FuncAddr) -> &FuncType { diff --git a/crates/tinywasm/src/module.rs b/crates/tinywasm/src/module.rs index 4f3575d..e26db90 100644 --- a/crates/tinywasm/src/module.rs +++ b/crates/tinywasm/src/module.rs @@ -1,6 +1,7 @@ +use alloc::vec::Vec; use tinywasm_types::TinyWasmModule; -use crate::{ModuleInstance, Result, Store}; +use crate::{instance::ModuleInstanceInner, ModuleInstance, Result, Store}; #[derive(Debug)] /// A WebAssembly Module @@ -49,8 +50,8 @@ 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::new` + // TODO: /// Runs the start function if it exists + // /// If you want to run the start function yourself, use `ModuleInstance::new` /// /// See pub fn instantiate( @@ -59,18 +60,35 @@ impl Module { // imports: Option<()>, ) -> Result { let idx = store.next_module_instance_idx(); + let func_addrs = store.add_funcs(self.data.funcs.into(), idx); + let table_addrs = store.add_tables(self.data.table_types.into(), idx); + let mem_addrs = store.add_mems(self.data.memory_types.into(), idx); + let global_addrs = store.add_globals(self.data.globals.into(), idx); + let elem_addrs = store.add_elems(self.data.elements.into(), idx); + let data_addrs = store.add_datas(self.data.data.into(), idx); - let instance = ModuleInstance::new( - self.data.func_types, - self.data.start_func, - self.data.exports, - func_addrs, + let instance = ModuleInstanceInner { + store_id: store.id(), idx, - store.id(), - ); + types: self.data.func_types, + func_addrs, + table_addrs, + mem_addrs, + global_addrs, + elem_addrs, + data_addrs, + + func_start: self.data.start_func, + imports: self.data.imports, + exports: crate::ExportInstance(self.data.exports), + }; + + let instance = ModuleInstance::new(instance); store.add_instance(instance.clone())?; + + // TODO: Auto-run start function? // let _ = instance.start(store)?; Ok(instance) } diff --git a/crates/tinywasm/src/store.rs b/crates/tinywasm/src/store.rs index f28a6cb..d0e7b4f 100644 --- a/crates/tinywasm/src/store.rs +++ b/crates/tinywasm/src/store.rs @@ -1,7 +1,10 @@ use core::sync::atomic::{AtomicUsize, Ordering}; use alloc::{format, rc::Rc, vec::Vec}; -use tinywasm_types::{FuncAddr, Function, Instruction, ModuleInstanceAddr, TypeAddr, ValType}; +use tinywasm_types::{ + Addr, Data, Element, ElementKind, FuncAddr, Function, Global, GlobalType, Instruction, MemAddr, MemoryType, + ModuleInstanceAddr, TableAddr, TableType, TypeAddr, ValType, +}; use crate::{ runtime::{self, DefaultRuntime}, @@ -69,42 +72,19 @@ impl Default for Store { } } -#[derive(Debug)] -/// A WebAssembly Function Instance -/// -/// See -pub struct FunctionInstance { - pub(crate) func: Function, - pub(crate) _module_instance: ModuleInstanceAddr, // index into store.module_instances -} - -impl FunctionInstance { - pub(crate) fn _module_instance_addr(&self) -> ModuleInstanceAddr { - self._module_instance - } - - pub(crate) fn locals(&self) -> &[ValType] { - &self.func.locals - } - - pub(crate) fn instructions(&self) -> &[Instruction] { - &self.func.instructions - } - - pub(crate) fn ty_addr(&self) -> TypeAddr { - self.func.ty - } -} - #[derive(Debug, Default)] /// Global state that can be manipulated by WebAssembly programs +/// +/// Data should only be addressable by the module that owns it +/// See +// TODO: Arena allocate these? pub(crate) struct StoreData { pub(crate) funcs: Vec>, - // pub tables: Vec, - // pub mems: Vec, - // pub globals: Vec, - // pub elems: Vec, - // pub datas: Vec, + pub(crate) tables: Vec, + pub(crate) mems: Vec>, + pub(crate) globals: Vec>, + pub(crate) elems: Vec, + pub(crate) datas: Vec, } impl Store { @@ -129,15 +109,69 @@ impl Store { let func_count = self.data.funcs.len(); let mut func_addrs = Vec::with_capacity(func_count); for (i, func) in funcs.into_iter().enumerate() { - self.data.funcs.push(Rc::new(FunctionInstance { - func, - _module_instance: idx, - })); + self.data.funcs.push(Rc::new(FunctionInstance { func, owner: idx })); func_addrs.push((i + func_count) as FuncAddr); } func_addrs } + /// Add tables to the store, returning their addresses in the store + pub(crate) fn add_tables(&mut self, tables: Vec, idx: ModuleInstanceAddr) -> Vec { + let table_count = self.data.tables.len(); + let mut table_addrs = Vec::with_capacity(table_count); + for (i, table) in tables.into_iter().enumerate() { + self.data.tables.push(TableInstance::new(table, idx)); + table_addrs.push((i + table_count) as TableAddr); + } + table_addrs + } + + /// Add memories to the store, returning their addresses in the store + pub(crate) fn add_mems(&mut self, mems: Vec, idx: ModuleInstanceAddr) -> Vec { + let mem_count = self.data.mems.len(); + let mut mem_addrs = Vec::with_capacity(mem_count); + for (i, mem) in mems.into_iter().enumerate() { + self.data.mems.push(Rc::new(MemoryInstance::new(mem, idx))); + mem_addrs.push((i + mem_count) as MemAddr); + } + mem_addrs + } + + /// Add globals to the store, returning their addresses in the store + pub(crate) fn add_globals(&mut self, globals: Vec, idx: ModuleInstanceAddr) -> Vec { + let global_count = self.data.globals.len(); + let mut global_addrs = Vec::with_capacity(global_count); + for (i, global) in globals.into_iter().enumerate() { + // TODO: initialize globals + // Don't fail here yet - we'll fail when we try to use the global + self.data.globals.push(Rc::new(GlobalInstance::new(global.ty, 0, idx))); + global_addrs.push((i + global_count) as Addr); + } + global_addrs + } + + /// Add elements to the store, returning their addresses in the store + pub(crate) fn add_elems(&mut self, elems: Vec, idx: ModuleInstanceAddr) -> Vec { + let elem_count = self.data.elems.len(); + let mut elem_addrs = Vec::with_capacity(elem_count); + for (i, elem) in elems.into_iter().enumerate() { + self.data.elems.push(ElemInstance::new(elem.kind, idx)); + elem_addrs.push((i + elem_count) as Addr); + } + elem_addrs + } + + /// Add data to the store, returning their addresses in the store + pub(crate) fn add_datas(&mut self, datas: Vec, idx: ModuleInstanceAddr) -> Vec { + let data_count = self.data.datas.len(); + let mut data_addrs = Vec::with_capacity(data_count); + for (i, data) in datas.into_iter().enumerate() { + self.data.datas.push(DataInstance::new(data.data.to_vec(), idx)); + data_addrs.push((i + data_count) as Addr); + } + data_addrs + } + /// Get the function at the actual index in the store pub(crate) fn get_func(&self, addr: usize) -> Result<&Rc> { self.data @@ -146,3 +180,116 @@ impl Store { .ok_or_else(|| Error::Other(format!("function {} not found", addr))) } } + +#[derive(Debug)] +/// A WebAssembly Function Instance +/// +/// See +pub struct FunctionInstance { + pub(crate) func: Function, + pub(crate) owner: ModuleInstanceAddr, // index into store.module_instances +} + +impl FunctionInstance { + pub(crate) fn _module_instance_addr(&self) -> ModuleInstanceAddr { + self.owner + } + + pub(crate) fn locals(&self) -> &[ValType] { + &self.func.locals + } + + pub(crate) fn instructions(&self) -> &[Instruction] { + &self.func.instructions + } + + pub(crate) fn ty_addr(&self) -> TypeAddr { + self.func.ty + } +} + +/// A WebAssembly Table Instance +/// +/// See +#[derive(Debug)] +pub(crate) struct TableInstance { + pub(crate) kind: TableType, + pub(crate) elements: Vec, + pub(crate) owner: ModuleInstanceAddr, // index into store.module_instances +} + +impl TableInstance { + pub(crate) fn new(kind: TableType, owner: ModuleInstanceAddr) -> Self { + Self { + kind, + elements: Vec::new(), + owner, + } + } +} + +/// A WebAssembly Memory Instance +/// +/// See +#[derive(Debug)] +pub(crate) struct MemoryInstance { + pub(crate) kind: MemoryType, + pub(crate) data: Vec, + pub(crate) owner: ModuleInstanceAddr, // index into store.module_instances +} + +impl MemoryInstance { + pub(crate) fn new(kind: MemoryType, owner: ModuleInstanceAddr) -> Self { + Self { + kind, + data: Vec::new(), + owner, + } + } +} + +/// A WebAssembly Global Instance +/// +/// See +#[derive(Debug)] +pub(crate) struct GlobalInstance { + pub(crate) ty: GlobalType, + pub(crate) value: Addr, + owner: ModuleInstanceAddr, // index into store.module_instances +} + +impl GlobalInstance { + pub(crate) fn new(ty: GlobalType, value: Addr, owner: ModuleInstanceAddr) -> Self { + Self { ty, value, owner } + } +} + +/// A WebAssembly Element Instance +/// +/// See +#[derive(Debug)] +pub(crate) struct ElemInstance { + kind: ElementKind, + owner: ModuleInstanceAddr, // index into store.module_instances +} + +impl ElemInstance { + pub(crate) fn new(kind: ElementKind, owner: ModuleInstanceAddr) -> Self { + Self { kind, owner } + } +} + +/// A WebAssembly Data Instance +/// +/// See +#[derive(Debug)] +pub(crate) struct DataInstance { + pub(crate) data: Vec, + owner: ModuleInstanceAddr, // index into store.module_instances +} + +impl DataInstance { + pub(crate) fn new(data: Vec, owner: ModuleInstanceAddr) -> Self { + Self { data, owner } + } +} diff --git a/crates/tinywasm/tests/generated/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index 042b0c0..ec72fb3 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -53,12 +53,12 @@ v0.1.0 (17630) -v0.2.0-alpha.0 (17639) +v0.2.0-alpha.0 (17747) - - + + From 405564c063f8d9270988a3e6df95cb7fd2eab9e2 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Fri, 5 Jan 2024 15:28:40 +0100 Subject: [PATCH 08/31] refactor: module instantiation Signed-off-by: Henry Gressmann --- Cargo.lock | 88 +++++++++---------- crates/tinywasm/src/instance.rs | 41 +++++++-- crates/tinywasm/src/module.rs | 42 ++------- crates/tinywasm/src/runtime/executor/mod.rs | 17 +++- .../tinywasm/tests/generated/progress-mvp.svg | 4 +- 5 files changed, 103 insertions(+), 89 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3b17097..da14548 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -71,7 +71,7 @@ dependencies = [ "argh_shared", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -139,9 +139,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "542f33a8835a0884b006a0c3df3dadd99c0c3f296ed26c2fdc8028e01ad6230c" +checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" dependencies = [ "memchr", "serde", @@ -310,9 +310,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -586,9 +586,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "iana-time-zone" -version = "0.1.58" +version = "0.1.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -636,13 +636,13 @@ checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590" [[package]] name = "is-terminal" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" dependencies = [ "hermit-abi", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -719,9 +719,9 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "miniz_oxide" @@ -886,9 +886,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.71" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8" +checksum = "907a61bd0f64c2f29cd1cf1dc34d05176426a3f504a78010f08416ddb7b13708" dependencies = [ "unicode-ident", ] @@ -915,9 +915,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -1017,9 +1017,9 @@ dependencies = [ [[package]] name = "rust-embed" -version = "8.1.0" +version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "810294a8a4a0853d4118e3b94bb079905f2107c7fe979d8f0faae98765eb6378" +checksum = "a82c0bbc10308ed323529fd3c1dce8badda635aa319a5ff0e6466f33b8101e3f" dependencies = [ "rust-embed-impl", "rust-embed-utils", @@ -1028,22 +1028,22 @@ dependencies = [ [[package]] name = "rust-embed-impl" -version = "8.1.0" +version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfc144a1273124a67b8c1d7cd19f5695d1878b31569c0512f6086f0f4676604e" +checksum = "6227c01b1783cdfee1bcf844eb44594cd16ec71c35305bf1c9fb5aade2735e16" dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.43", + "syn 2.0.48", "walkdir", ] [[package]] name = "rust-embed-utils" -version = "8.1.0" +version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "816ccd4875431253d6bb54b804bcff4369cbde9bae33defde25fdf6c2ef91d40" +checksum = "8cb0a25bfbb2d4b4402179c2cf030387d9990857ce08a32592c6238db9fa8665" dependencies = [ "globset", "sha2", @@ -1101,35 +1101,35 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "semver" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" [[package]] name = "serde" -version = "1.0.193" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "0b114498256798c94a0689e1a15fec6005dee8ac1f41de56404b67afc2a4b773" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "a3385e45322e8f9931410f01b3031ec534c3947d0e94c18049af4d9f9907d4e0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" dependencies = [ "itoa", "ryu", @@ -1172,9 +1172,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.43" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -1198,22 +1198,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.52" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a48fd946b02c0a526b2e9481c8e2a17755e47039164a86c4070446e3a4614d" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.52" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7fbe9b594d6568a6a1443250a7e67d80b74e1e96f6d1715e1e21cc1888291d3" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -1350,7 +1350,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", "wasm-bindgen-shared", ] @@ -1372,7 +1372,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1469,11 +1469,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" -version = "0.51.1" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.48.5", + "windows-targets 0.52.0", ] [[package]] diff --git a/crates/tinywasm/src/instance.rs b/crates/tinywasm/src/instance.rs index 86a9296..a584571 100644 --- a/crates/tinywasm/src/instance.rs +++ b/crates/tinywasm/src/instance.rs @@ -1,12 +1,11 @@ use alloc::{boxed::Box, string::ToString, sync::Arc, vec::Vec}; use tinywasm_types::{ - DataAddr, ElmAddr, Export, ExternalKind, FuncAddr, FuncType, GlobalAddr, Import, MemAddr, ModuleInstanceAddr, - TableAddr, + DataAddr, ElmAddr, ExternalKind, FuncAddr, FuncType, GlobalAddr, Import, MemAddr, ModuleInstanceAddr, TableAddr, }; use crate::{ func::{FromWasmValueTuple, IntoWasmValueTuple}, - Error, ExportInstance, FuncHandle, Result, Store, TypedFuncHandle, + Error, ExportInstance, FuncHandle, Module, Result, Store, TypedFuncHandle, }; /// A WebAssembly Module Instance @@ -36,6 +35,38 @@ pub(crate) struct ModuleInstanceInner { } impl ModuleInstance { + /// Instantiate the module in the given store + pub fn instantiate(store: &mut Store, module: Module) -> Result { + let idx = store.next_module_instance_idx(); + + let func_addrs = store.add_funcs(module.data.funcs.into(), idx); + let table_addrs = store.add_tables(module.data.table_types.into(), idx); + let mem_addrs = store.add_mems(module.data.memory_types.into(), idx); + let global_addrs = store.add_globals(module.data.globals.into(), idx); + let elem_addrs = store.add_elems(module.data.elements.into(), idx); + let data_addrs = store.add_datas(module.data.data.into(), idx); + + let instance = ModuleInstanceInner { + store_id: store.id(), + idx, + + types: module.data.func_types, + func_addrs, + table_addrs, + mem_addrs, + global_addrs, + elem_addrs, + data_addrs, + + func_start: module.data.start_func, + imports: module.data.imports, + exports: crate::ExportInstance(module.data.exports), + }; + let instance = ModuleInstance::new(instance); + store.add_instance(instance.clone())?; + Ok(instance) + } + /// Get the module's exports pub fn exports(&self) -> &ExportInstance { &self.0.exports @@ -101,7 +132,7 @@ impl ModuleInstance { /// (which is not part of the spec, but used by llvm) /// /// See - pub fn start_func(&mut self, store: &Store) -> Result> { + pub fn start_func(&self, store: &Store) -> Result> { if self.0.store_id != store.id() { return Err(Error::InvalidStore); } @@ -135,7 +166,7 @@ impl ModuleInstance { /// Returns None if the module has no start function /// /// See - pub fn start(&mut self, store: &mut Store) -> Result> { + pub fn start(&self, store: &mut Store) -> Result> { let Some(func) = self.start_func(store)? else { return Ok(None); }; diff --git a/crates/tinywasm/src/module.rs b/crates/tinywasm/src/module.rs index e26db90..51d9f33 100644 --- a/crates/tinywasm/src/module.rs +++ b/crates/tinywasm/src/module.rs @@ -1,14 +1,13 @@ -use alloc::vec::Vec; use tinywasm_types::TinyWasmModule; -use crate::{instance::ModuleInstanceInner, ModuleInstance, Result, Store}; +use crate::{ModuleInstance, Result, Store}; #[derive(Debug)] /// A WebAssembly Module /// /// See pub struct Module { - data: TinyWasmModule, + pub(crate) data: TinyWasmModule, } impl From<&TinyWasmModule> for Module { @@ -50,8 +49,8 @@ impl Module { /// Instantiate the module in the given store /// - // TODO: /// Runs the start function if it exists - // /// If you want to run the start function yourself, use `ModuleInstance::new` + /// Runs the start function if it exists + /// If you want to run the start function yourself, use `ModuleInstance::instantiate` /// /// See pub fn instantiate( @@ -59,37 +58,8 @@ impl Module { store: &mut Store, // imports: Option<()>, ) -> Result { - let idx = store.next_module_instance_idx(); - - let func_addrs = store.add_funcs(self.data.funcs.into(), idx); - let table_addrs = store.add_tables(self.data.table_types.into(), idx); - let mem_addrs = store.add_mems(self.data.memory_types.into(), idx); - let global_addrs = store.add_globals(self.data.globals.into(), idx); - let elem_addrs = store.add_elems(self.data.elements.into(), idx); - let data_addrs = store.add_datas(self.data.data.into(), idx); - - let instance = ModuleInstanceInner { - store_id: store.id(), - idx, - - types: self.data.func_types, - func_addrs, - table_addrs, - mem_addrs, - global_addrs, - elem_addrs, - data_addrs, - - func_start: self.data.start_func, - imports: self.data.imports, - exports: crate::ExportInstance(self.data.exports), - }; - - let instance = ModuleInstance::new(instance); - store.add_instance(instance.clone())?; - - // TODO: Auto-run start function? - // let _ = instance.start(store)?; + let instance = ModuleInstance::instantiate(store, self)?; + let _ = instance.start(store)?; Ok(instance) } } diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs index ca404fa..8ae703e 100644 --- a/crates/tinywasm/src/runtime/executor/mod.rs +++ b/crates/tinywasm/src/runtime/executor/mod.rs @@ -5,11 +5,11 @@ use crate::{ get_label_args, log::debug, runtime::{BlockType, LabelFrame}, - CallFrame, Error, ModuleInstance, Result, Store, + CallFrame, Error, ModuleInstance, RawWasmValue, Result, Store, }; use alloc::vec::Vec; use log::info; -use tinywasm_types::Instruction; +use tinywasm_types::{ConstInstruction, Instruction}; mod macros; mod traits; @@ -75,6 +75,19 @@ enum ExecResult { Trap(crate::Trap), } +/// Execute a const instruction +pub(crate) fn exec_const(instr: ConstInstruction) -> RawWasmValue { + match instr { + ConstInstruction::F32Const(val) => val.into(), + ConstInstruction::F64Const(val) => val.into(), + ConstInstruction::I32Const(val) => val.into(), + ConstInstruction::I64Const(val) => val.into(), + ConstInstruction::GlobalGet(_) => unimplemented!("global get"), + ConstInstruction::RefFunc(_) => unimplemented!("ref func"), + ConstInstruction::RefNull(_) => unimplemented!("ref null"), + } +} + /// Run a single step of the interpreter /// A seperate function is used so later, we can more easily implement /// a step-by-step debugger (using generators once they're stable?) diff --git a/crates/tinywasm/tests/generated/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index ec72fb3..0feea61 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -56,9 +56,9 @@ v0.1.0 (17630) v0.2.0-alpha.0 (17747) - - + + From 34dedd5989348bde863da93c19dbea4102a1d3ca Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Fri, 5 Jan 2024 17:01:06 +0100 Subject: [PATCH 09/31] feat: initial global support Signed-off-by: Henry Gressmann --- crates/tinywasm/src/instance.rs | 9 ++++ crates/tinywasm/src/runtime/executor/mod.rs | 24 ++++----- crates/tinywasm/src/runtime/value.rs | 2 +- crates/tinywasm/src/store.rs | 51 ++++++++++++++++--- crates/tinywasm/tests/generated/mvp.csv | 2 +- .../tinywasm/tests/generated/progress-mvp.svg | 6 +-- 6 files changed, 69 insertions(+), 25 deletions(-) diff --git a/crates/tinywasm/src/instance.rs b/crates/tinywasm/src/instance.rs index a584571..166fa27 100644 --- a/crates/tinywasm/src/instance.rs +++ b/crates/tinywasm/src/instance.rs @@ -76,6 +76,10 @@ impl ModuleInstance { &self.0.func_addrs } + pub(crate) fn global_addrs(&self) -> &[GlobalAddr] { + &self.0.global_addrs + } + pub(crate) fn func_ty_addrs(&self) -> &[FuncType] { &self.0.types } @@ -93,6 +97,11 @@ impl ModuleInstance { self.0.func_addrs[addr as usize] } + // resolve a global address to the global store address + pub(crate) fn resolve_global_addr(&self, addr: GlobalAddr) -> GlobalAddr { + self.0.global_addrs[addr as usize] + } + /// Get an exported function by name pub fn exported_func_by_name(&self, store: &Store, name: &str) -> Result { if self.0.store_id != store.id() { diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs index 8ae703e..9550780 100644 --- a/crates/tinywasm/src/runtime/executor/mod.rs +++ b/crates/tinywasm/src/runtime/executor/mod.rs @@ -75,19 +75,6 @@ enum ExecResult { Trap(crate::Trap), } -/// Execute a const instruction -pub(crate) fn exec_const(instr: ConstInstruction) -> RawWasmValue { - match instr { - ConstInstruction::F32Const(val) => val.into(), - ConstInstruction::F64Const(val) => val.into(), - ConstInstruction::I32Const(val) => val.into(), - ConstInstruction::I64Const(val) => val.into(), - ConstInstruction::GlobalGet(_) => unimplemented!("global get"), - ConstInstruction::RefFunc(_) => unimplemented!("ref func"), - ConstInstruction::RefNull(_) => unimplemented!("ref null"), - } -} - /// Run a single step of the interpreter /// A seperate function is used so later, we can more easily implement /// a step-by-step debugger (using generators once they're stable?) @@ -269,6 +256,17 @@ fn exec_one( LocalSet(local_index) => cf.set_local(*local_index as usize, stack.values.pop()?), LocalTee(local_index) => cf.set_local(*local_index as usize, *stack.values.last()?), + GlobalGet(global_index) => { + let idx = module.resolve_global_addr(*global_index); + let global = store.get_global_val(idx as usize)?; + stack.values.push(global); + } + + GlobalSet(global_index) => { + let idx = module.resolve_global_addr(*global_index); + store.set_global_val(idx as usize, stack.values.pop()?)?; + } + I32Const(val) => stack.values.push((*val).into()), I64Const(val) => stack.values.push((*val).into()), F32Const(val) => stack.values.push((*val).into()), diff --git a/crates/tinywasm/src/runtime/value.rs b/crates/tinywasm/src/runtime/value.rs index 16fb42c..0b837df 100644 --- a/crates/tinywasm/src/runtime/value.rs +++ b/crates/tinywasm/src/runtime/value.rs @@ -1,6 +1,6 @@ use core::fmt::Debug; -use tinywasm_types::{ValType, WasmValue}; +use tinywasm_types::{ConstInstruction, ValType, WasmValue}; /// A raw wasm value. /// diff --git a/crates/tinywasm/src/store.rs b/crates/tinywasm/src/store.rs index d0e7b4f..29ec1c8 100644 --- a/crates/tinywasm/src/store.rs +++ b/crates/tinywasm/src/store.rs @@ -1,4 +1,7 @@ -use core::sync::atomic::{AtomicUsize, Ordering}; +use core::{ + cell::RefCell, + sync::atomic::{AtomicUsize, Ordering}, +}; use alloc::{format, rc::Rc, vec::Vec}; use tinywasm_types::{ @@ -8,7 +11,7 @@ use tinywasm_types::{ use crate::{ runtime::{self, DefaultRuntime}, - Error, ModuleInstance, Result, + Error, ModuleInstance, RawWasmValue, Result, }; // global store id counter @@ -82,7 +85,7 @@ pub(crate) struct StoreData { pub(crate) funcs: Vec>, pub(crate) tables: Vec, pub(crate) mems: Vec>, - pub(crate) globals: Vec>, + pub(crate) globals: Vec>>, pub(crate) elems: Vec, pub(crate) datas: Vec, } @@ -143,8 +146,26 @@ impl Store { let mut global_addrs = Vec::with_capacity(global_count); for (i, global) in globals.into_iter().enumerate() { // TODO: initialize globals - // Don't fail here yet - we'll fail when we try to use the global - self.data.globals.push(Rc::new(GlobalInstance::new(global.ty, 0, idx))); + use tinywasm_types::ConstInstruction::*; + let val = match global.init { + F32Const(f) => RawWasmValue::from(f), + F64Const(f) => RawWasmValue::from(f), + I32Const(i) => RawWasmValue::from(i), + I64Const(i) => RawWasmValue::from(i), + GlobalGet(addr) => { + let addr = global_addrs[addr as usize]; + let global = self.data.globals[addr as usize].clone(); + let val = global.borrow().value; + val + } + RefNull(_) => RawWasmValue::default(), + RefFunc(idx) => RawWasmValue::from(idx as i64), + }; + + self.data + .globals + .push(Rc::new(RefCell::new(GlobalInstance::new(global.ty, val, idx)))); + global_addrs.push((i + global_count) as Addr); } global_addrs @@ -179,6 +200,22 @@ impl Store { .get(addr) .ok_or_else(|| Error::Other(format!("function {} not found", addr))) } + + pub(crate) fn get_global_val(&self, addr: usize) -> Result { + self.data + .globals + .get(addr) + .ok_or_else(|| Error::Other(format!("global {} not found", addr))) + .map(|global| global.borrow().value) + } + + pub(crate) fn set_global_val(&mut self, addr: usize, value: RawWasmValue) -> Result<()> { + self.data + .globals + .get(addr) + .ok_or_else(|| Error::Other(format!("global {} not found", addr))) + .map(|global| global.borrow_mut().value = value) + } } #[derive(Debug)] @@ -254,12 +291,12 @@ impl MemoryInstance { #[derive(Debug)] pub(crate) struct GlobalInstance { pub(crate) ty: GlobalType, - pub(crate) value: Addr, + pub(crate) value: RawWasmValue, owner: ModuleInstanceAddr, // index into store.module_instances } impl GlobalInstance { - pub(crate) fn new(ty: GlobalType, value: Addr, owner: ModuleInstanceAddr) -> Self { + pub(crate) fn new(ty: GlobalType, value: RawWasmValue, owner: ModuleInstanceAddr) -> Self { Self { ty, value, owner } } } diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index 7faedc8..ca7e8f0 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -2,4 +2,4 @@ 0.0.4,9258,10909,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"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.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17747,2473,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":208,"failed":15},{"name":"br.wast","passed":89,"failed":8},{"name":"br_if.wast","passed":101,"failed":17},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":49,"failed":42},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":55,"failed":44},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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 (skipped)","passed":0,"failed":0},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":52,"failed":58},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":22,"failed":110},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":77,"failed":20},{"name":"loop.wast","passed":105,"failed":15},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":56,"failed":32},{"name":"return.wast","passed":81,"failed":3},{"name":"select.wast","passed":96,"failed":52},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":60,"failed":4},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17767,2453,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":209,"failed":14},{"name":"br.wast","passed":89,"failed":8},{"name":"br_if.wast","passed":102,"failed":16},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":50,"failed":41},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":55,"failed":44},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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 (skipped)","passed":0,"failed":0},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":61,"failed":49},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":22,"failed":110},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":78,"failed":19},{"name":"loop.wast","passed":106,"failed":14},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":59,"failed":29},{"name":"return.wast","passed":81,"failed":3},{"name":"select.wast","passed":98,"failed":50},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":3,"failed":4},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":60,"failed":4},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index 0feea61..571dc4c 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -53,12 +53,12 @@ v0.1.0 (17630) -v0.2.0-alpha.0 (17747) +v0.2.0-alpha.0 (17767) - + + - From 9f82dd9e0feb77624557d2fbb13255ccd25c0ea9 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Fri, 5 Jan 2024 18:32:02 +0100 Subject: [PATCH 10/31] chore: improve global testing Signed-off-by: Henry Gressmann --- crates/tinywasm/src/instance.rs | 3 +- crates/tinywasm/src/module.rs | 4 +- crates/tinywasm/src/store.rs | 33 ++++++++++++++- crates/tinywasm/tests/generated/mvp.csv | 2 +- .../tinywasm/tests/generated/progress-mvp.svg | 6 +-- crates/tinywasm/tests/testsuite/run.rs | 40 ++++++++++++++----- crates/tinywasm/tests/testsuite/util.rs | 20 ++++++++-- crates/types/src/lib.rs | 6 +++ 8 files changed, 92 insertions(+), 22 deletions(-) diff --git a/crates/tinywasm/src/instance.rs b/crates/tinywasm/src/instance.rs index 166fa27..22f3112 100644 --- a/crates/tinywasm/src/instance.rs +++ b/crates/tinywasm/src/instance.rs @@ -42,7 +42,8 @@ impl ModuleInstance { let func_addrs = store.add_funcs(module.data.funcs.into(), idx); let table_addrs = store.add_tables(module.data.table_types.into(), idx); let mem_addrs = store.add_mems(module.data.memory_types.into(), idx); - let global_addrs = store.add_globals(module.data.globals.into(), idx); + + let global_addrs = store.add_globals(module.data.globals.into(), &module.data.imports, idx); let elem_addrs = store.add_elems(module.data.elements.into(), idx); let data_addrs = store.add_datas(module.data.data.into(), idx); diff --git a/crates/tinywasm/src/module.rs b/crates/tinywasm/src/module.rs index 51d9f33..d6799f3 100644 --- a/crates/tinywasm/src/module.rs +++ b/crates/tinywasm/src/module.rs @@ -59,7 +59,9 @@ impl Module { // imports: Option<()>, ) -> Result { let instance = ModuleInstance::instantiate(store, self)?; - let _ = instance.start(store)?; + + // TODO: this currently panics if theres no start fn + // let _ = instance.start(store)?; Ok(instance) } } diff --git a/crates/tinywasm/src/store.rs b/crates/tinywasm/src/store.rs index 29ec1c8..1632640 100644 --- a/crates/tinywasm/src/store.rs +++ b/crates/tinywasm/src/store.rs @@ -5,7 +5,7 @@ use core::{ use alloc::{format, rc::Rc, vec::Vec}; use tinywasm_types::{ - Addr, Data, Element, ElementKind, FuncAddr, Function, Global, GlobalType, Instruction, MemAddr, MemoryType, + Addr, Data, Element, ElementKind, FuncAddr, Function, Global, GlobalType, Import, Instruction, MemAddr, MemoryType, ModuleInstanceAddr, TableAddr, TableType, TypeAddr, ValType, }; @@ -141,11 +141,39 @@ impl Store { } /// Add globals to the store, returning their addresses in the store - pub(crate) fn add_globals(&mut self, globals: Vec, idx: ModuleInstanceAddr) -> Vec { + pub(crate) fn add_globals( + &mut self, + globals: Vec, + imports: &[Import], + idx: ModuleInstanceAddr, + ) -> Vec { let global_count = self.data.globals.len(); let mut global_addrs = Vec::with_capacity(global_count); + + // TODO: initialize imported globals + let imported_globals = imports + .iter() + .filter_map(|import| match &import.kind { + tinywasm_types::ImportKind::Global(t) => Some(t), + _ => None, + }) + .collect::>(); + + for (i, global) in imported_globals.into_iter().enumerate() { + log::debug!("imported global: {:?}", global); + self.data.globals.push(Rc::new(RefCell::new(GlobalInstance::new( + global.clone(), + global.ty.default_value().into(), + idx, + )))); + global_addrs.push((i + global_count) as Addr); + } + + let global_count = self.data.globals.len(); + log::debug!("globals: {:?}", globals); for (i, global) in globals.into_iter().enumerate() { // TODO: initialize globals + use tinywasm_types::ConstInstruction::*; let val = match global.init { F32Const(f) => RawWasmValue::from(f), @@ -168,6 +196,7 @@ impl Store { global_addrs.push((i + global_count) as Addr); } + log::debug!("global_addrs: {:?}", global_addrs); global_addrs } diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index ca7e8f0..6b43381 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -2,4 +2,4 @@ 0.0.4,9258,10909,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"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.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17767,2453,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":209,"failed":14},{"name":"br.wast","passed":89,"failed":8},{"name":"br_if.wast","passed":102,"failed":16},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":50,"failed":41},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":55,"failed":44},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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 (skipped)","passed":0,"failed":0},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":61,"failed":49},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":22,"failed":110},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":78,"failed":19},{"name":"loop.wast","passed":106,"failed":14},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":59,"failed":29},{"name":"return.wast","passed":81,"failed":3},{"name":"select.wast","passed":98,"failed":50},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":3,"failed":4},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":60,"failed":4},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17796,2424,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":209,"failed":14},{"name":"br.wast","passed":89,"failed":8},{"name":"br_if.wast","passed":102,"failed":16},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":50,"failed":41},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":54,"failed":45},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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 (skipped)","passed":0,"failed":0},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":91,"failed":19},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":78,"failed":19},{"name":"loop.wast","passed":106,"failed":14},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":59,"failed":29},{"name":"return.wast","passed":81,"failed":3},{"name":"select.wast","passed":98,"failed":50},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":4,"failed":3},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":60,"failed":4},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index 571dc4c..978d346 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -53,12 +53,12 @@ v0.1.0 (17630) -v0.2.0-alpha.0 (17767) +v0.2.0-alpha.0 (17796) + + - - diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index 38f025a..014cf01 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -1,9 +1,13 @@ use crate::testsuite::util::*; -use std::borrow::Cow; +use std::{ + borrow::Cow, + panic::{catch_unwind, AssertUnwindSafe}, +}; use super::TestSuite; use eyre::{eyre, Result}; use log::{debug, error, info}; +use tinywasm::ModuleInstance; use tinywasm_types::TinyWasmModule; use wast::{lexer::Lexer, parser::ParseBuffer, Wast}; @@ -45,20 +49,33 @@ impl TestSuite { 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"); - let mut last_module: Option = None; + let mut store = tinywasm::Store::default(); + let mut last_module: Option = None; + println!("running {} tests for group: {}", wast_data.directives.len(), group_name); for (i, directive) in wast_data.directives.into_iter().enumerate() { let span = directive.span(); use wast::WastDirective::*; - // let name = format!("{}-{}", group_name, i); match directive { Wat(mut module) => { debug!("got wat module"); - let result = catch_unwind_silent(move || parse_module_bytes(&module.encode().unwrap())) - .map_err(|e| eyre!("failed to parse module: {:?}", try_downcast_panic(e))) - .and_then(|res| res); + // TODO: Reusing store beaks some things + store = tinywasm::Store::default(); + let result = catch_unwind(AssertUnwindSafe(|| { + let m = parse_module_bytes(&module.encode().expect("failed to encode module")) + .expect("failed to parse module"); + tinywasm::Module::from(m) + .instantiate(&mut store) + .map_err(|e| { + println!("failed to instantiate module: {:?}", e); + e + }) + .expect("failed to instantiate module") + })) + .map_err(|e| eyre!("failed to parse module: {:?}", try_downcast_panic(e))) + .and_then(|res| Ok(res)); match &result { Err(_) => last_module = None, @@ -132,7 +149,7 @@ impl TestSuite { .collect::>>() .expect("failed to convert args"); - exec_fn(module, name, &args).map(|_| ()) + exec_fn_instance(module, &mut store, name, &args).map(|_| ()) }); match res { @@ -189,10 +206,11 @@ impl TestSuite { e })?; - let outcomes = exec_fn(last_module.as_ref(), invoke.name, &args).map_err(|e| { - error!("failed to execute function: {:?}", e); - e - })?; + let outcomes = + exec_fn_instance(last_module.as_ref(), &mut store, invoke.name, &args).map_err(|e| { + error!("failed to execute function: {:?}", e); + e + })?; debug!("outcomes: {:?}", outcomes); diff --git a/crates/tinywasm/tests/testsuite/util.rs b/crates/tinywasm/tests/testsuite/util.rs index 82c2699..9a4410e 100644 --- a/crates/tinywasm/tests/testsuite/util.rs +++ b/crates/tinywasm/tests/testsuite/util.rs @@ -1,4 +1,4 @@ -use std::panic; +use std::panic::{self, AssertUnwindSafe}; use eyre::{eyre, Result}; use tinywasm_types::{TinyWasmModule, WasmValue}; @@ -19,6 +19,20 @@ pub fn try_downcast_panic(panic: Box) -> String { ) } +pub fn exec_fn_instance( + instance: Option<&tinywasm::ModuleInstance>, + store: &mut tinywasm::Store, + name: &str, + args: &[tinywasm_types::WasmValue], +) -> Result, tinywasm::Error> { + let Some(instance) = instance else { + return Err(tinywasm::Error::Other("no instance found".to_string())); + }; + + let func = instance.exported_func_by_name(store, name)?; + func.call(store, args) +} + pub fn exec_fn( module: Option<&TinyWasmModule>, name: &str, @@ -34,10 +48,10 @@ pub fn exec_fn( instance.exported_func_by_name(&store, name)?.call(&mut store, args) } -pub fn catch_unwind_silent R + panic::UnwindSafe, R>(f: F) -> std::thread::Result { +pub fn catch_unwind_silent R, R>(f: F) -> std::thread::Result { let prev_hook = panic::take_hook(); panic::set_hook(Box::new(|_| {})); - let result = panic::catch_unwind(f); + let result = panic::catch_unwind(AssertUnwindSafe(|| f())); panic::set_hook(prev_hook); result } diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index ad82bd4..4895418 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -245,6 +245,12 @@ pub enum ValType { ExternRef, } +impl ValType { + pub fn default_value(&self) -> WasmValue { + WasmValue::default_for(*self) + } +} + /// A WebAssembly External Kind. /// /// See From f02817573dd9d7b29d78e0a051fbfbe3019b1136 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Fri, 5 Jan 2024 21:17:55 +0100 Subject: [PATCH 11/31] chore: improve breaking Signed-off-by: Henry Gressmann --- .gitignore | 2 +- .vscode/settings.json | 5 ++ crates/tinywasm/src/func.rs | 2 +- crates/tinywasm/src/runtime/executor/mod.rs | 2 +- .../tinywasm/src/runtime/stack/call_stack.rs | 3 +- .../tinywasm/src/runtime/stack/value_stack.rs | 83 +++++++------------ crates/tinywasm/src/runtime/value.rs | 6 +- crates/tinywasm/tests/generated/mvp.csv | 2 +- crates/tinywasm/tests/testsuite/indexmap.rs | 53 ++++++++++++ crates/tinywasm/tests/testsuite/mod.rs | 28 ++++--- crates/tinywasm/tests/testsuite/run.rs | 1 - 11 files changed, 113 insertions(+), 74 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 crates/tinywasm/tests/testsuite/indexmap.rs diff --git a/.gitignore b/.gitignore index 1e56606..7bb669d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ /target notes.md examples/tinywasm.wat -examples/wast/* \ No newline at end of file +examples/wast/* diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..4f9768f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "search.exclude": { + "**/wasm-testsuite/data": true + } +} \ No newline at end of file diff --git a/crates/tinywasm/src/func.rs b/crates/tinywasm/src/func.rs index 58890f6..97fed87 100644 --- a/crates/tinywasm/src/func.rs +++ b/crates/tinywasm/src/func.rs @@ -67,7 +67,7 @@ impl FuncHandle { // Once the function returns: let result_m = func_ty.results.len(); - let res = stack.values.pop_n(result_m)?; + let res = stack.values.last_n(result_m)?; Ok(res .iter() diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs index 9550780..7559670 100644 --- a/crates/tinywasm/src/runtime/executor/mod.rs +++ b/crates/tinywasm/src/runtime/executor/mod.rs @@ -203,7 +203,7 @@ fn exec_one( panic!("Expected {} BrLabel instructions, got {}", len, instr.len()); } - todo!() + todo!("br_table"); } Br(v) => cf.break_to(*v, &mut stack.values)?, diff --git a/crates/tinywasm/src/runtime/stack/call_stack.rs b/crates/tinywasm/src/runtime/stack/call_stack.rs index bf45753..36d30c4 100644 --- a/crates/tinywasm/src/runtime/stack/call_stack.rs +++ b/crates/tinywasm/src/runtime/stack/call_stack.rs @@ -97,8 +97,7 @@ impl CallFrame { .get_relative_to_top(break_to_relative as usize) .ok_or(Error::LabelStackUnderflow)?; - // trim the lable's stack from the stack - value_stack.truncate_keep(break_to.stack_ptr, break_to.args.results); + value_stack.break_to(break_to.stack_ptr, break_to.args.results as usize); // instr_ptr points to the label instruction, but the next step // will increment it by 1 since we're changing the "current" instr_ptr diff --git a/crates/tinywasm/src/runtime/stack/value_stack.rs b/crates/tinywasm/src/runtime/stack/value_stack.rs index 694eb29..a45c33f 100644 --- a/crates/tinywasm/src/runtime/stack/value_stack.rs +++ b/crates/tinywasm/src/runtime/stack/value_stack.rs @@ -42,31 +42,24 @@ impl ValueStack { self.top } - #[inline] - pub(crate) fn _truncate(&mut self, n: usize) { - assert!(self.top <= self.stack.len()); - self.top -= n; - self.stack.truncate(self.top); - } - - #[inline] - // example: [1, 2, 3] n=1, end_keep=1 => [1, 3] - // example: [1] n=1, end_keep=1 => [1] pub(crate) fn truncate_keep(&mut self, n: usize, end_keep: usize) { - if n == end_keep || n == 0 { - return; + let total_to_keep = n + end_keep; + assert!( + self.top >= total_to_keep, + "Total to keep should be less than or equal to self.top" + ); + + let current_size = self.stack.len(); + if current_size <= total_to_keep { + return; // No need to truncate if the current size is already less than or equal to total_to_keep } - assert!(self.top <= self.stack.len()); - info!("removing from {} to {}", self.top - n, self.top - end_keep); - self.stack.drain(self.top - n..self.top - end_keep); - self.top -= n - end_keep; - } + let items_to_remove = current_size - total_to_keep; + let remove_start_index = self.top - items_to_remove - end_keep; + let remove_end_index = self.top - end_keep; - #[inline] - pub(crate) fn _extend(&mut self, values: impl IntoIterator + ExactSizeIterator) { - self.top += values.len(); - self.stack.extend(values); + self.stack.drain(remove_start_index..remove_end_index); + self.top = total_to_keep; // Update top to reflect the new size } #[inline] @@ -92,6 +85,21 @@ impl ValueStack { self.stack.pop().ok_or(Error::StackUnderflow) } + pub(crate) fn break_to(&mut self, new_stack_size: usize, result_count: usize) { + self.stack + .copy_within((self.top - result_count)..self.top, new_stack_size); + self.top = new_stack_size + result_count; + self.stack.truncate(self.top); + } + + #[inline] + pub(crate) fn last_n(&self, n: usize) -> Result<&[RawWasmValue]> { + if self.top < n { + return Err(Error::StackUnderflow); + } + Ok(&self.stack[self.top - n..self.top]) + } + #[inline] pub(crate) fn pop_n(&mut self, n: usize) -> Result> { if self.top < n { @@ -120,39 +128,6 @@ impl ValueStack { #[cfg(test)] mod tests { use super::*; - use crate::std::panic; - - fn crate_stack + Copy>(data: &[T]) -> ValueStack { - let mut stack = ValueStack::default(); - stack._extend(data.iter().map(|v| (*v).into())); - stack - } - - fn assert_truncate_keep + Copy>(data: &[T], n: usize, end_keep: usize, expected: &[T]) { - let mut stack = crate_stack(data); - stack.truncate_keep(n, end_keep); - assert_eq!( - stack.data(), - expected.iter().map(|v| (*v).into()).collect::>().as_slice() - ); - } - - fn catch_unwind_silent R + panic::UnwindSafe, R>(f: F) -> crate::std::thread::Result { - let prev_hook = panic::take_hook(); - panic::set_hook(alloc::boxed::Box::new(|_| {})); - let result = panic::catch_unwind(f); - panic::set_hook(prev_hook); - result - } - - #[test] - fn test_truncate_keep() { - assert_truncate_keep(&[1, 2, 3], 1, 1, &[1, 2, 3]); - assert_truncate_keep(&[1], 1, 1, &[1]); - assert_truncate_keep(&[1, 2, 3], 2, 1, &[1, 3]); - assert_truncate_keep::(&[], 0, 0, &[]); - catch_unwind_silent(|| assert_truncate_keep(&[1, 2, 3], 4, 1, &[1, 3])).expect_err("should panic"); - } #[test] fn test_value_stack() { diff --git a/crates/tinywasm/src/runtime/value.rs b/crates/tinywasm/src/runtime/value.rs index 0b837df..227ecb4 100644 --- a/crates/tinywasm/src/runtime/value.rs +++ b/crates/tinywasm/src/runtime/value.rs @@ -23,9 +23,9 @@ impl RawWasmValue { ValType::I64 => WasmValue::I64(self.0 as i64), ValType::F32 => WasmValue::F32(f32::from_bits(self.0 as u32)), ValType::F64 => WasmValue::F64(f64::from_bits(self.0)), - ValType::ExternRef => todo!(), - ValType::FuncRef => todo!(), - ValType::V128 => todo!(), + ValType::ExternRef => todo!("externref"), + ValType::FuncRef => todo!("funcref"), + ValType::V128 => todo!("v128"), } } } diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index 6b43381..0f0f65a 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -2,4 +2,4 @@ 0.0.4,9258,10909,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"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.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17796,2424,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":209,"failed":14},{"name":"br.wast","passed":89,"failed":8},{"name":"br_if.wast","passed":102,"failed":16},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":50,"failed":41},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":54,"failed":45},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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 (skipped)","passed":0,"failed":0},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":91,"failed":19},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":78,"failed":19},{"name":"loop.wast","passed":106,"failed":14},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":59,"failed":29},{"name":"return.wast","passed":81,"failed":3},{"name":"select.wast","passed":98,"failed":50},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":4,"failed":3},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":60,"failed":4},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17821,2399,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":211,"failed":12},{"name":"br.wast","passed":94,"failed":3},{"name":"br_if.wast","passed":107,"failed":11},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":48,"failed":43},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":54,"failed":45},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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 (skipped)","passed":0,"failed":0},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":132,"failed":40},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":91,"failed":19},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":126,"failed":115},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":78,"failed":19},{"name":"loop.wast","passed":107,"failed":13},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":59,"failed":29},{"name":"return.wast","passed":81,"failed":3},{"name":"select.wast","passed":98,"failed":50},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":4,"failed":3},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":60,"failed":4},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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/testsuite/indexmap.rs b/crates/tinywasm/tests/testsuite/indexmap.rs new file mode 100644 index 0000000..de0de7e --- /dev/null +++ b/crates/tinywasm/tests/testsuite/indexmap.rs @@ -0,0 +1,53 @@ +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 self.map.contains_key(&key) { + return self.map.insert(key, value); + } + + self.keys.push(key.clone()); + self.map.insert(key, value) + } + + pub fn get(&self, key: &K) -> Option<&V> { + self.map.get(key) + } + + pub fn get_mut(&mut self, key: &K) -> Option<&mut V> { + self.map.get_mut(key) + } + + pub fn iter(&self) -> impl Iterator { + self.keys.iter().map(move |k| (k, self.map.get(k).unwrap())) + } + + pub fn len(&self) -> usize { + self.map.len() + } + + pub fn keys(&self) -> impl Iterator { + self.keys.iter() + } + + pub fn values(&self) -> impl Iterator { + self.map.values() + } + + pub fn values_mut(&mut self) -> impl Iterator { + self.map.values_mut() + } +} diff --git a/crates/tinywasm/tests/testsuite/mod.rs b/crates/tinywasm/tests/testsuite/mod.rs index a0b390a..36fc727 100644 --- a/crates/tinywasm/tests/testsuite/mod.rs +++ b/crates/tinywasm/tests/testsuite/mod.rs @@ -9,11 +9,14 @@ 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, @@ -38,14 +41,14 @@ impl TestSuite { pub fn print_errors(&self) { for (group_name, group) in &self.0 { - for (test_name, test) in &group.tests { + let tests = &group.tests; + for (test_name, test) in tests.iter() { if let Err(e) = &test.result { eprintln!( "{} {} failed: {:?}", - link( - format!("{}:{}", group_name.red().underline(), test.linecol.0 + 1).as_str(), - format!("{}:{}", group.file, test.linecol.0 + 1).as_str() - ), + link(group_name, &group.file, Some(test.linecol.0 + 1)) + .bold() + .underline(), test_name.bold(), e.to_string().bright_red() ); @@ -110,8 +113,13 @@ impl TestSuite { } } -fn link(name: &str, file: &str) -> String { - format!("\x1b]8;;file://{}\x1b\\{}\x1b]8;;\x1b\\", file, name) +fn link(name: &str, file: &str, line: Option) -> String { + let (path, name) = match line { + None => (file.to_string(), name.to_owned()), + Some(line) => (format!("{}:{}:0", file, line), (format!("{}:{}", name, line))), + }; + + format!("\x1b]8;;file://{}\x1b\\{}\x1b]8;;\x1b\\", path, name) } impl Debug for TestSuite { @@ -124,7 +132,7 @@ impl Debug for TestSuite { total_passed += group_passed; total_failed += group_failed; - writeln!(f, "{}", link(group_name, &group.file).bold().underline())?; + writeln!(f, "{}", link(group_name, &group.file, None).bold().underline())?; writeln!(f, " Tests Passed: {}", group_passed.to_string().green())?; writeln!(f, " Tests Failed: {}", group_failed.to_string().red())?; @@ -152,14 +160,14 @@ impl Debug for TestSuite { } struct TestGroup { - tests: BTreeMap, + tests: IndexMap, file: String, } impl TestGroup { fn new(file: &str) -> Self { Self { - tests: BTreeMap::new(), + tests: IndexMap::new(), file: file.to_string(), } } diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index 014cf01..7ddb2b7 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -8,7 +8,6 @@ use super::TestSuite; use eyre::{eyre, Result}; use log::{debug, error, info}; use tinywasm::ModuleInstance; -use tinywasm_types::TinyWasmModule; use wast::{lexer::Lexer, parser::ParseBuffer, Wast}; impl TestSuite { From 64606e091757deb5c3e4dbd5c4ef2c9eead6d891 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sat, 6 Jan 2024 03:12:52 +0100 Subject: [PATCH 12/31] docs: update chart Signed-off-by: Henry Gressmann --- crates/tinywasm/tests/generated/progress-mvp.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/tinywasm/tests/generated/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index 978d346..83066cf 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -53,7 +53,7 @@ v0.1.0 (17630) -v0.2.0-alpha.0 (17796) +v0.2.0-alpha.0 (17821) From 54c1b75f9a7bd80e45aa0356cf2cae30a646f383 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sat, 6 Jan 2024 15:03:41 +0100 Subject: [PATCH 13/31] feat: imports Signed-off-by: Henry Gressmann --- crates/cli/src/bin.rs | 2 +- crates/tinywasm/src/imports.rs | 70 +++++++++++++++++++ crates/tinywasm/src/instance.rs | 7 +- crates/tinywasm/src/lib.rs | 5 +- crates/tinywasm/src/module.rs | 10 +-- crates/tinywasm/src/store.rs | 50 +++++++------ crates/tinywasm/tests/generated/mvp.csv | 2 +- .../tinywasm/tests/generated/progress-mvp.svg | 8 +-- crates/tinywasm/tests/testsuite/run.rs | 15 +++- crates/tinywasm/tests/testsuite/util.rs | 3 +- crates/types/src/lib.rs | 13 +++- 11 files changed, 141 insertions(+), 44 deletions(-) create mode 100644 crates/tinywasm/src/imports.rs diff --git a/crates/cli/src/bin.rs b/crates/cli/src/bin.rs index fc680b1..c8ab379 100644 --- a/crates/cli/src/bin.rs +++ b/crates/cli/src/bin.rs @@ -114,7 +114,7 @@ fn main() -> Result<()> { fn run(module: Module, func: Option, args: Vec) -> Result<()> { let mut store = tinywasm::Store::default(); - let instance = module.instantiate(&mut store)?; + let instance = module.instantiate(&mut store, None)?; if let Some(func) = func { let func = instance.exported_func_by_name(&store, &func)?; diff --git a/crates/tinywasm/src/imports.rs b/crates/tinywasm/src/imports.rs new file mode 100644 index 0000000..99ebc4b --- /dev/null +++ b/crates/tinywasm/src/imports.rs @@ -0,0 +1,70 @@ +use crate::Result; +use alloc::{ + collections::BTreeMap, + string::{String, ToString}, +}; +use tinywasm_types::{Global, GlobalType, WasmValue}; + +#[derive(Debug)] +#[non_exhaustive] +/// An external value +pub enum Extern { + /// A global value + Global(Global), + // Func(HostFunc), + // Table(Table), +} + +impl Extern { + /// Create a new global import + pub fn global(val: WasmValue, mutable: bool) -> Self { + Self::Global(Global { + ty: GlobalType { + ty: val.val_type(), + mutable, + }, + init: val.const_instr(), + }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)] +/// Name of an import +pub struct ExternName { + module: String, + name: String, +} + +#[derive(Debug, Default)] +/// Imports for a module instance +pub struct Imports { + values: BTreeMap, +} + +impl Imports { + /// Create a new empty import set + pub fn new() -> Self { + Imports { + values: BTreeMap::new(), + } + } + + /// Define an import + pub fn define(&mut self, module: &str, name: &str, value: Extern) -> Result<&mut Self> { + self.values.insert( + ExternName { + module: module.to_string(), + name: name.to_string(), + }, + value, + ); + Ok(self) + } + + pub(crate) fn get(&self, module: &str, name: &str) -> Option<&Extern> { + self.values.get(&ExternName { + module: module.to_string(), + name: name.to_string(), + }) + } +} diff --git a/crates/tinywasm/src/instance.rs b/crates/tinywasm/src/instance.rs index 22f3112..55614e5 100644 --- a/crates/tinywasm/src/instance.rs +++ b/crates/tinywasm/src/instance.rs @@ -5,7 +5,7 @@ use tinywasm_types::{ use crate::{ func::{FromWasmValueTuple, IntoWasmValueTuple}, - Error, ExportInstance, FuncHandle, Module, Result, Store, TypedFuncHandle, + Error, ExportInstance, FuncHandle, Imports, Module, Result, Store, TypedFuncHandle, }; /// A WebAssembly Module Instance @@ -36,14 +36,15 @@ pub(crate) struct ModuleInstanceInner { impl ModuleInstance { /// Instantiate the module in the given store - pub fn instantiate(store: &mut Store, module: Module) -> Result { + pub fn instantiate(store: &mut Store, module: Module, imports: Option) -> Result { let idx = store.next_module_instance_idx(); + let imports = imports.unwrap_or_default(); let func_addrs = store.add_funcs(module.data.funcs.into(), idx); let table_addrs = store.add_tables(module.data.table_types.into(), idx); let mem_addrs = store.add_mems(module.data.memory_types.into(), idx); - let global_addrs = store.add_globals(module.data.globals.into(), &module.data.imports, idx); + let global_addrs = store.add_globals(module.data.globals.into(), &module.data.imports, &imports, idx)?; let elem_addrs = store.add_elems(module.data.elements.into(), idx); let data_addrs = store.add_datas(module.data.data.into(), idx); diff --git a/crates/tinywasm/src/lib.rs b/crates/tinywasm/src/lib.rs index ec48acf..0a2d875 100644 --- a/crates/tinywasm/src/lib.rs +++ b/crates/tinywasm/src/lib.rs @@ -38,7 +38,7 @@ //! // This will allocate the module and its globals into the store //! // and execute the module's start function. //! // Every ModuleInstance has its own ID space for functions, globals, etc. -//! let instance = module.instantiate(&mut store)?; +//! let instance = module.instantiate(&mut store, None)?; //! //! // Get a typed handle to the exported "add" function //! // Alternatively, you can use `instance.get_func` to get an untyped handle @@ -94,6 +94,9 @@ pub use export::ExportInstance; mod func; pub use func::{FuncHandle, TypedFuncHandle}; +mod imports; +pub use imports::*; + mod runtime; pub use runtime::*; diff --git a/crates/tinywasm/src/module.rs b/crates/tinywasm/src/module.rs index d6799f3..6dfca42 100644 --- a/crates/tinywasm/src/module.rs +++ b/crates/tinywasm/src/module.rs @@ -1,6 +1,6 @@ use tinywasm_types::TinyWasmModule; -use crate::{ModuleInstance, Result, Store}; +use crate::{Imports, ModuleInstance, Result, Store}; #[derive(Debug)] /// A WebAssembly Module @@ -53,12 +53,8 @@ impl Module { /// If you want to run the start function yourself, use `ModuleInstance::instantiate` /// /// See - pub fn instantiate( - self, - store: &mut Store, - // imports: Option<()>, - ) -> Result { - let instance = ModuleInstance::instantiate(store, self)?; + pub fn instantiate(self, store: &mut Store, imports: Option) -> Result { + let instance = ModuleInstance::instantiate(store, self, imports)?; // TODO: this currently panics if theres no start fn // let _ = instance.start(store)?; diff --git a/crates/tinywasm/src/store.rs b/crates/tinywasm/src/store.rs index 1632640..845d718 100644 --- a/crates/tinywasm/src/store.rs +++ b/crates/tinywasm/src/store.rs @@ -11,7 +11,7 @@ use tinywasm_types::{ use crate::{ runtime::{self, DefaultRuntime}, - Error, ModuleInstance, RawWasmValue, Result, + Error, Extern, Imports, ModuleInstance, RawWasmValue, Result, }; // global store id counter @@ -144,36 +144,42 @@ impl Store { pub(crate) fn add_globals( &mut self, globals: Vec, - imports: &[Import], + wasm_imports: &[Import], + user_imports: &Imports, idx: ModuleInstanceAddr, - ) -> Vec { - let global_count = self.data.globals.len(); - let mut global_addrs = Vec::with_capacity(global_count); - + ) -> Result> { // TODO: initialize imported globals - let imported_globals = imports + let imported_globals = wasm_imports .iter() .filter_map(|import| match &import.kind { - tinywasm_types::ImportKind::Global(t) => Some(t), + tinywasm_types::ImportKind::Global(_) => Some(import), _ => None, }) - .collect::>(); - - for (i, global) in imported_globals.into_iter().enumerate() { - log::debug!("imported global: {:?}", global); - self.data.globals.push(Rc::new(RefCell::new(GlobalInstance::new( - global.clone(), - global.ty.default_value().into(), - idx, - )))); - global_addrs.push((i + global_count) as Addr); - } + .map(|import| { + let Some(global) = user_imports.get(&import.module, &import.name) else { + return Err(Error::Other(format!( + "global import not found for {}::{}", + import.module, import.name + ))); + }; + match global { + Extern::Global(global) => Ok(global), + _ => Err(Error::Other(format!( + "expected global import for {}::{}", + import.module, import.name + ))), + } + }) + .collect::>>()?; let global_count = self.data.globals.len(); + let mut global_addrs = Vec::with_capacity(global_count); + log::debug!("globals: {:?}", globals); - for (i, global) in globals.into_iter().enumerate() { - // TODO: initialize globals + let globals = globals.into_iter(); + let iterator = imported_globals.into_iter().chain(globals.as_ref()); + for (i, global) in iterator.enumerate() { use tinywasm_types::ConstInstruction::*; let val = match global.init { F32Const(f) => RawWasmValue::from(f), @@ -197,7 +203,7 @@ impl Store { global_addrs.push((i + global_count) as Addr); } log::debug!("global_addrs: {:?}", global_addrs); - global_addrs + Ok(global_addrs) } /// Add elements to the store, returning their addresses in the store diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index 0f0f65a..d39acb9 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -2,4 +2,4 @@ 0.0.4,9258,10909,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"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.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17821,2399,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":211,"failed":12},{"name":"br.wast","passed":94,"failed":3},{"name":"br_if.wast","passed":107,"failed":11},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":48,"failed":43},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":54,"failed":45},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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 (skipped)","passed":0,"failed":0},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":132,"failed":40},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":91,"failed":19},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":126,"failed":115},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":78,"failed":19},{"name":"loop.wast","passed":107,"failed":13},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":59,"failed":29},{"name":"return.wast","passed":81,"failed":3},{"name":"select.wast","passed":98,"failed":50},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":4,"failed":3},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":60,"failed":4},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17823,2397,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":211,"failed":12},{"name":"br.wast","passed":94,"failed":3},{"name":"br_if.wast","passed":107,"failed":11},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":48,"failed":43},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":54,"failed":45},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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 (skipped)","passed":0,"failed":0},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":132,"failed":40},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":94,"failed":16},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":126,"failed":115},{"name":"imports.wast","passed":75,"failed":108},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":19,"failed":113},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":78,"failed":19},{"name":"loop.wast","passed":107,"failed":13},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":59,"failed":29},{"name":"return.wast","passed":81,"failed":3},{"name":"select.wast","passed":98,"failed":50},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":4,"failed":3},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":60,"failed":4},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index 83066cf..a95188f 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -53,12 +53,12 @@ v0.1.0 (17630) -v0.2.0-alpha.0 (17821) +v0.2.0-alpha.0 (17823) - - - + + + diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index 7ddb2b7..a4ae429 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -7,7 +7,8 @@ use std::{ use super::TestSuite; use eyre::{eyre, Result}; use log::{debug, error, info}; -use tinywasm::ModuleInstance; +use tinywasm::{Extern, Imports, ModuleInstance}; +use tinywasm_types::{Global, WasmValue}; use wast::{lexer::Lexer, parser::ParseBuffer, Wast}; impl TestSuite { @@ -21,6 +22,16 @@ impl TestSuite { Ok(()) } + fn imports() -> Result { + let mut imports = Imports::new(); + imports.define("spectest", "global_i32", Extern::global(WasmValue::I32(666), false))?; + imports.define("spectest", "global_i64", Extern::global(WasmValue::I64(666), false))?; + imports.define("spectest", "global_f32", Extern::global(WasmValue::F32(666.0), false))?; + imports.define("spectest", "global_f64", Extern::global(WasmValue::F64(666.0), false))?; + + Ok(imports) + } + pub fn run_spec_group(&mut self, tests: &[&str]) -> Result<()> { tests.iter().for_each(|group| { let group_wast = wasm_testsuite::get_test_wast(group).expect("failed to get test wast"); @@ -66,7 +77,7 @@ impl TestSuite { let m = parse_module_bytes(&module.encode().expect("failed to encode module")) .expect("failed to parse module"); tinywasm::Module::from(m) - .instantiate(&mut store) + .instantiate(&mut store, Some(Self::imports().unwrap())) .map_err(|e| { println!("failed to instantiate module: {:?}", e); e diff --git a/crates/tinywasm/tests/testsuite/util.rs b/crates/tinywasm/tests/testsuite/util.rs index 9a4410e..2546ba3 100644 --- a/crates/tinywasm/tests/testsuite/util.rs +++ b/crates/tinywasm/tests/testsuite/util.rs @@ -37,6 +37,7 @@ pub fn exec_fn( module: Option<&TinyWasmModule>, name: &str, args: &[tinywasm_types::WasmValue], + imports: Option, ) -> Result, tinywasm::Error> { let Some(module) = module else { return Err(tinywasm::Error::Other("no module found".to_string())); @@ -44,7 +45,7 @@ pub fn exec_fn( let mut store = tinywasm::Store::new(); let module = tinywasm::Module::from(module); - let instance = module.instantiate(&mut store)?; + let instance = module.instantiate(&mut store, imports)?; instance.exported_func_by_name(&store, name)?.call(&mut store, args) } diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index 4895418..1213515 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -91,6 +91,15 @@ pub enum WasmValue { } impl WasmValue { + pub fn const_instr(&self) -> ConstInstruction { + match self { + Self::I32(i) => ConstInstruction::I32Const(*i), + Self::I64(i) => ConstInstruction::I64Const(*i), + Self::F32(i) => ConstInstruction::F32Const(*i), + Self::F64(i) => ConstInstruction::F64Const(*i), + } + } + /// Get the default value for a given type. pub fn default_for(ty: ValType) -> Self { match ty { @@ -227,7 +236,7 @@ impl WasmValue { } /// Type of a WebAssembly value. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum ValType { /// A 32-bit integer. I32, @@ -340,7 +349,7 @@ pub struct Global { pub init: ConstInstruction, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct GlobalType { pub mutable: bool, pub ty: ValType, From 7d93300ca9491186b4a436bf4289d9724674af5a Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sat, 6 Jan 2024 18:03:28 +0100 Subject: [PATCH 14/31] feat: basic memory ops Signed-off-by: Henry Gressmann --- crates/tinywasm/src/instance.rs | 12 +++- crates/tinywasm/src/runtime/executor/mod.rs | 37 +++++++++++- crates/tinywasm/src/store.rs | 58 ++++++++++++++++--- crates/tinywasm/tests/generated/mvp.csv | 2 +- .../tinywasm/tests/generated/progress-mvp.svg | 8 +-- 5 files changed, 100 insertions(+), 17 deletions(-) diff --git a/crates/tinywasm/src/instance.rs b/crates/tinywasm/src/instance.rs index 55614e5..c6fef46 100644 --- a/crates/tinywasm/src/instance.rs +++ b/crates/tinywasm/src/instance.rs @@ -42,7 +42,7 @@ impl ModuleInstance { let func_addrs = store.add_funcs(module.data.funcs.into(), idx); let table_addrs = store.add_tables(module.data.table_types.into(), idx); - let mem_addrs = store.add_mems(module.data.memory_types.into(), idx); + let mem_addrs = store.add_mems(module.data.memory_types.into(), idx)?; let global_addrs = store.add_globals(module.data.globals.into(), &module.data.imports, &imports, idx)?; let elem_addrs = store.add_elems(module.data.elements.into(), idx); @@ -99,6 +99,16 @@ impl ModuleInstance { self.0.func_addrs[addr as usize] } + // resolve a table address to the global store address + pub(crate) fn resolve_table_addr(&self, addr: TableAddr) -> TableAddr { + self.0.table_addrs[addr as usize] + } + + // resolve a memory address to the global store address + pub(crate) fn resolve_mem_addr(&self, addr: MemAddr) -> MemAddr { + self.0.mem_addrs[addr as usize] + } + // resolve a global address to the global store address pub(crate) fn resolve_global_addr(&self, addr: GlobalAddr) -> GlobalAddr { self.0.global_addrs[addr as usize] diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs index 7559670..dccf71b 100644 --- a/crates/tinywasm/src/runtime/executor/mod.rs +++ b/crates/tinywasm/src/runtime/executor/mod.rs @@ -5,11 +5,11 @@ use crate::{ get_label_args, log::debug, runtime::{BlockType, LabelFrame}, - CallFrame, Error, ModuleInstance, RawWasmValue, Result, Store, + CallFrame, Error, ModuleInstance, Result, Store, }; -use alloc::vec::Vec; +use alloc::{format, vec::Vec}; use log::info; -use tinywasm_types::{ConstInstruction, Instruction}; +use tinywasm_types::Instruction; mod macros; mod traits; @@ -272,6 +272,37 @@ fn exec_one( F32Const(val) => stack.values.push((*val).into()), F64Const(val) => stack.values.push((*val).into()), + MemorySize(addr, byte) => { + if *byte != 0 { + unimplemented!("memory.size with byte != 0"); + } + + let mem_idx = module.resolve_mem_addr(*addr); + let mem = store.get_mem(mem_idx as usize)?; + stack.values.push(mem.borrow().size().into()); + } + + MemoryGrow(addr, byte) => { + if *byte != 0 { + unimplemented!("memory.grow with byte != 0"); + } + + let mem_idx = module.resolve_mem_addr(*addr); + let mem = store.get_mem(mem_idx as usize)?; + + let (res, prev_size) = { + let mut mem = mem.borrow_mut(); + let prev_size = mem.size(); + let new_size = prev_size + stack.values.pop_t::()?; + (mem.grow(new_size), prev_size) + }; + + match res { + Ok(_) => stack.values.push(prev_size.into()), + Err(_) => stack.values.push((-1).into()), + } + } + I64Eqz => comp_zero!(==, i64, stack), I32Eqz => comp_zero!(==, i32, stack), diff --git a/crates/tinywasm/src/store.rs b/crates/tinywasm/src/store.rs index 845d718..a584421 100644 --- a/crates/tinywasm/src/store.rs +++ b/crates/tinywasm/src/store.rs @@ -3,10 +3,10 @@ use core::{ sync::atomic::{AtomicUsize, Ordering}, }; -use alloc::{format, rc::Rc, vec::Vec}; +use alloc::{format, rc::Rc, string::ToString, vec, vec::Vec}; use tinywasm_types::{ - Addr, Data, Element, ElementKind, FuncAddr, Function, Global, GlobalType, Import, Instruction, MemAddr, MemoryType, - ModuleInstanceAddr, TableAddr, TableType, TypeAddr, ValType, + Addr, Data, Element, ElementKind, FuncAddr, Function, Global, GlobalType, Import, Instruction, MemAddr, MemoryArch, + MemoryType, ModuleInstanceAddr, TableAddr, TableType, TypeAddr, ValType, }; use crate::{ @@ -84,7 +84,7 @@ impl Default for Store { pub(crate) struct StoreData { pub(crate) funcs: Vec>, pub(crate) tables: Vec, - pub(crate) mems: Vec>, + pub(crate) mems: Vec>>, pub(crate) globals: Vec>>, pub(crate) elems: Vec, pub(crate) datas: Vec, @@ -130,14 +130,20 @@ impl Store { } /// Add memories to the store, returning their addresses in the store - pub(crate) fn add_mems(&mut self, mems: Vec, idx: ModuleInstanceAddr) -> Vec { + pub(crate) fn add_mems(&mut self, mems: Vec, idx: ModuleInstanceAddr) -> Result> { let mem_count = self.data.mems.len(); let mut mem_addrs = Vec::with_capacity(mem_count); for (i, mem) in mems.into_iter().enumerate() { - self.data.mems.push(Rc::new(MemoryInstance::new(mem, idx))); + if let MemoryArch::I64 = mem.arch { + return Err(Error::UnsupportedFeature("64-bit memories".to_string())); + } + self.data + .mems + .push(Rc::new(RefCell::new(MemoryInstance::new(mem, idx)))); + mem_addrs.push((i + mem_count) as MemAddr); } - mem_addrs + Ok(mem_addrs) } /// Add globals to the store, returning their addresses in the store @@ -236,6 +242,15 @@ impl Store { .ok_or_else(|| Error::Other(format!("function {} not found", addr))) } + /// Get the memory at the actual index in the store + pub(crate) fn get_mem(&self, addr: usize) -> Result<&Rc>> { + self.data + .mems + .get(addr) + .ok_or_else(|| Error::Other(format!("memory {} not found", addr))) + } + + /// Get the global at the actual index in the store pub(crate) fn get_global_val(&self, addr: usize) -> Result { self.data .globals @@ -300,6 +315,10 @@ impl TableInstance { } } +pub(crate) const PAGE_SIZE: usize = 64_000; +pub(crate) const MAX_PAGES: usize = 65536; +pub(crate) const MAX_SIZE: usize = PAGE_SIZE * MAX_PAGES; + /// A WebAssembly Memory Instance /// /// See @@ -307,17 +326,40 @@ impl TableInstance { pub(crate) struct MemoryInstance { pub(crate) kind: MemoryType, pub(crate) data: Vec, + pub(crate) page_count: usize, pub(crate) owner: ModuleInstanceAddr, // index into store.module_instances } impl MemoryInstance { pub(crate) fn new(kind: MemoryType, owner: ModuleInstanceAddr) -> Self { + debug_assert!(kind.page_count_initial <= kind.page_count_max.unwrap_or(MAX_PAGES as u64)); + Self { kind, - data: Vec::new(), + data: vec![0; PAGE_SIZE * kind.page_count_initial as usize], + page_count: kind.page_count_initial as usize, owner, } } + + pub(crate) fn size(&self) -> i32 { + self.page_count as i32 + } + + pub(crate) fn grow(&mut self, delta: i32) -> Result { + let current_pages = self.size(); + let new_pages = current_pages + delta; + if new_pages < 0 || new_pages > MAX_PAGES as i32 { + return Err(Error::Other(format!("memory size out of bounds: {}", new_pages))); + } + let new_size = new_pages as usize * PAGE_SIZE; + if new_size > MAX_SIZE { + return Err(Error::Other(format!("memory size out of bounds: {}", new_size))); + } + self.data.resize(new_size, 0); + self.page_count = new_pages as usize; + Ok(current_pages) + } } /// A WebAssembly Global Instance diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index d39acb9..f737556 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -2,4 +2,4 @@ 0.0.4,9258,10909,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"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.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17823,2397,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":211,"failed":12},{"name":"br.wast","passed":94,"failed":3},{"name":"br_if.wast","passed":107,"failed":11},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":48,"failed":43},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":54,"failed":45},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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 (skipped)","passed":0,"failed":0},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":132,"failed":40},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":94,"failed":16},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":126,"failed":115},{"name":"imports.wast","passed":75,"failed":108},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":19,"failed":113},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":78,"failed":19},{"name":"loop.wast","passed":107,"failed":13},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":59,"failed":29},{"name":"return.wast","passed":81,"failed":3},{"name":"select.wast","passed":98,"failed":50},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":4,"failed":3},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":60,"failed":4},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17882,2338,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":212,"failed":11},{"name":"br.wast","passed":94,"failed":3},{"name":"br_if.wast","passed":107,"failed":11},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":49,"failed":42},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":54,"failed":45},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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 (skipped)","passed":0,"failed":0},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":132,"failed":40},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":95,"failed":15},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":126,"failed":115},{"name":"imports.wast","passed":76,"failed":107},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":19,"failed":113},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":79,"failed":18},{"name":"loop.wast","passed":108,"failed":12},{"name":"memory.wast","passed":37,"failed":42},{"name":"memory_grow.wast","passed":38,"failed":58},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":27,"failed":15},{"name":"memory_trap.wast","passed":3,"failed":179},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":60,"failed":28},{"name":"return.wast","passed":81,"failed":3},{"name":"select.wast","passed":99,"failed":49},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":4,"failed":3},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":60,"failed":4},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index a95188f..9bf47fa 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -53,12 +53,12 @@ v0.1.0 (17630) -v0.2.0-alpha.0 (17823) +v0.2.0-alpha.0 (17882) - - - + + + From b87eea6fcfc3f319b7db0c10eafed45012538634 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sat, 6 Jan 2024 21:14:02 +0100 Subject: [PATCH 15/31] fix: wrong memory growth delta Signed-off-by: Henry Gressmann --- crates/tinywasm/src/runtime/executor/mod.rs | 3 +-- crates/tinywasm/src/store.rs | 6 ++++++ crates/tinywasm/tests/generated/mvp.csv | 2 +- crates/tinywasm/tests/testsuite/run.rs | 4 +--- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs index dccf71b..e644df3 100644 --- a/crates/tinywasm/src/runtime/executor/mod.rs +++ b/crates/tinywasm/src/runtime/executor/mod.rs @@ -293,8 +293,7 @@ fn exec_one( let (res, prev_size) = { let mut mem = mem.borrow_mut(); let prev_size = mem.size(); - let new_size = prev_size + stack.values.pop_t::()?; - (mem.grow(new_size), prev_size) + (mem.grow(stack.values.pop_t::()?), prev_size) }; match res { diff --git a/crates/tinywasm/src/store.rs b/crates/tinywasm/src/store.rs index a584421..c7cda26 100644 --- a/crates/tinywasm/src/store.rs +++ b/crates/tinywasm/src/store.rs @@ -333,6 +333,7 @@ pub(crate) struct MemoryInstance { impl MemoryInstance { pub(crate) fn new(kind: MemoryType, owner: ModuleInstanceAddr) -> Self { debug_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); Self { kind, @@ -358,6 +359,11 @@ impl MemoryInstance { } self.data.resize(new_size, 0); self.page_count = new_pages as usize; + + log::debug!("memory was {} pages", current_pages); + log::debug!("memory grown by {} pages", delta); + log::debug!("memory grown to {} pages", self.page_count); + Ok(current_pages) } } diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index f737556..4f7688c 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -2,4 +2,4 @@ 0.0.4,9258,10909,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"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.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17882,2338,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":212,"failed":11},{"name":"br.wast","passed":94,"failed":3},{"name":"br_if.wast","passed":107,"failed":11},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":49,"failed":42},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":54,"failed":45},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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 (skipped)","passed":0,"failed":0},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":132,"failed":40},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":95,"failed":15},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":126,"failed":115},{"name":"imports.wast","passed":76,"failed":107},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":19,"failed":113},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":79,"failed":18},{"name":"loop.wast","passed":108,"failed":12},{"name":"memory.wast","passed":37,"failed":42},{"name":"memory_grow.wast","passed":38,"failed":58},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":27,"failed":15},{"name":"memory_trap.wast","passed":3,"failed":179},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":60,"failed":28},{"name":"return.wast","passed":81,"failed":3},{"name":"select.wast","passed":99,"failed":49},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":4,"failed":3},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":60,"failed":4},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17913,2307,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":212,"failed":11},{"name":"br.wast","passed":94,"failed":3},{"name":"br_if.wast","passed":107,"failed":11},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":49,"failed":42},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":54,"failed":45},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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 (skipped)","passed":0,"failed":0},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":132,"failed":40},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":95,"failed":15},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":126,"failed":115},{"name":"imports.wast","passed":76,"failed":107},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":19,"failed":113},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":79,"failed":18},{"name":"loop.wast","passed":108,"failed":12},{"name":"memory.wast","passed":37,"failed":42},{"name":"memory_grow.wast","passed":58,"failed":38},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":3,"failed":179},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":62,"failed":26},{"name":"return.wast","passed":81,"failed":3},{"name":"select.wast","passed":100,"failed":48},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":4,"failed":3},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":60,"failed":4},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index a4ae429..70eb70c 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -8,7 +8,7 @@ use super::TestSuite; use eyre::{eyre, Result}; use log::{debug, error, info}; use tinywasm::{Extern, Imports, ModuleInstance}; -use tinywasm_types::{Global, WasmValue}; +use tinywasm_types::WasmValue; use wast::{lexer::Lexer, parser::ParseBuffer, Wast}; impl TestSuite { @@ -70,8 +70,6 @@ impl TestSuite { match directive { Wat(mut module) => { debug!("got wat module"); - - // TODO: Reusing store beaks some things store = tinywasm::Store::default(); let result = catch_unwind(AssertUnwindSafe(|| { let m = parse_module_bytes(&module.encode().expect("failed to encode module")) From f13e225192dd8294b48bcb429f09769055a4d973 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sun, 7 Jan 2024 00:30:17 +0100 Subject: [PATCH 16/31] feat: basic i32 loads/stores Signed-off-by: Henry Gressmann --- crates/parser/src/conversion.rs | 2 ++ crates/tinywasm/src/runtime/executor/mod.rs | 28 +++++++++++++++- crates/tinywasm/src/runtime/value.rs | 4 +++ crates/tinywasm/src/store.rs | 33 +++++++++++++++++-- crates/tinywasm/tests/generated/mvp.csv | 2 +- .../tinywasm/tests/generated/progress-mvp.svg | 6 ++-- crates/tinywasm/tests/test-mvp.rs | 3 -- crates/types/src/instructions.rs | 2 ++ 8 files changed, 70 insertions(+), 10 deletions(-) diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs index 1b22af8..b9e674e 100644 --- a/crates/parser/src/conversion.rs +++ b/crates/parser/src/conversion.rs @@ -280,6 +280,8 @@ pub(crate) fn convert_memarg(memarg: wasmparser::MemArg) -> MemArg { MemArg { offset: memarg.offset, align: memarg.align, + align_max: memarg.max_align, + mem_addr: memarg.memory, } } diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs index e644df3..dcb12d4 100644 --- a/crates/tinywasm/src/runtime/executor/mod.rs +++ b/crates/tinywasm/src/runtime/executor/mod.rs @@ -7,7 +7,7 @@ use crate::{ runtime::{BlockType, LabelFrame}, CallFrame, Error, ModuleInstance, Result, Store, }; -use alloc::{format, vec::Vec}; +use alloc::vec::Vec; use log::info; use tinywasm_types::Instruction; @@ -302,6 +302,32 @@ fn exec_one( } } + I32Store(arg) => { + let mem_idx = module.resolve_mem_addr(arg.mem_addr); + let mem = store.get_mem(mem_idx as usize)?; + + let val = stack.values.pop()?.raw_value(); + let addr = stack.values.pop()?.raw_value(); + + mem.borrow_mut() + .store((arg.offset + addr) as usize, arg.align as usize, &val.to_le_bytes())?; + } + + I32Load(arg) => { + let mem_idx = module.resolve_mem_addr(arg.mem_addr); + let mem = store.get_mem(mem_idx as usize)?; + + let addr = stack.values.pop()?.raw_value(); + + let val: [u8; 4] = { + let mem = mem.borrow_mut(); + let val = mem.load((arg.offset + addr) as usize, arg.align as usize, 4)?; + val.try_into().expect("slice with incorrect length") + }; + + stack.values.push(i32::from_le_bytes(val).into()); + } + I64Eqz => comp_zero!(==, i64, stack), I32Eqz => comp_zero!(==, i32, stack), diff --git a/crates/tinywasm/src/runtime/value.rs b/crates/tinywasm/src/runtime/value.rs index 227ecb4..7217873 100644 --- a/crates/tinywasm/src/runtime/value.rs +++ b/crates/tinywasm/src/runtime/value.rs @@ -17,6 +17,10 @@ impl Debug for RawWasmValue { } impl RawWasmValue { + pub fn raw_value(&self) -> u64 { + self.0 + } + pub fn attach_type(self, ty: ValType) -> WasmValue { match ty { ValType::I32 => WasmValue::I32(self.0 as i32), diff --git a/crates/tinywasm/src/store.rs b/crates/tinywasm/src/store.rs index c7cda26..dd945a6 100644 --- a/crates/tinywasm/src/store.rs +++ b/crates/tinywasm/src/store.rs @@ -5,8 +5,8 @@ use core::{ use alloc::{format, rc::Rc, string::ToString, vec, vec::Vec}; use tinywasm_types::{ - Addr, Data, Element, ElementKind, FuncAddr, Function, Global, GlobalType, Import, Instruction, MemAddr, MemoryArch, - MemoryType, ModuleInstanceAddr, TableAddr, TableType, TypeAddr, ValType, + Addr, Data, Element, ElementKind, FuncAddr, Function, Global, GlobalType, Import, Instruction, MemAddr, MemArg, + MemoryArch, MemoryType, ModuleInstanceAddr, TableAddr, TableType, TypeAddr, ValType, }; use crate::{ @@ -343,6 +343,35 @@ impl MemoryInstance { } } + pub(crate) fn store(&mut self, addr: usize, align: usize, data: &[u8]) -> Result<()> { + if addr + data.len() > self.data.len() { + return Err(Error::Other(format!( + "memory store out of bounds: offset={}, len={}, mem_size={}", + addr, + data.len(), + self.data.len() + ))); + } + + // WebAssembly doesn't require alignment for stores + self.data[addr..addr + data.len()].copy_from_slice(data); + Ok(()) + } + + pub(crate) fn load(&self, addr: usize, align: usize, len: usize) -> Result<&[u8]> { + if addr + len > self.data.len() { + return Err(Error::Other(format!( + "memory load out of bounds: offset={}, len={}, mem_size={}", + addr, + len, + self.data.len() + ))); + } + + // WebAssembly doesn't require alignment for loads + Ok(&self.data[addr..addr + len]) + } + pub(crate) fn size(&self) -> i32 { self.page_count as i32 } diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index 4f7688c..c2c0cf1 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -2,4 +2,4 @@ 0.0.4,9258,10909,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"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.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17913,2307,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":212,"failed":11},{"name":"br.wast","passed":94,"failed":3},{"name":"br_if.wast","passed":107,"failed":11},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":49,"failed":42},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":54,"failed":45},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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 (skipped)","passed":0,"failed":0},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":132,"failed":40},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":95,"failed":15},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":126,"failed":115},{"name":"imports.wast","passed":76,"failed":107},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":19,"failed":113},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":79,"failed":18},{"name":"loop.wast","passed":108,"failed":12},{"name":"memory.wast","passed":37,"failed":42},{"name":"memory_grow.wast","passed":58,"failed":38},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":3,"failed":179},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":62,"failed":26},{"name":"return.wast","passed":81,"failed":3},{"name":"select.wast","passed":100,"failed":48},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":4,"failed":3},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":60,"failed":4},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17991,2237,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":215,"failed":8},{"name":"br.wast","passed":94,"failed":3},{"name":"br_if.wast","passed":107,"failed":11},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":52,"failed":39},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":54,"failed":45},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":12,"failed":78},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":132,"failed":40},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":97,"failed":13},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":126,"failed":115},{"name":"imports.wast","passed":76,"failed":107},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":19,"failed":113},{"name":"load.wast","passed":84,"failed":13},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":82,"failed":15},{"name":"loop.wast","passed":111,"failed":9},{"name":"memory.wast","passed":37,"failed":42},{"name":"memory_grow.wast","passed":70,"failed":26},{"name":"memory_redundancy.wast","passed":2,"failed":6},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":3,"failed":179},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":69,"failed":19},{"name":"return.wast","passed":81,"failed":3},{"name":"select.wast","passed":105,"failed":43},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":4,"failed":3},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":66,"failed":2},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":60,"failed":4},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index 9bf47fa..72a3b41 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -53,12 +53,12 @@ v0.1.0 (17630) -v0.2.0-alpha.0 (17882) +v0.2.0-alpha.0 (17991) - - + + diff --git a/crates/tinywasm/tests/test-mvp.rs b/crates/tinywasm/tests/test-mvp.rs index b9ae416..6f6d9b3 100644 --- a/crates/tinywasm/tests/test-mvp.rs +++ b/crates/tinywasm/tests/test-mvp.rs @@ -10,9 +10,6 @@ fn main() -> Result<()> { fn test_mvp() -> Result<()> { let mut test_suite = TestSuite::new(); - // currently hangs, so skip it for now - test_suite.skip(&["fac.wast"]); - TestSuite::set_log_level(log::LevelFilter::Off); test_suite.run_spec_group(wasm_testsuite::MVP_TESTS)?; diff --git a/crates/types/src/instructions.rs b/crates/types/src/instructions.rs index 535b727..01c5b6e 100644 --- a/crates/types/src/instructions.rs +++ b/crates/types/src/instructions.rs @@ -12,7 +12,9 @@ pub enum BlockArgs { /// Represents a memory immediate in a WebAssembly memory instruction. #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct MemArg { + pub mem_addr: MemAddr, pub align: u8, + pub align_max: u8, pub offset: u64, } From 93f9383cca9fdce04564bcb38a67f202b587a722 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sun, 7 Jan 2024 13:33:17 +0100 Subject: [PATCH 17/31] feat: all mem loads Signed-off-by: Henry Gressmann --- .../tinywasm/src/runtime/executor/macros.rs | 43 ++++++++++++++++--- crates/tinywasm/src/runtime/executor/mod.rs | 28 ++++++------ crates/tinywasm/tests/generated/mvp.csv | 2 +- .../tinywasm/tests/generated/progress-mvp.svg | 8 ++-- 4 files changed, 56 insertions(+), 25 deletions(-) diff --git a/crates/tinywasm/src/runtime/executor/macros.rs b/crates/tinywasm/src/runtime/executor/macros.rs index 61678f2..d10a19e 100644 --- a/crates/tinywasm/src/runtime/executor/macros.rs +++ b/crates/tinywasm/src/runtime/executor/macros.rs @@ -2,6 +2,32 @@ //! //! These macros are used to generate the actual instruction implementations. +macro_rules! mem_load { + ($type:ty, $arg:ident, $stack:ident, $store:ident, $module:ident) => {{ + mem_load!($type, $type, $arg, $stack, $store, $module) + }}; + + ($load_type:ty, $target_type:ty, $arg:ident, $stack:ident, $store:ident, $module:ident) => {{ + let mem_idx = $module.resolve_mem_addr($arg.mem_addr); + let mem = $store.get_mem(mem_idx as usize)?; + + let addr = $stack.values.pop()?.raw_value(); + + let val: [u8; core::mem::size_of::<$load_type>()] = { + let mem = mem.borrow_mut(); + let val = mem.load( + ($arg.offset + addr) as usize, + $arg.align as usize, + core::mem::size_of::<$load_type>(), + )?; + val.try_into().expect("slice with incorrect length") + }; + + let loaded_value = <$load_type>::from_le_bytes(val); + $stack.values.push((loaded_value as $target_type).into()); + }}; +} + /// Convert the top value on the stack to a specific type macro_rules! conv_1 { ($from:ty, $to:ty, $stack:ident) => {{ @@ -10,6 +36,10 @@ macro_rules! conv_1 { }}; } +/// Doing the actual conversion from float to int is a bit tricky, because +/// we need to check for overflow. This macro generates the min/max values +/// for a specific conversion, which are then used in the actual conversion. +/// Rust sadly doesn't have wrapping casts for floats (yet) macro_rules! float_min_max { (f32, i32) => { (-2147483904.0_f32, 2147483648.0_f32) @@ -18,22 +48,22 @@ macro_rules! float_min_max { (-2147483649.0_f64, 2147483648.0_f64) }; (f32, u32) => { - (-1.0_f32, 4294967296.0_f32) + (-1.0_f32, 4294967296.0_f32) // 2^32 }; (f64, u32) => { - (-1.0_f64, 4294967296.0_f64) + (-1.0_f64, 4294967296.0_f64) // 2^32 }; (f32, i64) => { - (-9223373136366403584.0_f32, 9223372036854775808.0_f32) + (-9223373136366403584.0_f32, 9223372036854775808.0_f32) // 2^63 + 2^40 | 2^63 }; (f64, i64) => { - (-9223372036854777856.0_f64, 9223372036854775808.0_f64) + (-9223372036854777856.0_f64, 9223372036854775808.0_f64) // 2^63 + 2^40 | 2^63 }; (f32, u64) => { - (-1.0_f32, 18446744073709551616.0_f32) + (-1.0_f32, 18446744073709551616.0_f32) // 2^64 }; (f64, u64) => { - (-1.0_f64, 18446744073709551616.0_f64) + (-1.0_f64, 18446744073709551616.0_f64) // 2^64 }; // other conversions are not allowed ($from:ty, $to:ty) => { @@ -212,3 +242,4 @@ pub(super) use comp_zero; pub(super) use conv_1; pub(super) use conv_2; pub(super) use float_min_max; +pub(super) use mem_load; diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs index dcb12d4..342e99b 100644 --- a/crates/tinywasm/src/runtime/executor/mod.rs +++ b/crates/tinywasm/src/runtime/executor/mod.rs @@ -313,20 +313,20 @@ fn exec_one( .store((arg.offset + addr) as usize, arg.align as usize, &val.to_le_bytes())?; } - I32Load(arg) => { - let mem_idx = module.resolve_mem_addr(arg.mem_addr); - let mem = store.get_mem(mem_idx as usize)?; - - let addr = stack.values.pop()?.raw_value(); - - let val: [u8; 4] = { - let mem = mem.borrow_mut(); - let val = mem.load((arg.offset + addr) as usize, arg.align as usize, 4)?; - val.try_into().expect("slice with incorrect length") - }; - - stack.values.push(i32::from_le_bytes(val).into()); - } + I32Load(arg) => mem_load!(i32, arg, stack, store, module), + I64Load(arg) => mem_load!(i64, arg, stack, store, module), + F32Load(arg) => mem_load!(f32, arg, stack, store, module), + F64Load(arg) => mem_load!(f64, arg, stack, store, module), + I32Load8S(arg) => mem_load!(i8, i32, arg, stack, store, module), + I32Load8U(arg) => mem_load!(u8, i32, arg, stack, store, module), + I32Load16S(arg) => mem_load!(i16, i32, arg, stack, store, module), + I32Load16U(arg) => mem_load!(u16, i32, arg, stack, store, module), + I64Load8S(arg) => mem_load!(i8, i64, arg, stack, store, module), + I64Load8U(arg) => mem_load!(u8, i64, arg, stack, store, module), + I64Load16S(arg) => mem_load!(i16, i64, arg, stack, store, module), + I64Load16U(arg) => mem_load!(u16, i64, arg, stack, store, module), + I64Load32S(arg) => mem_load!(i32, i64, arg, stack, store, module), + I64Load32U(arg) => mem_load!(u32, i64, arg, stack, store, module), I64Eqz => comp_zero!(==, i64, stack), I32Eqz => comp_zero!(==, i32, stack), diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index c2c0cf1..e8229c0 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -2,4 +2,4 @@ 0.0.4,9258,10909,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"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.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,17991,2237,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":215,"failed":8},{"name":"br.wast","passed":94,"failed":3},{"name":"br_if.wast","passed":107,"failed":11},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":52,"failed":39},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":54,"failed":45},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":12,"failed":78},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":132,"failed":40},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":97,"failed":13},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":126,"failed":115},{"name":"imports.wast","passed":76,"failed":107},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":19,"failed":113},{"name":"load.wast","passed":84,"failed":13},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":82,"failed":15},{"name":"loop.wast","passed":111,"failed":9},{"name":"memory.wast","passed":37,"failed":42},{"name":"memory_grow.wast","passed":70,"failed":26},{"name":"memory_redundancy.wast","passed":2,"failed":6},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":3,"failed":179},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":69,"failed":19},{"name":"return.wast","passed":81,"failed":3},{"name":"select.wast","passed":105,"failed":43},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":4,"failed":3},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":66,"failed":2},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":60,"failed":4},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,18027,2201,[{"name":"address.wast","passed":13,"failed":247},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":215,"failed":8},{"name":"br.wast","passed":94,"failed":3},{"name":"br_if.wast","passed":107,"failed":11},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":52,"failed":39},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":54,"failed":45},{"name":"endianness.wast","passed":5,"failed":64},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":763,"failed":137},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":30,"failed":60},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":132,"failed":40},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":97,"failed":13},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":126,"failed":115},{"name":"imports.wast","passed":76,"failed":107},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":19,"failed":113},{"name":"load.wast","passed":85,"failed":12},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":83,"failed":14},{"name":"loop.wast","passed":111,"failed":9},{"name":"memory.wast","passed":37,"failed":42},{"name":"memory_grow.wast","passed":71,"failed":25},{"name":"memory_redundancy.wast","passed":3,"failed":5},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":3,"failed":179},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":69,"failed":19},{"name":"return.wast","passed":81,"failed":3},{"name":"select.wast","passed":105,"failed":43},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":4,"failed":3},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":66,"failed":2},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":60,"failed":4},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index 72a3b41..263a599 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -53,12 +53,12 @@ v0.1.0 (17630) -v0.2.0-alpha.0 (17991) +v0.2.0-alpha.0 (18027) - - - + + + From f5119e7c94f93988195bebcae7eed208c445936c Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sun, 7 Jan 2024 14:02:53 +0100 Subject: [PATCH 18/31] chore: refactor executer macros Signed-off-by: Henry Gressmann --- .../tinywasm/src/runtime/executor/macros.rs | 172 ++++++--------- crates/tinywasm/src/runtime/executor/mod.rs | 202 +++++++++--------- 2 files changed, 162 insertions(+), 212 deletions(-) diff --git a/crates/tinywasm/src/runtime/executor/macros.rs b/crates/tinywasm/src/runtime/executor/macros.rs index d10a19e..3346732 100644 --- a/crates/tinywasm/src/runtime/executor/macros.rs +++ b/crates/tinywasm/src/runtime/executor/macros.rs @@ -2,12 +2,14 @@ //! //! These macros are used to generate the actual instruction implementations. +/// Load a value from memory macro_rules! mem_load { ($type:ty, $arg:ident, $stack:ident, $store:ident, $module:ident) => {{ mem_load!($type, $type, $arg, $stack, $store, $module) }}; ($load_type:ty, $target_type:ty, $arg:ident, $stack:ident, $store:ident, $module:ident) => {{ + // TODO: there could be a lot of performance improvements here let mem_idx = $module.resolve_mem_addr($arg.mem_addr); let mem = $store.get_mem(mem_idx as usize)?; @@ -28,14 +30,6 @@ macro_rules! mem_load { }}; } -/// Convert the top value on the stack to a specific type -macro_rules! conv_1 { - ($from:ty, $to:ty, $stack:ident) => {{ - let a: $from = $stack.values.pop()?.into(); - $stack.values.push((a as $to).into()); - }}; -} - /// Doing the actual conversion from float to int is a bit tricky, because /// we need to check for overflow. This macro generates the min/max values /// for a specific conversion, which are then used in the actual conversion. @@ -71,75 +65,56 @@ macro_rules! float_min_max { }; } -// Convert a float to an int, checking for overflow -macro_rules! checked_float_conv_1 { - ($from:tt, $to:tt, $stack:ident) => {{ - let (min, max) = float_min_max!($from, $to); +/// Convert a value on the stack +macro_rules! conv { + ($from:ty, $intermediate:ty, $to:ty, $stack:ident) => {{ + let a: $from = $stack.values.pop()?.into(); + $stack.values.push((a as $intermediate as $to).into()); + }}; + ($from:ty, $to:ty, $stack:ident) => {{ let a: $from = $stack.values.pop()?.into(); - - if a.is_nan() { - return Err(Error::Trap(crate::Trap::InvalidConversionToInt)); - } - - if a <= min || a >= max { - return Err(Error::Trap(crate::Trap::IntegerOverflow)); - } - $stack.values.push((a as $to).into()); }}; } -// Convert a float to an int, checking for overflow -macro_rules! checked_float_conv_2 { - ($from:tt, $uty:tt, $to:tt, $stack:ident) => {{ - let (min, max) = float_min_max!($from, $uty); +/// Convert a value on the stack with error checking +macro_rules! checked_conv_float { + // Direct conversion with error checking (two types) + ($from:tt, $to:tt, $stack:ident) => {{ + checked_conv_float!($from, $to, $to, $stack) + }}; + // Conversion with an intermediate unsigned type and error checking (three types) + ($from:tt, $intermediate:tt, $to:tt, $stack:ident) => {{ + let (min, max) = float_min_max!($from, $intermediate); let a: $from = $stack.values.pop()?.into(); if a.is_nan() { return Err(Error::Trap(crate::Trap::InvalidConversionToInt)); } - log::info!("a: {}", a); - log::info!("min: {}", min); - log::info!("max: {}", max); - if a <= min || a >= max { return Err(Error::Trap(crate::Trap::IntegerOverflow)); } - $stack.values.push((a as $uty as $to).into()); - }}; -} - -/// Convert the unsigned value on the top of the stack to a specific type -macro_rules! conv_2 { - ($ty:ty, $uty:ty, $to:ty, $stack:ident) => {{ - let a: $ty = $stack.values.pop()?.into(); - $stack.values.push((a as $uty as $to).into()); + $stack.values.push((a as $intermediate as $to).into()); }}; } /// Compare two values on the stack macro_rules! comp { ($op:tt, $ty:ty, $stack:ident) => {{ - let [a, b] = $stack.values.pop_n_const::<2>()?; - let a: $ty = a.into(); - let b: $ty = b.into(); - $stack.values.push(((a $op b) as i32).into()); + comp!($op, $ty, $ty, $stack) }}; -} -/// Compare two values on the stack (cast to ty2 before comparison) -macro_rules! comp_cast { - ($op:tt, $ty:ty, $ty2:ty, $stack:ident) => {{ + ($op:tt, $intermediate:ty, $to:ty, $stack:ident) => {{ let [a, b] = $stack.values.pop_n_const::<2>()?; - let a: $ty = a.into(); - let b: $ty = b.into(); + let a: $intermediate = a.into(); + let b: $intermediate = b.into(); // Cast to unsigned type before comparison - let a_unsigned: $ty2 = a as $ty2; - let b_unsigned: $ty2 = b as $ty2; - $stack.values.push(((a_unsigned $op b_unsigned) as i32).into()); + let a = a as $to; + let b = b as $to; + $stack.values.push(((a $op b) as i32).into()); }}; } @@ -151,27 +126,35 @@ macro_rules! comp_zero { }}; } -/// Apply an arithmetic operation to two values on the stack -macro_rules! arithmetic_op { +/// Apply an arithmetic method to two values on the stack +macro_rules! arithmetic { + ($op:ident, $ty:ty, $stack:ident) => {{ + arithmetic!($op, $ty, $ty, $stack) + }}; + + // also allow operators such as +, - ($op:tt, $ty:ty, $stack:ident) => {{ let [a, b] = $stack.values.pop_n_const::<2>()?; let a: $ty = a.into(); let b: $ty = b.into(); $stack.values.push((a $op b).into()); }}; -} -macro_rules! arithmetic_method { - ($op:ident, $ty:ty, $stack:ident) => {{ + ($op:ident, $intermediate:ty, $to:ty, $stack:ident) => {{ let [a, b] = $stack.values.pop_n_const::<2>()?; - let a: $ty = a.into(); - let b: $ty = b.into(); + let a: $to = a.into(); + let b: $to = b.into(); + + let a = a as $intermediate; + let b = b as $intermediate; + let result = a.$op(b); - $stack.values.push(result.into()); + $stack.values.push((result as $to).into()); }}; } -macro_rules! arithmetic_method_self { +/// Apply an arithmetic method to a single value on the stack +macro_rules! arithmetic_single { ($op:ident, $ty:ty, $stack:ident) => {{ let a: $ty = $stack.values.pop()?.into(); let result = a.$op(); @@ -179,67 +162,34 @@ macro_rules! arithmetic_method_self { }}; } -macro_rules! arithmetic_method_cast { - ($op:ident, $ty:ty, $ty2:ty, $stack:ident) => {{ - let [a, b] = $stack.values.pop_n_const::<2>()?; - let a: $ty = a.into(); - let b: $ty = b.into(); - - // Cast to unsigned type before operation - let a_unsigned: $ty2 = a as $ty2; - let b_unsigned: $ty2 = b as $ty2; - - let result = a_unsigned.$op(b_unsigned); - $stack.values.push((result as $ty).into()); +/// Apply an arithmetic operation to two values on the stack with error checking +macro_rules! checked_arithmetic { + // Direct conversion with error checking (two types) + ($from:tt, $to:tt, $stack:ident, $trap:expr) => {{ + checked_arithmetic!($from, $to, $to, $stack, $trap) }}; -} -/// Apply an arithmetic operation to two values on the stack -macro_rules! checked_arithmetic_method { - ($op:ident, $ty:ty, $stack:ident, $trap:expr) => {{ + ($op:ident, $from:ty, $to:ty, $stack:ident, $trap:expr) => {{ let [a, b] = $stack.values.pop_n_const::<2>()?; - let a: $ty = a.into(); - let b: $ty = b.into(); - let result = a.$op(b).ok_or_else(|| Error::Trap($trap))?; - debug!( - "checked_arithmetic_method: {}, a: {}, b: {}, res: {}", - stringify!($op), - a, - b, - result - ); - $stack.values.push(result.into()); - }}; -} + let a: $from = a.into(); + let b: $from = b.into(); -/// Apply an arithmetic operation to two values on the stack (cast to ty2 before operation) -macro_rules! checked_arithmetic_method_cast { - ($op:ident, $ty:ty, $ty2:ty, $stack:ident, $trap:expr) => {{ - let [a, b] = $stack.values.pop_n_const::<2>()?; - let a: $ty = a.into(); - let b: $ty = b.into(); + let a_casted: $to = a as $to; + let b_casted: $to = b as $to; - // Cast to unsigned type before operation - let a_unsigned: $ty2 = a as $ty2; - let b_unsigned: $ty2 = b as $ty2; + let result = a_casted.$op(b_casted).ok_or_else(|| Error::Trap($trap))?; - let result = a_unsigned.$op(b_unsigned).ok_or_else(|| Error::Trap($trap))?; - $stack.values.push((result as $ty).into()); + // Cast back to original type if different + $stack.values.push((result as $from).into()); }}; } -pub(super) use arithmetic_method; -pub(super) use arithmetic_method_cast; -pub(super) use arithmetic_method_self; -pub(super) use arithmetic_op; -pub(super) use checked_arithmetic_method; -pub(super) use checked_arithmetic_method_cast; -pub(super) use checked_float_conv_1; -pub(super) use checked_float_conv_2; +pub(super) use arithmetic; +pub(super) use arithmetic_single; +pub(super) use checked_arithmetic; +pub(super) use checked_conv_float; pub(super) use comp; -pub(super) use comp_cast; pub(super) use comp_zero; -pub(super) use conv_1; -pub(super) use conv_2; +pub(super) use conv; pub(super) use float_min_max; pub(super) use mem_load; diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs index 342e99b..5dcab99 100644 --- a/crates/tinywasm/src/runtime/executor/mod.rs +++ b/crates/tinywasm/src/runtime/executor/mod.rs @@ -343,122 +343,122 @@ fn exec_one( I32LtS => comp!(<, i32, stack), I64LtS => comp!(<, i64, stack), - I32LtU => comp_cast!(<, i32, u32, stack), - I64LtU => comp_cast!(<, i64, u64, stack), + I32LtU => comp!(<, i32, u32, stack), + I64LtU => comp!(<, i64, u64, stack), F32Lt => comp!(<, f32, stack), F64Lt => comp!(<, f64, stack), I32LeS => comp!(<=, i32, stack), I64LeS => comp!(<=, i64, stack), - I32LeU => comp_cast!(<=, i32, u32, stack), - I64LeU => comp_cast!(<=, i64, u64, stack), + I32LeU => comp!(<=, i32, u32, stack), + I64LeU => comp!(<=, i64, u64, stack), F32Le => comp!(<=, f32, stack), F64Le => comp!(<=, f64, stack), I32GeS => comp!(>=, i32, stack), I64GeS => comp!(>=, i64, stack), - I32GeU => comp_cast!(>=, i32, u32, stack), - I64GeU => comp_cast!(>=, i64, u64, stack), + I32GeU => comp!(>=, i32, u32, stack), + I64GeU => comp!(>=, i64, u64, stack), F32Ge => comp!(>=, f32, stack), F64Ge => comp!(>=, f64, stack), I32GtS => comp!(>, i32, stack), I64GtS => comp!(>, i64, stack), - I32GtU => comp_cast!(>, i32, u32, stack), - I64GtU => comp_cast!(>, i64, u64, stack), + I32GtU => comp!(>, i32, u32, stack), + I64GtU => comp!(>, i64, u64, stack), F32Gt => comp!(>, f32, stack), F64Gt => comp!(>, f64, stack), - I64Add => arithmetic_method!(wrapping_add, i64, stack), - I32Add => arithmetic_method!(wrapping_add, i32, stack), - F32Add => arithmetic_op!(+, f32, stack), - F64Add => arithmetic_op!(+, f64, stack), + I64Add => arithmetic!(wrapping_add, i64, stack), + I32Add => arithmetic!(wrapping_add, i32, stack), + F32Add => arithmetic!(+, f32, stack), + F64Add => arithmetic!(+, f64, stack), - I32Sub => arithmetic_method!(wrapping_sub, i32, stack), - I64Sub => arithmetic_method!(wrapping_sub, i64, stack), - F32Sub => arithmetic_op!(-, f32, stack), - F64Sub => arithmetic_op!(-, f64, stack), + I32Sub => arithmetic!(wrapping_sub, i32, stack), + I64Sub => arithmetic!(wrapping_sub, i64, stack), + F32Sub => arithmetic!(-, f32, stack), + F64Sub => arithmetic!(-, f64, stack), - F32Div => arithmetic_op!(/, f32, stack), - F64Div => arithmetic_op!(/, f64, stack), + F32Div => arithmetic!(/, f32, stack), + F64Div => arithmetic!(/, f64, stack), - I32Mul => arithmetic_method!(wrapping_mul, i32, stack), - I64Mul => arithmetic_method!(wrapping_mul, i64, stack), - F32Mul => arithmetic_op!(*, f32, stack), - F64Mul => arithmetic_op!(*, f64, stack), + I32Mul => arithmetic!(wrapping_mul, i32, stack), + I64Mul => arithmetic!(wrapping_mul, i64, stack), + F32Mul => arithmetic!(*, f32, stack), + F64Mul => arithmetic!(*, f64, stack), // these can trap - I32DivS => checked_arithmetic_method!(checked_div, i32, stack, crate::Trap::DivisionByZero), - I64DivS => checked_arithmetic_method!(checked_div, i64, stack, crate::Trap::DivisionByZero), - I32DivU => checked_arithmetic_method_cast!(checked_div, i32, u32, stack, crate::Trap::DivisionByZero), - I64DivU => checked_arithmetic_method_cast!(checked_div, i64, u64, stack, crate::Trap::DivisionByZero), - - I32RemS => checked_arithmetic_method!(checked_wrapping_rem, i32, stack, crate::Trap::DivisionByZero), - I64RemS => checked_arithmetic_method!(checked_wrapping_rem, i64, stack, crate::Trap::DivisionByZero), - I32RemU => checked_arithmetic_method_cast!(checked_wrapping_rem, i32, u32, stack, crate::Trap::DivisionByZero), - I64RemU => checked_arithmetic_method_cast!(checked_wrapping_rem, i64, u64, stack, crate::Trap::DivisionByZero), - - I32And => arithmetic_method!(bitand, i32, stack), - I64And => arithmetic_method!(bitand, i64, stack), - I32Or => arithmetic_method!(bitor, i32, stack), - I64Or => arithmetic_method!(bitor, i64, stack), - I32Xor => arithmetic_method!(bitxor, i32, stack), - I64Xor => arithmetic_method!(bitxor, i64, stack), - I32Shl => arithmetic_method!(wasm_shl, i32, stack), - I64Shl => arithmetic_method!(wasm_shl, i64, stack), - I32ShrS => arithmetic_method!(wasm_shr, i32, stack), - I64ShrS => arithmetic_method!(wasm_shr, i64, stack), - I32ShrU => arithmetic_method_cast!(wasm_shr, i32, u32, stack), - I64ShrU => arithmetic_method_cast!(wasm_shr, i64, u64, stack), - I32Rotl => arithmetic_method!(wasm_rotl, i32, stack), - I64Rotl => arithmetic_method!(wasm_rotl, i64, stack), - I32Rotr => arithmetic_method!(wasm_rotr, i32, stack), - I64Rotr => arithmetic_method!(wasm_rotr, i64, stack), - - I32Clz => arithmetic_method_self!(leading_zeros, i32, stack), - I64Clz => arithmetic_method_self!(leading_zeros, i64, stack), - I32Ctz => arithmetic_method_self!(trailing_zeros, i32, stack), - I64Ctz => arithmetic_method_self!(trailing_zeros, i64, stack), - I32Popcnt => arithmetic_method_self!(count_ones, i32, stack), - I64Popcnt => arithmetic_method_self!(count_ones, i64, stack), - - F32ConvertI32S => conv_1!(i32, f32, stack), - F32ConvertI64S => conv_1!(i64, f32, stack), - F64ConvertI32S => conv_1!(i32, f64, stack), - F64ConvertI64S => conv_1!(i64, f64, stack), - F32ConvertI32U => conv_2!(i32, u32, f32, stack), - F32ConvertI64U => conv_2!(i64, u64, f32, stack), - F64ConvertI32U => conv_2!(i32, u32, f64, stack), - F64ConvertI64U => conv_2!(i64, u64, f64, stack), - I32Extend8S => conv_2!(i32, i8, i32, stack), - I32Extend16S => conv_2!(i32, i16, i32, stack), - I64Extend8S => conv_2!(i64, i8, i64, stack), - I64Extend16S => conv_2!(i64, i16, i64, stack), - I64Extend32S => conv_2!(i64, i32, i64, stack), - I64ExtendI32U => conv_2!(i32, u32, i64, stack), - I64ExtendI32S => conv_1!(i32, i64, stack), - I32WrapI64 => conv_1!(i64, i32, stack), - - F32Abs => arithmetic_method_self!(abs, f32, stack), - F64Abs => arithmetic_method_self!(abs, f64, stack), - F32Neg => arithmetic_method_self!(neg, f32, stack), - F64Neg => arithmetic_method_self!(neg, f64, stack), - F32Ceil => arithmetic_method_self!(ceil, f32, stack), - F64Ceil => arithmetic_method_self!(ceil, f64, stack), - F32Floor => arithmetic_method_self!(floor, f32, stack), - F64Floor => arithmetic_method_self!(floor, f64, stack), - F32Trunc => arithmetic_method_self!(trunc, f32, stack), - F64Trunc => arithmetic_method_self!(trunc, f64, stack), - F32Nearest => arithmetic_method_self!(wasm_nearest, f32, stack), - F64Nearest => arithmetic_method_self!(wasm_nearest, f64, stack), - F32Sqrt => arithmetic_method_self!(sqrt, f32, stack), - F64Sqrt => arithmetic_method_self!(sqrt, f64, stack), - F32Min => arithmetic_method!(wasm_min, f32, stack), - F64Min => arithmetic_method!(wasm_min, f64, stack), - F32Max => arithmetic_method!(wasm_max, f32, stack), - F64Max => arithmetic_method!(wasm_max, f64, stack), - F32Copysign => arithmetic_method!(copysign, f32, stack), - F64Copysign => arithmetic_method!(copysign, f64, stack), + I32DivS => checked_arithmetic!(checked_div, i32, stack, crate::Trap::DivisionByZero), + I64DivS => checked_arithmetic!(checked_div, i64, stack, crate::Trap::DivisionByZero), + I32DivU => checked_arithmetic!(checked_div, i32, u32, stack, crate::Trap::DivisionByZero), + I64DivU => checked_arithmetic!(checked_div, i64, u64, stack, crate::Trap::DivisionByZero), + + I32RemS => checked_arithmetic!(checked_wrapping_rem, i32, stack, crate::Trap::DivisionByZero), + I64RemS => checked_arithmetic!(checked_wrapping_rem, i64, stack, crate::Trap::DivisionByZero), + I32RemU => checked_arithmetic!(checked_wrapping_rem, i32, u32, stack, crate::Trap::DivisionByZero), + I64RemU => checked_arithmetic!(checked_wrapping_rem, i64, u64, stack, crate::Trap::DivisionByZero), + + I32And => arithmetic!(bitand, i32, stack), + I64And => arithmetic!(bitand, i64, stack), + I32Or => arithmetic!(bitor, i32, stack), + I64Or => arithmetic!(bitor, i64, stack), + I32Xor => arithmetic!(bitxor, i32, stack), + I64Xor => arithmetic!(bitxor, i64, stack), + I32Shl => arithmetic!(wasm_shl, i32, stack), + I64Shl => arithmetic!(wasm_shl, i64, stack), + I32ShrS => arithmetic!(wasm_shr, i32, stack), + I64ShrS => arithmetic!(wasm_shr, i64, stack), + I32ShrU => arithmetic!(wasm_shr, u32, i32, stack), + I64ShrU => arithmetic!(wasm_shr, u64, i64, stack), + I32Rotl => arithmetic!(wasm_rotl, i32, stack), + I64Rotl => arithmetic!(wasm_rotl, i64, stack), + I32Rotr => arithmetic!(wasm_rotr, i32, stack), + I64Rotr => arithmetic!(wasm_rotr, i64, stack), + + I32Clz => arithmetic_single!(leading_zeros, i32, stack), + I64Clz => arithmetic_single!(leading_zeros, i64, stack), + I32Ctz => arithmetic_single!(trailing_zeros, i32, stack), + I64Ctz => arithmetic_single!(trailing_zeros, i64, stack), + I32Popcnt => arithmetic_single!(count_ones, i32, stack), + I64Popcnt => arithmetic_single!(count_ones, i64, stack), + + F32ConvertI32S => conv!(i32, f32, stack), + F32ConvertI64S => conv!(i64, f32, stack), + F64ConvertI32S => conv!(i32, f64, stack), + F64ConvertI64S => conv!(i64, f64, stack), + F32ConvertI32U => conv!(i32, u32, f32, stack), + F32ConvertI64U => conv!(i64, u64, f32, stack), + F64ConvertI32U => conv!(i32, u32, f64, stack), + F64ConvertI64U => conv!(i64, u64, f64, stack), + I32Extend8S => conv!(i32, i8, i32, stack), + I32Extend16S => conv!(i32, i16, i32, stack), + I64Extend8S => conv!(i64, i8, i64, stack), + I64Extend16S => conv!(i64, i16, i64, stack), + I64Extend32S => conv!(i64, i32, i64, stack), + I64ExtendI32U => conv!(i32, u32, i64, stack), + I64ExtendI32S => conv!(i32, i64, stack), + I32WrapI64 => conv!(i64, i32, stack), + + F32Abs => arithmetic_single!(abs, f32, stack), + F64Abs => arithmetic_single!(abs, f64, stack), + F32Neg => arithmetic_single!(neg, f32, stack), + F64Neg => arithmetic_single!(neg, f64, stack), + F32Ceil => arithmetic_single!(ceil, f32, stack), + F64Ceil => arithmetic_single!(ceil, f64, stack), + F32Floor => arithmetic_single!(floor, f32, stack), + F64Floor => arithmetic_single!(floor, f64, stack), + F32Trunc => arithmetic_single!(trunc, f32, stack), + F64Trunc => arithmetic_single!(trunc, f64, stack), + F32Nearest => arithmetic_single!(wasm_nearest, f32, stack), + F64Nearest => arithmetic_single!(wasm_nearest, f64, stack), + F32Sqrt => arithmetic_single!(sqrt, f32, stack), + F64Sqrt => arithmetic_single!(sqrt, f64, stack), + F32Min => arithmetic!(wasm_min, f32, stack), + F64Min => arithmetic!(wasm_min, f64, stack), + F32Max => arithmetic!(wasm_max, f32, stack), + F64Max => arithmetic!(wasm_max, f64, stack), + F32Copysign => arithmetic!(copysign, f32, stack), + F64Copysign => arithmetic!(copysign, f64, stack), // no-op instructions since types are erased at runtime I32ReinterpretF32 => {} @@ -467,14 +467,14 @@ fn exec_one( F64ReinterpretI64 => {} // unsigned versions of these are a bit broken atm - I32TruncF32S => checked_float_conv_1!(f32, i32, stack), - I32TruncF64S => checked_float_conv_1!(f64, i32, stack), - I32TruncF32U => checked_float_conv_2!(f32, u32, i32, stack), - I32TruncF64U => checked_float_conv_2!(f64, u32, i32, stack), - I64TruncF32S => checked_float_conv_1!(f32, i64, stack), - I64TruncF64S => checked_float_conv_1!(f64, i64, stack), - I64TruncF32U => checked_float_conv_2!(f32, u64, i64, stack), - I64TruncF64U => checked_float_conv_2!(f64, u64, i64, stack), + I32TruncF32S => checked_conv_float!(f32, i32, stack), + I32TruncF64S => checked_conv_float!(f64, i32, stack), + I32TruncF32U => checked_conv_float!(f32, u32, i32, stack), + I32TruncF64U => checked_conv_float!(f64, u32, i32, stack), + I64TruncF32S => checked_conv_float!(f32, i64, stack), + I64TruncF64S => checked_conv_float!(f64, i64, stack), + I64TruncF32U => checked_conv_float!(f32, u64, i64, stack), + I64TruncF64U => checked_conv_float!(f64, u64, i64, stack), i => { log::error!("unimplemented instruction: {:?}", i); From d8e058d3570c369c5f65870578991c9da9ce7397 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sun, 7 Jan 2024 14:07:41 +0100 Subject: [PATCH 19/31] feat: all mem stores Signed-off-by: Henry Gressmann --- .../tinywasm/src/runtime/executor/macros.rs | 22 +++++++++++++++++++ crates/tinywasm/src/runtime/executor/mod.rs | 19 ++++++++-------- crates/tinywasm/tests/generated/mvp.csv | 2 +- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/crates/tinywasm/src/runtime/executor/macros.rs b/crates/tinywasm/src/runtime/executor/macros.rs index 3346732..e82c159 100644 --- a/crates/tinywasm/src/runtime/executor/macros.rs +++ b/crates/tinywasm/src/runtime/executor/macros.rs @@ -30,6 +30,27 @@ macro_rules! mem_load { }}; } +/// Store a value to memory +macro_rules! mem_store { + ($type:ty, $arg:ident, $stack:ident, $store:ident, $module:ident) => {{ + mem_store!($type, $type, $arg, $stack, $store, $module) + }}; + + ($store_type:ty, $target_type:ty, $arg:ident, $stack:ident, $store:ident, $module:ident) => {{ + let mem_idx = $module.resolve_mem_addr($arg.mem_addr); + let mem = $store.get_mem(mem_idx as usize)?; + + let val = $stack.values.pop()?.raw_value(); + let addr = $stack.values.pop()?.raw_value(); + + let val = val as $store_type; + let val = val.to_le_bytes(); + + mem.borrow_mut() + .store(($arg.offset + addr) as usize, $arg.align as usize, &val)?; + }}; +} + /// Doing the actual conversion from float to int is a bit tricky, because /// we need to check for overflow. This macro generates the min/max values /// for a specific conversion, which are then used in the actual conversion. @@ -193,3 +214,4 @@ pub(super) use comp_zero; pub(super) use conv; pub(super) use float_min_max; pub(super) use mem_load; +pub(super) use mem_store; diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs index 5dcab99..8191d83 100644 --- a/crates/tinywasm/src/runtime/executor/mod.rs +++ b/crates/tinywasm/src/runtime/executor/mod.rs @@ -302,16 +302,15 @@ fn exec_one( } } - I32Store(arg) => { - let mem_idx = module.resolve_mem_addr(arg.mem_addr); - let mem = store.get_mem(mem_idx as usize)?; - - let val = stack.values.pop()?.raw_value(); - let addr = stack.values.pop()?.raw_value(); - - mem.borrow_mut() - .store((arg.offset + addr) as usize, arg.align as usize, &val.to_le_bytes())?; - } + I32Store(arg) => mem_store!(i32, arg, stack, store, module), + I64Store(arg) => mem_store!(i64, arg, stack, store, module), + F32Store(arg) => mem_store!(f32, arg, stack, store, module), + F64Store(arg) => mem_store!(f64, arg, stack, store, module), + I32Store8(arg) => mem_store!(i8, i32, arg, stack, store, module), + I32Store16(arg) => mem_store!(i16, i32, arg, stack, store, module), + I64Store8(arg) => mem_store!(i8, i64, arg, stack, store, module), + I64Store16(arg) => mem_store!(i16, i64, arg, stack, store, module), + I64Store32(arg) => mem_store!(i32, i64, arg, stack, store, module), I32Load(arg) => mem_load!(i32, arg, stack, store, module), I64Load(arg) => mem_load!(i64, arg, stack, store, module), diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index e8229c0..1d10bbb 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -2,4 +2,4 @@ 0.0.4,9258,10909,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"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.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,18027,2201,[{"name":"address.wast","passed":13,"failed":247},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":215,"failed":8},{"name":"br.wast","passed":94,"failed":3},{"name":"br_if.wast","passed":107,"failed":11},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":52,"failed":39},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":54,"failed":45},{"name":"endianness.wast","passed":5,"failed":64},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":763,"failed":137},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":30,"failed":60},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":132,"failed":40},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":97,"failed":13},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":126,"failed":115},{"name":"imports.wast","passed":76,"failed":107},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":19,"failed":113},{"name":"load.wast","passed":85,"failed":12},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":83,"failed":14},{"name":"loop.wast","passed":111,"failed":9},{"name":"memory.wast","passed":37,"failed":42},{"name":"memory_grow.wast","passed":71,"failed":25},{"name":"memory_redundancy.wast","passed":3,"failed":5},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":3,"failed":179},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":69,"failed":19},{"name":"return.wast","passed":81,"failed":3},{"name":"select.wast","passed":105,"failed":43},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":4,"failed":3},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":66,"failed":2},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":60,"failed":4},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,18183,2045,[{"name":"address.wast","passed":13,"failed":247},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":215,"failed":8},{"name":"br.wast","passed":94,"failed":3},{"name":"br_if.wast","passed":107,"failed":11},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":52,"failed":39},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":54,"failed":45},{"name":"endianness.wast","passed":21,"failed":48},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":765,"failed":135},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":30,"failed":60},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":132,"failed":40},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":98,"failed":12},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":126,"failed":115},{"name":"imports.wast","passed":76,"failed":107},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":91,"failed":5},{"name":"linking.wast","passed":19,"failed":113},{"name":"load.wast","passed":87,"failed":10},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":85,"failed":12},{"name":"loop.wast","passed":111,"failed":9},{"name":"memory.wast","passed":77,"failed":2},{"name":"memory_grow.wast","passed":73,"failed":23},{"name":"memory_redundancy.wast","passed":3,"failed":5},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":3,"failed":179},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":69,"failed":19},{"name":"return.wast","passed":81,"failed":3},{"name":"select.wast","passed":106,"failed":42},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":4,"failed":3},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":66,"failed":2},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":60,"failed":4},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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}] From 40e5dcfe139fe7a7e25a96b671690d0d34821620 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sun, 7 Jan 2024 14:15:53 +0100 Subject: [PATCH 20/31] chore: cleanup clippy errors Signed-off-by: Henry Gressmann --- crates/tinywasm/src/instance.rs | 5 +++-- crates/tinywasm/src/runtime/stack/call_stack.rs | 2 +- crates/tinywasm/src/runtime/stack/value_stack.rs | 6 ------ crates/tinywasm/src/runtime/value.rs | 2 +- crates/tinywasm/src/store.rs | 13 +++++++++---- crates/tinywasm/tests/generated/progress-mvp.svg | 8 ++++---- crates/tinywasm/tests/testsuite/indexmap.rs | 4 ++-- crates/tinywasm/tests/testsuite/run.rs | 3 +-- crates/tinywasm/tests/testsuite/util.rs | 2 +- 9 files changed, 22 insertions(+), 23 deletions(-) diff --git a/crates/tinywasm/src/instance.rs b/crates/tinywasm/src/instance.rs index c6fef46..7415d85 100644 --- a/crates/tinywasm/src/instance.rs +++ b/crates/tinywasm/src/instance.rs @@ -16,6 +16,7 @@ use crate::{ #[derive(Debug, Clone)] pub struct ModuleInstance(Arc); +#[allow(dead_code)] #[derive(Debug)] pub(crate) struct ModuleInstanceInner { pub(crate) store_id: usize, @@ -78,7 +79,7 @@ impl ModuleInstance { &self.0.func_addrs } - pub(crate) fn global_addrs(&self) -> &[GlobalAddr] { + pub(crate) fn _global_addrs(&self) -> &[GlobalAddr] { &self.0.global_addrs } @@ -100,7 +101,7 @@ impl ModuleInstance { } // resolve a table address to the global store address - pub(crate) fn resolve_table_addr(&self, addr: TableAddr) -> TableAddr { + pub(crate) fn _resolve_table_addr(&self, addr: TableAddr) -> TableAddr { self.0.table_addrs[addr as usize] } diff --git a/crates/tinywasm/src/runtime/stack/call_stack.rs b/crates/tinywasm/src/runtime/stack/call_stack.rs index 36d30c4..7874c54 100644 --- a/crates/tinywasm/src/runtime/stack/call_stack.rs +++ b/crates/tinywasm/src/runtime/stack/call_stack.rs @@ -97,7 +97,7 @@ impl CallFrame { .get_relative_to_top(break_to_relative as usize) .ok_or(Error::LabelStackUnderflow)?; - value_stack.break_to(break_to.stack_ptr, break_to.args.results as usize); + value_stack.break_to(break_to.stack_ptr, break_to.args.results); // instr_ptr points to the label instruction, but the next step // will increment it by 1 since we're changing the "current" instr_ptr diff --git a/crates/tinywasm/src/runtime/stack/value_stack.rs b/crates/tinywasm/src/runtime/stack/value_stack.rs index a45c33f..10054bc 100644 --- a/crates/tinywasm/src/runtime/stack/value_stack.rs +++ b/crates/tinywasm/src/runtime/stack/value_stack.rs @@ -2,7 +2,6 @@ use core::ops::Range; use crate::{runtime::RawWasmValue, Error, Result}; use alloc::vec::Vec; -use log::info; // minimum stack size pub(crate) const STACK_SIZE: usize = 1024; @@ -25,11 +24,6 @@ impl Default for ValueStack { } impl ValueStack { - #[cfg(test)] - pub(crate) fn data(&self) -> &[RawWasmValue] { - &self.stack - } - #[inline] pub(crate) fn extend_from_within(&mut self, range: Range) { self.top += range.len(); diff --git a/crates/tinywasm/src/runtime/value.rs b/crates/tinywasm/src/runtime/value.rs index 7217873..da79b0b 100644 --- a/crates/tinywasm/src/runtime/value.rs +++ b/crates/tinywasm/src/runtime/value.rs @@ -1,6 +1,6 @@ use core::fmt::Debug; -use tinywasm_types::{ConstInstruction, ValType, WasmValue}; +use tinywasm_types::{ValType, WasmValue}; /// A raw wasm value. /// diff --git a/crates/tinywasm/src/store.rs b/crates/tinywasm/src/store.rs index dd945a6..289b5b6 100644 --- a/crates/tinywasm/src/store.rs +++ b/crates/tinywasm/src/store.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] // TODO: remove this + use core::{ cell::RefCell, sync::atomic::{AtomicUsize, Ordering}, @@ -5,8 +7,8 @@ use core::{ use alloc::{format, rc::Rc, string::ToString, vec, vec::Vec}; use tinywasm_types::{ - Addr, Data, Element, ElementKind, FuncAddr, Function, Global, GlobalType, Import, Instruction, MemAddr, MemArg, - MemoryArch, MemoryType, ModuleInstanceAddr, TableAddr, TableType, TypeAddr, ValType, + Addr, Data, Element, ElementKind, FuncAddr, Function, Global, GlobalType, Import, Instruction, MemAddr, MemoryArch, + MemoryType, ModuleInstanceAddr, TableAddr, TableType, TypeAddr, ValType, }; use crate::{ @@ -155,6 +157,7 @@ impl Store { idx: ModuleInstanceAddr, ) -> Result> { // TODO: initialize imported globals + #![allow(clippy::unnecessary_filter_map)] // this is cleaner let imported_globals = wasm_imports .iter() .filter_map(|import| match &import.kind { @@ -170,6 +173,8 @@ impl Store { }; match global { Extern::Global(global) => Ok(global), + + #[allow(unreachable_patterns)] // this is non-exhaustive _ => Err(Error::Other(format!( "expected global import for {}::{}", import.module, import.name @@ -343,7 +348,7 @@ impl MemoryInstance { } } - pub(crate) fn store(&mut self, addr: usize, align: usize, data: &[u8]) -> Result<()> { + pub(crate) fn store(&mut self, addr: usize, _align: usize, data: &[u8]) -> Result<()> { if addr + data.len() > self.data.len() { return Err(Error::Other(format!( "memory store out of bounds: offset={}, len={}, mem_size={}", @@ -358,7 +363,7 @@ impl MemoryInstance { Ok(()) } - pub(crate) fn load(&self, addr: usize, align: usize, len: usize) -> Result<&[u8]> { + pub(crate) fn load(&self, addr: usize, _align: usize, len: usize) -> Result<&[u8]> { if addr + len > self.data.len() { return Err(Error::Other(format!( "memory load out of bounds: offset={}, len={}, mem_size={}", diff --git a/crates/tinywasm/tests/generated/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index 263a599..9f7e7a4 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -53,12 +53,12 @@ v0.1.0 (17630) -v0.2.0-alpha.0 (18027) +v0.2.0-alpha.0 (18183) - + - + - + diff --git a/crates/tinywasm/tests/testsuite/indexmap.rs b/crates/tinywasm/tests/testsuite/indexmap.rs index de0de7e..d4e3869 100644 --- a/crates/tinywasm/tests/testsuite/indexmap.rs +++ b/crates/tinywasm/tests/testsuite/indexmap.rs @@ -15,8 +15,8 @@ where } pub fn insert(&mut self, key: K, value: V) -> Option { - if self.map.contains_key(&key) { - return self.map.insert(key, value); + 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()); diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index 70eb70c..0ed1d1e 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -82,8 +82,7 @@ impl TestSuite { }) .expect("failed to instantiate module") })) - .map_err(|e| eyre!("failed to parse module: {:?}", try_downcast_panic(e))) - .and_then(|res| Ok(res)); + .map_err(|e| eyre!("failed to parse module: {:?}", try_downcast_panic(e))); match &result { Err(_) => last_module = None, diff --git a/crates/tinywasm/tests/testsuite/util.rs b/crates/tinywasm/tests/testsuite/util.rs index 2546ba3..6d0970e 100644 --- a/crates/tinywasm/tests/testsuite/util.rs +++ b/crates/tinywasm/tests/testsuite/util.rs @@ -52,7 +52,7 @@ pub fn exec_fn( pub fn catch_unwind_silent R, R>(f: F) -> std::thread::Result { let prev_hook = panic::take_hook(); panic::set_hook(Box::new(|_| {})); - let result = panic::catch_unwind(AssertUnwindSafe(|| f())); + let result = panic::catch_unwind(AssertUnwindSafe(f)); panic::set_hook(prev_hook); result } From aac8cab84445b7d3e261fdd6499c94cf6f7b5976 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sun, 7 Jan 2024 17:24:11 +0100 Subject: [PATCH 21/31] feat: finish if/else Signed-off-by: Henry Gressmann --- crates/tinywasm/src/runtime/executor/mod.rs | 76 ++++++++++--------- crates/tinywasm/src/runtime/stack.rs | 2 +- crates/tinywasm/src/runtime/stack/blocks.rs | 27 +++---- .../tinywasm/src/runtime/stack/call_stack.rs | 4 +- crates/tinywasm/tests/generated/mvp.csv | 2 +- .../tinywasm/tests/generated/progress-mvp.svg | 6 +- 6 files changed, 59 insertions(+), 58 deletions(-) diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs index 8191d83..4ce1581 100644 --- a/crates/tinywasm/src/runtime/executor/mod.rs +++ b/crates/tinywasm/src/runtime/executor/mod.rs @@ -2,10 +2,9 @@ use core::ops::{BitAnd, BitOr, BitXor, Neg}; use super::{DefaultRuntime, Stack}; use crate::{ - get_label_args, log::debug, runtime::{BlockType, LabelFrame}, - CallFrame, Error, ModuleInstance, Result, Store, + CallFrame, Error, LabelArgs, ModuleInstance, Result, Store, }; use alloc::vec::Vec; use log::info; @@ -132,30 +131,32 @@ fn exec_one( } If(args, else_offset, end_offset) => { - let end_instr_ptr = cf.instr_ptr + *end_offset; - - info!( - "if it's true, we'll jump to the next instruction (@{})", - cf.instr_ptr + 1 - ); - - if let Some(else_offset) = else_offset { - info!( - "else: {:?} (@{})", - instrs[cf.instr_ptr + else_offset], - cf.instr_ptr + else_offset - ); - }; - - info!("end: {:?} (@{})", instrs[end_instr_ptr], end_instr_ptr); - - if stack.values.pop_t::()? != 0 { + if stack.values.pop_t::()? == 0 { + if let Some(else_offset) = else_offset { + log::info!("entering else at {}", cf.instr_ptr + *else_offset); + cf.enter_label( + LabelFrame { + instr_ptr: cf.instr_ptr + *else_offset, + end_instr_ptr: cf.instr_ptr + *end_offset, + stack_ptr: stack.values.len(), // - params, + args: crate::LabelArgs::new(*args, module)?, + ty: BlockType::Else, + }, + &mut stack.values, + ); + cf.instr_ptr += *else_offset; + } else { + log::info!("skipping if"); + cf.instr_ptr += *end_offset + } + } else { + log::info!("entering then"); cf.enter_label( LabelFrame { instr_ptr: cf.instr_ptr, end_instr_ptr: cf.instr_ptr + *end_offset, stack_ptr: stack.values.len(), // - params, - args: get_label_args(*args, module)?, + args: LabelArgs::new(*args, module)?, ty: BlockType::If, }, &mut stack.values, @@ -163,6 +164,10 @@ fn exec_one( } } + // Else(_end_offset) => { + // // end the if block + // cf.break_to(0, &mut stack.values)?; + // } Loop(args, end_offset) => { // let params = stack.values.pop_block_params(*args, &module)?; cf.enter_label( @@ -170,7 +175,7 @@ fn exec_one( instr_ptr: cf.instr_ptr, end_instr_ptr: cf.instr_ptr + *end_offset, stack_ptr: stack.values.len(), // - params, - args: get_label_args(*args, module)?, + args: LabelArgs::new(*args, module)?, ty: BlockType::Loop, }, &mut stack.values, @@ -183,7 +188,7 @@ fn exec_one( instr_ptr: cf.instr_ptr, end_instr_ptr: cf.instr_ptr + *end_offset, stack_ptr: stack.values.len(), //- params, - args: get_label_args(*args, module)?, + args: LabelArgs::new(*args, module)?, ty: BlockType::Block, }, &mut stack.values, @@ -210,7 +215,7 @@ fn exec_one( BrIf(v) => { if stack.values.pop_t::()? > 0 { cf.break_to(*v, &mut stack.values)? - }; + } } Return => match stack.call_stack.is_empty() { @@ -235,21 +240,22 @@ fn exec_one( } } - EndBlockFrame => { - let blocks = &mut cf.labels; - - // remove the label from the label stack - let Some(block) = blocks.pop() else { - panic!("end: no label to end, this should have been validated by the parser"); + Else(end_offset) => { + let Some(block) = cf.labels.pop() else { + panic!("else: no label to end, this should have been validated by the parser"); }; let res_count = block.args.results; - info!("we want to keep {} values on the stack", res_count); - info!("current block stack ptr: {}", block.stack_ptr); - info!("stack: {:?}", stack.values); + stack.values.truncate_keep(block.stack_ptr, res_count); + cf.instr_ptr += *end_offset; + } - // trim the lable's stack from the stack - stack.values.truncate_keep(block.stack_ptr, res_count) + EndBlockFrame => { + // remove the label from the label stack + let Some(block) = cf.labels.pop() else { + panic!("end: no label to end, this should have been validated by the parser"); + }; + stack.values.truncate_keep(block.stack_ptr, block.args.results) } LocalGet(local_index) => stack.values.push(cf.get_local(*local_index as usize)), diff --git a/crates/tinywasm/src/runtime/stack.rs b/crates/tinywasm/src/runtime/stack.rs index 0912640..a7074ad 100644 --- a/crates/tinywasm/src/runtime/stack.rs +++ b/crates/tinywasm/src/runtime/stack.rs @@ -3,7 +3,7 @@ mod call_stack; mod value_stack; use self::{call_stack::CallStack, value_stack::ValueStack}; -pub(crate) use blocks::{get_label_args, BlockType, LabelFrame}; +pub(crate) use blocks::{BlockType, LabelArgs, LabelFrame}; pub(crate) use call_stack::CallFrame; /// A WebAssembly Stack diff --git a/crates/tinywasm/src/runtime/stack/blocks.rs b/crates/tinywasm/src/runtime/stack/blocks.rs index 05c9043..f448492 100644 --- a/crates/tinywasm/src/runtime/stack/blocks.rs +++ b/crates/tinywasm/src/runtime/stack/blocks.rs @@ -17,11 +17,6 @@ impl Labels { self.0.push(block); } - #[inline] - pub(crate) fn top(&self) -> Option<&LabelFrame> { - self.0.last() - } - #[inline] /// get the block at the given index, where 0 is the top of the stack pub(crate) fn get_relative_to_top(&self, index: usize) -> Option<&LabelFrame> { @@ -64,19 +59,21 @@ pub(crate) enum BlockType { Block, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub(crate) struct LabelArgs { pub(crate) params: usize, pub(crate) results: usize, } -pub(crate) fn get_label_args(args: BlockArgs, module: &ModuleInstance) -> Result { - Ok(match args { - BlockArgs::Empty => LabelArgs { params: 0, results: 0 }, - BlockArgs::Type(_) => LabelArgs { params: 0, results: 1 }, - BlockArgs::FuncType(t) => LabelArgs { - params: module.func_ty(t).params.len(), - results: module.func_ty(t).results.len(), - }, - }) +impl LabelArgs { + pub(crate) fn new(args: BlockArgs, module: &ModuleInstance) -> Result { + Ok(match args { + BlockArgs::Empty => LabelArgs { params: 0, results: 0 }, + BlockArgs::Type(_) => LabelArgs { params: 0, results: 1 }, + BlockArgs::FuncType(t) => LabelArgs { + params: module.func_ty(t).params.len(), + results: module.func_ty(t).results.len(), + }, + }) + } } diff --git a/crates/tinywasm/src/runtime/stack/call_stack.rs b/crates/tinywasm/src/runtime/stack/call_stack.rs index 7874c54..88daa7f 100644 --- a/crates/tinywasm/src/runtime/stack/call_stack.rs +++ b/crates/tinywasm/src/runtime/stack/call_stack.rs @@ -91,7 +91,6 @@ impl CallFrame { /// Break to a block at the given index (relative to the current frame) #[inline] pub(crate) fn break_to(&mut self, break_to_relative: u32, value_stack: &mut super::ValueStack) -> Result<()> { - let current_label = self.labels.top().ok_or(Error::LabelStackUnderflow)?; let break_to = self .labels .get_relative_to_top(break_to_relative as usize) @@ -109,7 +108,7 @@ impl CallFrame { // we also want to trim the label stack to the loop (but not including the loop) self.labels.truncate(self.labels.len() - break_to_relative as usize); } - BlockType::Block => { + BlockType::Block | BlockType::If | BlockType::Else => { // this is a block, so we want to jump to the next instruction after the block ends (the inst_ptr will be incremented by 1 before the next instruction is executed) self.instr_ptr = break_to.end_instr_ptr; @@ -117,7 +116,6 @@ impl CallFrame { self.labels .truncate(self.labels.len() - (break_to_relative as usize + 1)); } - _ => unimplemented!("break to block type: {:?}", current_label.ty), } // self.instr_ptr = block_frame.instr_ptr; diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index 1d10bbb..ca9bc91 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -2,4 +2,4 @@ 0.0.4,9258,10909,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"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.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,18183,2045,[{"name":"address.wast","passed":13,"failed":247},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":215,"failed":8},{"name":"br.wast","passed":94,"failed":3},{"name":"br_if.wast","passed":107,"failed":11},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":52,"failed":39},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":54,"failed":45},{"name":"endianness.wast","passed":21,"failed":48},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":765,"failed":135},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":30,"failed":60},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":132,"failed":40},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":98,"failed":12},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":126,"failed":115},{"name":"imports.wast","passed":76,"failed":107},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":91,"failed":5},{"name":"linking.wast","passed":19,"failed":113},{"name":"load.wast","passed":87,"failed":10},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":85,"failed":12},{"name":"loop.wast","passed":111,"failed":9},{"name":"memory.wast","passed":77,"failed":2},{"name":"memory_grow.wast","passed":73,"failed":23},{"name":"memory_redundancy.wast","passed":3,"failed":5},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":3,"failed":179},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":69,"failed":19},{"name":"return.wast","passed":81,"failed":3},{"name":"select.wast","passed":106,"failed":42},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":4,"failed":3},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":66,"failed":2},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":60,"failed":4},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,18444,1784,[{"name":"address.wast","passed":13,"failed":247},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":217,"failed":6},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":115,"failed":3},{"name":"br_table.wast","passed":27,"failed":147},{"name":"call.wast","passed":71,"failed":20},{"name":"call_indirect.wast","passed":50,"failed":120},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":54,"failed":45},{"name":"endianness.wast","passed":21,"failed":48},{"name":"exports.wast","passed":92,"failed":4},{"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":6,"failed":2},{"name":"float_exprs.wast","passed":829,"failed":71},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":30,"failed":60},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":132,"failed":40},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":101,"failed":9},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":226,"failed":15},{"name":"imports.wast","passed":76,"failed":107},{"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":17,"failed":12},{"name":"left-to-right.wast","passed":91,"failed":5},{"name":"linking.wast","passed":19,"failed":113},{"name":"load.wast","passed":90,"failed":7},{"name":"local_get.wast","passed":34,"failed":2},{"name":"local_set.wast","passed":51,"failed":2},{"name":"local_tee.wast","passed":88,"failed":9},{"name":"loop.wast","passed":113,"failed":7},{"name":"memory.wast","passed":78,"failed":1},{"name":"memory_grow.wast","passed":76,"failed":20},{"name":"memory_redundancy.wast","passed":3,"failed":5},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":3,"failed":179},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":74,"failed":14},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":110,"failed":38},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":67,"failed":1},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index 9f7e7a4..256ac7c 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -53,12 +53,12 @@ v0.1.0 (17630) -v0.2.0-alpha.0 (18183) +v0.2.0-alpha.0 (18444) + - + - From cc1c5bb8326509f8e1af3e35ceeda200f00c93e4 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sun, 7 Jan 2024 17:47:19 +0100 Subject: [PATCH 22/31] feat: float improvments Signed-off-by: Henry Gressmann --- .../tinywasm/src/runtime/executor/macros.rs | 2 +- crates/tinywasm/src/runtime/executor/mod.rs | 3 +++ crates/tinywasm/src/runtime/value.rs | 3 +++ crates/tinywasm/tests/generated/mvp.csv | 2 +- .../tinywasm/tests/generated/progress-mvp.svg | 8 +++--- crates/tinywasm/tests/testsuite/run.rs | 27 +++++++++++++++++++ 6 files changed, 39 insertions(+), 6 deletions(-) diff --git a/crates/tinywasm/src/runtime/executor/macros.rs b/crates/tinywasm/src/runtime/executor/macros.rs index e82c159..5942f60 100644 --- a/crates/tinywasm/src/runtime/executor/macros.rs +++ b/crates/tinywasm/src/runtime/executor/macros.rs @@ -40,7 +40,7 @@ macro_rules! mem_store { let mem_idx = $module.resolve_mem_addr($arg.mem_addr); let mem = $store.get_mem(mem_idx as usize)?; - let val = $stack.values.pop()?.raw_value(); + let val = $stack.values.pop_t::<$store_type>()?; let addr = $stack.values.pop()?.raw_value(); let val = val as $store_type; diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs index 4ce1581..22cb204 100644 --- a/crates/tinywasm/src/runtime/executor/mod.rs +++ b/crates/tinywasm/src/runtime/executor/mod.rs @@ -444,6 +444,9 @@ fn exec_one( I64ExtendI32S => conv!(i32, i64, stack), I32WrapI64 => conv!(i64, i32, stack), + F32DemoteF64 => conv!(f64, f32, stack), + F64PromoteF32 => conv!(f32, f64, stack), + F32Abs => arithmetic_single!(abs, f32, stack), F64Abs => arithmetic_single!(abs, f64, stack), F32Neg => arithmetic_single!(neg, f32, stack), diff --git a/crates/tinywasm/src/runtime/value.rs b/crates/tinywasm/src/runtime/value.rs index da79b0b..aedb09d 100644 --- a/crates/tinywasm/src/runtime/value.rs +++ b/crates/tinywasm/src/runtime/value.rs @@ -69,3 +69,6 @@ impl_from_raw_wasm_value!(i32, |x| x as u64, |x| x as i32); impl_from_raw_wasm_value!(i64, |x| x as u64, |x| x as i64); impl_from_raw_wasm_value!(f32, |x| f32::to_bits(x) as u64, |x| f32::from_bits(x as u32)); impl_from_raw_wasm_value!(f64, f64::to_bits, f64::from_bits); + +impl_from_raw_wasm_value!(i8, |x| x as u64, |x| x as i8); +impl_from_raw_wasm_value!(i16, |x| x as u64, |x| x as i16); diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index ca9bc91..92002dd 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -2,4 +2,4 @@ 0.0.4,9258,10909,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"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.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,18444,1784,[{"name":"address.wast","passed":13,"failed":247},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":217,"failed":6},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":115,"failed":3},{"name":"br_table.wast","passed":27,"failed":147},{"name":"call.wast","passed":71,"failed":20},{"name":"call_indirect.wast","passed":50,"failed":120},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":54,"failed":45},{"name":"endianness.wast","passed":21,"failed":48},{"name":"exports.wast","passed":92,"failed":4},{"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":6,"failed":2},{"name":"float_exprs.wast","passed":829,"failed":71},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":30,"failed":60},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":132,"failed":40},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":101,"failed":9},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":226,"failed":15},{"name":"imports.wast","passed":76,"failed":107},{"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":17,"failed":12},{"name":"left-to-right.wast","passed":91,"failed":5},{"name":"linking.wast","passed":19,"failed":113},{"name":"load.wast","passed":90,"failed":7},{"name":"local_get.wast","passed":34,"failed":2},{"name":"local_set.wast","passed":51,"failed":2},{"name":"local_tee.wast","passed":88,"failed":9},{"name":"loop.wast","passed":113,"failed":7},{"name":"memory.wast","passed":78,"failed":1},{"name":"memory_grow.wast","passed":76,"failed":20},{"name":"memory_redundancy.wast","passed":3,"failed":5},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":3,"failed":179},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":74,"failed":14},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":110,"failed":38},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":67,"failed":1},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,18642,1586,[{"name":"address.wast","passed":13,"failed":247},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":217,"failed":6},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":115,"failed":3},{"name":"br_table.wast","passed":27,"failed":147},{"name":"call.wast","passed":71,"failed":20},{"name":"call_indirect.wast","passed":50,"failed":120},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":439,"failed":180},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":54,"failed":45},{"name":"endianness.wast","passed":29,"failed":40},{"name":"exports.wast","passed":92,"failed":4},{"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":6,"failed":2},{"name":"float_exprs.wast","passed":890,"failed":10},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":78,"failed":12},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":132,"failed":40},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":101,"failed":9},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":226,"failed":15},{"name":"imports.wast","passed":76,"failed":107},{"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":17,"failed":12},{"name":"left-to-right.wast","passed":91,"failed":5},{"name":"linking.wast","passed":19,"failed":113},{"name":"load.wast","passed":90,"failed":7},{"name":"local_get.wast","passed":35,"failed":1},{"name":"local_set.wast","passed":52,"failed":1},{"name":"local_tee.wast","passed":90,"failed":7},{"name":"loop.wast","passed":113,"failed":7},{"name":"memory.wast","passed":78,"failed":1},{"name":"memory_grow.wast","passed":76,"failed":20},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":3,"failed":179},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":74,"failed":14},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":110,"failed":38},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":13,"failed":7},{"name":"store.wast","passed":67,"failed":1},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index 256ac7c..8c00424 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -53,12 +53,12 @@ v0.1.0 (17630) -v0.2.0-alpha.0 (18444) +v0.2.0-alpha.0 (18642) + - - - + + diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index 0ed1d1e..f0f78cd 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -181,6 +181,33 @@ impl TestSuite { } } + Invoke(invoke) => { + let name = invoke.name; + let res: Result, _> = catch_unwind_silent(|| { + let args = invoke + .args + .into_iter() + .map(wastarg2tinywasmvalue) + .collect::>>() + .map_err(|e| { + error!("failed to convert args: {:?}", e); + e + })?; + + exec_fn_instance(last_module.as_ref(), &mut store, invoke.name, &args).map_err(|e| { + error!("failed to execute function: {:?}", e); + e + })?; + Ok(()) + }); + + 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); + } + AssertReturn { span, exec, results } => { info!("AssertReturn: {:?}", exec); From 29018ba694ef866cc06e0156acbe320226c5d10a Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sun, 7 Jan 2024 22:08:20 +0100 Subject: [PATCH 23/31] chore: progress towards linking modules Signed-off-by: Henry Gressmann --- crates/tinywasm/src/imports.rs | 35 ++++++++-- crates/tinywasm/src/instance.rs | 11 ++- .../tinywasm/src/runtime/executor/macros.rs | 3 + crates/tinywasm/src/runtime/executor/mod.rs | 5 +- crates/tinywasm/src/runtime/stack.rs | 4 -- crates/tinywasm/src/store.rs | 69 ++++++++++++------- crates/tinywasm/tests/generated/mvp.csv | 2 +- .../tinywasm/tests/generated/progress-mvp.svg | 8 +-- crates/tinywasm/tests/testsuite/run.rs | 39 ++++++++--- 9 files changed, 119 insertions(+), 57 deletions(-) diff --git a/crates/tinywasm/src/imports.rs b/crates/tinywasm/src/imports.rs index 99ebc4b..37fb60e 100644 --- a/crates/tinywasm/src/imports.rs +++ b/crates/tinywasm/src/imports.rs @@ -3,7 +3,7 @@ use alloc::{ collections::BTreeMap, string::{String, ToString}, }; -use tinywasm_types::{Global, GlobalType, WasmValue}; +use tinywasm_types::{Global, GlobalType, ModuleInstanceAddr, WasmValue}; #[derive(Debug)] #[non_exhaustive] @@ -11,6 +11,8 @@ use tinywasm_types::{Global, GlobalType, WasmValue}; pub enum Extern { /// A global value Global(Global), + /// A registered module + Module(String), // Func(HostFunc), // Table(Table), } @@ -39,6 +41,20 @@ pub struct ExternName { /// Imports for a module instance pub struct Imports { values: BTreeMap, + modules: BTreeMap, +} + +pub(crate) struct LinkedImports { + pub(crate) values: BTreeMap, +} + +impl LinkedImports { + pub(crate) fn get(&self, module: &str, name: &str) -> Option<&Extern> { + self.values.get(&ExternName { + module: module.to_string(), + name: name.to_string(), + }) + } } impl Imports { @@ -46,9 +62,18 @@ impl Imports { pub fn new() -> Self { Imports { values: BTreeMap::new(), + modules: BTreeMap::new(), } } + /// Link a module + /// + /// This will automatically link all imported values + pub fn link_module(&mut self, name: &str, addr: ModuleInstanceAddr) -> Result<&mut Self> { + self.modules.insert(name.to_string(), addr); + Ok(self) + } + /// Define an import pub fn define(&mut self, module: &str, name: &str, value: Extern) -> Result<&mut Self> { self.values.insert( @@ -61,10 +86,8 @@ impl Imports { Ok(self) } - pub(crate) fn get(&self, module: &str, name: &str) -> Option<&Extern> { - self.values.get(&ExternName { - module: module.to_string(), - name: name.to_string(), - }) + pub(crate) fn link(self, store: &mut crate::Store, module: &crate::Module) -> Result { + let values = self.values; + Ok(LinkedImports { values }) } } diff --git a/crates/tinywasm/src/instance.rs b/crates/tinywasm/src/instance.rs index 7415d85..0ef63a9 100644 --- a/crates/tinywasm/src/instance.rs +++ b/crates/tinywasm/src/instance.rs @@ -36,17 +36,22 @@ pub(crate) struct ModuleInstanceInner { } impl ModuleInstance { + /// Get the module instance's address + pub fn id(&self) -> ModuleInstanceAddr { + self.0.idx + } + /// Instantiate the module in the given store pub fn instantiate(store: &mut Store, module: Module, imports: Option) -> Result { let idx = store.next_module_instance_idx(); let imports = imports.unwrap_or_default(); + let linked_imports = imports.link(store, &module)?; let func_addrs = store.add_funcs(module.data.funcs.into(), idx); let table_addrs = store.add_tables(module.data.table_types.into(), idx); let mem_addrs = store.add_mems(module.data.memory_types.into(), idx)?; - - let global_addrs = store.add_globals(module.data.globals.into(), &module.data.imports, &imports, idx)?; - let elem_addrs = store.add_elems(module.data.elements.into(), idx); + let global_addrs = store.add_globals(module.data.globals.into(), &module.data.imports, &linked_imports, idx)?; + let elem_addrs = store.add_elems(module.data.elements.into(), idx)?; let data_addrs = store.add_datas(module.data.data.into(), idx); let instance = ModuleInstanceInner { diff --git a/crates/tinywasm/src/runtime/executor/macros.rs b/crates/tinywasm/src/runtime/executor/macros.rs index 5942f60..08e2149 100644 --- a/crates/tinywasm/src/runtime/executor/macros.rs +++ b/crates/tinywasm/src/runtime/executor/macros.rs @@ -1,6 +1,8 @@ //! More generic macros for various instructions //! //! These macros are used to generate the actual instruction implementations. +//! In some basic tests this generated better assembly than using generic functions, even when inlined. +//! (Something to revisit in the future) /// Load a value from memory macro_rules! mem_load { @@ -37,6 +39,7 @@ macro_rules! mem_store { }}; ($store_type:ty, $target_type:ty, $arg:ident, $stack:ident, $store:ident, $module:ident) => {{ + // likewise, there could be a lot of performance improvements here let mem_idx = $module.resolve_mem_addr($arg.mem_addr); let mem = $store.get_mem(mem_idx as usize)?; diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs index 22cb204..d7d8fc7 100644 --- a/crates/tinywasm/src/runtime/executor/mod.rs +++ b/crates/tinywasm/src/runtime/executor/mod.rs @@ -164,10 +164,6 @@ fn exec_one( } } - // Else(_end_offset) => { - // // end the if block - // cf.break_to(0, &mut stack.values)?; - // } Loop(args, end_offset) => { // let params = stack.values.pop_block_params(*args, &module)?; cf.enter_label( @@ -240,6 +236,7 @@ fn exec_one( } } + // We're essentially using else as a EndBlockFrame instruction Else(end_offset) => { let Some(block) = cf.labels.pop() else { panic!("else: no label to end, this should have been validated by the parser"); diff --git a/crates/tinywasm/src/runtime/stack.rs b/crates/tinywasm/src/runtime/stack.rs index a7074ad..07d9316 100644 --- a/crates/tinywasm/src/runtime/stack.rs +++ b/crates/tinywasm/src/runtime/stack.rs @@ -9,10 +9,6 @@ pub(crate) use call_stack::CallFrame; /// A WebAssembly Stack #[derive(Debug, Default)] pub struct Stack { - // keeping this typed for now to make it easier to debug - // TODO: Maybe split into Vec and Vec for better memory usage? pub(crate) values: ValueStack, - - /// The call stack pub(crate) call_stack: CallStack, } diff --git a/crates/tinywasm/src/store.rs b/crates/tinywasm/src/store.rs index 289b5b6..a50e8b2 100644 --- a/crates/tinywasm/src/store.rs +++ b/crates/tinywasm/src/store.rs @@ -13,7 +13,7 @@ use tinywasm_types::{ use crate::{ runtime::{self, DefaultRuntime}, - Error, Extern, Imports, ModuleInstance, RawWasmValue, Result, + Error, Extern, LinkedImports, ModuleInstance, RawWasmValue, Result, }; // global store id counter @@ -153,7 +153,7 @@ impl Store { &mut self, globals: Vec, wasm_imports: &[Import], - user_imports: &Imports, + user_imports: &LinkedImports, idx: ModuleInstanceAddr, ) -> Result> { // TODO: initialize imported globals @@ -191,41 +191,58 @@ impl Store { let iterator = imported_globals.into_iter().chain(globals.as_ref()); for (i, global) in iterator.enumerate() { - use tinywasm_types::ConstInstruction::*; - let val = match global.init { - F32Const(f) => RawWasmValue::from(f), - F64Const(f) => RawWasmValue::from(f), - I32Const(i) => RawWasmValue::from(i), - I64Const(i) => RawWasmValue::from(i), - GlobalGet(addr) => { - let addr = global_addrs[addr as usize]; - let global = self.data.globals[addr as usize].clone(); - let val = global.borrow().value; - val - } - RefNull(_) => RawWasmValue::default(), - RefFunc(idx) => RawWasmValue::from(idx as i64), - }; - - self.data - .globals - .push(Rc::new(RefCell::new(GlobalInstance::new(global.ty, val, idx)))); - + self.data.globals.push(Rc::new(RefCell::new(GlobalInstance::new( + global.ty, + self.eval_const(&global.init)?, + idx, + )))); global_addrs.push((i + global_count) as Addr); } - log::debug!("global_addrs: {:?}", global_addrs); + Ok(global_addrs) } + pub(crate) fn eval_const(&self, const_instr: &tinywasm_types::ConstInstruction) -> Result { + use tinywasm_types::ConstInstruction::*; + let val = match const_instr { + F32Const(f) => RawWasmValue::from(*f), + F64Const(f) => RawWasmValue::from(*f), + I32Const(i) => RawWasmValue::from(*i), + I64Const(i) => RawWasmValue::from(*i), + GlobalGet(addr) => { + let addr = *addr as usize; + let global = self.data.globals[addr].clone(); + let val = global.borrow().value; + val + } + RefNull(_) => RawWasmValue::default(), + RefFunc(idx) => RawWasmValue::from(*idx as i64), + }; + Ok(val) + } + /// Add elements to the store, returning their addresses in the store - pub(crate) fn add_elems(&mut self, elems: Vec, idx: ModuleInstanceAddr) -> Vec { + /// Should be called after the tables have been added + pub(crate) fn add_elems(&mut self, elems: Vec, idx: ModuleInstanceAddr) -> Result> { let elem_count = self.data.elems.len(); let mut elem_addrs = Vec::with_capacity(elem_count); for (i, elem) in elems.into_iter().enumerate() { self.data.elems.push(ElemInstance::new(elem.kind, idx)); elem_addrs.push((i + elem_count) as Addr); + + // match elem.kind { + // ElementKind::Active { table, offset } => { + // // let table = self.data.tables[table as usize]; + + // // let offset = self.eval_const(&offset)?; + // // let offset = offset.raw_value() as usize; + // // let offset = offset + elem_addrs[i] as usize; + // // let offset = offset as Addr; + // } + // } } - elem_addrs + + Ok(elem_addrs) } /// Add data to the store, returning their addresses in the store @@ -313,8 +330,8 @@ pub(crate) struct TableInstance { impl TableInstance { pub(crate) fn new(kind: TableType, owner: ModuleInstanceAddr) -> Self { Self { + elements: vec![0; kind.size_initial as usize], kind, - elements: Vec::new(), owner, } } diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index 92002dd..ff3e9cf 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -2,4 +2,4 @@ 0.0.4,9258,10909,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"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.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,18642,1586,[{"name":"address.wast","passed":13,"failed":247},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":217,"failed":6},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":115,"failed":3},{"name":"br_table.wast","passed":27,"failed":147},{"name":"call.wast","passed":71,"failed":20},{"name":"call_indirect.wast","passed":50,"failed":120},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":439,"failed":180},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":54,"failed":45},{"name":"endianness.wast","passed":29,"failed":40},{"name":"exports.wast","passed":92,"failed":4},{"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":6,"failed":2},{"name":"float_exprs.wast","passed":890,"failed":10},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":78,"failed":12},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":132,"failed":40},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":101,"failed":9},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":226,"failed":15},{"name":"imports.wast","passed":76,"failed":107},{"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":17,"failed":12},{"name":"left-to-right.wast","passed":91,"failed":5},{"name":"linking.wast","passed":19,"failed":113},{"name":"load.wast","passed":90,"failed":7},{"name":"local_get.wast","passed":35,"failed":1},{"name":"local_set.wast","passed":52,"failed":1},{"name":"local_tee.wast","passed":90,"failed":7},{"name":"loop.wast","passed":113,"failed":7},{"name":"memory.wast","passed":78,"failed":1},{"name":"memory_grow.wast","passed":76,"failed":20},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":3,"failed":179},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":74,"failed":14},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":110,"failed":38},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":13,"failed":7},{"name":"store.wast","passed":67,"failed":1},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,18657,1571,[{"name":"address.wast","passed":13,"failed":247},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":217,"failed":6},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":115,"failed":3},{"name":"br_table.wast","passed":27,"failed":147},{"name":"call.wast","passed":71,"failed":20},{"name":"call_indirect.wast","passed":50,"failed":120},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":439,"failed":180},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":56,"failed":43},{"name":"endianness.wast","passed":29,"failed":40},{"name":"exports.wast","passed":92,"failed":4},{"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":6,"failed":2},{"name":"float_exprs.wast","passed":890,"failed":10},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":78,"failed":12},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":132,"failed":40},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":101,"failed":9},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":226,"failed":15},{"name":"imports.wast","passed":80,"failed":103},{"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":17,"failed":12},{"name":"left-to-right.wast","passed":91,"failed":5},{"name":"linking.wast","passed":28,"failed":104},{"name":"load.wast","passed":90,"failed":7},{"name":"local_get.wast","passed":35,"failed":1},{"name":"local_set.wast","passed":52,"failed":1},{"name":"local_tee.wast","passed":90,"failed":7},{"name":"loop.wast","passed":113,"failed":7},{"name":"memory.wast","passed":78,"failed":1},{"name":"memory_grow.wast","passed":76,"failed":20},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":3,"failed":179},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":74,"failed":14},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":110,"failed":38},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":13,"failed":7},{"name":"store.wast","passed":67,"failed":1},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index 8c00424..caad2bb 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -53,12 +53,12 @@ v0.1.0 (17630) -v0.2.0-alpha.0 (18642) +v0.2.0-alpha.0 (18657) - - - + + + diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index f0f78cd..d34df6c 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -8,7 +8,7 @@ use super::TestSuite; use eyre::{eyre, Result}; use log::{debug, error, info}; use tinywasm::{Extern, Imports, ModuleInstance}; -use tinywasm_types::WasmValue; +use tinywasm_types::{ModuleInstanceAddr, WasmValue}; use wast::{lexer::Lexer, parser::ParseBuffer, Wast}; impl TestSuite { @@ -22,12 +22,18 @@ impl TestSuite { Ok(()) } - fn imports() -> Result { + fn imports(registered_modules: Vec<(String, ModuleInstanceAddr)>) -> Result { let mut imports = Imports::new(); - imports.define("spectest", "global_i32", Extern::global(WasmValue::I32(666), false))?; - imports.define("spectest", "global_i64", Extern::global(WasmValue::I64(666), false))?; - imports.define("spectest", "global_f32", Extern::global(WasmValue::F32(666.0), false))?; - imports.define("spectest", "global_f64", Extern::global(WasmValue::F64(666.0), false))?; + + imports + .define("spectest", "global_i32", Extern::global(WasmValue::I32(666), false))? + .define("spectest", "global_i64", Extern::global(WasmValue::I64(666), false))? + .define("spectest", "global_f32", Extern::global(WasmValue::F32(666.0), false))? + .define("spectest", "global_f64", Extern::global(WasmValue::F64(666.0), false))?; + + for (name, addr) in registered_modules { + imports.link_module(&name, addr)?; + } Ok(imports) } @@ -60,6 +66,7 @@ impl TestSuite { let wast_data = wast::parser::parse::(&buf).expect("failed to parse wat"); let mut store = tinywasm::Store::default(); + let mut registered_modules = Vec::new(); let mut last_module: Option = None; println!("running {} tests for group: {}", wast_data.directives.len(), group_name); @@ -68,14 +75,29 @@ impl TestSuite { use wast::WastDirective::*; match directive { + Register { span, name, .. } => { + let Some(last) = &last_module else { + test_group.add_result( + &format!("Register({})", i), + span.linecol_in(wast), + Err(eyre!("no module to register")), + ); + continue; + }; + + registered_modules.push((name.to_string(), last.id())); + test_group.add_result(&format!("Register({})", i), span.linecol_in(wast), Ok(())); + } + Wat(mut module) => { - debug!("got wat module"); + // TODO: modules are not properly isolated from each other - tests fail because of this otherwise store = tinywasm::Store::default(); + debug!("got wat module"); let result = catch_unwind(AssertUnwindSafe(|| { let m = parse_module_bytes(&module.encode().expect("failed to encode module")) .expect("failed to parse module"); tinywasm::Module::from(m) - .instantiate(&mut store, Some(Self::imports().unwrap())) + .instantiate(&mut store, Some(Self::imports(registered_modules.clone()).unwrap())) .map_err(|e| { println!("failed to instantiate module: {:?}", e); e @@ -210,7 +232,6 @@ impl TestSuite { AssertReturn { span, exec, results } => { info!("AssertReturn: {:?}", exec); - let invoke = match match exec { wast::WastExecute::Wat(_) => Err(eyre!("wat not supported")), wast::WastExecute::Get { module: _, global: _ } => Err(eyre!("get not supported")), From 4da23c0c6b374d2f7ef939e26921dde498b2b0af Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Mon, 8 Jan 2024 13:13:27 +0100 Subject: [PATCH 24/31] feat: implicit function lable Signed-off-by: Henry Gressmann --- crates/tinywasm/src/error.rs | 4 ++++ crates/tinywasm/src/func.rs | 3 +-- crates/tinywasm/src/imports.rs | 2 -- crates/tinywasm/src/runtime/executor/mod.rs | 22 +++++++++++++++++-- crates/tinywasm/src/runtime/stack/blocks.rs | 17 ++++++++------ .../tinywasm/src/runtime/stack/call_stack.rs | 12 +++++----- crates/tinywasm/tests/generated/mvp.csv | 2 +- 7 files changed, 42 insertions(+), 20 deletions(-) diff --git a/crates/tinywasm/src/error.rs b/crates/tinywasm/src/error.rs index 208dab1..7e9ca90 100644 --- a/crates/tinywasm/src/error.rs +++ b/crates/tinywasm/src/error.rs @@ -54,6 +54,9 @@ pub enum Error { /// The label stack is empty LabelStackUnderflow, + /// An invalid label type was encountered + InvalidLabelType, + /// The call stack is empty CallStackEmpty, @@ -72,6 +75,7 @@ impl Display for Error { Self::Trap(trap) => write!(f, "trap: {:?}", trap), + 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"), diff --git a/crates/tinywasm/src/func.rs b/crates/tinywasm/src/func.rs index 97fed87..2b70578 100644 --- a/crates/tinywasm/src/func.rs +++ b/crates/tinywasm/src/func.rs @@ -57,10 +57,9 @@ impl FuncHandle { let call_frame = CallFrame::new(self.addr as usize, params, func_inst.locals().to_vec()); // 7. Push the frame f to the call stack + // & 8. Push the values to the stack (Not needed since the call frame owns the values) stack.call_stack.push(call_frame); - // 8. Push the values to the stack (Not needed since the call frame owns the values) - // 9. Invoke the function instance let runtime = store.runtime(); runtime.exec(store, &mut stack, self.module.clone())?; diff --git a/crates/tinywasm/src/imports.rs b/crates/tinywasm/src/imports.rs index 37fb60e..a13e488 100644 --- a/crates/tinywasm/src/imports.rs +++ b/crates/tinywasm/src/imports.rs @@ -11,8 +11,6 @@ use tinywasm_types::{Global, GlobalType, ModuleInstanceAddr, WasmValue}; pub enum Extern { /// A global value Global(Global), - /// A registered module - Module(String), // Func(HostFunc), // Table(Table), } diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs index d7d8fc7..fae095f 100644 --- a/crates/tinywasm/src/runtime/executor/mod.rs +++ b/crates/tinywasm/src/runtime/executor/mod.rs @@ -74,6 +74,24 @@ enum ExecResult { Trap(crate::Trap), } +// Break to a block at the given index (relative to the current frame) +// If there is no block at the given index, return or call the parent function +macro_rules! break_to { + ($cf:ident, $stack:ident, $break_to_relative:ident) => {{ + let res = $cf.break_to(*$break_to_relative, &mut $stack.values); + match res { + Some(()) => {} + None => match $stack.call_stack.is_empty() { + true => return Ok(ExecResult::Return), + false => { + *$cf = $stack.call_stack.pop()?; + return Ok(ExecResult::Call); + } + }, + } + }}; +} + /// Run a single step of the interpreter /// A seperate function is used so later, we can more easily implement /// a step-by-step debugger (using generators once they're stable?) @@ -207,10 +225,10 @@ fn exec_one( todo!("br_table"); } - Br(v) => cf.break_to(*v, &mut stack.values)?, + Br(v) => break_to!(cf, stack, v), BrIf(v) => { if stack.values.pop_t::()? > 0 { - cf.break_to(*v, &mut stack.values)? + break_to!(cf, stack, v); } } diff --git a/crates/tinywasm/src/runtime/stack/blocks.rs b/crates/tinywasm/src/runtime/stack/blocks.rs index f448492..46c341d 100644 --- a/crates/tinywasm/src/runtime/stack/blocks.rs +++ b/crates/tinywasm/src/runtime/stack/blocks.rs @@ -1,10 +1,10 @@ -use alloc::vec::Vec; +use alloc::{vec, vec::Vec}; use log::info; use tinywasm_types::BlockArgs; use crate::{ModuleInstance, Result}; -#[derive(Debug, Default, Clone)] +#[derive(Debug, Clone, Default)] pub(crate) struct Labels(Vec); impl Labels { @@ -13,15 +13,18 @@ impl Labels { } #[inline] - pub(crate) fn push(&mut self, block: LabelFrame) { - self.0.push(block); + pub(crate) fn push(&mut self, label: LabelFrame) { + self.0.push(label); } #[inline] - /// get the block at the given index, where 0 is the top of the stack + /// get the label at the given index, where 0 is the top of the stack pub(crate) fn get_relative_to_top(&self, index: usize) -> Option<&LabelFrame> { - info!("get block: {}", index); - info!("blocks: {:?}", self.0); + let len = self.0.len(); + if index >= len { + return None; + } + self.0.get(self.0.len() - index - 1) } diff --git a/crates/tinywasm/src/runtime/stack/call_stack.rs b/crates/tinywasm/src/runtime/stack/call_stack.rs index 88daa7f..c5193c3 100644 --- a/crates/tinywasm/src/runtime/stack/call_stack.rs +++ b/crates/tinywasm/src/runtime/stack/call_stack.rs @@ -89,12 +89,12 @@ impl CallFrame { } /// 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 validated by the parser) #[inline] - pub(crate) fn break_to(&mut self, break_to_relative: u32, value_stack: &mut super::ValueStack) -> Result<()> { - let break_to = self - .labels - .get_relative_to_top(break_to_relative as usize) - .ok_or(Error::LabelStackUnderflow)?; + pub(crate) fn break_to(&mut self, break_to_relative: u32, value_stack: &mut super::ValueStack) -> Option<()> { + let Some(break_to) = self.labels.get_relative_to_top(break_to_relative as usize) else { + return None; + }; value_stack.break_to(break_to.stack_ptr, break_to.args.results); @@ -131,7 +131,7 @@ impl CallFrame { // // }; // self.block_frames.trim(block_index as usize); - Ok(()) + Some(()) } pub(crate) fn new_raw(func_ptr: usize, params: &[RawWasmValue], local_types: Vec) -> Self { diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index ff3e9cf..4df8c8d 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -2,4 +2,4 @@ 0.0.4,9258,10909,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"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.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,18657,1571,[{"name":"address.wast","passed":13,"failed":247},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":217,"failed":6},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":115,"failed":3},{"name":"br_table.wast","passed":27,"failed":147},{"name":"call.wast","passed":71,"failed":20},{"name":"call_indirect.wast","passed":50,"failed":120},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":439,"failed":180},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":56,"failed":43},{"name":"endianness.wast","passed":29,"failed":40},{"name":"exports.wast","passed":92,"failed":4},{"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":6,"failed":2},{"name":"float_exprs.wast","passed":890,"failed":10},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":78,"failed":12},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":132,"failed":40},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":101,"failed":9},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":226,"failed":15},{"name":"imports.wast","passed":80,"failed":103},{"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":17,"failed":12},{"name":"left-to-right.wast","passed":91,"failed":5},{"name":"linking.wast","passed":28,"failed":104},{"name":"load.wast","passed":90,"failed":7},{"name":"local_get.wast","passed":35,"failed":1},{"name":"local_set.wast","passed":52,"failed":1},{"name":"local_tee.wast","passed":90,"failed":7},{"name":"loop.wast","passed":113,"failed":7},{"name":"memory.wast","passed":78,"failed":1},{"name":"memory_grow.wast","passed":76,"failed":20},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":3,"failed":179},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":74,"failed":14},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":110,"failed":38},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":13,"failed":7},{"name":"store.wast","passed":67,"failed":1},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,18674,1554,[{"name":"address.wast","passed":13,"failed":247},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":217,"failed":6},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":116,"failed":2},{"name":"br_table.wast","passed":27,"failed":147},{"name":"call.wast","passed":71,"failed":20},{"name":"call_indirect.wast","passed":50,"failed":120},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":439,"failed":180},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":56,"failed":43},{"name":"endianness.wast","passed":29,"failed":40},{"name":"exports.wast","passed":92,"failed":4},{"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":6,"failed":2},{"name":"float_exprs.wast","passed":890,"failed":10},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":78,"failed":12},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":144,"failed":28},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":101,"failed":9},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":226,"failed":15},{"name":"imports.wast","passed":80,"failed":103},{"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":17,"failed":12},{"name":"left-to-right.wast","passed":91,"failed":5},{"name":"linking.wast","passed":28,"failed":104},{"name":"load.wast","passed":90,"failed":7},{"name":"local_get.wast","passed":35,"failed":1},{"name":"local_set.wast","passed":52,"failed":1},{"name":"local_tee.wast","passed":90,"failed":7},{"name":"loop.wast","passed":113,"failed":7},{"name":"memory.wast","passed":78,"failed":1},{"name":"memory_grow.wast","passed":76,"failed":20},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":3,"failed":179},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":74,"failed":14},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":110,"failed":38},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":13,"failed":7},{"name":"store.wast","passed":67,"failed":1},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":39,"failed":11},{"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}] From e85771cd76a410895e231e09a0a7c3105fc5f27c Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Mon, 8 Jan 2024 13:24:40 +0100 Subject: [PATCH 25/31] chore: general cleanup Signed-off-by: Henry Gressmann --- Cargo.lock | 16 +++---- crates/tinywasm/src/imports.rs | 3 +- crates/tinywasm/src/runtime/executor/mod.rs | 42 ++++++++----------- crates/tinywasm/src/runtime/stack/blocks.rs | 3 +- .../tinywasm/src/runtime/stack/call_stack.rs | 7 +--- .../tinywasm/tests/generated/progress-mvp.svg | 6 +-- 6 files changed, 34 insertions(+), 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index da14548..e214f4c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -680,9 +680,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.151" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libloading" @@ -886,9 +886,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.75" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907a61bd0f64c2f29cd1cf1dc34d05176426a3f504a78010f08416ddb7b13708" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] @@ -1107,18 +1107,18 @@ checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" [[package]] name = "serde" -version = "1.0.194" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b114498256798c94a0689e1a15fec6005dee8ac1f41de56404b67afc2a4b773" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.194" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3385e45322e8f9931410f01b3031ec534c3947d0e94c18049af4d9f9907d4e0" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", diff --git a/crates/tinywasm/src/imports.rs b/crates/tinywasm/src/imports.rs index a13e488..1b3a9cf 100644 --- a/crates/tinywasm/src/imports.rs +++ b/crates/tinywasm/src/imports.rs @@ -84,7 +84,8 @@ impl Imports { Ok(self) } - pub(crate) fn link(self, store: &mut crate::Store, module: &crate::Module) -> Result { + pub(crate) fn link(self, _store: &mut crate::Store, _module: &crate::Module) -> Result { + // TODO: link to other modules (currently only direct imports are supported) let values = self.values; Ok(LinkedImports { values }) } diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs index fae095f..e3d8a93 100644 --- a/crates/tinywasm/src/runtime/executor/mod.rs +++ b/crates/tinywasm/src/runtime/executor/mod.rs @@ -35,6 +35,7 @@ impl DefaultRuntime { match exec_one(&mut cf, instr, instrs, stack, store, &module)? { // Continue execution at the new top of the call stack ExecResult::Call => { + cf = stack.call_stack.pop()?; func = store.get_func(cf.func_ptr)?.clone(); instrs = func.instructions(); continue; @@ -76,18 +77,17 @@ enum ExecResult { // Break to a block at the given index (relative to the current frame) // If there is no block at the given index, return or call the parent function +// +// This is a bit hard to see from the spec, but it's vaild to use breaks to return +// from a function, so we need to check if the label stack is empty macro_rules! break_to { ($cf:ident, $stack:ident, $break_to_relative:ident) => {{ - let res = $cf.break_to(*$break_to_relative, &mut $stack.values); - match res { - Some(()) => {} - None => match $stack.call_stack.is_empty() { - true => return Ok(ExecResult::Return), - false => { - *$cf = $stack.call_stack.pop()?; - return Ok(ExecResult::Call); - } - }, + if $cf.break_to(*$break_to_relative, &mut $stack.values).is_none() { + if $stack.call_stack.is_empty() { + return Ok(ExecResult::Return); + } else { + return Ok(ExecResult::Call); + } } }}; } @@ -143,8 +143,6 @@ fn exec_one( stack.call_stack.push(call_frame); // call the function - *cf = stack.call_stack.pop()?; - debug!("calling: {:?}", func); return Ok(ExecResult::Call); } @@ -221,6 +219,7 @@ fn exec_one( if instr.len() != *len { panic!("Expected {} BrLabel instructions, got {}", len, instr.len()); } + cf.instr_ptr += *len; todo!("br_table"); } @@ -234,27 +233,22 @@ fn exec_one( Return => match stack.call_stack.is_empty() { true => return Ok(ExecResult::Return), - false => { - *cf = stack.call_stack.pop()?; - return Ok(ExecResult::Call); - } + false => return Ok(ExecResult::Call), }, EndFunc => { - if cf.labels.len() > 0 { - panic!("endfunc: block frames not empty, this should have been validated by the parser"); - } + debug_assert!( + cf.labels.len() > 0, + "endfunc: block frames not empty, this should have been validated by the parser" + ); match stack.call_stack.is_empty() { true => return Ok(ExecResult::Return), - false => { - *cf = stack.call_stack.pop()?; - return Ok(ExecResult::Call); - } + false => return Ok(ExecResult::Call), } } - // We're essentially using else as a EndBlockFrame instruction + // We're essentially using else as a EndBlockFrame instruction for if blocks Else(end_offset) => { let Some(block) = cf.labels.pop() else { panic!("else: no label to end, this should have been validated by the parser"); diff --git a/crates/tinywasm/src/runtime/stack/blocks.rs b/crates/tinywasm/src/runtime/stack/blocks.rs index 46c341d..f5a0d8d 100644 --- a/crates/tinywasm/src/runtime/stack/blocks.rs +++ b/crates/tinywasm/src/runtime/stack/blocks.rs @@ -1,5 +1,4 @@ -use alloc::{vec, vec::Vec}; -use log::info; +use alloc::vec::Vec; use tinywasm_types::BlockArgs; use crate::{ModuleInstance, Result}; diff --git a/crates/tinywasm/src/runtime/stack/call_stack.rs b/crates/tinywasm/src/runtime/stack/call_stack.rs index c5193c3..239659c 100644 --- a/crates/tinywasm/src/runtime/stack/call_stack.rs +++ b/crates/tinywasm/src/runtime/stack/call_stack.rs @@ -89,13 +89,10 @@ impl CallFrame { } /// 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 validated by the parser) + /// 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] pub(crate) fn break_to(&mut self, break_to_relative: u32, value_stack: &mut super::ValueStack) -> Option<()> { - let Some(break_to) = self.labels.get_relative_to_top(break_to_relative as usize) else { - return None; - }; - + let break_to = self.labels.get_relative_to_top(break_to_relative as usize)?; value_stack.break_to(break_to.stack_ptr, break_to.args.results); // instr_ptr points to the label instruction, but the next step diff --git a/crates/tinywasm/tests/generated/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index caad2bb..7829bdc 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -53,12 +53,12 @@ v0.1.0 (17630) -v0.2.0-alpha.0 (18657) +v0.2.0-alpha.0 (18674) - + + - From 8d6e1e14c4f73e9793b7f7b15cf801a332f8aa5c Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Mon, 8 Jan 2024 15:00:49 +0100 Subject: [PATCH 26/31] feat: correct memory trapping behaviour Signed-off-by: Henry Gressmann --- crates/tinywasm/src/error.rs | 9 +++- .../tinywasm/src/runtime/executor/macros.rs | 2 + crates/tinywasm/src/runtime/executor/mod.rs | 2 +- crates/tinywasm/src/store.rs | 48 ++++++++++++------- crates/tinywasm/tests/generated/mvp.csv | 2 +- .../tinywasm/tests/generated/progress-mvp.svg | 6 +-- 6 files changed, 47 insertions(+), 22 deletions(-) diff --git a/crates/tinywasm/src/error.rs b/crates/tinywasm/src/error.rs index 7e9ca90..a7dac81 100644 --- a/crates/tinywasm/src/error.rs +++ b/crates/tinywasm/src/error.rs @@ -13,7 +13,14 @@ pub enum Trap { Unreachable, /// An out-of-bounds memory access occurred - MemoryOutOfBounds, + MemoryOutOfBounds { + /// The offset of the access + offset: usize, + /// The size of the access + len: usize, + /// The maximum size of the memory + max: usize, + }, /// A division by zero occurred DivisionByZero, diff --git a/crates/tinywasm/src/runtime/executor/macros.rs b/crates/tinywasm/src/runtime/executor/macros.rs index 08e2149..8a92ac2 100644 --- a/crates/tinywasm/src/runtime/executor/macros.rs +++ b/crates/tinywasm/src/runtime/executor/macros.rs @@ -35,6 +35,8 @@ macro_rules! mem_load { /// Store a value to memory macro_rules! mem_store { ($type:ty, $arg:ident, $stack:ident, $store:ident, $module:ident) => {{ + log::debug!("mem_store!({}, {:?})", stringify!($type), $arg); + mem_store!($type, $type, $arg, $stack, $store, $module) }}; diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs index e3d8a93..bff81af 100644 --- a/crates/tinywasm/src/runtime/executor/mod.rs +++ b/crates/tinywasm/src/runtime/executor/mod.rs @@ -238,7 +238,7 @@ fn exec_one( EndFunc => { debug_assert!( - cf.labels.len() > 0, + cf.labels.len() == 0, "endfunc: block frames not empty, this should have been validated by the parser" ); diff --git a/crates/tinywasm/src/store.rs b/crates/tinywasm/src/store.rs index a50e8b2..db996c8 100644 --- a/crates/tinywasm/src/store.rs +++ b/crates/tinywasm/src/store.rs @@ -337,7 +337,7 @@ impl TableInstance { } } -pub(crate) const PAGE_SIZE: usize = 64_000; +pub(crate) const PAGE_SIZE: usize = 65536; pub(crate) const MAX_PAGES: usize = 65536; pub(crate) const MAX_SIZE: usize = PAGE_SIZE * MAX_PAGES; @@ -366,35 +366,51 @@ impl MemoryInstance { } pub(crate) fn store(&mut self, addr: usize, _align: usize, data: &[u8]) -> Result<()> { - if addr + data.len() > self.data.len() { - return Err(Error::Other(format!( - "memory store out of bounds: offset={}, len={}, mem_size={}", - addr, - data.len(), - self.data.len() - ))); + let end = addr.checked_add(data.len()).ok_or_else(|| { + Error::Trap(crate::Trap::MemoryOutOfBounds { + offset: addr, + len: data.len(), + max: self.data.len(), + }) + })?; + + if end > self.data.len() || end < addr { + return Err(Error::Trap(crate::Trap::MemoryOutOfBounds { + offset: addr, + len: data.len(), + max: self.data.len(), + })); } // WebAssembly doesn't require alignment for stores - self.data[addr..addr + data.len()].copy_from_slice(data); + self.data[addr..end].copy_from_slice(data); Ok(()) } pub(crate) fn load(&self, addr: usize, _align: usize, len: usize) -> Result<&[u8]> { - if addr + len > self.data.len() { - return Err(Error::Other(format!( - "memory load out of bounds: offset={}, len={}, mem_size={}", - addr, + let end = addr.checked_add(len).ok_or_else(|| { + Error::Trap(crate::Trap::MemoryOutOfBounds { + offset: addr, + len, + max: self.data.len(), + }) + })?; + + if end > self.data.len() { + return Err(Error::Trap(crate::Trap::MemoryOutOfBounds { + offset: addr, len, - self.data.len() - ))); + max: self.data.len(), + })); } // WebAssembly doesn't require alignment for loads - Ok(&self.data[addr..addr + len]) + Ok(&self.data[addr..end]) } pub(crate) fn size(&self) -> i32 { + log::debug!("memory pages: {}", self.page_count); + log::debug!("memory size: {}", self.page_count * PAGE_SIZE); self.page_count as i32 } diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index 4df8c8d..d715231 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -2,4 +2,4 @@ 0.0.4,9258,10909,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"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.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,18674,1554,[{"name":"address.wast","passed":13,"failed":247},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":217,"failed":6},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":116,"failed":2},{"name":"br_table.wast","passed":27,"failed":147},{"name":"call.wast","passed":71,"failed":20},{"name":"call_indirect.wast","passed":50,"failed":120},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":439,"failed":180},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":56,"failed":43},{"name":"endianness.wast","passed":29,"failed":40},{"name":"exports.wast","passed":92,"failed":4},{"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":6,"failed":2},{"name":"float_exprs.wast","passed":890,"failed":10},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":78,"failed":12},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":144,"failed":28},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":101,"failed":9},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":226,"failed":15},{"name":"imports.wast","passed":80,"failed":103},{"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":17,"failed":12},{"name":"left-to-right.wast","passed":91,"failed":5},{"name":"linking.wast","passed":28,"failed":104},{"name":"load.wast","passed":90,"failed":7},{"name":"local_get.wast","passed":35,"failed":1},{"name":"local_set.wast","passed":52,"failed":1},{"name":"local_tee.wast","passed":90,"failed":7},{"name":"loop.wast","passed":113,"failed":7},{"name":"memory.wast","passed":78,"failed":1},{"name":"memory_grow.wast","passed":76,"failed":20},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":3,"failed":179},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":74,"failed":14},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":110,"failed":38},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":13,"failed":7},{"name":"store.wast","passed":67,"failed":1},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":39,"failed":11},{"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.2.0-alpha.0,19047,1181,[{"name":"address.wast","passed":181,"failed":79},{"name":"align.wast","passed":110,"failed":46},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":217,"failed":6},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":116,"failed":2},{"name":"br_table.wast","passed":27,"failed":147},{"name":"call.wast","passed":71,"failed":20},{"name":"call_indirect.wast","passed":50,"failed":120},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":439,"failed":180},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":56,"failed":43},{"name":"endianness.wast","passed":29,"failed":40},{"name":"exports.wast","passed":92,"failed":4},{"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":6,"failed":2},{"name":"float_exprs.wast","passed":890,"failed":10},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":78,"failed":12},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":144,"failed":28},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":101,"failed":9},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":226,"failed":15},{"name":"imports.wast","passed":80,"failed":103},{"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":17,"failed":12},{"name":"left-to-right.wast","passed":91,"failed":5},{"name":"linking.wast","passed":28,"failed":104},{"name":"load.wast","passed":90,"failed":7},{"name":"local_get.wast","passed":35,"failed":1},{"name":"local_set.wast","passed":52,"failed":1},{"name":"local_tee.wast","passed":90,"failed":7},{"name":"loop.wast","passed":113,"failed":7},{"name":"memory.wast","passed":78,"failed":1},{"name":"memory_grow.wast","passed":88,"failed":8},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":180,"failed":2},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":74,"failed":14},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":110,"failed":38},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":13,"failed":7},{"name":"store.wast","passed":67,"failed":1},{"name":"switch.wast","passed":2,"failed":26},{"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":"unwind.wast","passed":39,"failed":11},{"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/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index 7829bdc..0dfb68b 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -53,12 +53,12 @@ v0.1.0 (17630) -v0.2.0-alpha.0 (18674) +v0.2.0-alpha.0 (19047) + + - - From 8077653ddf3d4c555bc90d1647f4a3e9eed576a5 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Mon, 8 Jan 2024 16:20:58 +0100 Subject: [PATCH 27/31] feat: br_table Signed-off-by: Henry Gressmann --- crates/tinywasm/src/runtime/executor/mod.rs | 10 +++++++--- crates/tinywasm/src/runtime/value.rs | 1 + crates/tinywasm/tests/generated/mvp.csv | 2 +- crates/tinywasm/tests/generated/progress-mvp.svg | 6 +++--- crates/tinywasm/tests/testsuite/util.rs | 10 ++++++++-- crates/types/src/lib.rs | 8 ++++++++ 6 files changed, 28 insertions(+), 9 deletions(-) diff --git a/crates/tinywasm/src/runtime/executor/mod.rs b/crates/tinywasm/src/runtime/executor/mod.rs index bff81af..541c0a7 100644 --- a/crates/tinywasm/src/runtime/executor/mod.rs +++ b/crates/tinywasm/src/runtime/executor/mod.rs @@ -207,7 +207,7 @@ fn exec_one( ); } - BrTable(_default, len) => { + BrTable(default, len) => { let instr = instrs[cf.instr_ptr + 1..cf.instr_ptr + 1 + *len] .iter() .map(|i| match i { @@ -219,9 +219,13 @@ fn exec_one( if instr.len() != *len { panic!("Expected {} BrLabel instructions, got {}", len, instr.len()); } - cf.instr_ptr += *len; - todo!("br_table"); + let idx = stack.values.pop_t::()? as usize; + if let Some(label) = instr.get(idx) { + break_to!(cf, stack, label); + } else { + break_to!(cf, stack, default); + } } Br(v) => break_to!(cf, stack, v), diff --git a/crates/tinywasm/src/runtime/value.rs b/crates/tinywasm/src/runtime/value.rs index aedb09d..b25f634 100644 --- a/crates/tinywasm/src/runtime/value.rs +++ b/crates/tinywasm/src/runtime/value.rs @@ -41,6 +41,7 @@ impl From for RawWasmValue { WasmValue::I64(i) => Self(i as u64), WasmValue::F32(i) => Self(i.to_bits() as u64), WasmValue::F64(i) => Self(i.to_bits()), + WasmValue::RefNull(_) => Self(0), } } } diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index d715231..b22675c 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -2,4 +2,4 @@ 0.0.4,9258,10909,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"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.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,19047,1181,[{"name":"address.wast","passed":181,"failed":79},{"name":"align.wast","passed":110,"failed":46},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":217,"failed":6},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":116,"failed":2},{"name":"br_table.wast","passed":27,"failed":147},{"name":"call.wast","passed":71,"failed":20},{"name":"call_indirect.wast","passed":50,"failed":120},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":439,"failed":180},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":56,"failed":43},{"name":"endianness.wast","passed":29,"failed":40},{"name":"exports.wast","passed":92,"failed":4},{"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":6,"failed":2},{"name":"float_exprs.wast","passed":890,"failed":10},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":78,"failed":12},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":144,"failed":28},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":101,"failed":9},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":226,"failed":15},{"name":"imports.wast","passed":80,"failed":103},{"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":17,"failed":12},{"name":"left-to-right.wast","passed":91,"failed":5},{"name":"linking.wast","passed":28,"failed":104},{"name":"load.wast","passed":90,"failed":7},{"name":"local_get.wast","passed":35,"failed":1},{"name":"local_set.wast","passed":52,"failed":1},{"name":"local_tee.wast","passed":90,"failed":7},{"name":"loop.wast","passed":113,"failed":7},{"name":"memory.wast","passed":78,"failed":1},{"name":"memory_grow.wast","passed":88,"failed":8},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":180,"failed":2},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":74,"failed":14},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":110,"failed":38},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":13,"failed":7},{"name":"store.wast","passed":67,"failed":1},{"name":"switch.wast","passed":2,"failed":26},{"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":"unwind.wast","passed":39,"failed":11},{"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.2.0-alpha.0,19345,883,[{"name":"address.wast","passed":181,"failed":79},{"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":220,"failed":3},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":118,"failed":0},{"name":"br_table.wast","passed":171,"failed":3},{"name":"call.wast","passed":73,"failed":18},{"name":"call_indirect.wast","passed":50,"failed":120},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":439,"failed":180},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":56,"failed":43},{"name":"endianness.wast","passed":29,"failed":40},{"name":"exports.wast","passed":92,"failed":4},{"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":6,"failed":2},{"name":"float_exprs.wast","passed":890,"failed":10},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":78,"failed":12},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":168,"failed":4},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":103,"failed":7},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":231,"failed":10},{"name":"imports.wast","passed":80,"failed":103},{"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":26,"failed":3},{"name":"left-to-right.wast","passed":92,"failed":4},{"name":"linking.wast","passed":28,"failed":104},{"name":"load.wast","passed":93,"failed":4},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":93,"failed":4},{"name":"loop.wast","passed":116,"failed":4},{"name":"memory.wast","passed":78,"failed":1},{"name":"memory_grow.wast","passed":91,"failed":5},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":180,"failed":2},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":78,"failed":10},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":114,"failed":34},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":13,"failed":7},{"name":"store.wast","passed":68,"failed":0},{"name":"switch.wast","passed":28,"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":"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/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index 0dfb68b..6bd9be7 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -53,12 +53,12 @@ v0.1.0 (17630) -v0.2.0-alpha.0 (19047) +v0.2.0-alpha.0 (19345) - - + + diff --git a/crates/tinywasm/tests/testsuite/util.rs b/crates/tinywasm/tests/testsuite/util.rs index 6d0970e..9ba7934 100644 --- a/crates/tinywasm/tests/testsuite/util.rs +++ b/crates/tinywasm/tests/testsuite/util.rs @@ -64,7 +64,7 @@ pub fn parse_module_bytes(bytes: &[u8]) -> Result { pub fn wastarg2tinywasmvalue(arg: wast::WastArg) -> Result { let wast::WastArg::Core(arg) = arg else { - return Err(eyre!("unsupported arg type")); + return Err(eyre!("unsupported arg type: Component")); }; use wast::core::WastArgCore::*; @@ -73,7 +73,13 @@ pub fn wastarg2tinywasmvalue(arg: wast::WastArg) -> Result WasmValue::F64(f64::from_bits(f.bits)), I32(i) => WasmValue::I32(i), I64(i) => WasmValue::I64(i), - _ => return Err(eyre!("unsupported arg type")), + // RefExtern(v) => WasmValue::RefExtern(v), + RefNull(t) => WasmValue::RefNull(match t { + wast::core::HeapType::Func => tinywasm_types::ValType::FuncRef, + wast::core::HeapType::Extern => tinywasm_types::ValType::ExternRef, + _ => return Err(eyre!("unsupported arg type: refnull: {:?}", t)), + }), + v => return Err(eyre!("unsupported arg type: {:?}", v)), }) } diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index 1213515..d3bf81a 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -88,6 +88,9 @@ pub enum WasmValue { F64(f64), // Vec types // V128(i128), + // RefExtern(ExternAddr), + // RefHost(FuncAddr), + RefNull(ValType), } impl WasmValue { @@ -97,6 +100,9 @@ impl WasmValue { Self::I64(i) => ConstInstruction::I64Const(*i), Self::F32(i) => ConstInstruction::F32Const(*i), Self::F64(i) => ConstInstruction::F64Const(*i), + Self::RefNull(ty) => ConstInstruction::RefNull(*ty), + // Self::RefExtern(addr) => ConstInstruction::RefExtern(*addr), + // _ => unimplemented!("const_instr for {:?}", self), } } @@ -217,6 +223,7 @@ impl Debug for WasmValue { WasmValue::I64(i) => write!(f, "i64({})", i), WasmValue::F32(i) => write!(f, "f32({})", i), WasmValue::F64(i) => write!(f, "f64({})", i), + WasmValue::RefNull(ty) => write!(f, "ref.null({:?})", ty), // WasmValue::V128(i) => write!(f, "v128({})", i), } } @@ -230,6 +237,7 @@ impl WasmValue { Self::I64(_) => ValType::I64, Self::F32(_) => ValType::F32, Self::F64(_) => ValType::F64, + Self::RefNull(ty) => *ty, // Self::V128(_) => ValType::V128, } } From 525208ec8e86eaf57feb412e6c6c71e6d56d3cb3 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Wed, 10 Jan 2024 01:11:55 +0100 Subject: [PATCH 28/31] chore: improve documentation, tests Signed-off-by: Henry Gressmann --- .cargo/config.toml | 6 +-- .github/workflows/test.yaml | 8 ++-- Cargo.lock | 12 ++--- crates/cli/Cargo.toml | 2 +- crates/parser/Cargo.toml | 1 - crates/parser/src/lib.rs | 1 + crates/tinywasm/Cargo.toml | 2 +- crates/tinywasm/src/func.rs | 8 +++- crates/tinywasm/src/instance.rs | 29 ++++++++++-- crates/tinywasm/src/lib.rs | 5 ++- crates/tinywasm/src/module.rs | 4 +- crates/tinywasm/src/store.rs | 45 ++++++++++++++----- crates/tinywasm/tests/generate-charts.rs | 7 +++ crates/tinywasm/tests/generated/mvp.csv | 2 +- .../tinywasm/tests/generated/progress-mvp.svg | 6 +-- crates/tinywasm/tests/test-mvp.rs | 5 +++ crates/tinywasm/tests/test-wast.rs | 10 +++-- crates/tinywasm/tests/testsuite/run.rs | 21 ++++++--- 18 files changed, 123 insertions(+), 51 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 743421a..3e15584 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -2,6 +2,6 @@ version-dev="workspaces version --no-git-commit --force tinywasm*" dev="run -- -l debug run" -test-mvp="test --package tinywasm --test test-mvp" -test-wast="test --package tinywasm --test test-wast --" -generate-charts="test --package tinywasm --test generate-charts" +test-mvp="test --package tinywasm --test test-mvp --release -- --enable " +test-wast="test --package tinywasm --test test-wast -- --enable " +generate-charts="test --package tinywasm --test generate-charts -- --enable " diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index c4ae296..d65198f 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -20,10 +20,10 @@ jobs: rustup default stable - name: Build (stable) - run: cargo +stable build --verbose + run: cargo +stable build --all - name: Run tests (stable) - run: cargo +stable test --verbose + run: cargo +stable test --all test-no-std: name: Test without default features on nightly Rust @@ -37,7 +37,7 @@ jobs: rustup default nightly - name: Build (nightly, no default features) - run: cargo +nightly build --verbose --no-default-features + run: cargo +nightly build --all --no-default-features - name: Run tests (nightly, no default features) - run: cargo +nightly test --verbose --no-default-features + run: cargo +nightly test --all --no-default-features diff --git a/Cargo.lock b/Cargo.lock index e214f4c..7907fb9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -525,9 +525,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "libc", @@ -1385,9 +1385,9 @@ checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "wasm-encoder" -version = "0.38.1" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f" +checksum = "111495d6204760238512f57a9af162f45086504da332af210f2f75dd80b34f1d" dependencies = [ "leb128", ] @@ -1410,9 +1410,9 @@ dependencies = [ [[package]] name = "wast" -version = "69.0.1" +version = "70.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ee37317321afde358e4d7593745942c48d6d17e0e6e943704de9bbee121e7a" +checksum = "2ee4bc54bbe1c6924160b9f75e374a1d07532e7580eb632c0ee6cdd109bb217e" dependencies = [ "leb128", "memchr", diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 571dfc0..65a9e72 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -19,7 +19,7 @@ argh="0.1" color-eyre={version="0.6", default-features=false} log="0.4" pretty_env_logger="0.5" -wast={version="69.0", optional=true} +wast={version="70.0", optional=true} [features] default=["wat"] diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index 1bd4ea3..9e6dc71 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -9,7 +9,6 @@ repository.workspace=true [dependencies] # fork of wasmparser with no_std support, see https://github.com/bytecodealliance/wasmtime/issues/3495 -# TODO: create dependency free parser wasmparser={version="0.100", package="wasmparser-nostd", default-features=false} log={version="0.4", optional=true} tinywasm-types={version="0.2.0-alpha.0", path="../types"} diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index 22e2661..561d5c6 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -10,6 +10,7 @@ extern crate alloc; #[allow(clippy::single_component_path_imports)] use log; +// noop fallback if logging is disabled. #[cfg(not(feature = "logging"))] mod log { macro_rules! debug ( ($($tt:tt)*) => {{}} ); diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index d04a227..931bb45 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -19,7 +19,7 @@ tinywasm-types={version="0.2.0-alpha.0", path="../types", default-features=false [dev-dependencies] wasm-testsuite={path="../wasm-testsuite"} -wast={version="69.0"} +wast={version="70.0"} owo-colors={version="4.0"} eyre={version="0.6"} serde_json={version="1.0"} diff --git a/crates/tinywasm/src/func.rs b/crates/tinywasm/src/func.rs index 2b70578..b0b359d 100644 --- a/crates/tinywasm/src/func.rs +++ b/crates/tinywasm/src/func.rs @@ -19,7 +19,7 @@ pub struct FuncHandle { } impl FuncHandle { - /// Call a function + /// Call a function (Invocation) /// /// See pub fn call(&self, store: &mut Store, params: &[WasmValue]) -> Result> { @@ -66,8 +66,14 @@ impl FuncHandle { // Once the function returns: let result_m = func_ty.results.len(); + + // 1. Assert: m values are on the top of the stack (Ensured by validation) + debug_assert!(stack.values.len() >= result_m); + + // 2. Pop m values from the stack let res = stack.values.last_n(result_m)?; + // The values are returned as the results of the invocation. Ok(res .iter() .zip(func_ty.results.iter()) diff --git a/crates/tinywasm/src/instance.rs b/crates/tinywasm/src/instance.rs index 0ef63a9..ad5e937 100644 --- a/crates/tinywasm/src/instance.rs +++ b/crates/tinywasm/src/instance.rs @@ -42,16 +42,30 @@ impl ModuleInstance { } /// Instantiate the module in the given store + /// + /// See pub fn instantiate(store: &mut Store, module: Module, imports: Option) -> Result { + // This doesn't completely follow the steps in the spec, but the end result is the same + // Constant expressions are evaluated directly where they are used, so we + // don't need to create a auxiliary frame etc. + let idx = store.next_module_instance_idx(); let imports = imports.unwrap_or_default(); + + // TODO: doesn't link other modules yet let linked_imports = imports.link(store, &module)?; + let global_addrs = store.add_globals(module.data.globals.into(), &module.data.imports, &linked_imports, idx)?; + // TODO: imported functions missing let func_addrs = store.add_funcs(module.data.funcs.into(), idx); + let table_addrs = store.add_tables(module.data.table_types.into(), idx); let mem_addrs = store.add_mems(module.data.memory_types.into(), idx)?; - let global_addrs = store.add_globals(module.data.globals.into(), &module.data.imports, &linked_imports, idx)?; + + // TODO: active/declared elems need to be initialized let elem_addrs = store.add_elems(module.data.elements.into(), idx)?; + + // TODO: active data segments need to be initialized let data_addrs = store.add_datas(module.data.data.into(), idx); let instance = ModuleInstanceInner { @@ -70,8 +84,10 @@ impl ModuleInstance { imports: module.data.imports, exports: crate::ExportInstance(module.data.exports), }; + let instance = ModuleInstance::new(instance); store.add_instance(instance.clone())?; + Ok(instance) } @@ -176,13 +192,18 @@ impl ModuleInstance { } }; - let func_addr = self.0.func_addrs[func_index as usize]; - let func = store.get_func(func_addr as usize)?; + let func_addr = self + .0 + .func_addrs + .get(func_index as usize) + .expect("No func addr for start func, this is a bug"); + + let func = store.get_func(*func_addr as usize)?; let ty = self.0.types[func.ty_addr() as usize].clone(); Ok(Some(FuncHandle { module: self.clone(), - addr: func_addr, + addr: *func_addr, ty, name: None, })) diff --git a/crates/tinywasm/src/lib.rs b/crates/tinywasm/src/lib.rs index 0a2d875..0c1863f 100644 --- a/crates/tinywasm/src/lib.rs +++ b/crates/tinywasm/src/lib.rs @@ -43,7 +43,7 @@ //! // Get a typed handle to the exported "add" function //! // Alternatively, you can use `instance.get_func` to get an untyped handle //! // that takes and returns WasmValue types -//! let func = instance.get_typed_func::<(i32, i32), (i32,)>(&mut store, "add")?; +//! let func = instance.typed_func::<(i32, i32), (i32,)>(&mut store, "add")?; //! let res = func.call(&mut store, (1, 2))?; //! //! assert_eq!(res, (3,)); @@ -60,7 +60,7 @@ //! a custom allocator. This removes support for parsing from files and streams, //! but otherwise the API is the same. //! -//! Additionally, if you want proper error types, you must use a `nightly` compiler. +//! Additionally, if you want proper error types, you must use a `nightly` compiler to have the error trait in core. mod std; extern crate alloc; @@ -70,6 +70,7 @@ extern crate alloc; #[allow(clippy::single_component_path_imports)] use log; +// noop fallback if logging is disabled. #[cfg(not(feature = "logging"))] pub(crate) mod log { macro_rules! debug ( ($($tt:tt)*) => {{}} ); diff --git a/crates/tinywasm/src/module.rs b/crates/tinywasm/src/module.rs index 6dfca42..5a2c4f7 100644 --- a/crates/tinywasm/src/module.rs +++ b/crates/tinywasm/src/module.rs @@ -55,9 +55,7 @@ impl Module { /// See pub fn instantiate(self, store: &mut Store, imports: Option) -> Result { let instance = ModuleInstance::instantiate(store, self, imports)?; - - // TODO: this currently panics if theres no start fn - // let _ = instance.start(store)?; + let _ = instance.start(store)?; Ok(instance) } } diff --git a/crates/tinywasm/src/store.rs b/crates/tinywasm/src/store.rs index db996c8..564232d 100644 --- a/crates/tinywasm/src/store.rs +++ b/crates/tinywasm/src/store.rs @@ -227,19 +227,28 @@ impl Store { let elem_count = self.data.elems.len(); let mut elem_addrs = Vec::with_capacity(elem_count); for (i, elem) in elems.into_iter().enumerate() { - self.data.elems.push(ElemInstance::new(elem.kind, idx)); - elem_addrs.push((i + elem_count) as Addr); + match elem.kind { + // doesn't need to be initialized, can be initialized lazily using the `table.init` instruction + ElementKind::Passive => {} + + // this one is active, so we need to initialize it (essentially a `table.init` instruction) + ElementKind::Active { .. } => { + // a. Let n be the length of the vector elem[i].init + // b. Execute the instruction sequence einstrs + // c. Execute the instruction i32.const 0 + // d. Execute the instruction i32.const n + // e. Execute the instruction table.init tableidx i + // f. Execute the instruction elm.drop i + } - // match elem.kind { - // ElementKind::Active { table, offset } => { - // // let table = self.data.tables[table as usize]; + // this one is not available to the runtime but needs to be initialized to declare references + ElementKind::Declared => { + // a. Execute the instruction elm.drop i + } + } - // // let offset = self.eval_const(&offset)?; - // // let offset = offset.raw_value() as usize; - // // let offset = offset + elem_addrs[i] as usize; - // // let offset = offset as Addr; - // } - // } + self.data.elems.push(ElemInstance::new(elem.kind, idx)); + elem_addrs.push((i + elem_count) as Addr); } Ok(elem_addrs) @@ -252,6 +261,20 @@ impl Store { for (i, data) in datas.into_iter().enumerate() { self.data.datas.push(DataInstance::new(data.data.to_vec(), idx)); data_addrs.push((i + data_count) as Addr); + + use tinywasm_types::DataKind::*; + match data.kind { + Active { .. } => { + // a. Assert: memidx == 0 + // b. Let n be the length of the vector + // c. Execute the instruction sequence + // d. Execute the instruction + // e. Execute the instruction + // f. Execute the instruction + // g. Execute the instruction + } + Passive => {} + } } data_addrs } diff --git a/crates/tinywasm/tests/generate-charts.rs b/crates/tinywasm/tests/generate-charts.rs index f80b092..e8e323d 100644 --- a/crates/tinywasm/tests/generate-charts.rs +++ b/crates/tinywasm/tests/generate-charts.rs @@ -6,11 +6,18 @@ fn main() -> Result<()> { } fn generate_charts() -> Result<()> { + let args = std::env::args().collect::>(); + if args.len() < 2 || args[1] != "--enable" { + return Ok(()); + } + // Create a line chart charts::create_progress_chart( std::path::Path::new("./tests/generated/mvp.csv"), std::path::Path::new("./tests/generated/progress-mvp.svg"), )?; + println!("created progress chart: ./tests/generated/progress-mvp.svg"); + Ok(()) } diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv index b22675c..a238586 100644 --- a/crates/tinywasm/tests/generated/mvp.csv +++ b/crates/tinywasm/tests/generated/mvp.csv @@ -2,4 +2,4 @@ 0.0.4,9258,10909,[{"name":"address.wast","passed":0,"failed":54},{"name":"align.wast","passed":0,"failed":109},{"name":"binary-leb128.wast","passed":66,"failed":25},{"name":"binary.wast","passed":104,"failed":8},{"name":"block.wast","passed":0,"failed":171},{"name":"br.wast","passed":0,"failed":21},{"name":"br_if.wast","passed":0,"failed":30},{"name":"br_table.wast","passed":0,"failed":25},{"name":"call.wast","passed":0,"failed":22},{"name":"call_indirect.wast","passed":0,"failed":56},{"name":"comments.wast","passed":4,"failed":4},{"name":"const.wast","passed":702,"failed":76},{"name":"conversions.wast","passed":0,"failed":93},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":0,"failed":61},{"name":"elem.wast","passed":0,"failed":76},{"name":"endianness.wast","passed":0,"failed":1},{"name":"exports.wast","passed":21,"failed":73},{"name":"f32.wast","passed":1005,"failed":1509},{"name":"f32_bitwise.wast","passed":1,"failed":363},{"name":"f32_cmp.wast","passed":2401,"failed":6},{"name":"f64.wast","passed":1005,"failed":1509},{"name":"f64_bitwise.wast","passed":1,"failed":363},{"name":"f64_cmp.wast","passed":2401,"failed":6},{"name":"fac.wast","passed":0,"failed":2},{"name":"float_exprs.wast","passed":269,"failed":591},{"name":"float_literals.wast","passed":34,"failed":129},{"name":"float_memory.wast","passed":0,"failed":6},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":4,"failed":75},{"name":"func_ptrs.wast","passed":0,"failed":16},{"name":"global.wast","passed":4,"failed":49},{"name":"i32.wast","passed":0,"failed":96},{"name":"i64.wast","passed":0,"failed":42},{"name":"if.wast","passed":0,"failed":118},{"name":"imports.wast","passed":1,"failed":156},{"name":"inline-module.wast","passed":0,"failed":1},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":5,"failed":46},{"name":"labels.wast","passed":1,"failed":28},{"name":"left-to-right.wast","passed":0,"failed":1},{"name":"linking.wast","passed":1,"failed":66},{"name":"load.wast","passed":0,"failed":60},{"name":"local_get.wast","passed":2,"failed":34},{"name":"local_set.wast","passed":5,"failed":48},{"name":"local_tee.wast","passed":0,"failed":42},{"name":"loop.wast","passed":0,"failed":43},{"name":"memory.wast","passed":0,"failed":34},{"name":"memory_grow.wast","passed":0,"failed":19},{"name":"memory_redundancy.wast","passed":0,"failed":1},{"name":"memory_size.wast","passed":0,"failed":6},{"name":"memory_trap.wast","passed":0,"failed":172},{"name":"names.wast","passed":484,"failed":1},{"name":"nop.wast","passed":0,"failed":5},{"name":"return.wast","passed":0,"failed":21},{"name":"select.wast","passed":0,"failed":32},{"name":"skip-stack-guard-page.wast","passed":0,"failed":11},{"name":"stack.wast","passed":0,"failed":2},{"name":"start.wast","passed":0,"failed":10},{"name":"store.wast","passed":0,"failed":59},{"name":"switch.wast","passed":1,"failed":27},{"name":"token.wast","passed":16,"failed":42},{"name":"traps.wast","passed":3,"failed":33},{"name":"type.wast","passed":1,"failed":2},{"name":"unreachable.wast","passed":0,"failed":59},{"name":"unreached-invalid.wast","passed":0,"failed":118},{"name":"unwind.wast","passed":1,"failed":49},{"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":0,"failed":176}] 0.0.5,11135,9093,[{"name":"address.wast","passed":1,"failed":259},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":78,"failed":13},{"name":"binary.wast","passed":107,"failed":5},{"name":"block.wast","passed":170,"failed":53},{"name":"br.wast","passed":20,"failed":77},{"name":"br_if.wast","passed":29,"failed":89},{"name":"br_table.wast","passed":24,"failed":150},{"name":"call.wast","passed":18,"failed":73},{"name":"call_indirect.wast","passed":34,"failed":136},{"name":"comments.wast","passed":5,"failed":3},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":25,"failed":594},{"name":"custom.wast","passed":10,"failed":1},{"name":"data.wast","passed":22,"failed":39},{"name":"elem.wast","passed":27,"failed":72},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":90,"failed":6},{"name":"f32.wast","passed":1018,"failed":1496},{"name":"f32_bitwise.wast","passed":4,"failed":360},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":1018,"failed":1496},{"name":"f64_bitwise.wast","passed":4,"failed":360},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":1,"failed":7},{"name":"float_exprs.wast","passed":275,"failed":625},{"name":"float_literals.wast","passed":112,"failed":51},{"name":"float_memory.wast","passed":0,"failed":90},{"name":"float_misc.wast","passed":138,"failed":303},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":81,"failed":91},{"name":"func_ptrs.wast","passed":7,"failed":29},{"name":"global.wast","passed":50,"failed":60},{"name":"i32.wast","passed":85,"failed":375},{"name":"i64.wast","passed":31,"failed":385},{"name":"if.wast","passed":116,"failed":125},{"name":"imports.wast","passed":23,"failed":160},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":38,"failed":70},{"name":"int_literals.wast","passed":25,"failed":26},{"name":"labels.wast","passed":13,"failed":16},{"name":"left-to-right.wast","passed":0,"failed":96},{"name":"linking.wast","passed":5,"failed":127},{"name":"load.wast","passed":59,"failed":38},{"name":"local_get.wast","passed":18,"failed":18},{"name":"local_set.wast","passed":38,"failed":15},{"name":"local_tee.wast","passed":41,"failed":56},{"name":"loop.wast","passed":42,"failed":78},{"name":"memory.wast","passed":30,"failed":49},{"name":"memory_grow.wast","passed":11,"failed":85},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":1,"failed":181},{"name":"names.wast","passed":484,"failed":2},{"name":"nop.wast","passed":4,"failed":84},{"name":"return.wast","passed":20,"failed":64},{"name":"select.wast","passed":28,"failed":120},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":4,"failed":16},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":39,"failed":19},{"name":"traps.wast","passed":4,"failed":32},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":0,"failed":64},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":9,"failed":41},{"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.1.0,17630,2598,[{"name":"address.wast","passed":5,"failed":255},{"name":"align.wast","passed":108,"failed":48},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":110,"failed":2},{"name":"block.wast","passed":193,"failed":30},{"name":"br.wast","passed":84,"failed":13},{"name":"br_if.wast","passed":90,"failed":28},{"name":"br_table.wast","passed":25,"failed":149},{"name":"call.wast","passed":29,"failed":62},{"name":"call_indirect.wast","passed":36,"failed":134},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":371,"failed":248},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":50,"failed":49},{"name":"endianness.wast","passed":1,"failed":68},{"name":"exports.wast","passed":92,"failed":4},{"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":2,"failed":6},{"name":"float_exprs.wast","passed":761,"failed":139},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":1,"failed":4},{"name":"func.wast","passed":124,"failed":48},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":51,"failed":59},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":120,"failed":121},{"name":"imports.wast","passed":74,"failed":109},{"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":14,"failed":15},{"name":"left-to-right.wast","passed":1,"failed":95},{"name":"linking.wast","passed":21,"failed":111},{"name":"load.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":32,"failed":4},{"name":"local_set.wast","passed":50,"failed":3},{"name":"local_tee.wast","passed":68,"failed":29},{"name":"loop.wast","passed":93,"failed":27},{"name":"memory.wast","passed":34,"failed":45},{"name":"memory_grow.wast","passed":12,"failed":84},{"name":"memory_redundancy.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":6,"failed":36},{"name":"memory_trap.wast","passed":2,"failed":180},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":46,"failed":42},{"name":"return.wast","passed":73,"failed":11},{"name":"select.wast","passed":86,"failed":62},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":2,"failed":5},{"name":"start.wast","passed":9,"failed":11},{"name":"store.wast","passed":59,"failed":9},{"name":"switch.wast","passed":2,"failed":26},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":22,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":50,"failed":14},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unwind.wast","passed":35,"failed":15},{"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.2.0-alpha.0,19345,883,[{"name":"address.wast","passed":181,"failed":79},{"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":220,"failed":3},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":118,"failed":0},{"name":"br_table.wast","passed":171,"failed":3},{"name":"call.wast","passed":73,"failed":18},{"name":"call_indirect.wast","passed":50,"failed":120},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":439,"failed":180},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":56,"failed":43},{"name":"endianness.wast","passed":29,"failed":40},{"name":"exports.wast","passed":92,"failed":4},{"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":6,"failed":2},{"name":"float_exprs.wast","passed":890,"failed":10},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":78,"failed":12},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":168,"failed":4},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":103,"failed":7},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":231,"failed":10},{"name":"imports.wast","passed":80,"failed":103},{"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":26,"failed":3},{"name":"left-to-right.wast","passed":92,"failed":4},{"name":"linking.wast","passed":28,"failed":104},{"name":"load.wast","passed":93,"failed":4},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":93,"failed":4},{"name":"loop.wast","passed":116,"failed":4},{"name":"memory.wast","passed":78,"failed":1},{"name":"memory_grow.wast","passed":91,"failed":5},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":180,"failed":2},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":78,"failed":10},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":114,"failed":34},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":13,"failed":7},{"name":"store.wast","passed":68,"failed":0},{"name":"switch.wast","passed":28,"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":"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.2.0-alpha.0,19344,884,[{"name":"address.wast","passed":181,"failed":79},{"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":220,"failed":3},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":118,"failed":0},{"name":"br_table.wast","passed":171,"failed":3},{"name":"call.wast","passed":73,"failed":18},{"name":"call_indirect.wast","passed":50,"failed":120},{"name":"comments.wast","passed":7,"failed":1},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":439,"failed":180},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":47,"failed":14},{"name":"elem.wast","passed":56,"failed":43},{"name":"endianness.wast","passed":29,"failed":40},{"name":"exports.wast","passed":92,"failed":4},{"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":6,"failed":2},{"name":"float_exprs.wast","passed":890,"failed":10},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":78,"failed":12},{"name":"float_misc.wast","passed":437,"failed":4},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":168,"failed":4},{"name":"func_ptrs.wast","passed":10,"failed":26},{"name":"global.wast","passed":103,"failed":7},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":231,"failed":10},{"name":"imports.wast","passed":80,"failed":103},{"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":26,"failed":3},{"name":"left-to-right.wast","passed":92,"failed":4},{"name":"linking.wast","passed":29,"failed":103},{"name":"load.wast","passed":93,"failed":4},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":93,"failed":4},{"name":"loop.wast","passed":116,"failed":4},{"name":"memory.wast","passed":78,"failed":1},{"name":"memory_grow.wast","passed":91,"failed":5},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":35,"failed":7},{"name":"memory_trap.wast","passed":180,"failed":2},{"name":"names.wast","passed":485,"failed":1},{"name":"nop.wast","passed":78,"failed":10},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":114,"failed":34},{"name":"skip-stack-guard-page.wast","passed":1,"failed":10},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":11,"failed":9},{"name":"store.wast","passed":68,"failed":0},{"name":"switch.wast","passed":28,"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":"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/progress-mvp.svg b/crates/tinywasm/tests/generated/progress-mvp.svg index 6bd9be7..e1fd709 100644 --- a/crates/tinywasm/tests/generated/progress-mvp.svg +++ b/crates/tinywasm/tests/generated/progress-mvp.svg @@ -53,12 +53,12 @@ v0.1.0 (17630) -v0.2.0-alpha.0 (19345) +v0.2.0-alpha.0 (19344) - - + + diff --git a/crates/tinywasm/tests/test-mvp.rs b/crates/tinywasm/tests/test-mvp.rs index 6f6d9b3..5107551 100644 --- a/crates/tinywasm/tests/test-mvp.rs +++ b/crates/tinywasm/tests/test-mvp.rs @@ -4,6 +4,11 @@ use owo_colors::OwoColorize; use testsuite::TestSuite; fn main() -> Result<()> { + let args = std::env::args().collect::>(); + if args.len() < 2 || args[1] != "--enable" { + return Ok(()); + } + test_mvp() } diff --git a/crates/tinywasm/tests/test-wast.rs b/crates/tinywasm/tests/test-wast.rs index 8537956..42f7091 100644 --- a/crates/tinywasm/tests/test-wast.rs +++ b/crates/tinywasm/tests/test-wast.rs @@ -8,8 +8,12 @@ mod testsuite; fn main() -> Result<()> { let args = std::env::args().collect::>(); - if args.len() < 2 { - bail!("usage: cargo test-wast ") + if args.len() < 2 || args[1] != "--enable" { + return Ok(()); + } + + if args.len() < 3 { + bail!("usage: cargo test-wast "); } // cwd for relative paths, absolute paths are kept as-is @@ -22,7 +26,7 @@ fn main() -> Result<()> { PathBuf::from("./") }; - wast_file.push(&args[1]); + wast_file.push(&args[2]); let wast_file = cwd.join(wast_file); test_wast(wast_file.to_str().expect("wast_file is not a valid path"))?; diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index d34df6c..8a1ddf4 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -95,7 +95,7 @@ impl TestSuite { debug!("got wat module"); let result = catch_unwind(AssertUnwindSafe(|| { let m = parse_module_bytes(&module.encode().expect("failed to encode module")) - .expect("failed to parse module"); + .expect("failed to parse module bytes"); tinywasm::Module::from(m) .instantiate(&mut store, Some(Self::imports(registered_modules.clone()).unwrap())) .map_err(|e| { @@ -104,7 +104,7 @@ impl TestSuite { }) .expect("failed to instantiate module") })) - .map_err(|e| eyre!("failed to parse module: {:?}", try_downcast_panic(e))); + .map_err(|e| eyre!("failed to parse wat module: {:?}", try_downcast_panic(e))); match &result { Err(_) => last_module = None, @@ -129,7 +129,7 @@ impl TestSuite { }; let res = catch_unwind_silent(|| parse_module_bytes(&module)) - .map_err(|e| eyre!("failed to parse module: {:?}", try_downcast_panic(e))) + .map_err(|e| eyre!("failed to parse module (expected): {:?}", try_downcast_panic(e))) .and_then(|res| res); test_group.add_result( @@ -148,7 +148,7 @@ impl TestSuite { message: _, } => { let res = catch_unwind_silent(move || parse_module_bytes(&module.encode().unwrap())) - .map_err(|e| eyre!("failed to parse module: {:?}", try_downcast_panic(e))) + .map_err(|e| eyre!("failed to parse module (invalid): {:?}", try_downcast_panic(e))) .and_then(|res| res); test_group.add_result( @@ -164,11 +164,18 @@ impl TestSuite { AssertTrap { exec, message: _, span } => { let res: Result, _> = catch_unwind_silent(|| { let (module, name, args) = match exec { - wast::WastExecute::Wat(_wat) => { - panic!("wat not supported"); + wast::WastExecute::Wat(mut wat) => { + 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.clone()).unwrap()), + )?; + return Ok(()); } wast::WastExecute::Get { module: _, global: _ } => { - panic!("wat not supported"); + panic!("get not supported"); } wast::WastExecute::Invoke(invoke) => (last_module.as_ref(), invoke.name, invoke.args), }; From f4fca66b87851ae343ce4cd47c9684cbab62a0b3 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Wed, 10 Jan 2024 01:14:58 +0100 Subject: [PATCH 29/31] ci: checkout submodules Signed-off-by: Henry Gressmann --- .github/workflows/test.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index d65198f..2718b2c 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -13,6 +13,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + submodules: true - name: Install stable Rust toolchain run: | From 53fe20ae76461ff8835fd6d8b3b5a1c550390bd9 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Wed, 10 Jan 2024 01:19:19 +0100 Subject: [PATCH 30/31] ci: exclude wasm-testsuite Signed-off-by: Henry Gressmann --- .github/workflows/test.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 2718b2c..0baaba9 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -22,10 +22,10 @@ jobs: rustup default stable - name: Build (stable) - run: cargo +stable build --all + run: cargo +stable build --workspace --exclude wasm-testsuite - name: Run tests (stable) - run: cargo +stable test --all + run: cargo +stable test --workspace --exclude wasm-testsuite test-no-std: name: Test without default features on nightly Rust @@ -39,7 +39,7 @@ jobs: rustup default nightly - name: Build (nightly, no default features) - run: cargo +nightly build --all --no-default-features + run: cargo +nightly build --workspace --exclude wasm-testsuite --no-default-features - name: Run tests (nightly, no default features) - run: cargo +nightly test --all --no-default-features + run: cargo +nightly test --workspace --exclude wasm-testsuite --no-default-features From 5879ff0b1bc268f1ae6483bdd94e3d0d8f80154a Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Wed, 10 Jan 2024 23:55:04 +0100 Subject: [PATCH 31/31] Release 0.2.0 tinywasm@0.2.0 tinywasm-cli@0.2.0 tinywasm-parser@0.2.0 tinywasm-types@0.2.0 Generated by cargo-workspaces --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7907fb9..0bbe617 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1233,7 +1233,7 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tinywasm" -version = "0.2.0-alpha.0" +version = "0.2.0" dependencies = [ "eyre", "log", @@ -1250,7 +1250,7 @@ dependencies = [ [[package]] name = "tinywasm-cli" -version = "0.2.0-alpha.0" +version = "0.2.0" dependencies = [ "argh", "color-eyre", @@ -1262,7 +1262,7 @@ dependencies = [ [[package]] name = "tinywasm-parser" -version = "0.2.0-alpha.0" +version = "0.2.0" dependencies = [ "log", "tinywasm-types", @@ -1271,7 +1271,7 @@ dependencies = [ [[package]] name = "tinywasm-types" -version = "0.2.0-alpha.0" +version = "0.2.0" dependencies = [ "log", "rkyv", diff --git a/Cargo.toml b/Cargo.toml index ae4fd11..90f4e32 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ default-members=["crates/cli"] resolver="2" [workspace.package] -version="0.2.0-alpha.0" +version="0.2.0" edition="2021" license="MIT OR Apache-2.0" authors=["Henry Gressmann "]