├── .gitignore ├── .travis.yml ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── etc └── fuzz_loop.py ├── greenwasm-binary-format ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md └── src │ ├── lib.rs │ └── tests_binary_format.rs ├── greenwasm-execution ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md └── src │ ├── instructions.rs │ ├── lib.rs │ ├── modules.rs │ ├── numerics.rs │ └── runtime_structure.rs ├── greenwasm-spectest ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── src │ ├── lib.rs │ └── spectest.wasm └── testsuite │ ├── .gitignore │ ├── Contributing.md │ ├── LICENSE │ ├── README.md │ ├── address.wast │ ├── align.wast │ ├── binary.wast │ ├── block.wast │ ├── br.wast │ ├── br_if.wast │ ├── br_table.wast │ ├── break-drop.wast │ ├── call.wast │ ├── call_indirect.wast │ ├── comments.wast │ ├── const.wast │ ├── conversions.wast │ ├── custom.wast │ ├── custom_section.wast │ ├── data.wast │ ├── elem.wast │ ├── endianness.wast │ ├── exports.wast │ ├── extract-parts.sh │ ├── f32.wast │ ├── f32_bitwise.wast │ ├── f32_cmp.wast │ ├── f64.wast │ ├── f64_bitwise.wast │ ├── f64_cmp.wast │ ├── fac.wast │ ├── float_exprs.wast │ ├── float_literals.wast │ ├── float_memory.wast │ ├── float_misc.wast │ ├── forward.wast │ ├── func.wast │ ├── func_ptrs.wast │ ├── get_local.wast │ ├── globals.wast │ ├── i32.wast │ ├── i64.wast │ ├── if.wast │ ├── imports.wast │ ├── inline-module.wast │ ├── int_exprs.wast │ ├── int_literals.wast │ ├── labels.wast │ ├── left-to-right.wast │ ├── linking.wast │ ├── loop.wast │ ├── memory.wast │ ├── memory_grow.wast │ ├── memory_redundancy.wast │ ├── memory_trap.wast │ ├── names.wast │ ├── nop.wast │ ├── proposals │ ├── multi-value │ │ ├── block.wast │ │ ├── br.wast │ │ ├── call.wast │ │ ├── call_indirect.wast │ │ ├── fac.wast │ │ ├── func.wast │ │ ├── if.wast │ │ ├── loop.wast │ │ └── type.wast │ ├── mutable-global │ │ ├── globals.wast │ │ └── linking.wast │ ├── nontrapping-float-to-int-conversions │ │ └── conversions.wast │ ├── sign-extension-ops │ │ ├── i32.wast │ │ └── i64.wast │ └── threads │ │ ├── atomic.wast │ │ ├── exports.wast │ │ ├── imports.wast │ │ └── memory.wast │ ├── resizing.wast │ ├── return.wast │ ├── run.py │ ├── select.wast │ ├── set_local.wast │ ├── skip-stack-guard-page.wast │ ├── stack.wast │ ├── start.wast │ ├── store_retval.wast │ ├── switch.wast │ ├── tee_local.wast │ ├── token.wast │ ├── traps.wast │ ├── type.wast │ ├── typecheck.wast │ ├── unreachable.wast │ ├── unreached-invalid.wast │ ├── unwind.wast │ ├── update-testsuite.sh │ ├── utf8-custom-section-id.wast │ ├── utf8-import-field.wast │ ├── utf8-import-module.wast │ └── utf8-invalid-encoding.wast ├── greenwasm-structure ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md └── src │ ├── instructions.rs │ ├── lib.rs │ ├── modules.rs │ └── types.rs ├── greenwasm-validation ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md └── src │ └── lib.rs ├── src ├── bin │ ├── fuzz_generator.rs │ └── fuzz_launcher.rs └── lib.rs └── tests ├── function_space.wat ├── spec_testsuite.rs ├── wasm_files.rs └── wasm_files ├── factorial.wasm ├── function_space.wasm ├── fuzz0.wasm ├── parser_abort.wasm ├── pong.wasm └── stuff.wasm /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | rust: 3 | - nightly 4 | script: 5 | - cargo build --verbose 6 | - cargo test --all --verbose -- --nocapture 7 | cache: cargo 8 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | 3 | [package] 4 | name = "greenwasm" 5 | version = "0.3.1" 6 | authors = ["Marvin Löbel "] 7 | license = "MIT/Apache-2.0" 8 | 9 | documentation = "https://docs.rs/greenwasm" 10 | description = "An implementation of the Webassembly spec in Rust." 11 | readme = "README.md" 12 | repository = "https://github.com/Kimundi/greenwasm" 13 | categories = ["wasm"] 14 | keywords = [] 15 | 16 | [dependencies.greenwasm-structure] 17 | version = "0.3.0" 18 | path = "greenwasm-structure" 19 | 20 | [dependencies.greenwasm-validation] 21 | version = "0.3.0" 22 | path = "greenwasm-validation" 23 | 24 | [dependencies.greenwasm-binary-format] 25 | version = "0.3.0" 26 | path = "greenwasm-binary-format" 27 | 28 | [dependencies.greenwasm-execution] 29 | version = "0.3.0" 30 | path = "greenwasm-execution" 31 | 32 | [dependencies.binaryen] 33 | version = "0.4.0" 34 | 35 | [dev-dependencies.greenwasm-spectest] 36 | version = "0.3.1" 37 | path = "greenwasm-spectest" 38 | 39 | [profile.dev] 40 | opt-level = 1 # The parser is horribly slow otherwise 41 | 42 | [badges] 43 | appveyor = { repository = "Kimundi/greenwasm" } 44 | travis-ci = { repository = "Kimundi/greenwasm" } 45 | 46 | is-it-maintained-issue-resolution = { repository = "Kimundi/greenwasm" } 47 | is-it-maintained-open-issues = { repository = "Kimundi/greenwasm" } 48 | 49 | maintenance = { status = "experimental" } 50 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 The Rust Project Developers 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # greenwasm 2 | An implementation of the Webassembly spec in Rust. 3 | 4 | The structure of the project tries to follow the structure of the Spec where possible. Current progress: 5 | 6 | - [x] __Stucture__ (crate `greenwasm-structure`): Typedefs for Wasm Types, Instructions and Modules. 7 | - [x] __Validation__ (crate `greenwasm-validation`): Validator for a Wasm Module. 8 | - [x] __Execution__ (crate `greenwasm-execution`): Naive Execution Engine for a Wasm Module. 9 | - [x] __Binary-Format__ (crate `greenwasm-binary-format`) parser for the `.wasm` binary format. 10 | - [ ] __Text-Format__: Parser for the `.wat` text format. 11 | 12 | The individual crates are reexported from the central `greenwasm` crate, 13 | which also ties them together with a testsuite and some fuzzer scripts. 14 | 15 | In the current version this is mainly a learning exercise, but the long-term goals include: 16 | 17 | - __Modularity__: It should be possible to use the parser/validator/typedefs independent from each other. This is already somewhat possible due to the split in different crates. 18 | - __Genericy__: It should be possible to parse/validate independent from the underlying AST format. 19 | - __Performance__: It should be usable for performance-oriented projects. 20 | 21 | ## Testsuite 22 | 23 | The `greenwasm-spectest` crate contains a library shim around a mirror of the official [Webasembly MVP testsuite](https://github.com/WebAssembly/spec/tree/master/test/core). 24 | 25 | It is used as a dev-dependency by the main `greenwasm` crate, 26 | but has no dependencies on other crates in this repo. As such, it can be used 27 | as a independent testsuite launcher for other Webassembly implementations. 28 | 29 | ## License 30 | 31 | Licensed under either of 32 | 33 | * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) 34 | * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) 35 | 36 | at your option. 37 | 38 | ### Contribution 39 | 40 | Unless you explicitly state otherwise, any contribution intentionally submitted 41 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any 42 | additional terms or conditions. 43 | -------------------------------------------------------------------------------- /etc/fuzz_loop.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python3 2 | 3 | import subprocess 4 | import os.path 5 | import random 6 | 7 | iter_counter = 0; 8 | counter = 0; 9 | random_bytes = "/tmp/greenwasm_fuzz_random_bytes.bin" 10 | random_wasm = "/tmp/greenwasm_fuzz_random.wasm" 11 | test = "/tmp/greenwasm_fuzz_test.wasm" 12 | work = "/tmp/greenwasm_fuzz_work.wasm" 13 | 14 | def shell(s, *args): 15 | subprocess.run(s.format(*args), shell=True, check=True) 16 | 17 | def fuzz_launch_cmd(file): 18 | return "../target/debug/fuzz_launcher {}".format(file) 19 | 20 | def fuzz_gen_cmd(random, out): 21 | return "../target/debug/fuzz_generator {} {}".format(random, out) 22 | 23 | def testcase_filename(counter): 24 | return "testcases/testcase_{:03}".format(counter) 25 | 26 | shell("mkdir -p testcases") 27 | shell("cargo build") 28 | 29 | while True: 30 | rcount = random.randint(0, 20) ** 2 + random.randint(0, 3) 31 | shell("cat /dev/urandom | dd bs=1k count={} > {} 2> /dev/null", rcount, random_bytes) 32 | shell(fuzz_gen_cmd(random_bytes, random_wasm)) 33 | 34 | try: 35 | shell(fuzz_launch_cmd(random_wasm)) 36 | except subprocess.CalledProcessError: 37 | filename = "{}.wasm".format(testcase_filename(counter)) 38 | while os.path.isfile(filename): 39 | counter = counter + 1 40 | filename = "{}.wasm".format(testcase_filename(counter)) 41 | 42 | unreduced = "{}.unreduced.wasm".format(testcase_filename(counter)) 43 | shell("cp {} {}", random_wasm, unreduced) 44 | 45 | shell("wasm-reduce {} '--command={}' -t {} -w {} -f", random_wasm, fuzz_launch_cmd(test), test, work) 46 | reduced = "{}.reduced.wasm".format(testcase_filename(counter)) 47 | shell("cp {} {}", work, reduced) 48 | 49 | shell("wasm-gc {}", work) 50 | shell("cp {} {}", work, filename) 51 | 52 | print("Iteration {} DONE\n".format(iter_counter)) 53 | iter_counter = iter_counter + 1 54 | -------------------------------------------------------------------------------- /greenwasm-binary-format/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "greenwasm-binary-format" 3 | version = "0.3.0" 4 | authors = ["Marvin Löbel "] 5 | license = "MIT/Apache-2.0" 6 | 7 | documentation = "https://docs.rs/greenwasm-binary-format" 8 | description = "An implementation of the binary format section from the Webassembly spec." 9 | readme = "README.md" 10 | repository = "https://github.com/Kimundi/greenwasm" 11 | categories = ["wasm"] 12 | keywords = ["nom", "binary-format", "parser"] 13 | 14 | workspace = ".." 15 | 16 | [dependencies.greenwasm-structure] 17 | version = "0.3.0" 18 | path = "../greenwasm-structure" 19 | 20 | [dependencies.nom] 21 | version = "4.0" 22 | features = ["verbose-errors"] 23 | 24 | [badges] 25 | appveyor = { repository = "Kimundi/greenwasm" } 26 | travis-ci = { repository = "Kimundi/greenwasm" } 27 | 28 | is-it-maintained-issue-resolution = { repository = "Kimundi/greenwasm" } 29 | is-it-maintained-open-issues = { repository = "Kimundi/greenwasm" } 30 | 31 | maintenance = { status = "experimental" } 32 | -------------------------------------------------------------------------------- /greenwasm-binary-format/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 The Rust Project Developers 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /greenwasm-binary-format/README.md: -------------------------------------------------------------------------------- 1 | # greenwasm-binary-format 2 | An implementation of the _Binary Format_ section from the Webassembly spec in Rust. 3 | 4 | Contains a parser for the `.wasm` binary format. 5 | 6 | ## License 7 | 8 | Licensed under either of 9 | 10 | * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) 11 | * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) 12 | 13 | at your option. 14 | 15 | ### Contribution 16 | 17 | Unless you explicitly state otherwise, any contribution intentionally submitted 18 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any 19 | additional terms or conditions. 20 | -------------------------------------------------------------------------------- /greenwasm-execution/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "greenwasm-execution" 3 | version = "0.3.0" 4 | authors = ["Marvin Löbel "] 5 | license = "MIT/Apache-2.0" 6 | 7 | documentation = "https://docs.rs/greenwasm-execution" 8 | description = "An implementation of the execution section from the Webassembly spec." 9 | readme = "README.md" 10 | repository = "https://github.com/Kimundi/greenwasm" 11 | categories = ["wasm", "emulators"] 12 | keywords = ["vm", "execution"] 13 | 14 | workspace = ".." 15 | 16 | [dependencies.greenwasm-structure] 17 | version = "0.3.0" 18 | path = "../greenwasm-structure" 19 | 20 | [dependencies.greenwasm-validation] 21 | version = "0.3.0" 22 | path = "../greenwasm-validation" 23 | 24 | [dependencies.frounding] 25 | version = "0.0.4" 26 | 27 | [badges] 28 | appveyor = { repository = "Kimundi/greenwasm" } 29 | travis-ci = { repository = "Kimundi/greenwasm" } 30 | 31 | is-it-maintained-issue-resolution = { repository = "Kimundi/greenwasm" } 32 | is-it-maintained-open-issues = { repository = "Kimundi/greenwasm" } 33 | 34 | maintenance = { status = "experimental" } 35 | -------------------------------------------------------------------------------- /greenwasm-execution/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 The Rust Project Developers 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /greenwasm-execution/README.md: -------------------------------------------------------------------------------- 1 | # greenwasm-execution 2 | An implementation of the _Execution_ section from the Webassembly spec in Rust. 3 | 4 | Contains a naive implementation of an execution framework 5 | that borrows the AST. 6 | 7 | ## License 8 | 9 | Licensed under either of 10 | 11 | * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) 12 | * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) 13 | 14 | at your option. 15 | 16 | ### Contribution 17 | 18 | Unless you explicitly state otherwise, any contribution intentionally submitted 19 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any 20 | additional terms or conditions. 21 | -------------------------------------------------------------------------------- /greenwasm-execution/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(macro_at_most_once_rep)] 2 | #![feature(core_intrinsics)] 3 | #![feature(int_to_from_bytes)] 4 | #![feature(nll)] 5 | 6 | extern crate greenwasm_structure; 7 | extern crate greenwasm_validation; 8 | extern crate frounding; 9 | 10 | const DEBUG_EXECUTION: bool = false; 11 | 12 | pub mod runtime_structure; 13 | pub mod modules; 14 | pub mod numerics; 15 | pub mod instructions; 16 | -------------------------------------------------------------------------------- /greenwasm-spectest/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "greenwasm-spectest" 3 | version = "0.3.3" 4 | authors = ["Marvin Löbel "] 5 | license = "MIT/Apache-2.0" 6 | 7 | documentation = "https://docs.rs/greenwasm-spectest" 8 | description = "A library shim around a mirror of the official Webasembly MVP testsuite." 9 | readme = "README.md" 10 | repository = "https://github.com/Kimundi/greenwasm" 11 | categories = ["wasm", "development-tools"] 12 | keywords = ["testsuite"] 13 | 14 | workspace = ".." 15 | 16 | [dependencies] 17 | wabt = "0.5.0" 18 | 19 | [badges] 20 | appveyor = { repository = "Kimundi/greenwasm" } 21 | travis-ci = { repository = "Kimundi/greenwasm" } 22 | 23 | is-it-maintained-issue-resolution = { repository = "Kimundi/greenwasm" } 24 | is-it-maintained-open-issues = { repository = "Kimundi/greenwasm" } 25 | 26 | maintenance = { status = "experimental" } 27 | -------------------------------------------------------------------------------- /greenwasm-spectest/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 The Rust Project Developers 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /greenwasm-spectest/README.md: -------------------------------------------------------------------------------- 1 | # greenwasm-spectest 2 | A library shim around a mirror of the official [Webasembly MVP testsuite](https://github.com/WebAssembly/spec/tree/master/test/core). 3 | 4 | It can be used as a independent testsuite launcher for other Webassembly implementations. 5 | 6 | ## License 7 | 8 | Licensed under either of 9 | 10 | * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) 11 | * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) 12 | 13 | at your option. 14 | 15 | ### Contribution 16 | 17 | Unless you explicitly state otherwise, any contribution intentionally submitted 18 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any 19 | additional terms or conditions. 20 | -------------------------------------------------------------------------------- /greenwasm-spectest/src/spectest.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kimundi/greenwasm/9afe805aa534c752dd1c62b8978a305a9bc2f640/greenwasm-spectest/src/spectest.wasm -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/.gitignore: -------------------------------------------------------------------------------- 1 | /commit_message 2 | /repos/ 3 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/Contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing to WebAssembly 2 | 3 | Interested in participating? Please follow 4 | [the same contributing guidelines as the design repository][]. 5 | 6 | [the same contributing guidelines as the design repository]: https://github.com/WebAssembly/design/blob/master/Contributing.md 7 | 8 | Also, please be sure to read [the README.md](README.md) for this repository. 9 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/README.md: -------------------------------------------------------------------------------- 1 | This directory contains tests for the core WebAssembly semantics, as described in [Semantics.md](https://github.com/WebAssembly/design/blob/master/Semantics.md) and specified by the [spec interpreter](https://github.com/WebAssembly/spec/blob/master/interpreter/spec). 2 | 3 | Tests are written in the [S-Expression script format](https://github.com/WebAssembly/spec/blob/master/interpreter/README.md#s-expression-syntax) defined by the interpreter. 4 | 5 | The test suite can be run with the spec interpreter as follows: 6 | ``` 7 | ./run.py --wasm 8 | ``` 9 | where the path points to the spec interpreter executable (or a tool that understands similar options). If the binary is in the working directory, this option can be omitted. 10 | 11 | In addition, the option `--js ` can be given to point to a stand-alone JavaScript interpreter supporting the WebAssembly API. If provided, all tests are also executed in JavaScript. 12 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/break-drop.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "br") (block (br 0))) 3 | (func (export "br_if") (block (br_if 0 (i32.const 1)))) 4 | (func (export "br_table") (block (br_table 0 (i32.const 0)))) 5 | ) 6 | 7 | (assert_return (invoke "br")) 8 | (assert_return (invoke "br_if")) 9 | (assert_return (invoke "br_table")) 10 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/call.wast: -------------------------------------------------------------------------------- 1 | ;; Test `call` operator 2 | 3 | (module 4 | ;; Auxiliary definitions 5 | (func $const-i32 (result i32) (i32.const 0x132)) 6 | (func $const-i64 (result i64) (i64.const 0x164)) 7 | (func $const-f32 (result f32) (f32.const 0xf32)) 8 | (func $const-f64 (result f64) (f64.const 0xf64)) 9 | 10 | (func $id-i32 (param i32) (result i32) (get_local 0)) 11 | (func $id-i64 (param i64) (result i64) (get_local 0)) 12 | (func $id-f32 (param f32) (result f32) (get_local 0)) 13 | (func $id-f64 (param f64) (result f64) (get_local 0)) 14 | 15 | (func $f32-i32 (param f32 i32) (result i32) (get_local 1)) 16 | (func $i32-i64 (param i32 i64) (result i64) (get_local 1)) 17 | (func $f64-f32 (param f64 f32) (result f32) (get_local 1)) 18 | (func $i64-f64 (param i64 f64) (result f64) (get_local 1)) 19 | 20 | ;; Typing 21 | 22 | (func (export "type-i32") (result i32) (call $const-i32)) 23 | (func (export "type-i64") (result i64) (call $const-i64)) 24 | (func (export "type-f32") (result f32) (call $const-f32)) 25 | (func (export "type-f64") (result f64) (call $const-f64)) 26 | 27 | (func (export "type-first-i32") (result i32) (call $id-i32 (i32.const 32))) 28 | (func (export "type-first-i64") (result i64) (call $id-i64 (i64.const 64))) 29 | (func (export "type-first-f32") (result f32) (call $id-f32 (f32.const 1.32))) 30 | (func (export "type-first-f64") (result f64) (call $id-f64 (f64.const 1.64))) 31 | 32 | (func (export "type-second-i32") (result i32) 33 | (call $f32-i32 (f32.const 32.1) (i32.const 32)) 34 | ) 35 | (func (export "type-second-i64") (result i64) 36 | (call $i32-i64 (i32.const 32) (i64.const 64)) 37 | ) 38 | (func (export "type-second-f32") (result f32) 39 | (call $f64-f32 (f64.const 64) (f32.const 32)) 40 | ) 41 | (func (export "type-second-f64") (result f64) 42 | (call $i64-f64 (i64.const 64) (f64.const 64.1)) 43 | ) 44 | 45 | ;; Recursion 46 | 47 | (func $fac (export "fac") (param i64) (result i64) 48 | (if (result i64) (i64.eqz (get_local 0)) 49 | (then (i64.const 1)) 50 | (else 51 | (i64.mul 52 | (get_local 0) 53 | (call $fac (i64.sub (get_local 0) (i64.const 1))) 54 | ) 55 | ) 56 | ) 57 | ) 58 | 59 | (func $fac-acc (export "fac-acc") (param i64 i64) (result i64) 60 | (if (result i64) (i64.eqz (get_local 0)) 61 | (then (get_local 1)) 62 | (else 63 | (call $fac-acc 64 | (i64.sub (get_local 0) (i64.const 1)) 65 | (i64.mul (get_local 0) (get_local 1)) 66 | ) 67 | ) 68 | ) 69 | ) 70 | 71 | (func $fib (export "fib") (param i64) (result i64) 72 | (if (result i64) (i64.le_u (get_local 0) (i64.const 1)) 73 | (then (i64.const 1)) 74 | (else 75 | (i64.add 76 | (call $fib (i64.sub (get_local 0) (i64.const 2))) 77 | (call $fib (i64.sub (get_local 0) (i64.const 1))) 78 | ) 79 | ) 80 | ) 81 | ) 82 | 83 | (func $even (export "even") (param i64) (result i32) 84 | (if (result i32) (i64.eqz (get_local 0)) 85 | (then (i32.const 44)) 86 | (else (call $odd (i64.sub (get_local 0) (i64.const 1)))) 87 | ) 88 | ) 89 | (func $odd (export "odd") (param i64) (result i32) 90 | (if (result i32) (i64.eqz (get_local 0)) 91 | (then (i32.const 99)) 92 | (else (call $even (i64.sub (get_local 0) (i64.const 1)))) 93 | ) 94 | ) 95 | 96 | ;; Stack exhaustion 97 | 98 | ;; Implementations are required to have every call consume some abstract 99 | ;; resource towards exhausting some abstract finite limit, such that 100 | ;; infinitely recursive test cases reliably trap in finite time. This is 101 | ;; because otherwise applications could come to depend on it on those 102 | ;; implementations and be incompatible with implementations that don't do 103 | ;; it (or don't do it under the same circumstances). 104 | 105 | (func $runaway (export "runaway") (call $runaway)) 106 | 107 | (func $mutual-runaway1 (export "mutual-runaway") (call $mutual-runaway2)) 108 | (func $mutual-runaway2 (call $mutual-runaway1)) 109 | ) 110 | 111 | (assert_return (invoke "type-i32") (i32.const 0x132)) 112 | (assert_return (invoke "type-i64") (i64.const 0x164)) 113 | (assert_return (invoke "type-f32") (f32.const 0xf32)) 114 | (assert_return (invoke "type-f64") (f64.const 0xf64)) 115 | 116 | (assert_return (invoke "type-first-i32") (i32.const 32)) 117 | (assert_return (invoke "type-first-i64") (i64.const 64)) 118 | (assert_return (invoke "type-first-f32") (f32.const 1.32)) 119 | (assert_return (invoke "type-first-f64") (f64.const 1.64)) 120 | 121 | (assert_return (invoke "type-second-i32") (i32.const 32)) 122 | (assert_return (invoke "type-second-i64") (i64.const 64)) 123 | (assert_return (invoke "type-second-f32") (f32.const 32)) 124 | (assert_return (invoke "type-second-f64") (f64.const 64.1)) 125 | 126 | (assert_return (invoke "fac" (i64.const 0)) (i64.const 1)) 127 | (assert_return (invoke "fac" (i64.const 1)) (i64.const 1)) 128 | (assert_return (invoke "fac" (i64.const 5)) (i64.const 120)) 129 | (assert_return (invoke "fac" (i64.const 25)) (i64.const 7034535277573963776)) 130 | (assert_return (invoke "fac-acc" (i64.const 0) (i64.const 1)) (i64.const 1)) 131 | (assert_return (invoke "fac-acc" (i64.const 1) (i64.const 1)) (i64.const 1)) 132 | (assert_return (invoke "fac-acc" (i64.const 5) (i64.const 1)) (i64.const 120)) 133 | (assert_return 134 | (invoke "fac-acc" (i64.const 25) (i64.const 1)) 135 | (i64.const 7034535277573963776) 136 | ) 137 | 138 | (assert_return (invoke "fib" (i64.const 0)) (i64.const 1)) 139 | (assert_return (invoke "fib" (i64.const 1)) (i64.const 1)) 140 | (assert_return (invoke "fib" (i64.const 2)) (i64.const 2)) 141 | (assert_return (invoke "fib" (i64.const 5)) (i64.const 8)) 142 | (assert_return (invoke "fib" (i64.const 20)) (i64.const 10946)) 143 | 144 | (assert_return (invoke "even" (i64.const 0)) (i32.const 44)) 145 | (assert_return (invoke "even" (i64.const 1)) (i32.const 99)) 146 | (assert_return (invoke "even" (i64.const 100)) (i32.const 44)) 147 | (assert_return (invoke "even" (i64.const 77)) (i32.const 99)) 148 | (assert_return (invoke "odd" (i64.const 0)) (i32.const 99)) 149 | (assert_return (invoke "odd" (i64.const 1)) (i32.const 44)) 150 | (assert_return (invoke "odd" (i64.const 200)) (i32.const 99)) 151 | (assert_return (invoke "odd" (i64.const 77)) (i32.const 44)) 152 | 153 | (assert_exhaustion (invoke "runaway") "call stack exhausted") 154 | (assert_exhaustion (invoke "mutual-runaway") "call stack exhausted") 155 | 156 | 157 | ;; Invalid typing 158 | 159 | (assert_invalid 160 | (module 161 | (func $type-void-vs-num (i32.eqz (call 1))) 162 | (func) 163 | ) 164 | "type mismatch" 165 | ) 166 | (assert_invalid 167 | (module 168 | (func $type-num-vs-num (i32.eqz (call 1))) 169 | (func (result i64) (i64.const 1)) 170 | ) 171 | "type mismatch" 172 | ) 173 | 174 | (assert_invalid 175 | (module 176 | (func $arity-0-vs-1 (call 1)) 177 | (func (param i32)) 178 | ) 179 | "type mismatch" 180 | ) 181 | (assert_invalid 182 | (module 183 | (func $arity-0-vs-2 (call 1)) 184 | (func (param f64 i32)) 185 | ) 186 | "type mismatch" 187 | ) 188 | (assert_invalid 189 | (module 190 | (func $arity-1-vs-0 (call 1 (i32.const 1))) 191 | (func) 192 | ) 193 | "type mismatch" 194 | ) 195 | (assert_invalid 196 | (module 197 | (func $arity-2-vs-0 (call 1 (f64.const 2) (i32.const 1))) 198 | (func) 199 | ) 200 | "type mismatch" 201 | ) 202 | 203 | (assert_invalid 204 | (module 205 | (func $type-first-void-vs-num (call 1 (nop) (i32.const 1))) 206 | (func (param i32 i32)) 207 | ) 208 | "type mismatch" 209 | ) 210 | (assert_invalid 211 | (module 212 | (func $type-second-void-vs-num (call 1 (i32.const 1) (nop))) 213 | (func (param i32 i32)) 214 | ) 215 | "type mismatch" 216 | ) 217 | (assert_invalid 218 | (module 219 | (func $type-first-num-vs-num (call 1 (f64.const 1) (i32.const 1))) 220 | (func (param i32 f64)) 221 | ) 222 | "type mismatch" 223 | ) 224 | (assert_invalid 225 | (module 226 | (func $type-second-num-vs-num (call 1 (i32.const 1) (f64.const 1))) 227 | (func (param f64 i32)) 228 | ) 229 | "type mismatch" 230 | ) 231 | 232 | 233 | ;; Unbound function 234 | 235 | (assert_invalid 236 | (module (func $unbound-func (call 1))) 237 | "unknown function" 238 | ) 239 | (assert_invalid 240 | (module (func $large-func (call 1012321300))) 241 | "unknown function" 242 | ) 243 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/comments.wast: -------------------------------------------------------------------------------- 1 | ;; Test comment syntax 2 | 3 | ;;comment 4 | 5 | ;;;;;;;;;;; 6 | 7 | ;;comment 8 | 9 | ( ;;comment 10 | module;;comment 11 | );;comment 12 | 13 | ;;) 14 | ;;;) 15 | ;; ;) 16 | ;; (; 17 | 18 | (;;) 19 | 20 | (;comment;) 21 | 22 | (;;comment;) 23 | 24 | (;;;comment;) 25 | 26 | (;;;;;;;;;;;;;;) 27 | 28 | (;(((((((((( ;) 29 | 30 | (;)))))))))));) 31 | 32 | (;comment";) 33 | 34 | (;comment"";) 35 | 36 | (;comment""";) 37 | 38 | ;; ASCII 00-1F, 7F 39 | (; 40 | ;) 41 | 42 | (;Heiße Würstchen;) 43 | 44 | (;;) 45 | 46 | (;comment 47 | comment;) 48 | 49 | (;comment;) 50 | 51 | (;comment;)((;comment;) 52 | (;comment;)module(;comment;) 53 | (;comment;))(;comment;) 54 | 55 | (;comment(;nested;)comment;) 56 | 57 | (;comment 58 | (;nested 59 | ;)comment 60 | ;) 61 | 62 | (module 63 | (;comment(;nested(;further;)nested;)comment;) 64 | ) 65 | 66 | (;comment;;comment;) 67 | 68 | (;comment;;comment 69 | ;) 70 | 71 | (module 72 | (;comment;;comment(;nested;)comment;) 73 | ) -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/const.wast: -------------------------------------------------------------------------------- 1 | ;; Test t.const instructions 2 | 3 | ;; Syntax error 4 | 5 | (module (func (i32.const 0xffffffff) drop)) 6 | (module (func (i32.const -0x80000000) drop)) 7 | (assert_malformed 8 | (module quote "(func (i32.const 0x100000000) drop)") 9 | "constant out of range" 10 | ) 11 | (assert_malformed 12 | (module quote "(func (i32.const -0x80000001) drop)") 13 | "constant out of range" 14 | ) 15 | 16 | (module (func (i32.const 4294967295) drop)) 17 | (module (func (i32.const -2147483648) drop)) 18 | (assert_malformed 19 | (module quote "(func (i32.const 4294967296) drop)") 20 | "constant out of range" 21 | ) 22 | (assert_malformed 23 | (module quote "(func (i32.const -2147483649) drop)") 24 | "constant out of range" 25 | ) 26 | 27 | (module (func (i64.const 0xffffffffffffffff) drop)) 28 | (module (func (i64.const -0x8000000000000000) drop)) 29 | (assert_malformed 30 | (module quote "(func (i64.const 0x10000000000000000) drop)") 31 | "constant out of range" 32 | ) 33 | (assert_malformed 34 | (module quote "(func (i64.const -0x8000000000000001) drop)") 35 | "constant out of range" 36 | ) 37 | 38 | (module (func (i64.const 18446744073709551615) drop)) 39 | (module (func (i64.const -9223372036854775808) drop)) 40 | (assert_malformed 41 | (module quote "(func (i64.const 18446744073709551616) drop)") 42 | "constant out of range" 43 | ) 44 | (assert_malformed 45 | (module quote "(func (i64.const -9223372036854775809) drop)") 46 | "constant out of range" 47 | ) 48 | 49 | (module (func (f32.const 0x1p127) drop)) 50 | (module (func (f32.const -0x1p127) drop)) 51 | (module (func (f32.const 0x1.fffffep127) drop)) 52 | (module (func (f32.const -0x1.fffffep127) drop)) 53 | (module (func (f32.const 0x1.fffffe7p127) drop)) 54 | (module (func (f32.const -0x1.fffffe7p127) drop)) 55 | (assert_malformed 56 | (module quote "(func (f32.const 0x1p128) drop)") 57 | "constant out of range" 58 | ) 59 | (assert_malformed 60 | (module quote "(func (f32.const -0x1p128) drop)") 61 | "constant out of range" 62 | ) 63 | (assert_malformed 64 | (module quote "(func (f32.const 0x1.ffffffp127) drop)") 65 | "constant out of range" 66 | ) 67 | (assert_malformed 68 | (module quote "(func (f32.const -0x1.ffffffp127) drop)") 69 | "constant out of range" 70 | ) 71 | 72 | (module (func (f32.const 1e38) drop)) 73 | (module (func (f32.const -1e38) drop)) 74 | (assert_malformed 75 | (module quote "(func (f32.const 1e39) drop)") 76 | "constant out of range" 77 | ) 78 | (assert_malformed 79 | (module quote "(func (f32.const -1e39) drop)") 80 | "constant out of range" 81 | ) 82 | 83 | (module (func (f32.const 340282356779733623858607532500980858880) drop)) 84 | (module (func (f32.const -340282356779733623858607532500980858880) drop)) 85 | (assert_malformed 86 | (module quote "(func (f32.const 340282356779733661637539395458142568448) drop)") 87 | "constant out of range" 88 | ) 89 | (assert_malformed 90 | (module quote "(func (f32.const -340282356779733661637539395458142568448) drop)") 91 | "constant out of range" 92 | ) 93 | 94 | (module (func (f64.const 0x1p1023) drop)) 95 | (module (func (f64.const -0x1p1023) drop)) 96 | (module (func (f64.const 0x1.fffffffffffffp1023) drop)) 97 | (module (func (f64.const -0x1.fffffffffffffp1023) drop)) 98 | (module (func (f64.const 0x1.fffffffffffff7p1023) drop)) 99 | (module (func (f64.const -0x1.fffffffffffff7p1023) drop)) 100 | (assert_malformed 101 | (module quote "(func (f64.const 0x1p1024) drop)") 102 | "constant out of range" 103 | ) 104 | (assert_malformed 105 | (module quote "(func (f64.const -0x1p1024) drop)") 106 | "constant out of range" 107 | ) 108 | (assert_malformed 109 | (module quote "(func (f64.const 0x1.fffffffffffff8p1023) drop)") 110 | "constant out of range" 111 | ) 112 | (assert_malformed 113 | (module quote "(func (f64.const -0x1.fffffffffffff8p1023) drop)") 114 | "constant out of range" 115 | ) 116 | 117 | (module (func (f64.const 1e308) drop)) 118 | (module (func (f64.const -1e308) drop)) 119 | (assert_malformed 120 | (module quote "(func (f64.const 1e309) drop)") 121 | "constant out of range" 122 | ) 123 | (assert_malformed 124 | (module quote "(func (f64.const -1e309) drop)") 125 | "constant out of range" 126 | ) 127 | 128 | (module (func (f64.const 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368) drop)) 129 | (module (func (f64.const -179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368) drop)) 130 | (assert_malformed 131 | (module quote "(func (f64.const 269653970229347356221791135597556535197105851288767494898376215204735891170042808140884337949150317257310688430271573696351481990334196274152701320055306275479074865864826923114368235135583993416113802762682700913456874855354834422248712838998185022412196739306217084753107265771378949821875606039276187287552) drop)") 132 | "constant out of range" 133 | ) 134 | (assert_malformed 135 | (module quote "(func (f64.const -269653970229347356221791135597556535197105851288767494898376215204735891170042808140884337949150317257310688430271573696351481990334196274152701320055306275479074865864826923114368235135583993416113802762682700913456874855354834422248712838998185022412196739306217084753107265771378949821875606039276187287552) drop)") 136 | "constant out of range" 137 | ) 138 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/custom.wast: -------------------------------------------------------------------------------- 1 | (module binary 2 | "\00asm" "\01\00\00\00" 3 | "\00\24\10" "a custom section" "this is the payload" 4 | "\00\20\10" "a custom section" "this is payload" 5 | "\00\11\10" "a custom section" "" 6 | "\00\10\00" "" "this is payload" 7 | "\00\01\00" "" "" 8 | "\00\24\10" "\00\00custom sectio\00" "this is the payload" 9 | "\00\24\10" "\ef\bb\bfa custom sect" "this is the payload" 10 | "\00\24\10" "a custom sect\e2\8c\a3" "this is the payload" 11 | "\00\1f\16" "module within a module" "\00asm" "\01\00\00\00" 12 | ) 13 | 14 | (module binary 15 | "\00asm" "\01\00\00\00" 16 | "\00\0e\06" "custom" "payload" 17 | "\00\0e\06" "custom" "payload" 18 | "\01\01\00" ;; type section 19 | "\00\0e\06" "custom" "payload" 20 | "\00\0e\06" "custom" "payload" 21 | "\02\01\00" ;; import section 22 | "\00\0e\06" "custom" "payload" 23 | "\00\0e\06" "custom" "payload" 24 | "\03\01\00" ;; function section 25 | "\00\0e\06" "custom" "payload" 26 | "\00\0e\06" "custom" "payload" 27 | "\04\01\00" ;; table section 28 | "\00\0e\06" "custom" "payload" 29 | "\00\0e\06" "custom" "payload" 30 | "\05\01\00" ;; memory section 31 | "\00\0e\06" "custom" "payload" 32 | "\00\0e\06" "custom" "payload" 33 | "\06\01\00" ;; global section 34 | "\00\0e\06" "custom" "payload" 35 | "\00\0e\06" "custom" "payload" 36 | "\07\01\00" ;; export section 37 | "\00\0e\06" "custom" "payload" 38 | "\00\0e\06" "custom" "payload" 39 | "\09\01\00" ;; element section 40 | "\00\0e\06" "custom" "payload" 41 | "\00\0e\06" "custom" "payload" 42 | "\0a\01\00" ;; code section 43 | "\00\0e\06" "custom" "payload" 44 | "\00\0e\06" "custom" "payload" 45 | "\0b\01\00" ;; data section 46 | "\00\0e\06" "custom" "payload" 47 | "\00\0e\06" "custom" "payload" 48 | ) 49 | 50 | (module binary 51 | "\00asm" "\01\00\00\00" 52 | "\01\07\01\60\02\7f\7f\01\7f" ;; type section 53 | "\00\1a\06" "custom" "this is the payload" ;; custom section 54 | "\03\02\01\00" ;; function section 55 | "\07\0a\01\06\61\64\64\54\77\6f\00\00" ;; export section 56 | "\0a\09\01\07\00\20\00\20\01\6a\0b" ;; code section 57 | "\00\1b\07" "custom2" "this is the payload" ;; custom section 58 | ) 59 | 60 | (assert_malformed 61 | (module binary 62 | "\00asm" "\01\00\00\00" 63 | "\00" 64 | ) 65 | "unexpected end" 66 | ) 67 | 68 | (assert_malformed 69 | (module binary 70 | "\00asm" "\01\00\00\00" 71 | "\00\00" 72 | ) 73 | "unexpected end" 74 | ) 75 | 76 | (assert_malformed 77 | (module binary 78 | "\00asm" "\01\00\00\00" 79 | "\00\00\00\05\01\00\07\00\00" 80 | ) 81 | "unexpected end" 82 | ) 83 | 84 | (assert_malformed 85 | (module binary 86 | "\00asm" "\01\00\00\00" 87 | "\00\26\10" "a custom section" "this is the payload" 88 | ) 89 | "unexpected end" 90 | ) 91 | 92 | (assert_malformed 93 | (module binary 94 | "\00asm" "\01\00\00\00" 95 | "\00\25\10" "a custom section" "this is the payload" 96 | "\00\24\10" "a custom section" "this is the payload" 97 | ) 98 | "invalid section id" 99 | ) 100 | 101 | (assert_malformed 102 | (module binary 103 | "\00asm" "\01\00\00\00" 104 | "\01\07\01\60\02\7f\7f\01\7f" ;; type section 105 | "\00\25\10" "a custom section" "this is the payload" ;; invalid length! 106 | "\03\02\01\00" ;; function section 107 | "\0a\09\01\07\00\20\00\20\01\6a\0b" ;; code section 108 | "\00\1b\07" "custom2" "this is the payload" ;; custom section 109 | ) 110 | "function and code section have inconsistent lengths" 111 | ) 112 | 113 | ;; Test concatenated modules. 114 | (assert_malformed 115 | (module binary 116 | "\00asm\01\00\00\00" 117 | "\00asm\01\00\00\00" 118 | ) 119 | "length out of bounds" 120 | ) 121 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/custom_section.wast: -------------------------------------------------------------------------------- 1 | (module binary 2 | "\00asm" "\01\00\00\00" 3 | "\00\24\10" "a custom section" "this is the payload" 4 | "\00\20\10" "a custom section" "this is payload" 5 | "\00\11\10" "a custom section" "" 6 | "\00\10\00" "" "this is payload" 7 | "\00\01\00" "" "" 8 | "\00\24\10" "\00\00custom sectio\00" "this is the payload" 9 | "\00\24\10" "\ef\bb\bfa custom sect" "this is the payload" 10 | "\00\24\10" "a custom sect\e2\8c\a3" "this is the payload" 11 | "\00\1f\16" "module within a module" "\00asm" "\01\00\00\00" 12 | ) 13 | 14 | (module binary 15 | "\00asm" "\01\00\00\00" 16 | "\00\0e\06" "custom" "payload" 17 | "\00\0e\06" "custom" "payload" 18 | "\01\01\00" ;; type section 19 | "\00\0e\06" "custom" "payload" 20 | "\00\0e\06" "custom" "payload" 21 | "\02\01\00" ;; import section 22 | "\00\0e\06" "custom" "payload" 23 | "\00\0e\06" "custom" "payload" 24 | "\03\01\00" ;; function section 25 | "\00\0e\06" "custom" "payload" 26 | "\00\0e\06" "custom" "payload" 27 | "\04\01\00" ;; table section 28 | "\00\0e\06" "custom" "payload" 29 | "\00\0e\06" "custom" "payload" 30 | "\05\01\00" ;; memory section 31 | "\00\0e\06" "custom" "payload" 32 | "\00\0e\06" "custom" "payload" 33 | "\06\01\00" ;; global section 34 | "\00\0e\06" "custom" "payload" 35 | "\00\0e\06" "custom" "payload" 36 | "\07\01\00" ;; export section 37 | "\00\0e\06" "custom" "payload" 38 | "\00\0e\06" "custom" "payload" 39 | "\09\01\00" ;; element section 40 | "\00\0e\06" "custom" "payload" 41 | "\00\0e\06" "custom" "payload" 42 | "\0a\01\00" ;; code section 43 | "\00\0e\06" "custom" "payload" 44 | "\00\0e\06" "custom" "payload" 45 | "\0b\01\00" ;; data section 46 | "\00\0e\06" "custom" "payload" 47 | "\00\0e\06" "custom" "payload" 48 | ) 49 | 50 | (module binary 51 | "\00asm" "\01\00\00\00" 52 | "\01\07\01\60\02\7f\7f\01\7f" ;; type section 53 | "\00\1a\06" "custom" "this is the payload" ;; custom section 54 | "\03\02\01\00" ;; function section 55 | "\07\0a\01\06\61\64\64\54\77\6f\00\00" ;; export section 56 | "\0a\09\01\07\00\20\00\20\01\6a\0b" ;; code section 57 | "\00\1b\07" "custom2" "this is the payload" ;; custom section 58 | ) 59 | 60 | (assert_malformed 61 | (module binary 62 | "\00asm" "\01\00\00\00" 63 | "\00" 64 | ) 65 | "unexpected end" 66 | ) 67 | 68 | (assert_malformed 69 | (module binary 70 | "\00asm" "\01\00\00\00" 71 | "\00\00" 72 | ) 73 | "unexpected end" 74 | ) 75 | 76 | (assert_malformed 77 | (module binary 78 | "\00asm" "\01\00\00\00" 79 | "\00\26\10" "a custom section" "this is the payload" 80 | ) 81 | "unexpected end" 82 | ) 83 | 84 | (assert_malformed 85 | (module binary 86 | "\00asm" "\01\00\00\00" 87 | "\00\25\10" "a custom section" "this is the payload" 88 | "\00\24\10" "a custom section" "this is the payload" 89 | ) 90 | "invalid section id" 91 | ) 92 | 93 | (assert_malformed 94 | (module binary 95 | "\00asm" "\01\00\00\00" 96 | "\01\07\01\60\02\7f\7f\01\7f" ;; type section 97 | "\00\25\10" "a custom section" "this is the payload" ;; invalid length! 98 | "\03\02\01\00" ;; function section 99 | "\0a\09\01\07\00\20\00\20\01\6a\0b" ;; code section 100 | "\00\1b\07" "custom2" "this is the payload" ;; custom section 101 | ) 102 | "function and code section have inconsistent lengths" 103 | ) 104 | 105 | ;; Test concatenated modules. 106 | (assert_malformed 107 | (module binary 108 | "\00asm\01\00\00\00" 109 | "\00asm\01\00\00\00" 110 | ) 111 | "length out of bounds" 112 | ) 113 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/data.wast: -------------------------------------------------------------------------------- 1 | ;; Test the data section 2 | 3 | ;; Syntax 4 | 5 | (module 6 | (memory $m 1) 7 | (data (i32.const 0)) 8 | (data (i32.const 1) "a" "" "bcd") 9 | (data (offset (i32.const 0))) 10 | (data (offset (i32.const 0)) "" "a" "bc" "") 11 | (data 0 (i32.const 0)) 12 | (data 0x0 (i32.const 1) "a" "" "bcd") 13 | (data 0x000 (offset (i32.const 0))) 14 | (data 0 (offset (i32.const 0)) "" "a" "bc" "") 15 | (data $m (i32.const 0)) 16 | (data $m (i32.const 1) "a" "" "bcd") 17 | (data $m (offset (i32.const 0))) 18 | (data $m (offset (i32.const 0)) "" "a" "bc" "") 19 | ) 20 | 21 | ;; Basic use 22 | 23 | (module 24 | (memory 1) 25 | (data (i32.const 0) "a") 26 | ) 27 | (module 28 | (import "spectest" "memory" (memory 1)) 29 | (data (i32.const 0) "a") 30 | ) 31 | 32 | (module 33 | (memory 1) 34 | (data (i32.const 0) "a") 35 | (data (i32.const 3) "b") 36 | (data (i32.const 100) "cde") 37 | (data (i32.const 5) "x") 38 | (data (i32.const 3) "c") 39 | ) 40 | (module 41 | (import "spectest" "memory" (memory 1)) 42 | (data (i32.const 0) "a") 43 | (data (i32.const 1) "b") 44 | (data (i32.const 2) "cde") 45 | (data (i32.const 3) "f") 46 | (data (i32.const 2) "g") 47 | (data (i32.const 1) "h") 48 | ) 49 | 50 | (module 51 | (global (import "spectest" "global_i32") i32) 52 | (memory 1) 53 | (data (get_global 0) "a") 54 | ) 55 | (module 56 | (global (import "spectest" "global_i32") i32) 57 | (import "spectest" "memory" (memory 1)) 58 | (data (get_global 0) "a") 59 | ) 60 | 61 | (module 62 | (global $g (import "spectest" "global_i32") i32) 63 | (memory 1) 64 | (data (get_global $g) "a") 65 | ) 66 | (module 67 | (global $g (import "spectest" "global_i32") i32) 68 | (import "spectest" "memory" (memory 1)) 69 | (data (get_global $g) "a") 70 | ) 71 | 72 | ;; Use of internal globals in constant expressions is not allowed in MVP. 73 | ;; (module (memory 1) (data (get_global 0) "a") (global i32 (i32.const 0))) 74 | ;; (module (memory 1) (data (get_global $g) "a") (global $g i32 (i32.const 0))) 75 | 76 | ;; Corner cases 77 | 78 | (module 79 | (memory 1) 80 | (data (i32.const 0) "a") 81 | (data (i32.const 0xffff) "b") 82 | ) 83 | (module 84 | (import "spectest" "memory" (memory 1)) 85 | (data (i32.const 0) "a") 86 | (data (i32.const 0xffff) "b") 87 | ) 88 | 89 | (module 90 | (memory 2) 91 | (data (i32.const 0x1_ffff) "a") 92 | ) 93 | 94 | (module 95 | (memory 0) 96 | (data (i32.const 0)) 97 | ) 98 | (module 99 | (import "spectest" "memory" (memory 0)) 100 | (data (i32.const 0)) 101 | ) 102 | 103 | (module 104 | (memory 0 0) 105 | (data (i32.const 0)) 106 | ) 107 | 108 | (module 109 | (memory 1) 110 | (data (i32.const 0x1_0000) "") 111 | ) 112 | 113 | (module 114 | (memory 0) 115 | (data (i32.const 0) "" "") 116 | ) 117 | (module 118 | (import "spectest" "memory" (memory 0)) 119 | (data (i32.const 0) "" "") 120 | ) 121 | 122 | (module 123 | (memory 0 0) 124 | (data (i32.const 0) "" "") 125 | ) 126 | 127 | (module 128 | (import "spectest" "memory" (memory 0)) 129 | (data (i32.const 0) "a") 130 | ) 131 | 132 | (module 133 | (import "spectest" "memory" (memory 0 3)) 134 | (data (i32.const 0) "a") 135 | ) 136 | 137 | (module 138 | (global (import "spectest" "global_i32") i32) 139 | (import "spectest" "memory" (memory 0)) 140 | (data (get_global 0) "a") 141 | ) 142 | 143 | (module 144 | (global (import "spectest" "global_i32") i32) 145 | (import "spectest" "memory" (memory 0 3)) 146 | (data (get_global 0) "a") 147 | ) 148 | 149 | (module 150 | (import "spectest" "memory" (memory 0)) 151 | (data (i32.const 1) "a") 152 | ) 153 | 154 | (module 155 | (import "spectest" "memory" (memory 0 3)) 156 | (data (i32.const 1) "a") 157 | ) 158 | 159 | ;; Invalid bounds for data 160 | 161 | (assert_unlinkable 162 | (module 163 | (memory 0) 164 | (data (i32.const 0) "a") 165 | ) 166 | "data segment does not fit" 167 | ) 168 | 169 | (assert_unlinkable 170 | (module 171 | (memory 0 0) 172 | (data (i32.const 0) "a") 173 | ) 174 | "data segment does not fit" 175 | ) 176 | 177 | (assert_unlinkable 178 | (module 179 | (memory 0 1) 180 | (data (i32.const 0) "a") 181 | ) 182 | "data segment does not fit" 183 | ) 184 | 185 | (assert_unlinkable 186 | (module 187 | (memory 0) 188 | (data (i32.const 1)) 189 | ) 190 | "data segment does not fit" 191 | ) 192 | 193 | (assert_unlinkable 194 | (module 195 | (memory 0 1) 196 | (data (i32.const 1)) 197 | ) 198 | "data segment does not fit" 199 | ) 200 | 201 | ;; This seems to cause a time-out on Travis. 202 | (;assert_unlinkable 203 | (module 204 | (memory 0x10000) 205 | (data (i32.const 0xffffffff) "ab") 206 | ) 207 | "" ;; either out of memory or segment does not fit 208 | ;) 209 | 210 | (assert_unlinkable 211 | (module 212 | (global (import "spectest" "global_i32") i32) 213 | (memory 0) 214 | (data (get_global 0) "a") 215 | ) 216 | "data segment does not fit" 217 | ) 218 | 219 | (assert_unlinkable 220 | (module 221 | (memory 1 2) 222 | (data (i32.const 0x1_0000) "a") 223 | ) 224 | "data segment does not fit" 225 | ) 226 | (assert_unlinkable 227 | (module 228 | (import "spectest" "memory" (memory 1)) 229 | (data (i32.const 0x1_0000) "a") 230 | ) 231 | "data segment does not fit" 232 | ) 233 | 234 | (assert_unlinkable 235 | (module 236 | (memory 2) 237 | (data (i32.const 0x2_0000) "a") 238 | ) 239 | "data segment does not fit" 240 | ) 241 | 242 | (assert_unlinkable 243 | (module 244 | (memory 2 3) 245 | (data (i32.const 0x2_0000) "a") 246 | ) 247 | "data segment does not fit" 248 | ) 249 | 250 | (assert_unlinkable 251 | (module 252 | (memory 1) 253 | (data (i32.const -1) "a") 254 | ) 255 | "data segment does not fit" 256 | ) 257 | (assert_unlinkable 258 | (module 259 | (import "spectest" "memory" (memory 1)) 260 | (data (i32.const -1) "a") 261 | ) 262 | "data segment does not fit" 263 | ) 264 | 265 | (assert_unlinkable 266 | (module 267 | (memory 2) 268 | (data (i32.const -100) "a") 269 | ) 270 | "data segment does not fit" 271 | ) 272 | (assert_unlinkable 273 | (module 274 | (import "spectest" "memory" (memory 1)) 275 | (data (i32.const -100) "a") 276 | ) 277 | "data segment does not fit" 278 | ) 279 | 280 | ;; Data without memory 281 | 282 | (assert_invalid 283 | (module 284 | (data (i32.const 0) "") 285 | ) 286 | "unknown memory 0" 287 | ) 288 | 289 | ;; Invalid offsets 290 | 291 | (assert_invalid 292 | (module 293 | (memory 1) 294 | (data (i64.const 0)) 295 | ) 296 | "type mismatch" 297 | ) 298 | 299 | (assert_invalid 300 | (module 301 | (memory 1) 302 | (data (i32.ctz (i32.const 0))) 303 | ) 304 | "constant expression required" 305 | ) 306 | 307 | (assert_invalid 308 | (module 309 | (memory 1) 310 | (data (nop)) 311 | ) 312 | "constant expression required" 313 | ) 314 | 315 | (assert_invalid 316 | (module 317 | (memory 1) 318 | (data (offset (nop) (i32.const 0))) 319 | ) 320 | "constant expression required" 321 | ) 322 | 323 | (assert_invalid 324 | (module 325 | (memory 1) 326 | (data (offset (i32.const 0) (nop))) 327 | ) 328 | "constant expression required" 329 | ) 330 | 331 | ;; Use of internal globals in constant expressions is not allowed in MVP. 332 | ;; (assert_invalid 333 | ;; (module (memory 1) (data (get_global $g)) (global $g (mut i32) (i32.const 0))) 334 | ;; "constant expression required" 335 | ;; ) 336 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/elem.wast: -------------------------------------------------------------------------------- 1 | ;; Test the element section 2 | 3 | ;; Syntax 4 | (module 5 | (table $t 10 anyfunc) 6 | (func $f) 7 | (elem (i32.const 0)) 8 | (elem (i32.const 0) $f $f) 9 | (elem (offset (i32.const 0))) 10 | (elem (offset (i32.const 0)) $f $f) 11 | (elem 0 (i32.const 0)) 12 | (elem 0x0 (i32.const 0) $f $f) 13 | (elem 0x000 (offset (i32.const 0))) 14 | (elem 0 (offset (i32.const 0)) $f $f) 15 | (elem $t (i32.const 0)) 16 | (elem $t (i32.const 0) $f $f) 17 | (elem $t (offset (i32.const 0))) 18 | (elem $t (offset (i32.const 0)) $f $f) 19 | ) 20 | 21 | ;; Basic use 22 | 23 | (module 24 | (table 10 anyfunc) 25 | (func $f) 26 | (elem (i32.const 0) $f) 27 | ) 28 | (module 29 | (import "spectest" "table" (table 10 anyfunc)) 30 | (func $f) 31 | (elem (i32.const 0) $f) 32 | ) 33 | 34 | (module 35 | (table 10 anyfunc) 36 | (func $f) 37 | (elem (i32.const 0) $f) 38 | (elem (i32.const 3) $f) 39 | (elem (i32.const 7) $f) 40 | (elem (i32.const 5) $f) 41 | (elem (i32.const 3) $f) 42 | ) 43 | (module 44 | (import "spectest" "table" (table 10 anyfunc)) 45 | (func $f) 46 | (elem (i32.const 9) $f) 47 | (elem (i32.const 3) $f) 48 | (elem (i32.const 7) $f) 49 | (elem (i32.const 3) $f) 50 | (elem (i32.const 5) $f) 51 | ) 52 | 53 | (module 54 | (global (import "spectest" "global_i32") i32) 55 | (table 1000 anyfunc) 56 | (func $f) 57 | (elem (get_global 0) $f) 58 | ) 59 | 60 | (module 61 | (global $g (import "spectest" "global_i32") i32) 62 | (table 1000 anyfunc) 63 | (func $f) 64 | (elem (get_global $g) $f) 65 | ) 66 | 67 | (module 68 | (type $out-i32 (func (result i32))) 69 | (table 10 anyfunc) 70 | (elem (i32.const 7) $const-i32-a) 71 | (elem (i32.const 9) $const-i32-b) 72 | (func $const-i32-a (type $out-i32) (i32.const 65)) 73 | (func $const-i32-b (type $out-i32) (i32.const 66)) 74 | (func (export "call-7") (type $out-i32) 75 | (call_indirect (type $out-i32) (i32.const 7)) 76 | ) 77 | (func (export "call-9") (type $out-i32) 78 | (call_indirect (type $out-i32) (i32.const 9)) 79 | ) 80 | ) 81 | (assert_return (invoke "call-7") (i32.const 65)) 82 | (assert_return (invoke "call-9") (i32.const 66)) 83 | 84 | ;; Corner cases 85 | 86 | (module 87 | (table 10 anyfunc) 88 | (func $f) 89 | (elem (i32.const 9) $f) 90 | ) 91 | (module 92 | (import "spectest" "table" (table 10 anyfunc)) 93 | (func $f) 94 | (elem (i32.const 9) $f) 95 | ) 96 | 97 | (module 98 | (table 0 anyfunc) 99 | (elem (i32.const 0)) 100 | ) 101 | (module 102 | (import "spectest" "table" (table 0 anyfunc)) 103 | (elem (i32.const 0)) 104 | ) 105 | 106 | (module 107 | (table 0 0 anyfunc) 108 | (elem (i32.const 0)) 109 | ) 110 | 111 | (module 112 | (table 20 anyfunc) 113 | (elem (i32.const 20)) 114 | ) 115 | 116 | (module 117 | (import "spectest" "table" (table 0 anyfunc)) 118 | (func $f) 119 | (elem (i32.const 0) $f) 120 | ) 121 | 122 | (module 123 | (import "spectest" "table" (table 0 100 anyfunc)) 124 | (func $f) 125 | (elem (i32.const 0) $f) 126 | ) 127 | 128 | (module 129 | (import "spectest" "table" (table 0 anyfunc)) 130 | (func $f) 131 | (elem (i32.const 1) $f) 132 | ) 133 | 134 | (module 135 | (import "spectest" "table" (table 0 30 anyfunc)) 136 | (func $f) 137 | (elem (i32.const 1) $f) 138 | ) 139 | 140 | ;; Invalid bounds for elements 141 | 142 | (assert_unlinkable 143 | (module 144 | (table 0 anyfunc) 145 | (func $f) 146 | (elem (i32.const 0) $f) 147 | ) 148 | "elements segment does not fit" 149 | ) 150 | 151 | (assert_unlinkable 152 | (module 153 | (table 0 0 anyfunc) 154 | (func $f) 155 | (elem (i32.const 0) $f) 156 | ) 157 | "elements segment does not fit" 158 | ) 159 | 160 | (assert_unlinkable 161 | (module 162 | (table 0 1 anyfunc) 163 | (func $f) 164 | (elem (i32.const 0) $f) 165 | ) 166 | "elements segment does not fit" 167 | ) 168 | 169 | (assert_unlinkable 170 | (module 171 | (table 0 anyfunc) 172 | (elem (i32.const 1)) 173 | ) 174 | "elements segment does not fit" 175 | ) 176 | 177 | (assert_unlinkable 178 | (module 179 | (table 10 anyfunc) 180 | (func $f) 181 | (elem (i32.const 10) $f) 182 | ) 183 | "elements segment does not fit" 184 | ) 185 | (assert_unlinkable 186 | (module 187 | (import "spectest" "table" (table 10 anyfunc)) 188 | (func $f) 189 | (elem (i32.const 10) $f) 190 | ) 191 | "elements segment does not fit" 192 | ) 193 | 194 | (assert_unlinkable 195 | (module 196 | (table 10 20 anyfunc) 197 | (func $f) 198 | (elem (i32.const 10) $f) 199 | ) 200 | "elements segment does not fit" 201 | ) 202 | (assert_unlinkable 203 | (module 204 | (import "spectest" "table" (table 10 anyfunc)) 205 | (func $f) 206 | (elem (i32.const 10) $f) 207 | ) 208 | "elements segment does not fit" 209 | ) 210 | 211 | (assert_unlinkable 212 | (module 213 | (table 10 anyfunc) 214 | (func $f) 215 | (elem (i32.const -1) $f) 216 | ) 217 | "elements segment does not fit" 218 | ) 219 | (assert_unlinkable 220 | (module 221 | (import "spectest" "table" (table 10 anyfunc)) 222 | (func $f) 223 | (elem (i32.const -1) $f) 224 | ) 225 | "elements segment does not fit" 226 | ) 227 | 228 | (assert_unlinkable 229 | (module 230 | (table 10 anyfunc) 231 | (func $f) 232 | (elem (i32.const -10) $f) 233 | ) 234 | "elements segment does not fit" 235 | ) 236 | (assert_unlinkable 237 | (module 238 | (import "spectest" "table" (table 10 anyfunc)) 239 | (func $f) 240 | (elem (i32.const -10) $f) 241 | ) 242 | "elements segment does not fit" 243 | ) 244 | 245 | ;; Element without table 246 | 247 | (assert_invalid 248 | (module 249 | (func $f) 250 | (elem (i32.const 0) $f) 251 | ) 252 | "unknown table 0" 253 | ) 254 | 255 | ;; Invalid offsets 256 | 257 | (assert_invalid 258 | (module 259 | (table 1 anyfunc) 260 | (elem (i64.const 0)) 261 | ) 262 | "type mismatch" 263 | ) 264 | 265 | (assert_invalid 266 | (module 267 | (table 1 anyfunc) 268 | (elem (i32.ctz (i32.const 0))) 269 | ) 270 | "constant expression required" 271 | ) 272 | 273 | (assert_invalid 274 | (module 275 | (table 1 anyfunc) 276 | (elem (nop)) 277 | ) 278 | "constant expression required" 279 | ) 280 | 281 | (assert_invalid 282 | (module 283 | (table 1 anyfunc) 284 | (elem (offset (nop) (i32.const 0))) 285 | ) 286 | "constant expression required" 287 | ) 288 | 289 | (assert_invalid 290 | (module 291 | (table 1 anyfunc) 292 | (elem (offset (i32.const 0) (nop))) 293 | ) 294 | "constant expression required" 295 | ) 296 | 297 | ;; Use of internal globals in constant expressions is not allowed in MVP. 298 | ;; (assert_invalid 299 | ;; (module (memory 1) (data (get_global $g)) (global $g (mut i32) (i32.const 0))) 300 | ;; "constant expression required" 301 | ;; ) 302 | 303 | ;; Two elements target the same slot 304 | 305 | (module 306 | (type $out-i32 (func (result i32))) 307 | (table 10 anyfunc) 308 | (elem (i32.const 9) $const-i32-a) 309 | (elem (i32.const 9) $const-i32-b) 310 | (func $const-i32-a (type $out-i32) (i32.const 65)) 311 | (func $const-i32-b (type $out-i32) (i32.const 66)) 312 | (func (export "call-overwritten") (type $out-i32) 313 | (call_indirect (type $out-i32) (i32.const 9)) 314 | ) 315 | ) 316 | (assert_return (invoke "call-overwritten") (i32.const 66)) 317 | 318 | (module 319 | (type $out-i32 (func (result i32))) 320 | (import "spectest" "table" (table 10 anyfunc)) 321 | (elem (i32.const 9) $const-i32-a) 322 | (elem (i32.const 9) $const-i32-b) 323 | (func $const-i32-a (type $out-i32) (i32.const 65)) 324 | (func $const-i32-b (type $out-i32) (i32.const 66)) 325 | (func (export "call-overwritten-element") (type $out-i32) 326 | (call_indirect (type $out-i32) (i32.const 9)) 327 | ) 328 | ) 329 | (assert_return (invoke "call-overwritten-element") (i32.const 66)) 330 | 331 | ;; Element sections across multiple modules change the same table 332 | 333 | (module $module1 334 | (type $out-i32 (func (result i32))) 335 | (table (export "shared-table") 10 anyfunc) 336 | (elem (i32.const 8) $const-i32-a) 337 | (elem (i32.const 9) $const-i32-b) 338 | (func $const-i32-a (type $out-i32) (i32.const 65)) 339 | (func $const-i32-b (type $out-i32) (i32.const 66)) 340 | (func (export "call-7") (type $out-i32) 341 | (call_indirect (type $out-i32) (i32.const 7)) 342 | ) 343 | (func (export "call-8") (type $out-i32) 344 | (call_indirect (type $out-i32) (i32.const 8)) 345 | ) 346 | (func (export "call-9") (type $out-i32) 347 | (call_indirect (type $out-i32) (i32.const 9)) 348 | ) 349 | ) 350 | 351 | (register "module1" $module1) 352 | 353 | (assert_trap (invoke $module1 "call-7") "uninitialized element 7") 354 | (assert_return (invoke $module1 "call-8") (i32.const 65)) 355 | (assert_return (invoke $module1 "call-9") (i32.const 66)) 356 | 357 | (module $module2 358 | (type $out-i32 (func (result i32))) 359 | (import "module1" "shared-table" (table 10 anyfunc)) 360 | (elem (i32.const 7) $const-i32-c) 361 | (elem (i32.const 8) $const-i32-d) 362 | (func $const-i32-c (type $out-i32) (i32.const 67)) 363 | (func $const-i32-d (type $out-i32) (i32.const 68)) 364 | ) 365 | 366 | (assert_return (invoke $module1 "call-7") (i32.const 67)) 367 | (assert_return (invoke $module1 "call-8") (i32.const 68)) 368 | (assert_return (invoke $module1 "call-9") (i32.const 66)) 369 | 370 | (module $module3 371 | (type $out-i32 (func (result i32))) 372 | (import "module1" "shared-table" (table 10 anyfunc)) 373 | (elem (i32.const 8) $const-i32-e) 374 | (elem (i32.const 9) $const-i32-f) 375 | (func $const-i32-e (type $out-i32) (i32.const 69)) 376 | (func $const-i32-f (type $out-i32) (i32.const 70)) 377 | ) 378 | 379 | (assert_return (invoke $module1 "call-7") (i32.const 67)) 380 | (assert_return (invoke $module1 "call-8") (i32.const 69)) 381 | (assert_return (invoke $module1 "call-9") (i32.const 70)) 382 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/exports.wast: -------------------------------------------------------------------------------- 1 | ;; Functions 2 | 3 | (module (func) (export "a" (func 0))) 4 | (module (func) (export "a" (func 0)) (export "b" (func 0))) 5 | (module (func) (func) (export "a" (func 0)) (export "b" (func 1))) 6 | 7 | (module (func (export "a"))) 8 | (module (func (export "a") (export "b") (export "c"))) 9 | (module (func (export "a") (export "b") (param i32))) 10 | (module (func) (export "a" (func 0))) 11 | (module (func $a (export "a"))) 12 | (module (func $a) (export "a" (func $a))) 13 | (module (export "a" (func 0)) (func)) 14 | (module (export "a" (func $a)) (func $a)) 15 | 16 | (module $Func 17 | (export "e" (func $f)) 18 | (func $f (param $n i32) (result i32) 19 | (return (i32.add (get_local $n) (i32.const 1))) 20 | ) 21 | ) 22 | (assert_return (invoke "e" (i32.const 42)) (i32.const 43)) 23 | (assert_return (invoke $Func "e" (i32.const 42)) (i32.const 43)) 24 | (module) 25 | (module $Other1) 26 | (assert_return (invoke $Func "e" (i32.const 42)) (i32.const 43)) 27 | 28 | (assert_invalid 29 | (module (func) (export "a" (func 1))) 30 | "unknown function" 31 | ) 32 | (assert_invalid 33 | (module (func) (export "a" (func 0)) (export "a" (func 0))) 34 | "duplicate export name" 35 | ) 36 | (assert_invalid 37 | (module (func) (func) (export "a" (func 0)) (export "a" (func 1))) 38 | "duplicate export name" 39 | ) 40 | (assert_invalid 41 | (module (func) (global i32 (i32.const 0)) (export "a" (func 0)) (export "a" (global 0))) 42 | "duplicate export name" 43 | ) 44 | (assert_invalid 45 | (module (func) (table 0 anyfunc) (export "a" (func 0)) (export "a" (table 0))) 46 | "duplicate export name" 47 | ) 48 | (assert_invalid 49 | (module (func) (memory 0) (export "a" (func 0)) (export "a" (memory 0))) 50 | "duplicate export name" 51 | ) 52 | 53 | 54 | ;; Globals 55 | 56 | (module (global i32 (i32.const 0)) (export "a" (global 0))) 57 | (module (global i32 (i32.const 0)) (export "a" (global 0)) (export "b" (global 0))) 58 | (module (global i32 (i32.const 0)) (global i32 (i32.const 0)) (export "a" (global 0)) (export "b" (global 1))) 59 | 60 | (module (global (export "a") i32 (i32.const 0))) 61 | (module (global i32 (i32.const 0)) (export "a" (global 0))) 62 | (module (global $a (export "a") i32 (i32.const 0))) 63 | (module (global $a i32 (i32.const 0)) (export "a" (global $a))) 64 | (module (export "a" (global 0)) (global i32 (i32.const 0))) 65 | (module (export "a" (global $a)) (global $a i32 (i32.const 0))) 66 | 67 | (module $Global 68 | (export "e" (global $g)) 69 | (global $g i32 (i32.const 42)) 70 | ) 71 | (assert_return (get "e") (i32.const 42)) 72 | (assert_return (get $Global "e") (i32.const 42)) 73 | (module) 74 | (module $Other2) 75 | (assert_return (get $Global "e") (i32.const 42)) 76 | 77 | (assert_invalid 78 | (module (global i32 (i32.const 0)) (export "a" (global 1))) 79 | "unknown global" 80 | ) 81 | (assert_invalid 82 | (module (global i32 (i32.const 0)) (export "a" (global 0)) (export "a" (global 0))) 83 | "duplicate export name" 84 | ) 85 | (assert_invalid 86 | (module (global i32 (i32.const 0)) (global i32 (i32.const 0)) (export "a" (global 0)) (export "a" (global 1))) 87 | "duplicate export name" 88 | ) 89 | (assert_invalid 90 | (module (global i32 (i32.const 0)) (func) (export "a" (global 0)) (export "a" (func 0))) 91 | "duplicate export name" 92 | ) 93 | (assert_invalid 94 | (module (global i32 (i32.const 0)) (table 0 anyfunc) (export "a" (global 0)) (export "a" (table 0))) 95 | "duplicate export name" 96 | ) 97 | (assert_invalid 98 | (module (global i32 (i32.const 0)) (memory 0) (export "a" (global 0)) (export "a" (memory 0))) 99 | "duplicate export name" 100 | ) 101 | 102 | 103 | ;; Tables 104 | 105 | (module (table 0 anyfunc) (export "a" (table 0))) 106 | (module (table 0 anyfunc) (export "a" (table 0)) (export "b" (table 0))) 107 | ;; No multiple tables yet. 108 | ;; (module (table 0 anyfunc) (table 0 anyfunc) (export "a" (table 0)) (export "b" (table 1))) 109 | 110 | (module (table (export "a") 0 anyfunc)) 111 | (module (table (export "a") 0 1 anyfunc)) 112 | (module (table 0 anyfunc) (export "a" (table 0))) 113 | (module (table 0 1 anyfunc) (export "a" (table 0))) 114 | (module (table $a (export "a") 0 anyfunc)) 115 | (module (table $a (export "a") 0 1 anyfunc)) 116 | (module (table $a 0 anyfunc) (export "a" (table $a))) 117 | (module (table $a 0 1 anyfunc) (export "a" (table $a))) 118 | (module (export "a" (table 0)) (table 0 anyfunc)) 119 | (module (export "a" (table 0)) (table 0 1 anyfunc)) 120 | (module (export "a" (table $a)) (table $a 0 anyfunc)) 121 | (module (export "a" (table $a)) (table $a 0 1 anyfunc)) 122 | 123 | (; TODO: access table ;) 124 | 125 | (assert_invalid 126 | (module (table 0 anyfunc) (export "a" (table 1))) 127 | "unknown table" 128 | ) 129 | (assert_invalid 130 | (module (table 0 anyfunc) (export "a" (table 0)) (export "a" (table 0))) 131 | "duplicate export name" 132 | ) 133 | ;; No multiple tables yet. 134 | ;; (assert_invalid 135 | ;; (module (table 0 anyfunc) (table 0 anyfunc) (export "a" (table 0)) (export "a" (table 1))) 136 | ;; "duplicate export name" 137 | ;; ) 138 | (assert_invalid 139 | (module (table 0 anyfunc) (func) (export "a" (table 0)) (export "a" (func 0))) 140 | "duplicate export name" 141 | ) 142 | (assert_invalid 143 | (module (table 0 anyfunc) (global i32 (i32.const 0)) (export "a" (table 0)) (export "a" (global 0))) 144 | "duplicate export name" 145 | ) 146 | (assert_invalid 147 | (module (table 0 anyfunc) (memory 0) (export "a" (table 0)) (export "a" (memory 0))) 148 | "duplicate export name" 149 | ) 150 | 151 | 152 | ;; Memories 153 | 154 | (module (memory 0) (export "a" (memory 0))) 155 | (module (memory 0) (export "a" (memory 0)) (export "b" (memory 0))) 156 | ;; No multiple memories yet. 157 | ;; (module (memory 0) (memory 0) (export "a" (memory 0)) (export "b" (memory 1))) 158 | 159 | (module (memory (export "a") 0)) 160 | (module (memory (export "a") 0 1)) 161 | (module (memory 0) (export "a" (memory 0))) 162 | (module (memory 0 1) (export "a" (memory 0))) 163 | (module (memory $a (export "a") 0)) 164 | (module (memory $a (export "a") 0 1)) 165 | (module (memory $a 0) (export "a" (memory $a))) 166 | (module (memory $a 0 1) (export "a" (memory $a))) 167 | (module (export "a" (memory 0)) (memory 0)) 168 | (module (export "a" (memory 0)) (memory 0 1)) 169 | (module (export "a" (memory $a)) (memory $a 0)) 170 | (module (export "a" (memory $a)) (memory $a 0 1)) 171 | 172 | (; TODO: access memory ;) 173 | 174 | (assert_invalid 175 | (module (memory 0) (export "a" (memory 1))) 176 | "unknown memory" 177 | ) 178 | (assert_invalid 179 | (module (memory 0) (export "a" (memory 0)) (export "a" (memory 0))) 180 | "duplicate export name" 181 | ) 182 | ;; No multiple memories yet. 183 | ;; (assert_invalid 184 | ;; (module (memory 0) (memory 0) (export "a" (memory 0)) (export "a" (memory 1))) 185 | ;; "duplicate export name" 186 | ;; ) 187 | (assert_invalid 188 | (module (memory 0) (func) (export "a" (memory 0)) (export "a" (func 0))) 189 | "duplicate export name" 190 | ) 191 | (assert_invalid 192 | (module (memory 0) (global i32 (i32.const 0)) (export "a" (memory 0)) (export "a" (global 0))) 193 | "duplicate export name" 194 | ) 195 | (assert_invalid 196 | (module (memory 0) (table 0 anyfunc) (export "a" (memory 0)) (export "a" (table 0))) 197 | "duplicate export name" 198 | ) 199 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/extract-parts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | # This script extracts the modules from the testsuite test files into 7 | # individual files in the following directories: 8 | # - valid - valid wasm modules 9 | # - invalid - wasm modules that fail to validate 10 | # - malformed - wasm text tests that fail to parse 11 | 12 | wabt="../wabt" 13 | wabtbin="$wabt/bin" 14 | 15 | mkdir -p valid invalid malformed 16 | rm -f valid/*.wasm 17 | rm -f invalid/*.wasm 18 | rm -f malformed/*.wat 19 | 20 | for wast in *.wast; do 21 | base="${wast##*/}" 22 | json="invalid/${base%.wast}.json" 23 | "$wabtbin/wast2json" "$wast" -o "$json" 24 | rm "$json" 25 | done 26 | 27 | mv invalid/*.wat malformed 28 | 29 | for wasm in invalid/*.wasm; do 30 | if "$wabtbin/wasm2wat" "$wasm" -o invalid/t.wat 2>/dev/null && \ 31 | "$wabtbin/wat2wasm" invalid/t.wat -o /dev/null 2>/dev/null ; then 32 | mv "$wasm" valid 33 | fi 34 | done 35 | rm invalid/t.wat 36 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/fac.wast: -------------------------------------------------------------------------------- 1 | (module 2 | ;; Recursive factorial 3 | (func (export "fac-rec") (param i64) (result i64) 4 | (if (result i64) (i64.eq (get_local 0) (i64.const 0)) 5 | (then (i64.const 1)) 6 | (else 7 | (i64.mul (get_local 0) (call 0 (i64.sub (get_local 0) (i64.const 1)))) 8 | ) 9 | ) 10 | ) 11 | 12 | ;; Recursive factorial named 13 | (func $fac-rec-named (export "fac-rec-named") (param $n i64) (result i64) 14 | (if (result i64) (i64.eq (get_local $n) (i64.const 0)) 15 | (then (i64.const 1)) 16 | (else 17 | (i64.mul 18 | (get_local $n) 19 | (call $fac-rec-named (i64.sub (get_local $n) (i64.const 1))) 20 | ) 21 | ) 22 | ) 23 | ) 24 | 25 | ;; Iterative factorial 26 | (func (export "fac-iter") (param i64) (result i64) 27 | (local i64 i64) 28 | (set_local 1 (get_local 0)) 29 | (set_local 2 (i64.const 1)) 30 | (block 31 | (loop 32 | (if 33 | (i64.eq (get_local 1) (i64.const 0)) 34 | (then (br 2)) 35 | (else 36 | (set_local 2 (i64.mul (get_local 1) (get_local 2))) 37 | (set_local 1 (i64.sub (get_local 1) (i64.const 1))) 38 | ) 39 | ) 40 | (br 0) 41 | ) 42 | ) 43 | (get_local 2) 44 | ) 45 | 46 | ;; Iterative factorial named 47 | (func (export "fac-iter-named") (param $n i64) (result i64) 48 | (local $i i64) 49 | (local $res i64) 50 | (set_local $i (get_local $n)) 51 | (set_local $res (i64.const 1)) 52 | (block $done 53 | (loop $loop 54 | (if 55 | (i64.eq (get_local $i) (i64.const 0)) 56 | (then (br $done)) 57 | (else 58 | (set_local $res (i64.mul (get_local $i) (get_local $res))) 59 | (set_local $i (i64.sub (get_local $i) (i64.const 1))) 60 | ) 61 | ) 62 | (br $loop) 63 | ) 64 | ) 65 | (get_local $res) 66 | ) 67 | 68 | ;; Optimized factorial. 69 | (func (export "fac-opt") (param i64) (result i64) 70 | (local i64) 71 | (set_local 1 (i64.const 1)) 72 | (block 73 | (br_if 0 (i64.lt_s (get_local 0) (i64.const 2))) 74 | (loop 75 | (set_local 1 (i64.mul (get_local 1) (get_local 0))) 76 | (set_local 0 (i64.add (get_local 0) (i64.const -1))) 77 | (br_if 0 (i64.gt_s (get_local 0) (i64.const 1))) 78 | ) 79 | ) 80 | (get_local 1) 81 | ) 82 | ) 83 | 84 | (assert_return (invoke "fac-rec" (i64.const 25)) (i64.const 7034535277573963776)) 85 | (assert_return (invoke "fac-iter" (i64.const 25)) (i64.const 7034535277573963776)) 86 | (assert_return (invoke "fac-rec-named" (i64.const 25)) (i64.const 7034535277573963776)) 87 | (assert_return (invoke "fac-iter-named" (i64.const 25)) (i64.const 7034535277573963776)) 88 | (assert_return (invoke "fac-opt" (i64.const 25)) (i64.const 7034535277573963776)) 89 | (assert_exhaustion (invoke "fac-rec" (i64.const 1073741824)) "call stack exhausted") 90 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/float_memory.wast: -------------------------------------------------------------------------------- 1 | ;; Test that floating-point load and store are bit-preserving. 2 | 3 | ;; Test that load and store do not canonicalize NaNs as x87 does. 4 | 5 | (module 6 | (memory (data "\00\00\a0\7f")) 7 | 8 | (func (export "f32.load") (result f32) (f32.load (i32.const 0))) 9 | (func (export "i32.load") (result i32) (i32.load (i32.const 0))) 10 | (func (export "f32.store") (f32.store (i32.const 0) (f32.const nan:0x200000))) 11 | (func (export "i32.store") (i32.store (i32.const 0) (i32.const 0x7fa00000))) 12 | (func (export "reset") (i32.store (i32.const 0) (i32.const 0))) 13 | ) 14 | 15 | (assert_return (invoke "i32.load") (i32.const 0x7fa00000)) 16 | (assert_return (invoke "f32.load") (f32.const nan:0x200000)) 17 | (invoke "reset") 18 | (assert_return (invoke "i32.load") (i32.const 0x0)) 19 | (assert_return (invoke "f32.load") (f32.const 0.0)) 20 | (invoke "f32.store") 21 | (assert_return (invoke "i32.load") (i32.const 0x7fa00000)) 22 | (assert_return (invoke "f32.load") (f32.const nan:0x200000)) 23 | (invoke "reset") 24 | (assert_return (invoke "i32.load") (i32.const 0x0)) 25 | (assert_return (invoke "f32.load") (f32.const 0.0)) 26 | (invoke "i32.store") 27 | (assert_return (invoke "i32.load") (i32.const 0x7fa00000)) 28 | (assert_return (invoke "f32.load") (f32.const nan:0x200000)) 29 | 30 | (module 31 | (memory (data "\00\00\00\00\00\00\f4\7f")) 32 | 33 | (func (export "f64.load") (result f64) (f64.load (i32.const 0))) 34 | (func (export "i64.load") (result i64) (i64.load (i32.const 0))) 35 | (func (export "f64.store") (f64.store (i32.const 0) (f64.const nan:0x4000000000000))) 36 | (func (export "i64.store") (i64.store (i32.const 0) (i64.const 0x7ff4000000000000))) 37 | (func (export "reset") (i64.store (i32.const 0) (i64.const 0))) 38 | ) 39 | 40 | (assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) 41 | (assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) 42 | (invoke "reset") 43 | (assert_return (invoke "i64.load") (i64.const 0x0)) 44 | (assert_return (invoke "f64.load") (f64.const 0.0)) 45 | (invoke "f64.store") 46 | (assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) 47 | (assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) 48 | (invoke "reset") 49 | (assert_return (invoke "i64.load") (i64.const 0x0)) 50 | (assert_return (invoke "f64.load") (f64.const 0.0)) 51 | (invoke "i64.store") 52 | (assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) 53 | (assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) 54 | 55 | ;; Test that unaligned load and store do not canonicalize NaNs. 56 | 57 | (module 58 | (memory (data "\00\00\00\a0\7f")) 59 | 60 | (func (export "f32.load") (result f32) (f32.load (i32.const 1))) 61 | (func (export "i32.load") (result i32) (i32.load (i32.const 1))) 62 | (func (export "f32.store") (f32.store (i32.const 1) (f32.const nan:0x200000))) 63 | (func (export "i32.store") (i32.store (i32.const 1) (i32.const 0x7fa00000))) 64 | (func (export "reset") (i32.store (i32.const 1) (i32.const 0))) 65 | ) 66 | 67 | (assert_return (invoke "i32.load") (i32.const 0x7fa00000)) 68 | (assert_return (invoke "f32.load") (f32.const nan:0x200000)) 69 | (invoke "reset") 70 | (assert_return (invoke "i32.load") (i32.const 0x0)) 71 | (assert_return (invoke "f32.load") (f32.const 0.0)) 72 | (invoke "f32.store") 73 | (assert_return (invoke "i32.load") (i32.const 0x7fa00000)) 74 | (assert_return (invoke "f32.load") (f32.const nan:0x200000)) 75 | (invoke "reset") 76 | (assert_return (invoke "i32.load") (i32.const 0x0)) 77 | (assert_return (invoke "f32.load") (f32.const 0.0)) 78 | (invoke "i32.store") 79 | (assert_return (invoke "i32.load") (i32.const 0x7fa00000)) 80 | (assert_return (invoke "f32.load") (f32.const nan:0x200000)) 81 | 82 | (module 83 | (memory (data "\00\00\00\00\00\00\00\f4\7f")) 84 | 85 | (func (export "f64.load") (result f64) (f64.load (i32.const 1))) 86 | (func (export "i64.load") (result i64) (i64.load (i32.const 1))) 87 | (func (export "f64.store") (f64.store (i32.const 1) (f64.const nan:0x4000000000000))) 88 | (func (export "i64.store") (i64.store (i32.const 1) (i64.const 0x7ff4000000000000))) 89 | (func (export "reset") (i64.store (i32.const 1) (i64.const 0))) 90 | ) 91 | 92 | (assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) 93 | (assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) 94 | (invoke "reset") 95 | (assert_return (invoke "i64.load") (i64.const 0x0)) 96 | (assert_return (invoke "f64.load") (f64.const 0.0)) 97 | (invoke "f64.store") 98 | (assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) 99 | (assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) 100 | (invoke "reset") 101 | (assert_return (invoke "i64.load") (i64.const 0x0)) 102 | (assert_return (invoke "f64.load") (f64.const 0.0)) 103 | (invoke "i64.store") 104 | (assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) 105 | (assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) 106 | 107 | ;; Test that load and store do not canonicalize NaNs as some JS engines do. 108 | 109 | (module 110 | (memory (data "\01\00\d0\7f")) 111 | 112 | (func (export "f32.load") (result f32) (f32.load (i32.const 0))) 113 | (func (export "i32.load") (result i32) (i32.load (i32.const 0))) 114 | (func (export "f32.store") (f32.store (i32.const 0) (f32.const nan:0x500001))) 115 | (func (export "i32.store") (i32.store (i32.const 0) (i32.const 0x7fd00001))) 116 | (func (export "reset") (i32.store (i32.const 0) (i32.const 0))) 117 | ) 118 | 119 | (assert_return (invoke "i32.load") (i32.const 0x7fd00001)) 120 | (assert_return (invoke "f32.load") (f32.const nan:0x500001)) 121 | (invoke "reset") 122 | (assert_return (invoke "i32.load") (i32.const 0x0)) 123 | (assert_return (invoke "f32.load") (f32.const 0.0)) 124 | (invoke "f32.store") 125 | (assert_return (invoke "i32.load") (i32.const 0x7fd00001)) 126 | (assert_return (invoke "f32.load") (f32.const nan:0x500001)) 127 | (invoke "reset") 128 | (assert_return (invoke "i32.load") (i32.const 0x0)) 129 | (assert_return (invoke "f32.load") (f32.const 0.0)) 130 | (invoke "i32.store") 131 | (assert_return (invoke "i32.load") (i32.const 0x7fd00001)) 132 | (assert_return (invoke "f32.load") (f32.const nan:0x500001)) 133 | 134 | (module 135 | (memory (data "\01\00\00\00\00\00\fc\7f")) 136 | 137 | (func (export "f64.load") (result f64) (f64.load (i32.const 0))) 138 | (func (export "i64.load") (result i64) (i64.load (i32.const 0))) 139 | (func (export "f64.store") (f64.store (i32.const 0) (f64.const nan:0xc000000000001))) 140 | (func (export "i64.store") (i64.store (i32.const 0) (i64.const 0x7ffc000000000001))) 141 | (func (export "reset") (i64.store (i32.const 0) (i64.const 0))) 142 | ) 143 | 144 | (assert_return (invoke "i64.load") (i64.const 0x7ffc000000000001)) 145 | (assert_return (invoke "f64.load") (f64.const nan:0xc000000000001)) 146 | (invoke "reset") 147 | (assert_return (invoke "i64.load") (i64.const 0x0)) 148 | (assert_return (invoke "f64.load") (f64.const 0.0)) 149 | (invoke "f64.store") 150 | (assert_return (invoke "i64.load") (i64.const 0x7ffc000000000001)) 151 | (assert_return (invoke "f64.load") (f64.const nan:0xc000000000001)) 152 | (invoke "reset") 153 | (assert_return (invoke "i64.load") (i64.const 0x0)) 154 | (assert_return (invoke "f64.load") (f64.const 0.0)) 155 | (invoke "i64.store") 156 | (assert_return (invoke "i64.load") (i64.const 0x7ffc000000000001)) 157 | (assert_return (invoke "f64.load") (f64.const nan:0xc000000000001)) 158 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/forward.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func $even (export "even") (param $n i32) (result i32) 3 | (if (result i32) (i32.eq (get_local $n) (i32.const 0)) 4 | (then (i32.const 1)) 5 | (else (call $odd (i32.sub (get_local $n) (i32.const 1)))) 6 | ) 7 | ) 8 | 9 | (func $odd (export "odd") (param $n i32) (result i32) 10 | (if (result i32) (i32.eq (get_local $n) (i32.const 0)) 11 | (then (i32.const 0)) 12 | (else (call $even (i32.sub (get_local $n) (i32.const 1)))) 13 | ) 14 | ) 15 | ) 16 | 17 | (assert_return (invoke "even" (i32.const 13)) (i32.const 0)) 18 | (assert_return (invoke "even" (i32.const 20)) (i32.const 1)) 19 | (assert_return (invoke "odd" (i32.const 13)) (i32.const 1)) 20 | (assert_return (invoke "odd" (i32.const 20)) (i32.const 0)) 21 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/func_ptrs.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (type (func)) ;; 0: void -> void 3 | (type $S (func)) ;; 1: void -> void 4 | (type (func (param))) ;; 2: void -> void 5 | (type (func (result i32))) ;; 3: void -> i32 6 | (type (func (param) (result i32))) ;; 4: void -> i32 7 | (type $T (func (param i32) (result i32))) ;; 5: i32 -> i32 8 | (type $U (func (param i32))) ;; 6: i32 -> void 9 | 10 | (func $print (import "spectest" "print_i32") (type 6)) 11 | 12 | (func (type 0)) 13 | (func (type $S)) 14 | 15 | (func (export "one") (type 4) (i32.const 13)) 16 | (func (export "two") (type $T) (i32.add (get_local 0) (i32.const 1))) 17 | 18 | ;; Both signature and parameters are allowed (and required to match) 19 | ;; since this allows the naming of parameters. 20 | (func (export "three") (type $T) (param $a i32) (result i32) 21 | (i32.sub (get_local 0) (i32.const 2)) 22 | ) 23 | 24 | (func (export "four") (type $U) (call $print (get_local 0))) 25 | ) 26 | 27 | (assert_return (invoke "one") (i32.const 13)) 28 | (assert_return (invoke "two" (i32.const 13)) (i32.const 14)) 29 | (assert_return (invoke "three" (i32.const 13)) (i32.const 11)) 30 | (invoke "four" (i32.const 83)) 31 | 32 | (assert_invalid (module (elem (i32.const 0))) "unknown table") 33 | (assert_invalid (module (elem (i32.const 0) 0) (func)) "unknown table") 34 | 35 | (assert_invalid 36 | (module (table 1 anyfunc) (elem (i64.const 0))) 37 | "type mismatch" 38 | ) 39 | (assert_invalid 40 | (module (table 1 anyfunc) (elem (i32.ctz (i32.const 0)))) 41 | "constant expression required" 42 | ) 43 | (assert_invalid 44 | (module (table 1 anyfunc) (elem (nop))) 45 | "constant expression required" 46 | ) 47 | 48 | (assert_invalid (module (func (type 42))) "unknown type") 49 | (assert_invalid (module (import "spectest" "print_i32" (func (type 43)))) "unknown type") 50 | 51 | (module 52 | (type $T (func (param) (result i32))) 53 | (type $U (func (param) (result i32))) 54 | (table anyfunc (elem $t1 $t2 $t3 $u1 $u2 $t1 $t3)) 55 | 56 | (func $t1 (type $T) (i32.const 1)) 57 | (func $t2 (type $T) (i32.const 2)) 58 | (func $t3 (type $T) (i32.const 3)) 59 | (func $u1 (type $U) (i32.const 4)) 60 | (func $u2 (type $U) (i32.const 5)) 61 | 62 | (func (export "callt") (param $i i32) (result i32) 63 | (call_indirect (type $T) (get_local $i)) 64 | ) 65 | 66 | (func (export "callu") (param $i i32) (result i32) 67 | (call_indirect (type $U) (get_local $i)) 68 | ) 69 | ) 70 | 71 | (assert_return (invoke "callt" (i32.const 0)) (i32.const 1)) 72 | (assert_return (invoke "callt" (i32.const 1)) (i32.const 2)) 73 | (assert_return (invoke "callt" (i32.const 2)) (i32.const 3)) 74 | (assert_return (invoke "callt" (i32.const 3)) (i32.const 4)) 75 | (assert_return (invoke "callt" (i32.const 4)) (i32.const 5)) 76 | (assert_return (invoke "callt" (i32.const 5)) (i32.const 1)) 77 | (assert_return (invoke "callt" (i32.const 6)) (i32.const 3)) 78 | (assert_trap (invoke "callt" (i32.const 7)) "undefined element") 79 | (assert_trap (invoke "callt" (i32.const 100)) "undefined element") 80 | (assert_trap (invoke "callt" (i32.const -1)) "undefined element") 81 | 82 | (assert_return (invoke "callu" (i32.const 0)) (i32.const 1)) 83 | (assert_return (invoke "callu" (i32.const 1)) (i32.const 2)) 84 | (assert_return (invoke "callu" (i32.const 2)) (i32.const 3)) 85 | (assert_return (invoke "callu" (i32.const 3)) (i32.const 4)) 86 | (assert_return (invoke "callu" (i32.const 4)) (i32.const 5)) 87 | (assert_return (invoke "callu" (i32.const 5)) (i32.const 1)) 88 | (assert_return (invoke "callu" (i32.const 6)) (i32.const 3)) 89 | (assert_trap (invoke "callu" (i32.const 7)) "undefined element") 90 | (assert_trap (invoke "callu" (i32.const 100)) "undefined element") 91 | (assert_trap (invoke "callu" (i32.const -1)) "undefined element") 92 | 93 | (module 94 | (type $T (func (result i32))) 95 | (table anyfunc (elem 0 1)) 96 | 97 | (func $t1 (type $T) (i32.const 1)) 98 | (func $t2 (type $T) (i32.const 2)) 99 | 100 | (func (export "callt") (param $i i32) (result i32) 101 | (call_indirect (type $T) (get_local $i)) 102 | ) 103 | ) 104 | 105 | (assert_return (invoke "callt" (i32.const 0)) (i32.const 1)) 106 | (assert_return (invoke "callt" (i32.const 1)) (i32.const 2)) 107 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/get_local.wast: -------------------------------------------------------------------------------- 1 | ;; Test `get_local` operator 2 | 3 | (module 4 | ;; Typing 5 | 6 | (func (export "type-local-i32") (result i32) (local i32) (get_local 0)) 7 | (func (export "type-local-i64") (result i64) (local i64) (get_local 0)) 8 | (func (export "type-local-f32") (result f32) (local f32) (get_local 0)) 9 | (func (export "type-local-f64") (result f64) (local f64) (get_local 0)) 10 | 11 | (func (export "type-param-i32") (param i32) (result i32) (get_local 0)) 12 | (func (export "type-param-i64") (param i64) (result i64) (get_local 0)) 13 | (func (export "type-param-f32") (param f32) (result f32) (get_local 0)) 14 | (func (export "type-param-f64") (param f64) (result f64) (get_local 0)) 15 | 16 | (func (export "type-mixed") (param i64 f32 f64 i32 i32) 17 | (local f32 i64 i64 f64) 18 | (drop (i64.eqz (get_local 0))) 19 | (drop (f32.neg (get_local 1))) 20 | (drop (f64.neg (get_local 2))) 21 | (drop (i32.eqz (get_local 3))) 22 | (drop (i32.eqz (get_local 4))) 23 | (drop (f32.neg (get_local 5))) 24 | (drop (i64.eqz (get_local 6))) 25 | (drop (i64.eqz (get_local 7))) 26 | (drop (f64.neg (get_local 8))) 27 | ) 28 | 29 | ;; Reading 30 | 31 | (func (export "read") (param i64 f32 f64 i32 i32) (result f64) 32 | (local f32 i64 i64 f64) 33 | (set_local 5 (f32.const 5.5)) 34 | (set_local 6 (i64.const 6)) 35 | (set_local 8 (f64.const 8)) 36 | (f64.add 37 | (f64.convert_u/i64 (get_local 0)) 38 | (f64.add 39 | (f64.promote/f32 (get_local 1)) 40 | (f64.add 41 | (get_local 2) 42 | (f64.add 43 | (f64.convert_u/i32 (get_local 3)) 44 | (f64.add 45 | (f64.convert_s/i32 (get_local 4)) 46 | (f64.add 47 | (f64.promote/f32 (get_local 5)) 48 | (f64.add 49 | (f64.convert_u/i64 (get_local 6)) 50 | (f64.add 51 | (f64.convert_u/i64 (get_local 7)) 52 | (get_local 8) 53 | ) 54 | ) 55 | ) 56 | ) 57 | ) 58 | ) 59 | ) 60 | ) 61 | ) 62 | ) 63 | 64 | (assert_return (invoke "type-local-i32") (i32.const 0)) 65 | (assert_return (invoke "type-local-i64") (i64.const 0)) 66 | (assert_return (invoke "type-local-f32") (f32.const 0)) 67 | (assert_return (invoke "type-local-f64") (f64.const 0)) 68 | 69 | (assert_return (invoke "type-param-i32" (i32.const 2)) (i32.const 2)) 70 | (assert_return (invoke "type-param-i64" (i64.const 3)) (i64.const 3)) 71 | (assert_return (invoke "type-param-f32" (f32.const 4.4)) (f32.const 4.4)) 72 | (assert_return (invoke "type-param-f64" (f64.const 5.5)) (f64.const 5.5)) 73 | 74 | (assert_return 75 | (invoke "type-mixed" 76 | (i64.const 1) (f32.const 2.2) (f64.const 3.3) (i32.const 4) (i32.const 5) 77 | ) 78 | ) 79 | 80 | (assert_return 81 | (invoke "read" 82 | (i64.const 1) (f32.const 2) (f64.const 3.3) (i32.const 4) (i32.const 5) 83 | ) 84 | (f64.const 34.8) 85 | ) 86 | 87 | 88 | ;; Invalid typing of access to locals 89 | 90 | (assert_invalid 91 | (module (func $type-local-num-vs-num (result i64) (local i32) (get_local 0))) 92 | "type mismatch" 93 | ) 94 | (assert_invalid 95 | (module (func $type-local-num-vs-num (local f32) (i32.eqz (get_local 0)))) 96 | "type mismatch" 97 | ) 98 | (assert_invalid 99 | (module (func $type-local-num-vs-num (local f64 i64) (f64.neg (get_local 1)))) 100 | "type mismatch" 101 | ) 102 | 103 | 104 | ;; Invalid typing of access to parameters 105 | 106 | (assert_invalid 107 | (module (func $type-param-num-vs-num (param i32) (result i64) (get_local 0))) 108 | "type mismatch" 109 | ) 110 | (assert_invalid 111 | (module (func $type-param-num-vs-num (param f32) (i32.eqz (get_local 0)))) 112 | "type mismatch" 113 | ) 114 | (assert_invalid 115 | (module (func $type-param-num-vs-num (param f64 i64) (f64.neg (get_local 1)))) 116 | "type mismatch" 117 | ) 118 | 119 | 120 | ;; Invalid local index 121 | 122 | (assert_invalid 123 | (module (func $unbound-local (local i32 i64) (get_local 3))) 124 | "unknown local" 125 | ) 126 | (assert_invalid 127 | (module (func $large-local (local i32 i64) (get_local 14324343))) 128 | "unknown local" 129 | ) 130 | 131 | (assert_invalid 132 | (module (func $unbound-param (param i32 i64) (get_local 2))) 133 | "unknown local" 134 | ) 135 | (assert_invalid 136 | (module (func $large-param (local i32 i64) (get_local 714324343))) 137 | "unknown local" 138 | ) 139 | 140 | (assert_invalid 141 | (module (func $unbound-mixed (param i32) (local i32 i64) (get_local 3))) 142 | "unknown local" 143 | ) 144 | (assert_invalid 145 | (module (func $large-mixed (param i64) (local i32 i64) (get_local 214324343))) 146 | "unknown local" 147 | ) 148 | 149 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/globals.wast: -------------------------------------------------------------------------------- 1 | ;; Test globals 2 | 3 | (module 4 | (global $a i32 (i32.const -2)) 5 | (global (;1;) f32 (f32.const -3)) 6 | (global (;2;) f64 (f64.const -4)) 7 | (global $b i64 (i64.const -5)) 8 | 9 | (global $x (mut i32) (i32.const -12)) 10 | (global (;5;) (mut f32) (f32.const -13)) 11 | (global (;6;) (mut f64) (f64.const -14)) 12 | (global $y (mut i64) (i64.const -15)) 13 | 14 | (func (export "get-a") (result i32) (get_global $a)) 15 | (func (export "get-b") (result i64) (get_global $b)) 16 | (func (export "get-x") (result i32) (get_global $x)) 17 | (func (export "get-y") (result i64) (get_global $y)) 18 | (func (export "set-x") (param i32) (set_global $x (get_local 0))) 19 | (func (export "set-y") (param i64) (set_global $y (get_local 0))) 20 | 21 | (func (export "get-1") (result f32) (get_global 1)) 22 | (func (export "get-2") (result f64) (get_global 2)) 23 | (func (export "get-5") (result f32) (get_global 5)) 24 | (func (export "get-6") (result f64) (get_global 6)) 25 | (func (export "set-5") (param f32) (set_global 5 (get_local 0))) 26 | (func (export "set-6") (param f64) (set_global 6 (get_local 0))) 27 | ) 28 | 29 | (assert_return (invoke "get-a") (i32.const -2)) 30 | (assert_return (invoke "get-b") (i64.const -5)) 31 | (assert_return (invoke "get-x") (i32.const -12)) 32 | (assert_return (invoke "get-y") (i64.const -15)) 33 | 34 | (assert_return (invoke "get-1") (f32.const -3)) 35 | (assert_return (invoke "get-2") (f64.const -4)) 36 | (assert_return (invoke "get-5") (f32.const -13)) 37 | (assert_return (invoke "get-6") (f64.const -14)) 38 | 39 | (assert_return (invoke "set-x" (i32.const 6))) 40 | (assert_return (invoke "set-y" (i64.const 7))) 41 | (assert_return (invoke "set-5" (f32.const 8))) 42 | (assert_return (invoke "set-6" (f64.const 9))) 43 | 44 | (assert_return (invoke "get-x") (i32.const 6)) 45 | (assert_return (invoke "get-y") (i64.const 7)) 46 | (assert_return (invoke "get-5") (f32.const 8)) 47 | (assert_return (invoke "get-6") (f64.const 9)) 48 | 49 | (assert_invalid 50 | (module (global f32 (f32.const 0)) (func (set_global 0 (i32.const 1)))) 51 | "global is immutable" 52 | ) 53 | 54 | ;; mutable globals can be exported 55 | (module (global (mut f32) (f32.const 0)) (export "a" (global 0))) 56 | (module (global (export "a") (mut f32) (f32.const 0))) 57 | 58 | (assert_invalid 59 | (module (global f32 (f32.neg (f32.const 0)))) 60 | "constant expression required" 61 | ) 62 | 63 | (assert_invalid 64 | (module (global f32 (get_local 0))) 65 | "constant expression required" 66 | ) 67 | 68 | (assert_invalid 69 | (module (global f32 (f32.neg (f32.const 1)))) 70 | "constant expression required" 71 | ) 72 | 73 | (assert_invalid 74 | (module (global i32 (i32.const 0) (nop))) 75 | "constant expression required" 76 | ) 77 | 78 | (assert_invalid 79 | (module (global i32 (nop))) 80 | "constant expression required" 81 | ) 82 | 83 | (assert_invalid 84 | (module (global i32 (f32.const 0))) 85 | "type mismatch" 86 | ) 87 | 88 | (assert_invalid 89 | (module (global i32 (i32.const 0) (i32.const 0))) 90 | "type mismatch" 91 | ) 92 | 93 | (assert_invalid 94 | (module (global i32 (;empty instruction sequence;))) 95 | "type mismatch" 96 | ) 97 | 98 | (assert_invalid 99 | (module (global i32 (get_global 0))) 100 | "unknown global" 101 | ) 102 | 103 | (assert_invalid 104 | (module (global i32 (get_global 1)) (global i32 (i32.const 0))) 105 | "unknown global" 106 | ) 107 | 108 | (module 109 | (import "spectest" "global_i32" (global i32)) 110 | ) 111 | (assert_malformed 112 | (module binary 113 | "\00asm" "\01\00\00\00" 114 | "\02\94\80\80\80\00" ;; import section 115 | "\01" ;; length 1 116 | "\08\73\70\65\63\74\65\73\74" ;; "spectest" 117 | "\0a\67\6c\6f\62\61\6c\5f\69\33\32" ;; "global_i32" 118 | "\03" ;; GlobalImport 119 | "\7f" ;; i32 120 | "\02" ;; invalid mutability 121 | ) 122 | "invalid mutability" 123 | ) 124 | (assert_malformed 125 | (module binary 126 | "\00asm" "\01\00\00\00" 127 | "\02\94\80\80\80\00" ;; import section 128 | "\01" ;; length 1 129 | "\08\73\70\65\63\74\65\73\74" ;; "spectest" 130 | "\0a\67\6c\6f\62\61\6c\5f\69\33\32" ;; "global_i32" 131 | "\03" ;; GlobalImport 132 | "\7f" ;; i32 133 | "\ff" ;; invalid mutability 134 | ) 135 | "invalid mutability" 136 | ) 137 | 138 | (module 139 | (global i32 (i32.const 0)) 140 | ) 141 | (assert_malformed 142 | (module binary 143 | "\00asm" "\01\00\00\00" 144 | "\06\86\80\80\80\00" ;; global section 145 | "\01" ;; length 1 146 | "\7f" ;; i32 147 | "\02" ;; invalid mutability 148 | "\41\00" ;; i32.const 0 149 | "\0b" ;; end 150 | ) 151 | "invalid mutability" 152 | ) 153 | (assert_malformed 154 | (module binary 155 | "\00asm" "\01\00\00\00" 156 | "\06\86\80\80\80\00" ;; global section 157 | "\01" ;; length 1 158 | "\7f" ;; i32 159 | "\ff" ;; invalid mutability 160 | "\41\00" ;; i32.const 0 161 | "\0b" ;; end 162 | ) 163 | "invalid mutability" 164 | ) 165 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/inline-module.wast: -------------------------------------------------------------------------------- 1 | (func) (memory 0) (func (export "f")) 2 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/int_literals.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "i32.test") (result i32) (return (i32.const 0x0bAdD00D))) 3 | (func (export "i32.umax") (result i32) (return (i32.const 0xffffffff))) 4 | (func (export "i32.smax") (result i32) (return (i32.const 0x7fffffff))) 5 | (func (export "i32.neg_smax") (result i32) (return (i32.const -0x7fffffff))) 6 | (func (export "i32.smin") (result i32) (return (i32.const -0x80000000))) 7 | (func (export "i32.alt_smin") (result i32) (return (i32.const 0x80000000))) 8 | (func (export "i32.inc_smin") (result i32) (return (i32.add (i32.const -0x80000000) (i32.const 1)))) 9 | (func (export "i32.neg_zero") (result i32) (return (i32.const -0x0))) 10 | (func (export "i32.not_octal") (result i32) (return (i32.const 010))) 11 | (func (export "i32.unsigned_decimal") (result i32) (return (i32.const 4294967295))) 12 | (func (export "i32.plus_sign") (result i32) (return (i32.const +42))) 13 | 14 | (func (export "i64.test") (result i64) (return (i64.const 0x0CABBA6E0ba66a6e))) 15 | (func (export "i64.umax") (result i64) (return (i64.const 0xffffffffffffffff))) 16 | (func (export "i64.smax") (result i64) (return (i64.const 0x7fffffffffffffff))) 17 | (func (export "i64.neg_smax") (result i64) (return (i64.const -0x7fffffffffffffff))) 18 | (func (export "i64.smin") (result i64) (return (i64.const -0x8000000000000000))) 19 | (func (export "i64.alt_smin") (result i64) (return (i64.const 0x8000000000000000))) 20 | (func (export "i64.inc_smin") (result i64) (return (i64.add (i64.const -0x8000000000000000) (i64.const 1)))) 21 | (func (export "i64.neg_zero") (result i64) (return (i64.const -0x0))) 22 | (func (export "i64.not_octal") (result i64) (return (i64.const 010))) 23 | (func (export "i64.unsigned_decimal") (result i64) (return (i64.const 18446744073709551615))) 24 | (func (export "i64.plus_sign") (result i64) (return (i64.const +42))) 25 | 26 | (func (export "i32-dec-sep1") (result i32) (i32.const 1_000_000)) 27 | (func (export "i32-dec-sep2") (result i32) (i32.const 1_0_0_0)) 28 | (func (export "i32-hex-sep1") (result i32) (i32.const 0xa_0f_00_99)) 29 | (func (export "i32-hex-sep2") (result i32) (i32.const 0x1_a_A_0_f)) 30 | 31 | (func (export "i64-dec-sep1") (result i64) (i64.const 1_000_000)) 32 | (func (export "i64-dec-sep2") (result i64) (i64.const 1_0_0_0)) 33 | (func (export "i64-hex-sep1") (result i64) (i64.const 0xa_f00f_0000_9999)) 34 | (func (export "i64-hex-sep2") (result i64) (i64.const 0x1_a_A_0_f)) 35 | ) 36 | 37 | (assert_return (invoke "i32.test") (i32.const 195940365)) 38 | (assert_return (invoke "i32.umax") (i32.const -1)) 39 | (assert_return (invoke "i32.smax") (i32.const 2147483647)) 40 | (assert_return (invoke "i32.neg_smax") (i32.const -2147483647)) 41 | (assert_return (invoke "i32.smin") (i32.const -2147483648)) 42 | (assert_return (invoke "i32.alt_smin") (i32.const -2147483648)) 43 | (assert_return (invoke "i32.inc_smin") (i32.const -2147483647)) 44 | (assert_return (invoke "i32.neg_zero") (i32.const 0)) 45 | (assert_return (invoke "i32.not_octal") (i32.const 10)) 46 | (assert_return (invoke "i32.unsigned_decimal") (i32.const -1)) 47 | (assert_return (invoke "i32.plus_sign") (i32.const 42)) 48 | 49 | (assert_return (invoke "i64.test") (i64.const 913028331277281902)) 50 | (assert_return (invoke "i64.umax") (i64.const -1)) 51 | (assert_return (invoke "i64.smax") (i64.const 9223372036854775807)) 52 | (assert_return (invoke "i64.neg_smax") (i64.const -9223372036854775807)) 53 | (assert_return (invoke "i64.smin") (i64.const -9223372036854775808)) 54 | (assert_return (invoke "i64.alt_smin") (i64.const -9223372036854775808)) 55 | (assert_return (invoke "i64.inc_smin") (i64.const -9223372036854775807)) 56 | (assert_return (invoke "i64.neg_zero") (i64.const 0)) 57 | (assert_return (invoke "i64.not_octal") (i64.const 10)) 58 | (assert_return (invoke "i64.unsigned_decimal") (i64.const -1)) 59 | (assert_return (invoke "i64.plus_sign") (i64.const 42)) 60 | 61 | (assert_return (invoke "i32-dec-sep1") (i32.const 1000000)) 62 | (assert_return (invoke "i32-dec-sep2") (i32.const 1000)) 63 | (assert_return (invoke "i32-hex-sep1") (i32.const 0xa0f0099)) 64 | (assert_return (invoke "i32-hex-sep2") (i32.const 0x1aa0f)) 65 | 66 | (assert_return (invoke "i64-dec-sep1") (i64.const 1000000)) 67 | (assert_return (invoke "i64-dec-sep2") (i64.const 1000)) 68 | (assert_return (invoke "i64-hex-sep1") (i64.const 0xaf00f00009999)) 69 | (assert_return (invoke "i64-hex-sep2") (i64.const 0x1aa0f)) 70 | 71 | (assert_malformed 72 | (module quote "(global i32 (i32.const _100))") 73 | "unknown operator" 74 | ) 75 | (assert_malformed 76 | (module quote "(global i32 (i32.const +_100))") 77 | "unknown operator" 78 | ) 79 | (assert_malformed 80 | (module quote "(global i32 (i32.const -_100))") 81 | "unknown operator" 82 | ) 83 | (assert_malformed 84 | (module quote "(global i32 (i32.const 99_))") 85 | "unknown operator" 86 | ) 87 | (assert_malformed 88 | (module quote "(global i32 (i32.const 1__000))") 89 | "unknown operator" 90 | ) 91 | (assert_malformed 92 | (module quote "(global i32 (i32.const _0x100))") 93 | "unknown operator" 94 | ) 95 | (assert_malformed 96 | (module quote "(global i32 (i32.const 0_x100))") 97 | "unknown operator" 98 | ) 99 | (assert_malformed 100 | (module quote "(global i32 (i32.const 0x_100))") 101 | "unknown operator" 102 | ) 103 | (assert_malformed 104 | (module quote "(global i32 (i32.const 0x00_))") 105 | "unknown operator" 106 | ) 107 | (assert_malformed 108 | (module quote "(global i32 (i32.const 0xff__ffff))") 109 | "unknown operator" 110 | ) 111 | 112 | (assert_malformed 113 | (module quote "(global i64 (i64.const _100))") 114 | "unknown operator" 115 | ) 116 | (assert_malformed 117 | (module quote "(global i64 (i64.const +_100))") 118 | "unknown operator" 119 | ) 120 | (assert_malformed 121 | (module quote "(global i64 (i64.const -_100))") 122 | "unknown operator" 123 | ) 124 | (assert_malformed 125 | (module quote "(global i64 (i64.const 99_))") 126 | "unknown operator" 127 | ) 128 | (assert_malformed 129 | (module quote "(global i64 (i64.const 1__000))") 130 | "unknown operator" 131 | ) 132 | (assert_malformed 133 | (module quote "(global i64 (i64.const _0x100))") 134 | "unknown operator" 135 | ) 136 | (assert_malformed 137 | (module quote "(global i64 (i64.const 0_x100))") 138 | "unknown operator" 139 | ) 140 | (assert_malformed 141 | (module quote "(global i64 (i64.const 0x_100))") 142 | "unknown operator" 143 | ) 144 | (assert_malformed 145 | (module quote "(global i64 (i64.const 0x00_))") 146 | "unknown operator" 147 | ) 148 | (assert_malformed 149 | (module quote "(global i64 (i64.const 0xff__ffff))") 150 | "unknown operator" 151 | ) 152 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/labels.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "block") (result i32) 3 | (block $exit (result i32) 4 | (br $exit (i32.const 1)) 5 | (i32.const 0) 6 | ) 7 | ) 8 | 9 | (func (export "loop1") (result i32) 10 | (local $i i32) 11 | (set_local $i (i32.const 0)) 12 | (block $exit (result i32) 13 | (loop $cont (result i32) 14 | (set_local $i (i32.add (get_local $i) (i32.const 1))) 15 | (if (i32.eq (get_local $i) (i32.const 5)) 16 | (then (br $exit (get_local $i))) 17 | ) 18 | (br $cont) 19 | ) 20 | ) 21 | ) 22 | 23 | (func (export "loop2") (result i32) 24 | (local $i i32) 25 | (set_local $i (i32.const 0)) 26 | (block $exit (result i32) 27 | (loop $cont (result i32) 28 | (set_local $i (i32.add (get_local $i) (i32.const 1))) 29 | (if (i32.eq (get_local $i) (i32.const 5)) 30 | (then (br $cont)) 31 | ) 32 | (if (i32.eq (get_local $i) (i32.const 8)) 33 | (then (br $exit (get_local $i))) 34 | ) 35 | (set_local $i (i32.add (get_local $i) (i32.const 1))) 36 | (br $cont) 37 | ) 38 | ) 39 | ) 40 | 41 | (func (export "loop3") (result i32) 42 | (local $i i32) 43 | (set_local $i (i32.const 0)) 44 | (block $exit (result i32) 45 | (loop $cont (result i32) 46 | (set_local $i (i32.add (get_local $i) (i32.const 1))) 47 | (if (i32.eq (get_local $i) (i32.const 5)) 48 | (then (br $exit (get_local $i))) 49 | ) 50 | (get_local $i) 51 | ) 52 | ) 53 | ) 54 | 55 | (func (export "loop4") (param $max i32) (result i32) 56 | (local $i i32) 57 | (set_local $i (i32.const 1)) 58 | (block $exit (result i32) 59 | (loop $cont (result i32) 60 | (set_local $i (i32.add (get_local $i) (get_local $i))) 61 | (if (i32.gt_u (get_local $i) (get_local $max)) 62 | (then (br $exit (get_local $i))) 63 | ) 64 | (br $cont) 65 | ) 66 | ) 67 | ) 68 | 69 | (func (export "loop5") (result i32) 70 | (i32.add 71 | (loop $l (result i32) (i32.const 1)) 72 | (i32.const 1) 73 | ) 74 | ) 75 | 76 | (func (export "loop6") (result i32) 77 | (loop (result i32) 78 | (br_if 0 (i32.const 0)) 79 | (i32.const 3) 80 | ) 81 | ) 82 | 83 | (func (export "if") (result i32) 84 | (local $i i32) 85 | (set_local $i (i32.const 0)) 86 | (block 87 | (if $l 88 | (i32.const 1) 89 | (then (br $l) (set_local $i (i32.const 666))) 90 | ) 91 | (set_local $i (i32.add (get_local $i) (i32.const 1))) 92 | (if $l 93 | (i32.const 1) 94 | (then (br $l) (set_local $i (i32.const 666))) 95 | (else (set_local $i (i32.const 888))) 96 | ) 97 | (set_local $i (i32.add (get_local $i) (i32.const 1))) 98 | (if $l 99 | (i32.const 1) 100 | (then (br $l) (set_local $i (i32.const 666))) 101 | (else (set_local $i (i32.const 888))) 102 | ) 103 | (set_local $i (i32.add (get_local $i) (i32.const 1))) 104 | (if $l 105 | (i32.const 0) 106 | (then (set_local $i (i32.const 888))) 107 | (else (br $l) (set_local $i (i32.const 666))) 108 | ) 109 | (set_local $i (i32.add (get_local $i) (i32.const 1))) 110 | (if $l 111 | (i32.const 0) 112 | (then (set_local $i (i32.const 888))) 113 | (else (br $l) (set_local $i (i32.const 666))) 114 | ) 115 | (set_local $i (i32.add (get_local $i) (i32.const 1))) 116 | ) 117 | (get_local $i) 118 | ) 119 | 120 | (func (export "if2") (result i32) 121 | (local $i i32) 122 | (set_local $i (i32.const 0)) 123 | (block 124 | (if 125 | (i32.const 1) 126 | (then (br 0) (set_local $i (i32.const 666))) 127 | ) 128 | (set_local $i (i32.add (get_local $i) (i32.const 1))) 129 | (if 130 | (i32.const 1) 131 | (then (br 0) (set_local $i (i32.const 666))) 132 | (else (set_local $i (i32.const 888))) 133 | ) 134 | (set_local $i (i32.add (get_local $i) (i32.const 1))) 135 | (if 136 | (i32.const 1) 137 | (then (br 0) (set_local $i (i32.const 666))) 138 | (else (set_local $i (i32.const 888))) 139 | ) 140 | (set_local $i (i32.add (get_local $i) (i32.const 1))) 141 | (if 142 | (i32.const 0) 143 | (then (set_local $i (i32.const 888))) 144 | (else (br 0) (set_local $i (i32.const 666))) 145 | ) 146 | (set_local $i (i32.add (get_local $i) (i32.const 1))) 147 | (if 148 | (i32.const 0) 149 | (then (set_local $i (i32.const 888))) 150 | (else (br 0) (set_local $i (i32.const 666))) 151 | ) 152 | (set_local $i (i32.add (get_local $i) (i32.const 1))) 153 | ) 154 | (get_local $i) 155 | ) 156 | 157 | (func (export "switch") (param i32) (result i32) 158 | (block $ret (result i32) 159 | (i32.mul (i32.const 10) 160 | (block $exit (result i32) 161 | (block $0 162 | (block $default 163 | (block $3 164 | (block $2 165 | (block $1 166 | (br_table $0 $1 $2 $3 $default (get_local 0)) 167 | ) ;; 1 168 | ) ;; 2 169 | (br $exit (i32.const 2)) 170 | ) ;; 3 171 | (br $ret (i32.const 3)) 172 | ) ;; default 173 | ) ;; 0 174 | (i32.const 5) 175 | ) 176 | ) 177 | ) 178 | ) 179 | 180 | (func (export "return") (param i32) (result i32) 181 | (block $default 182 | (block $1 183 | (block $0 184 | (br_table $0 $1 (get_local 0)) 185 | (br $default) 186 | ) ;; 0 187 | (return (i32.const 0)) 188 | ) ;; 1 189 | ) ;; default 190 | (i32.const 2) 191 | ) 192 | 193 | (func (export "br_if0") (result i32) 194 | (local $i i32) 195 | (set_local $i (i32.const 0)) 196 | (block $outer (result i32) 197 | (block $inner 198 | (br_if $inner (i32.const 0)) 199 | (set_local $i (i32.or (get_local $i) (i32.const 0x1))) 200 | (br_if $inner (i32.const 1)) 201 | (set_local $i (i32.or (get_local $i) (i32.const 0x2))) 202 | ) 203 | (drop (br_if $outer 204 | (block (result i32) 205 | (set_local $i (i32.or (get_local $i) (i32.const 0x4))) 206 | (get_local $i) 207 | ) 208 | (i32.const 0) 209 | )) 210 | (set_local $i (i32.or (get_local $i) (i32.const 0x8))) 211 | (drop (br_if $outer 212 | (block (result i32) 213 | (set_local $i (i32.or (get_local $i) (i32.const 0x10))) 214 | (get_local $i) 215 | ) 216 | (i32.const 1) 217 | )) 218 | (set_local $i (i32.or (get_local $i) (i32.const 0x20))) (get_local $i) 219 | ) 220 | ) 221 | 222 | (func (export "br_if1") (result i32) 223 | (block $l0 (result i32) 224 | (drop 225 | (br_if $l0 226 | (block $l1 (result i32) (br $l1 (i32.const 1))) 227 | (i32.const 1) 228 | ) 229 | ) 230 | (i32.const 1) 231 | ) 232 | ) 233 | 234 | (func (export "br_if2") (result i32) 235 | (block $l0 (result i32) 236 | (if (i32.const 1) 237 | (then (br $l0 (block $l1 (result i32) (br $l1 (i32.const 1))))) 238 | ) 239 | (i32.const 1) 240 | ) 241 | ) 242 | 243 | (func (export "br_if3") (result i32) 244 | (local $i1 i32) 245 | (drop 246 | (i32.add 247 | (block $l0 (result i32) 248 | (drop (br_if $l0 249 | (block (result i32) (set_local $i1 (i32.const 1)) (get_local $i1)) 250 | (block (result i32) (set_local $i1 (i32.const 2)) (get_local $i1)) 251 | )) 252 | (i32.const 0) 253 | ) 254 | (i32.const 0) 255 | ) 256 | ) 257 | (get_local $i1) 258 | ) 259 | 260 | (func (export "br") (result i32) 261 | (block $l0 (result i32) 262 | (if (i32.const 1) 263 | (then (br $l0 (block $l1 (result i32) (br $l1 (i32.const 1))))) 264 | (else (block (drop (block $l1 (result i32) (br $l1 (i32.const 1)))))) 265 | ) 266 | (i32.const 1) 267 | ) 268 | ) 269 | 270 | (func (export "shadowing") (result i32) 271 | (block $l1 (result i32) (i32.xor (br $l1 (i32.const 1)) (i32.const 2))) 272 | ) 273 | 274 | (func (export "redefinition") (result i32) 275 | (block $l1 (result i32) 276 | (i32.add 277 | (block $l1 (result i32) (i32.const 2)) 278 | (block $l1 (result i32) (br $l1 (i32.const 3))) 279 | ) 280 | ) 281 | ) 282 | ) 283 | 284 | (assert_return (invoke "block") (i32.const 1)) 285 | (assert_return (invoke "loop1") (i32.const 5)) 286 | (assert_return (invoke "loop2") (i32.const 8)) 287 | (assert_return (invoke "loop3") (i32.const 1)) 288 | (assert_return (invoke "loop4" (i32.const 8)) (i32.const 16)) 289 | (assert_return (invoke "loop5") (i32.const 2)) 290 | (assert_return (invoke "loop6") (i32.const 3)) 291 | (assert_return (invoke "if") (i32.const 5)) 292 | (assert_return (invoke "if2") (i32.const 5)) 293 | (assert_return (invoke "switch" (i32.const 0)) (i32.const 50)) 294 | (assert_return (invoke "switch" (i32.const 1)) (i32.const 20)) 295 | (assert_return (invoke "switch" (i32.const 2)) (i32.const 20)) 296 | (assert_return (invoke "switch" (i32.const 3)) (i32.const 3)) 297 | (assert_return (invoke "switch" (i32.const 4)) (i32.const 50)) 298 | (assert_return (invoke "switch" (i32.const 5)) (i32.const 50)) 299 | (assert_return (invoke "return" (i32.const 0)) (i32.const 0)) 300 | (assert_return (invoke "return" (i32.const 1)) (i32.const 2)) 301 | (assert_return (invoke "return" (i32.const 2)) (i32.const 2)) 302 | (assert_return (invoke "br_if0") (i32.const 0x1d)) 303 | (assert_return (invoke "br_if1") (i32.const 1)) 304 | (assert_return (invoke "br_if2") (i32.const 1)) 305 | (assert_return (invoke "br_if3") (i32.const 2)) 306 | (assert_return (invoke "br") (i32.const 1)) 307 | (assert_return (invoke "shadowing") (i32.const 1)) 308 | (assert_return (invoke "redefinition") (i32.const 5)) 309 | 310 | (assert_invalid 311 | (module (func (block $l (f32.neg (br_if $l (i32.const 1))) (nop)))) 312 | "type mismatch" 313 | ) 314 | (assert_invalid 315 | (module (func (block $l (br_if $l (f32.const 0) (i32.const 1))))) 316 | "type mismatch" 317 | ) 318 | (assert_invalid 319 | (module (func (block $l (br_if $l (f32.const 0) (i32.const 1))))) 320 | "type mismatch" 321 | ) 322 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/memory_grow.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory 0) 3 | 4 | (func (export "load_at_zero") (result i32) (i32.load (i32.const 0))) 5 | (func (export "store_at_zero") (i32.store (i32.const 0) (i32.const 2))) 6 | 7 | (func (export "load_at_page_size") (result i32) (i32.load (i32.const 0x10000))) 8 | (func (export "store_at_page_size") (i32.store (i32.const 0x10000) (i32.const 3))) 9 | 10 | (func (export "grow") (param $sz i32) (result i32) (memory.grow (get_local $sz))) 11 | (func (export "size") (result i32) (memory.size)) 12 | ) 13 | 14 | (assert_return (invoke "size") (i32.const 0)) 15 | (assert_trap (invoke "store_at_zero") "out of bounds memory access") 16 | (assert_trap (invoke "load_at_zero") "out of bounds memory access") 17 | (assert_trap (invoke "store_at_page_size") "out of bounds memory access") 18 | (assert_trap (invoke "load_at_page_size") "out of bounds memory access") 19 | (assert_return (invoke "grow" (i32.const 1)) (i32.const 0)) 20 | (assert_return (invoke "size") (i32.const 1)) 21 | (assert_return (invoke "load_at_zero") (i32.const 0)) 22 | (assert_return (invoke "store_at_zero")) 23 | (assert_return (invoke "load_at_zero") (i32.const 2)) 24 | (assert_trap (invoke "store_at_page_size") "out of bounds memory access") 25 | (assert_trap (invoke "load_at_page_size") "out of bounds memory access") 26 | (assert_return (invoke "grow" (i32.const 4)) (i32.const 1)) 27 | (assert_return (invoke "size") (i32.const 5)) 28 | (assert_return (invoke "load_at_zero") (i32.const 2)) 29 | (assert_return (invoke "store_at_zero")) 30 | (assert_return (invoke "load_at_zero") (i32.const 2)) 31 | (assert_return (invoke "load_at_page_size") (i32.const 0)) 32 | (assert_return (invoke "store_at_page_size")) 33 | (assert_return (invoke "load_at_page_size") (i32.const 3)) 34 | 35 | 36 | (module 37 | (memory 0) 38 | (func (export "grow") (param i32) (result i32) (memory.grow (get_local 0))) 39 | ) 40 | 41 | (assert_return (invoke "grow" (i32.const 0)) (i32.const 0)) 42 | (assert_return (invoke "grow" (i32.const 1)) (i32.const 0)) 43 | (assert_return (invoke "grow" (i32.const 0)) (i32.const 1)) 44 | (assert_return (invoke "grow" (i32.const 2)) (i32.const 1)) 45 | (assert_return (invoke "grow" (i32.const 800)) (i32.const 3)) 46 | (assert_return (invoke "grow" (i32.const 0x10000)) (i32.const -1)) 47 | (assert_return (invoke "grow" (i32.const 64736)) (i32.const -1)) 48 | (assert_return (invoke "grow" (i32.const 1)) (i32.const 803)) 49 | 50 | (module 51 | (memory 0 10) 52 | (func (export "grow") (param i32) (result i32) (memory.grow (get_local 0))) 53 | ) 54 | 55 | (assert_return (invoke "grow" (i32.const 0)) (i32.const 0)) 56 | (assert_return (invoke "grow" (i32.const 1)) (i32.const 0)) 57 | (assert_return (invoke "grow" (i32.const 1)) (i32.const 1)) 58 | (assert_return (invoke "grow" (i32.const 2)) (i32.const 2)) 59 | (assert_return (invoke "grow" (i32.const 6)) (i32.const 4)) 60 | (assert_return (invoke "grow" (i32.const 0)) (i32.const 10)) 61 | (assert_return (invoke "grow" (i32.const 1)) (i32.const -1)) 62 | (assert_return (invoke "grow" (i32.const 0x10000)) (i32.const -1)) 63 | 64 | ;; Test that newly allocated memory (program start and memory.grow) is zeroed 65 | 66 | (module 67 | (memory 1) 68 | (func (export "grow") (param i32) (result i32) 69 | (memory.grow (get_local 0)) 70 | ) 71 | (func (export "check-memory-zero") (param i32 i32) (result i32) 72 | (local i32) 73 | (set_local 2 (i32.const 1)) 74 | (block 75 | (loop 76 | (set_local 2 (i32.load8_u (get_local 0))) 77 | (br_if 1 (i32.ne (get_local 2) (i32.const 0))) 78 | (br_if 1 (i32.ge_u (get_local 0) (get_local 1))) 79 | (set_local 0 (i32.add (get_local 0) (i32.const 1))) 80 | (br_if 0 (i32.le_u (get_local 0) (get_local 1))) 81 | ) 82 | ) 83 | (get_local 2) 84 | ) 85 | ) 86 | 87 | (assert_return (invoke "check-memory-zero" (i32.const 0) (i32.const 0xffff)) (i32.const 0)) 88 | (assert_return (invoke "grow" (i32.const 1)) (i32.const 1)) 89 | (assert_return (invoke "check-memory-zero" (i32.const 0x10000) (i32.const 0x1_ffff)) (i32.const 0)) 90 | (assert_return (invoke "grow" (i32.const 1)) (i32.const 2)) 91 | (assert_return (invoke "check-memory-zero" (i32.const 0x20000) (i32.const 0x2_ffff)) (i32.const 0)) 92 | (assert_return (invoke "grow" (i32.const 1)) (i32.const 3)) 93 | (assert_return (invoke "check-memory-zero" (i32.const 0x30000) (i32.const 0x3_ffff)) (i32.const 0)) 94 | (assert_return (invoke "grow" (i32.const 1)) (i32.const 4)) 95 | (assert_return (invoke "check-memory-zero" (i32.const 0x40000) (i32.const 0x4_ffff)) (i32.const 0)) 96 | (assert_return (invoke "grow" (i32.const 1)) (i32.const 5)) 97 | (assert_return (invoke "check-memory-zero" (i32.const 0x50000) (i32.const 0x5_ffff)) (i32.const 0)) 98 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/memory_redundancy.wast: -------------------------------------------------------------------------------- 1 | ;; Test that optimizers don't do redundant-load, store-to-load, or dead-store 2 | ;; optimizations when there are interfering stores, even of different types 3 | ;; and to non-identical addresses. 4 | 5 | (module 6 | (memory 1 1) 7 | 8 | (func (export "zero_everything") 9 | (i32.store (i32.const 0) (i32.const 0)) 10 | (i32.store (i32.const 4) (i32.const 0)) 11 | (i32.store (i32.const 8) (i32.const 0)) 12 | (i32.store (i32.const 12) (i32.const 0)) 13 | ) 14 | 15 | (func (export "test_store_to_load") (result i32) 16 | (i32.store (i32.const 8) (i32.const 0)) 17 | (f32.store (i32.const 5) (f32.const -0.0)) 18 | (i32.load (i32.const 8)) 19 | ) 20 | 21 | (func (export "test_redundant_load") (result i32) 22 | (local $t i32) 23 | (local $s i32) 24 | (set_local $t (i32.load (i32.const 8))) 25 | (i32.store (i32.const 5) (i32.const 0x80000000)) 26 | (set_local $s (i32.load (i32.const 8))) 27 | (i32.add (get_local $t) (get_local $s)) 28 | ) 29 | 30 | (func (export "test_dead_store") (result f32) 31 | (local $t f32) 32 | (i32.store (i32.const 8) (i32.const 0x23232323)) 33 | (set_local $t (f32.load (i32.const 11))) 34 | (i32.store (i32.const 8) (i32.const 0)) 35 | (get_local $t) 36 | ) 37 | 38 | ;; A function named "malloc" which implementations nonetheless shouldn't 39 | ;; assume behaves like C malloc. 40 | (func $malloc (export "malloc") 41 | (param $size i32) 42 | (result i32) 43 | (i32.const 16) 44 | ) 45 | 46 | ;; Call malloc twice, but unlike C malloc, we don't get non-aliasing pointers. 47 | (func (export "malloc_aliasing") 48 | (result i32) 49 | (local $x i32) 50 | (local $y i32) 51 | (set_local $x (call $malloc (i32.const 4))) 52 | (set_local $y (call $malloc (i32.const 4))) 53 | (i32.store (get_local $x) (i32.const 42)) 54 | (i32.store (get_local $y) (i32.const 43)) 55 | (i32.load (get_local $x)) 56 | ) 57 | ) 58 | 59 | (assert_return (invoke "test_store_to_load") (i32.const 0x00000080)) 60 | (invoke "zero_everything") 61 | (assert_return (invoke "test_redundant_load") (i32.const 0x00000080)) 62 | (invoke "zero_everything") 63 | (assert_return (invoke "test_dead_store") (f32.const 0x1.18p-144)) 64 | (invoke "zero_everything") 65 | (assert_return (invoke "malloc_aliasing") (i32.const 43)) 66 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/proposals/multi-value/fac.wast: -------------------------------------------------------------------------------- 1 | (module 2 | ;; Recursive factorial 3 | (func (export "fac-rec") (param i64) (result i64) 4 | (if (result i64) (i64.eq (get_local 0) (i64.const 0)) 5 | (then (i64.const 1)) 6 | (else 7 | (i64.mul (get_local 0) (call 0 (i64.sub (get_local 0) (i64.const 1)))) 8 | ) 9 | ) 10 | ) 11 | 12 | ;; Recursive factorial named 13 | (func $fac-rec-named (export "fac-rec-named") (param $n i64) (result i64) 14 | (if (result i64) (i64.eq (get_local $n) (i64.const 0)) 15 | (then (i64.const 1)) 16 | (else 17 | (i64.mul 18 | (get_local $n) 19 | (call $fac-rec-named (i64.sub (get_local $n) (i64.const 1))) 20 | ) 21 | ) 22 | ) 23 | ) 24 | 25 | ;; Iterative factorial 26 | (func (export "fac-iter") (param i64) (result i64) 27 | (local i64 i64) 28 | (set_local 1 (get_local 0)) 29 | (set_local 2 (i64.const 1)) 30 | (block 31 | (loop 32 | (if 33 | (i64.eq (get_local 1) (i64.const 0)) 34 | (then (br 2)) 35 | (else 36 | (set_local 2 (i64.mul (get_local 1) (get_local 2))) 37 | (set_local 1 (i64.sub (get_local 1) (i64.const 1))) 38 | ) 39 | ) 40 | (br 0) 41 | ) 42 | ) 43 | (get_local 2) 44 | ) 45 | 46 | ;; Iterative factorial named 47 | (func (export "fac-iter-named") (param $n i64) (result i64) 48 | (local $i i64) 49 | (local $res i64) 50 | (set_local $i (get_local $n)) 51 | (set_local $res (i64.const 1)) 52 | (block $done 53 | (loop $loop 54 | (if 55 | (i64.eq (get_local $i) (i64.const 0)) 56 | (then (br $done)) 57 | (else 58 | (set_local $res (i64.mul (get_local $i) (get_local $res))) 59 | (set_local $i (i64.sub (get_local $i) (i64.const 1))) 60 | ) 61 | ) 62 | (br $loop) 63 | ) 64 | ) 65 | (get_local $res) 66 | ) 67 | 68 | ;; Optimized factorial. 69 | (func (export "fac-opt") (param i64) (result i64) 70 | (local i64) 71 | (set_local 1 (i64.const 1)) 72 | (block 73 | (br_if 0 (i64.lt_s (get_local 0) (i64.const 2))) 74 | (loop 75 | (set_local 1 (i64.mul (get_local 1) (get_local 0))) 76 | (set_local 0 (i64.add (get_local 0) (i64.const -1))) 77 | (br_if 0 (i64.gt_s (get_local 0) (i64.const 1))) 78 | ) 79 | ) 80 | (get_local 1) 81 | ) 82 | 83 | ;; Iterative factorial without locals. 84 | (func $pick0 (param i64) (result i64 i64) 85 | (get_local 0) (get_local 0) 86 | ) 87 | (func $pick1 (param i64 i64) (result i64 i64 i64) 88 | (get_local 0) (get_local 1) (get_local 0) 89 | ) 90 | (func (export "fac-ssa") (param i64) (result i64) 91 | (i64.const 1) (get_local 0) 92 | (loop $l (param i64 i64) (result i64) 93 | (call $pick1) (call $pick1) (i64.mul) 94 | (call $pick1) (i64.const 1) (i64.sub) 95 | (call $pick0) (i64.const 0) (i64.gt_u) 96 | (br_if $l) 97 | (drop) (return) 98 | ) 99 | ) 100 | ) 101 | 102 | (assert_return (invoke "fac-rec" (i64.const 25)) (i64.const 7034535277573963776)) 103 | (assert_return (invoke "fac-iter" (i64.const 25)) (i64.const 7034535277573963776)) 104 | (assert_return (invoke "fac-rec-named" (i64.const 25)) (i64.const 7034535277573963776)) 105 | (assert_return (invoke "fac-iter-named" (i64.const 25)) (i64.const 7034535277573963776)) 106 | (assert_return (invoke "fac-opt" (i64.const 25)) (i64.const 7034535277573963776)) 107 | (assert_return (invoke "fac-ssa" (i64.const 25)) (i64.const 7034535277573963776)) 108 | 109 | (assert_exhaustion (invoke "fac-rec" (i64.const 1073741824)) "call stack exhausted") 110 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/proposals/multi-value/type.wast: -------------------------------------------------------------------------------- 1 | ;; Test type definitions 2 | 3 | (module 4 | (type (func)) 5 | (type $t (func)) 6 | 7 | (type (func (param i32))) 8 | (type (func (param $x i32))) 9 | (type (func (result i32))) 10 | (type (func (param i32) (result i32))) 11 | (type (func (param $x i32) (result i32))) 12 | 13 | (type (func (param f32 f64))) 14 | (type (func (result i64 f32))) 15 | (type (func (param i32 i64) (result f32 f64))) 16 | 17 | (type (func (param f32) (param f64))) 18 | (type (func (param $x f32) (param f64))) 19 | (type (func (param f32) (param $y f64))) 20 | (type (func (param $x f32) (param $y f64))) 21 | (type (func (result i64) (result f32))) 22 | (type (func (param i32) (param i64) (result f32) (result f64))) 23 | (type (func (param $x i32) (param $y i64) (result f32) (result f64))) 24 | 25 | (type (func (param f32 f64) (param $x i32) (param f64 i32 i32))) 26 | (type (func (result i64 i64 f32) (result f32 i32))) 27 | (type 28 | (func (param i32 i32) (param i64 i32) (result f32 f64) (result f64 i32)) 29 | ) 30 | 31 | (type (func (param) (param $x f32) (param) (param) (param f64 i32) (param))) 32 | (type 33 | (func (result) (result) (result i64 i64) (result) (result f32) (result)) 34 | ) 35 | (type 36 | (func 37 | (param i32 i32) (param i64 i32) (param) (param $x i32) (param) 38 | (result) (result f32 f64) (result f64 i32) (result) 39 | ) 40 | ) 41 | ) 42 | 43 | (assert_malformed 44 | (module quote "(type (func (result i32) (param i32)))") 45 | "result before parameter" 46 | ) 47 | (assert_malformed 48 | (module quote "(type (func (result $x i32)))") 49 | "unexpected token" 50 | ) 51 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/proposals/mutable-global/globals.wast: -------------------------------------------------------------------------------- 1 | ;; Test globals 2 | 3 | (module 4 | (global $a i32 (i32.const -2)) 5 | (global (;1;) f32 (f32.const -3)) 6 | (global (;2;) f64 (f64.const -4)) 7 | (global $b i64 (i64.const -5)) 8 | 9 | (global $x (mut i32) (i32.const -12)) 10 | (global (;5;) (mut f32) (f32.const -13)) 11 | (global (;6;) (mut f64) (f64.const -14)) 12 | (global $y (mut i64) (i64.const -15)) 13 | 14 | (func (export "get-a") (result i32) (get_global $a)) 15 | (func (export "get-b") (result i64) (get_global $b)) 16 | (func (export "get-x") (result i32) (get_global $x)) 17 | (func (export "get-y") (result i64) (get_global $y)) 18 | (func (export "set-x") (param i32) (set_global $x (get_local 0))) 19 | (func (export "set-y") (param i64) (set_global $y (get_local 0))) 20 | 21 | (func (export "get-1") (result f32) (get_global 1)) 22 | (func (export "get-2") (result f64) (get_global 2)) 23 | (func (export "get-5") (result f32) (get_global 5)) 24 | (func (export "get-6") (result f64) (get_global 6)) 25 | (func (export "set-5") (param f32) (set_global 5 (get_local 0))) 26 | (func (export "set-6") (param f64) (set_global 6 (get_local 0))) 27 | ) 28 | 29 | (assert_return (invoke "get-a") (i32.const -2)) 30 | (assert_return (invoke "get-b") (i64.const -5)) 31 | (assert_return (invoke "get-x") (i32.const -12)) 32 | (assert_return (invoke "get-y") (i64.const -15)) 33 | 34 | (assert_return (invoke "get-1") (f32.const -3)) 35 | (assert_return (invoke "get-2") (f64.const -4)) 36 | (assert_return (invoke "get-5") (f32.const -13)) 37 | (assert_return (invoke "get-6") (f64.const -14)) 38 | 39 | (assert_return (invoke "set-x" (i32.const 6))) 40 | (assert_return (invoke "set-y" (i64.const 7))) 41 | (assert_return (invoke "set-5" (f32.const 8))) 42 | (assert_return (invoke "set-6" (f64.const 9))) 43 | 44 | (assert_return (invoke "get-x") (i32.const 6)) 45 | (assert_return (invoke "get-y") (i64.const 7)) 46 | (assert_return (invoke "get-5") (f32.const 8)) 47 | (assert_return (invoke "get-6") (f64.const 9)) 48 | 49 | (assert_invalid 50 | (module (global f32 (f32.const 0)) (func (set_global 0 (i32.const 1)))) 51 | "global is immutable" 52 | ) 53 | 54 | ;; mutable globals can be exported 55 | (module (global (mut f32) (f32.const 0)) (export "a" (global 0))) 56 | (module (global (export "a") (mut f32) (f32.const 0))) 57 | 58 | (assert_invalid 59 | (module (global f32 (f32.neg (f32.const 0)))) 60 | "constant expression required" 61 | ) 62 | 63 | (assert_invalid 64 | (module (global f32 (get_local 0))) 65 | "constant expression required" 66 | ) 67 | 68 | (assert_invalid 69 | (module (global f32 (f32.neg (f32.const 1)))) 70 | "constant expression required" 71 | ) 72 | 73 | (assert_invalid 74 | (module (global i32 (i32.const 0) (nop))) 75 | "constant expression required" 76 | ) 77 | 78 | (assert_invalid 79 | (module (global i32 (nop))) 80 | "constant expression required" 81 | ) 82 | 83 | (assert_invalid 84 | (module (global i32 (f32.const 0))) 85 | "type mismatch" 86 | ) 87 | 88 | (assert_invalid 89 | (module (global i32 (i32.const 0) (i32.const 0))) 90 | "type mismatch" 91 | ) 92 | 93 | (assert_invalid 94 | (module (global i32 (;empty instruction sequence;))) 95 | "type mismatch" 96 | ) 97 | 98 | (assert_invalid 99 | (module (global i32 (get_global 0))) 100 | "unknown global" 101 | ) 102 | 103 | (assert_invalid 104 | (module (global i32 (get_global 1)) (global i32 (i32.const 0))) 105 | "unknown global" 106 | ) 107 | 108 | (module 109 | (import "spectest" "global_i32" (global i32)) 110 | ) 111 | (assert_malformed 112 | (module binary 113 | "\00asm" "\01\00\00\00" 114 | "\02\94\80\80\80\00" ;; import section 115 | "\01" ;; length 1 116 | "\08\73\70\65\63\74\65\73\74" ;; "spectest" 117 | "\0a\67\6c\6f\62\61\6c\5f\69\33\32" ;; "global_i32" 118 | "\03" ;; GlobalImport 119 | "\7f" ;; i32 120 | "\02" ;; invalid mutability 121 | ) 122 | "invalid mutability" 123 | ) 124 | (assert_malformed 125 | (module binary 126 | "\00asm" "\01\00\00\00" 127 | "\02\94\80\80\80\00" ;; import section 128 | "\01" ;; length 1 129 | "\08\73\70\65\63\74\65\73\74" ;; "spectest" 130 | "\0a\67\6c\6f\62\61\6c\5f\69\33\32" ;; "global_i32" 131 | "\03" ;; GlobalImport 132 | "\7f" ;; i32 133 | "\ff" ;; invalid mutability 134 | ) 135 | "invalid mutability" 136 | ) 137 | 138 | (module 139 | (global i32 (i32.const 0)) 140 | ) 141 | (assert_malformed 142 | (module binary 143 | "\00asm" "\01\00\00\00" 144 | "\06\86\80\80\80\00" ;; global section 145 | "\01" ;; length 1 146 | "\7f" ;; i32 147 | "\02" ;; invalid mutability 148 | "\41\00" ;; i32.const 0 149 | "\0b" ;; end 150 | ) 151 | "invalid mutability" 152 | ) 153 | (assert_malformed 154 | (module binary 155 | "\00asm" "\01\00\00\00" 156 | "\06\86\80\80\80\00" ;; global section 157 | "\01" ;; length 1 158 | "\7f" ;; i32 159 | "\ff" ;; invalid mutability 160 | "\41\00" ;; i32.const 0 161 | "\0b" ;; end 162 | ) 163 | "invalid mutability" 164 | ) 165 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/proposals/threads/exports.wast: -------------------------------------------------------------------------------- 1 | ;; Functions 2 | 3 | (module (func) (export "a" (func 0))) 4 | (module (func) (export "a" (func 0)) (export "b" (func 0))) 5 | (module (func) (func) (export "a" (func 0)) (export "b" (func 1))) 6 | 7 | (module (func (export "a"))) 8 | (module (func (export "a") (export "b") (export "c"))) 9 | (module (func (export "a") (export "b") (param i32))) 10 | (module (func) (export "a" (func 0))) 11 | (module (func $a (export "a"))) 12 | (module (func $a) (export "a" (func $a))) 13 | (module (export "a" (func 0)) (func)) 14 | (module (export "a" (func $a)) (func $a)) 15 | 16 | (module $Func 17 | (export "e" (func $f)) 18 | (func $f (param $n i32) (result i32) 19 | (return (i32.add (get_local $n) (i32.const 1))) 20 | ) 21 | ) 22 | (assert_return (invoke "e" (i32.const 42)) (i32.const 43)) 23 | (assert_return (invoke $Func "e" (i32.const 42)) (i32.const 43)) 24 | (module) 25 | (module $Other1) 26 | (assert_return (invoke $Func "e" (i32.const 42)) (i32.const 43)) 27 | 28 | (assert_invalid 29 | (module (func) (export "a" (func 1))) 30 | "unknown function" 31 | ) 32 | (assert_invalid 33 | (module (func) (export "a" (func 0)) (export "a" (func 0))) 34 | "duplicate export name" 35 | ) 36 | (assert_invalid 37 | (module (func) (func) (export "a" (func 0)) (export "a" (func 1))) 38 | "duplicate export name" 39 | ) 40 | (assert_invalid 41 | (module (func) (global i32 (i32.const 0)) (export "a" (func 0)) (export "a" (global 0))) 42 | "duplicate export name" 43 | ) 44 | (assert_invalid 45 | (module (func) (table 0 anyfunc) (export "a" (func 0)) (export "a" (table 0))) 46 | "duplicate export name" 47 | ) 48 | (assert_invalid 49 | (module (func) (memory 0) (export "a" (func 0)) (export "a" (memory 0))) 50 | "duplicate export name" 51 | ) 52 | 53 | 54 | ;; Globals 55 | 56 | (module (global i32 (i32.const 0)) (export "a" (global 0))) 57 | (module (global i32 (i32.const 0)) (export "a" (global 0)) (export "b" (global 0))) 58 | (module (global i32 (i32.const 0)) (global i32 (i32.const 0)) (export "a" (global 0)) (export "b" (global 1))) 59 | 60 | (module (global (export "a") i32 (i32.const 0))) 61 | (module (global i32 (i32.const 0)) (export "a" (global 0))) 62 | (module (global $a (export "a") i32 (i32.const 0))) 63 | (module (global $a i32 (i32.const 0)) (export "a" (global $a))) 64 | (module (export "a" (global 0)) (global i32 (i32.const 0))) 65 | (module (export "a" (global $a)) (global $a i32 (i32.const 0))) 66 | 67 | (module $Global 68 | (export "e" (global $g)) 69 | (global $g i32 (i32.const 42)) 70 | ) 71 | (assert_return (get "e") (i32.const 42)) 72 | (assert_return (get $Global "e") (i32.const 42)) 73 | (module) 74 | (module $Other2) 75 | (assert_return (get $Global "e") (i32.const 42)) 76 | 77 | (assert_invalid 78 | (module (global i32 (i32.const 0)) (export "a" (global 1))) 79 | "unknown global" 80 | ) 81 | (assert_invalid 82 | (module (global i32 (i32.const 0)) (export "a" (global 0)) (export "a" (global 0))) 83 | "duplicate export name" 84 | ) 85 | (assert_invalid 86 | (module (global i32 (i32.const 0)) (global i32 (i32.const 0)) (export "a" (global 0)) (export "a" (global 1))) 87 | "duplicate export name" 88 | ) 89 | (assert_invalid 90 | (module (global i32 (i32.const 0)) (func) (export "a" (global 0)) (export "a" (func 0))) 91 | "duplicate export name" 92 | ) 93 | (assert_invalid 94 | (module (global i32 (i32.const 0)) (table 0 anyfunc) (export "a" (global 0)) (export "a" (table 0))) 95 | "duplicate export name" 96 | ) 97 | (assert_invalid 98 | (module (global i32 (i32.const 0)) (memory 0) (export "a" (global 0)) (export "a" (memory 0))) 99 | "duplicate export name" 100 | ) 101 | 102 | 103 | ;; Tables 104 | 105 | (module (table 0 anyfunc) (export "a" (table 0))) 106 | (module (table 0 anyfunc) (export "a" (table 0)) (export "b" (table 0))) 107 | ;; No multiple tables yet. 108 | ;; (module (table 0 anyfunc) (table 0 anyfunc) (export "a" (table 0)) (export "b" (table 1))) 109 | 110 | (module (table (export "a") 0 anyfunc)) 111 | (module (table (export "a") 0 1 anyfunc)) 112 | (module (table 0 anyfunc) (export "a" (table 0))) 113 | (module (table 0 1 anyfunc) (export "a" (table 0))) 114 | (module (table $a (export "a") 0 anyfunc)) 115 | (module (table $a (export "a") 0 1 anyfunc)) 116 | (module (table $a 0 anyfunc) (export "a" (table $a))) 117 | (module (table $a 0 1 anyfunc) (export "a" (table $a))) 118 | (module (export "a" (table 0)) (table 0 anyfunc)) 119 | (module (export "a" (table 0)) (table 0 1 anyfunc)) 120 | (module (export "a" (table $a)) (table $a 0 anyfunc)) 121 | (module (export "a" (table $a)) (table $a 0 1 anyfunc)) 122 | 123 | (; TODO: access table ;) 124 | 125 | (assert_invalid 126 | (module (table 0 anyfunc) (export "a" (table 1))) 127 | "unknown table" 128 | ) 129 | (assert_invalid 130 | (module (table 0 anyfunc) (export "a" (table 0)) (export "a" (table 0))) 131 | "duplicate export name" 132 | ) 133 | ;; No multiple tables yet. 134 | ;; (assert_invalid 135 | ;; (module (table 0 anyfunc) (table 0 anyfunc) (export "a" (table 0)) (export "a" (table 1))) 136 | ;; "duplicate export name" 137 | ;; ) 138 | (assert_invalid 139 | (module (table 0 anyfunc) (func) (export "a" (table 0)) (export "a" (func 0))) 140 | "duplicate export name" 141 | ) 142 | (assert_invalid 143 | (module (table 0 anyfunc) (global i32 (i32.const 0)) (export "a" (table 0)) (export "a" (global 0))) 144 | "duplicate export name" 145 | ) 146 | (assert_invalid 147 | (module (table 0 anyfunc) (memory 0) (export "a" (table 0)) (export "a" (memory 0))) 148 | "duplicate export name" 149 | ) 150 | 151 | 152 | ;; Memories 153 | 154 | (module (memory 0) (export "a" (memory 0))) 155 | (module (memory 0) (export "a" (memory 0)) (export "b" (memory 0))) 156 | ;; No multiple memories yet. 157 | ;; (module (memory 0) (memory 0) (export "a" (memory 0)) (export "b" (memory 1))) 158 | 159 | (module (memory (export "a") 0)) 160 | (module (memory (export "a") 0 1)) 161 | (module (memory 0) (export "a" (memory 0))) 162 | (module (memory 0 1) (export "a" (memory 0))) 163 | (module (memory $a (export "a") 0)) 164 | (module (memory $a (export "a") 0 1)) 165 | (module (memory $a 0) (export "a" (memory $a))) 166 | (module (memory $a 0 1) (export "a" (memory $a))) 167 | (module (export "a" (memory 0)) (memory 0)) 168 | (module (export "a" (memory 0)) (memory 0 1)) 169 | (module (export "a" (memory $a)) (memory $a 0)) 170 | (module (export "a" (memory $a)) (memory $a 0 1)) 171 | 172 | (module (memory (export "a") 0 1 shared)) 173 | (module (memory 0 1 shared) (export "a" (memory 0))) 174 | (module (memory $a (export "a") 0 1 shared)) 175 | (module (memory $a 0 1 shared) (export "a" (memory $a))) 176 | (module (export "a" (memory 0)) (memory 0 1 shared)) 177 | (module (export "a" (memory $a)) (memory $a 0 1 shared)) 178 | 179 | (; TODO: access memory ;) 180 | 181 | (assert_invalid 182 | (module (memory 0) (export "a" (memory 1))) 183 | "unknown memory" 184 | ) 185 | (assert_invalid 186 | (module (memory 0) (export "a" (memory 0)) (export "a" (memory 0))) 187 | "duplicate export name" 188 | ) 189 | ;; No multiple memories yet. 190 | ;; (assert_invalid 191 | ;; (module (memory 0) (memory 0) (export "a" (memory 0)) (export "a" (memory 1))) 192 | ;; "duplicate export name" 193 | ;; ) 194 | (assert_invalid 195 | (module (memory 0) (func) (export "a" (memory 0)) (export "a" (func 0))) 196 | "duplicate export name" 197 | ) 198 | (assert_invalid 199 | (module (memory 0) (global i32 (i32.const 0)) (export "a" (memory 0)) (export "a" (global 0))) 200 | "duplicate export name" 201 | ) 202 | (assert_invalid 203 | (module (memory 0) (table 0 anyfunc) (export "a" (memory 0)) (export "a" (table 0))) 204 | "duplicate export name" 205 | ) 206 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/resizing.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory 0) 3 | 4 | (func (export "load_at_zero") (result i32) (i32.load (i32.const 0))) 5 | (func (export "store_at_zero") (i32.store (i32.const 0) (i32.const 2))) 6 | 7 | (func (export "load_at_page_size") (result i32) (i32.load (i32.const 0x10000))) 8 | (func (export "store_at_page_size") (i32.store (i32.const 0x10000) (i32.const 3))) 9 | 10 | (func (export "grow") (param $sz i32) (result i32) (memory.grow (get_local $sz))) 11 | (func (export "size") (result i32) (memory.size)) 12 | ) 13 | 14 | (assert_return (invoke "size") (i32.const 0)) 15 | (assert_trap (invoke "store_at_zero") "out of bounds memory access") 16 | (assert_trap (invoke "load_at_zero") "out of bounds memory access") 17 | (assert_trap (invoke "store_at_page_size") "out of bounds memory access") 18 | (assert_trap (invoke "load_at_page_size") "out of bounds memory access") 19 | (assert_return (invoke "grow" (i32.const 1)) (i32.const 0)) 20 | (assert_return (invoke "size") (i32.const 1)) 21 | (assert_return (invoke "load_at_zero") (i32.const 0)) 22 | (assert_return (invoke "store_at_zero")) 23 | (assert_return (invoke "load_at_zero") (i32.const 2)) 24 | (assert_trap (invoke "store_at_page_size") "out of bounds memory access") 25 | (assert_trap (invoke "load_at_page_size") "out of bounds memory access") 26 | (assert_return (invoke "grow" (i32.const 4)) (i32.const 1)) 27 | (assert_return (invoke "size") (i32.const 5)) 28 | (assert_return (invoke "load_at_zero") (i32.const 2)) 29 | (assert_return (invoke "store_at_zero")) 30 | (assert_return (invoke "load_at_zero") (i32.const 2)) 31 | (assert_return (invoke "load_at_page_size") (i32.const 0)) 32 | (assert_return (invoke "store_at_page_size")) 33 | (assert_return (invoke "load_at_page_size") (i32.const 3)) 34 | 35 | 36 | (module 37 | (memory 0) 38 | (func (export "grow") (param i32) (result i32) (memory.grow (get_local 0))) 39 | ) 40 | 41 | (assert_return (invoke "grow" (i32.const 0)) (i32.const 0)) 42 | (assert_return (invoke "grow" (i32.const 1)) (i32.const 0)) 43 | (assert_return (invoke "grow" (i32.const 0)) (i32.const 1)) 44 | (assert_return (invoke "grow" (i32.const 2)) (i32.const 1)) 45 | (assert_return (invoke "grow" (i32.const 800)) (i32.const 3)) 46 | (assert_return (invoke "grow" (i32.const 0x10000)) (i32.const -1)) 47 | 48 | (module 49 | (memory 0 10) 50 | (func (export "grow") (param i32) (result i32) (memory.grow (get_local 0))) 51 | ) 52 | 53 | (assert_return (invoke "grow" (i32.const 0)) (i32.const 0)) 54 | (assert_return (invoke "grow" (i32.const 1)) (i32.const 0)) 55 | (assert_return (invoke "grow" (i32.const 1)) (i32.const 1)) 56 | (assert_return (invoke "grow" (i32.const 2)) (i32.const 2)) 57 | (assert_return (invoke "grow" (i32.const 6)) (i32.const 4)) 58 | (assert_return (invoke "grow" (i32.const 0)) (i32.const 10)) 59 | (assert_return (invoke "grow" (i32.const 1)) (i32.const -1)) 60 | (assert_return (invoke "grow" (i32.const 0x10000)) (i32.const -1)) 61 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/run.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from __future__ import print_function 4 | import argparse 5 | import os 6 | import os.path 7 | import unittest 8 | import subprocess 9 | import glob 10 | import sys 11 | 12 | 13 | ownDir = os.path.dirname(os.path.abspath(sys.argv[0])) 14 | inputDir = ownDir 15 | outputDir = os.path.join(inputDir, "_output") 16 | 17 | parser = argparse.ArgumentParser() 18 | parser.add_argument("--wasm", metavar="", default=os.path.join(os.getcwd(), "wasm")) 19 | parser.add_argument("--js", metavar="") 20 | parser.add_argument("--out", metavar="", default=outputDir) 21 | parser.add_argument("file", nargs='*') 22 | arguments = parser.parse_args() 23 | sys.argv = sys.argv[:1] 24 | 25 | wasmCommand = arguments.wasm 26 | jsCommand = arguments.js 27 | outputDir = arguments.out 28 | inputFiles = arguments.file if arguments.file else glob.glob(os.path.join(inputDir, "*.wast")) 29 | 30 | 31 | class RunTests(unittest.TestCase): 32 | def _runCommand(self, command, logPath, expectedExitCode = 0): 33 | with open(logPath, 'w+') as out: 34 | exitCode = subprocess.call(command, shell=True, stdout=out, stderr=subprocess.STDOUT) 35 | self.assertEqual(expectedExitCode, exitCode, "failed with exit code %i (expected %i) for %s" % (exitCode, expectedExitCode, command)) 36 | 37 | def _auxFile(self, path): 38 | if os.path.exists(path): 39 | os.remove(path) 40 | return path 41 | 42 | def _compareFile(self, expectFile, actualFile): 43 | if os.path.exists(expectFile): 44 | with open(expectFile) as expect: 45 | with open(actualFile) as actual: 46 | expectText = expect.read() 47 | actualText = actual.read() 48 | self.assertEqual(expectText, actualText) 49 | 50 | def _runTestFile(self, inputPath): 51 | dir, inputFile = os.path.split(inputPath) 52 | outputPath = os.path.join(outputDir, inputFile) 53 | 54 | # Run original file 55 | expectedExitCode = 1 if ".fail." in inputFile else 0 56 | logPath = self._auxFile(outputPath + ".log") 57 | self._runCommand(('%s "%s"') % (wasmCommand, inputPath), logPath, expectedExitCode) 58 | 59 | if expectedExitCode != 0: 60 | return 61 | 62 | # Convert to binary and validate again 63 | wasmPath = self._auxFile(outputPath + ".bin.wast") 64 | logPath = self._auxFile(wasmPath + ".log") 65 | self._runCommand(('%s -d "%s" -o "%s"') % (wasmCommand, inputPath, wasmPath), logPath) 66 | self._runCommand(('%s -d "%s"') % (wasmCommand, wasmPath), logPath) 67 | 68 | # Convert back to text and validate again 69 | wastPath = self._auxFile(wasmPath + ".wast") 70 | logPath = self._auxFile(wastPath + ".log") 71 | self._runCommand(('%s -d "%s" -o "%s"') % (wasmCommand, wasmPath, wastPath), logPath) 72 | self._runCommand(('%s -d "%s" ') % (wasmCommand, wastPath), logPath) 73 | 74 | # Convert back to binary once more and compare 75 | wasm2Path = self._auxFile(wastPath + ".bin.wast") 76 | logPath = self._auxFile(wasm2Path + ".log") 77 | self._runCommand(('%s -d "%s" -o "%s"') % (wasmCommand, wastPath, wasm2Path), logPath) 78 | self._runCommand(('%s -d "%s"') % (wasmCommand, wasm2Path), logPath) 79 | # TODO: The binary should stay the same, but OCaml's float-string conversions are inaccurate. 80 | # Once we upgrade to OCaml 4.03, use sprintf "%s" for printing floats. 81 | # self._compareFile(wasmPath, wasm2Path) 82 | 83 | # Convert to JavaScript 84 | jsPath = self._auxFile(outputPath.replace(".wast", ".js")) 85 | logPath = self._auxFile(jsPath + ".log") 86 | self._runCommand(('%s -d "%s" -o "%s"') % (wasmCommand, inputPath, jsPath), logPath) 87 | if jsCommand != None: 88 | self._runCommand(('%s "%s"') % (jsCommand, jsPath), logPath) 89 | 90 | 91 | if __name__ == "__main__": 92 | if not os.path.exists(outputDir): 93 | os.makedirs(outputDir) 94 | for fileName in inputFiles: 95 | testName = 'test ' + os.path.basename(fileName) 96 | setattr(RunTests, testName, lambda self, file=fileName: self._runTestFile(file)) 97 | unittest.main() 98 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/select.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "select_i32") (param $lhs i32) (param $rhs i32) (param $cond i32) (result i32) 3 | (select (get_local $lhs) (get_local $rhs) (get_local $cond))) 4 | 5 | (func (export "select_i64") (param $lhs i64) (param $rhs i64) (param $cond i32) (result i64) 6 | (select (get_local $lhs) (get_local $rhs) (get_local $cond))) 7 | 8 | (func (export "select_f32") (param $lhs f32) (param $rhs f32) (param $cond i32) (result f32) 9 | (select (get_local $lhs) (get_local $rhs) (get_local $cond))) 10 | 11 | (func (export "select_f64") (param $lhs f64) (param $rhs f64) (param $cond i32) (result f64) 12 | (select (get_local $lhs) (get_local $rhs) (get_local $cond))) 13 | 14 | ;; Check that both sides of the select are evaluated 15 | (func (export "select_trap_l") (param $cond i32) (result i32) 16 | (select (unreachable) (i32.const 0) (get_local $cond)) 17 | ) 18 | (func (export "select_trap_r") (param $cond i32) (result i32) 19 | (select (i32.const 0) (unreachable) (get_local $cond)) 20 | ) 21 | 22 | (func (export "select_unreached") 23 | (unreachable) (select) 24 | (unreachable) (i32.const 0) (select) 25 | (unreachable) (i32.const 0) (i32.const 0) (select) 26 | (unreachable) (f32.const 0) (i32.const 0) (select) 27 | (unreachable) 28 | ) 29 | ) 30 | 31 | (assert_return (invoke "select_i32" (i32.const 1) (i32.const 2) (i32.const 1)) (i32.const 1)) 32 | (assert_return (invoke "select_i64" (i64.const 2) (i64.const 1) (i32.const 1)) (i64.const 2)) 33 | (assert_return (invoke "select_f32" (f32.const 1) (f32.const 2) (i32.const 1)) (f32.const 1)) 34 | (assert_return (invoke "select_f64" (f64.const 1) (f64.const 2) (i32.const 1)) (f64.const 1)) 35 | 36 | (assert_return (invoke "select_i32" (i32.const 1) (i32.const 2) (i32.const 0)) (i32.const 2)) 37 | (assert_return (invoke "select_i32" (i32.const 2) (i32.const 1) (i32.const 0)) (i32.const 1)) 38 | (assert_return (invoke "select_i64" (i64.const 2) (i64.const 1) (i32.const -1)) (i64.const 2)) 39 | (assert_return (invoke "select_i64" (i64.const 2) (i64.const 1) (i32.const 0xf0f0f0f0)) (i64.const 2)) 40 | 41 | (assert_return (invoke "select_f32" (f32.const nan) (f32.const 1) (i32.const 1)) (f32.const nan)) 42 | (assert_return (invoke "select_f32" (f32.const nan:0x20304) (f32.const 1) (i32.const 1)) (f32.const nan:0x20304)) 43 | (assert_return (invoke "select_f32" (f32.const nan) (f32.const 1) (i32.const 0)) (f32.const 1)) 44 | (assert_return (invoke "select_f32" (f32.const nan:0x20304) (f32.const 1) (i32.const 0)) (f32.const 1)) 45 | (assert_return (invoke "select_f32" (f32.const 2) (f32.const nan) (i32.const 1)) (f32.const 2)) 46 | (assert_return (invoke "select_f32" (f32.const 2) (f32.const nan:0x20304) (i32.const 1)) (f32.const 2)) 47 | (assert_return (invoke "select_f32" (f32.const 2) (f32.const nan) (i32.const 0)) (f32.const nan)) 48 | (assert_return (invoke "select_f32" (f32.const 2) (f32.const nan:0x20304) (i32.const 0)) (f32.const nan:0x20304)) 49 | 50 | (assert_return (invoke "select_f64" (f64.const nan) (f64.const 1) (i32.const 1)) (f64.const nan)) 51 | (assert_return (invoke "select_f64" (f64.const nan:0x20304) (f64.const 1) (i32.const 1)) (f64.const nan:0x20304)) 52 | (assert_return (invoke "select_f64" (f64.const nan) (f64.const 1) (i32.const 0)) (f64.const 1)) 53 | (assert_return (invoke "select_f64" (f64.const nan:0x20304) (f64.const 1) (i32.const 0)) (f64.const 1)) 54 | (assert_return (invoke "select_f64" (f64.const 2) (f64.const nan) (i32.const 1)) (f64.const 2)) 55 | (assert_return (invoke "select_f64" (f64.const 2) (f64.const nan:0x20304) (i32.const 1)) (f64.const 2)) 56 | (assert_return (invoke "select_f64" (f64.const 2) (f64.const nan) (i32.const 0)) (f64.const nan)) 57 | (assert_return (invoke "select_f64" (f64.const 2) (f64.const nan:0x20304) (i32.const 0)) (f64.const nan:0x20304)) 58 | 59 | (assert_trap (invoke "select_trap_l" (i32.const 1)) "unreachable executed") 60 | (assert_trap (invoke "select_trap_l" (i32.const 0)) "unreachable executed") 61 | (assert_trap (invoke "select_trap_r" (i32.const 1)) "unreachable executed") 62 | (assert_trap (invoke "select_trap_r" (i32.const 0)) "unreachable executed") 63 | 64 | (assert_invalid 65 | (module (func $arity-0 (select (nop) (nop) (i32.const 1)))) 66 | "type mismatch" 67 | ) 68 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/set_local.wast: -------------------------------------------------------------------------------- 1 | ;; Test `set_local` operator 2 | 3 | (module 4 | ;; Typing 5 | 6 | (func (export "type-local-i32") (local i32) (set_local 0 (i32.const 0))) 7 | (func (export "type-local-i64") (local i64) (set_local 0 (i64.const 0))) 8 | (func (export "type-local-f32") (local f32) (set_local 0 (f32.const 0))) 9 | (func (export "type-local-f64") (local f64) (set_local 0 (f64.const 0))) 10 | 11 | (func (export "type-param-i32") (param i32) (set_local 0 (i32.const 10))) 12 | (func (export "type-param-i64") (param i64) (set_local 0 (i64.const 11))) 13 | (func (export "type-param-f32") (param f32) (set_local 0 (f32.const 11.1))) 14 | (func (export "type-param-f64") (param f64) (set_local 0 (f64.const 12.2))) 15 | 16 | (func (export "type-mixed") (param i64 f32 f64 i32 i32) (local f32 i64 i64 f64) 17 | (set_local 0 (i64.const 0)) 18 | (set_local 1 (f32.const 0)) 19 | (set_local 2 (f64.const 0)) 20 | (set_local 3 (i32.const 0)) 21 | (set_local 4 (i32.const 0)) 22 | (set_local 5 (f32.const 0)) 23 | (set_local 6 (i64.const 0)) 24 | (set_local 7 (i64.const 0)) 25 | (set_local 8 (f64.const 0)) 26 | ) 27 | 28 | ;; Writing 29 | 30 | (func (export "write") (param i64 f32 f64 i32 i32) (result i64) 31 | (local f32 i64 i64 f64) 32 | (set_local 1 (f32.const -0.3)) 33 | (set_local 3 (i32.const 40)) 34 | (set_local 4 (i32.const -7)) 35 | (set_local 5 (f32.const 5.5)) 36 | (set_local 6 (i64.const 6)) 37 | (set_local 8 (f64.const 8)) 38 | (i64.trunc_s/f64 39 | (f64.add 40 | (f64.convert_u/i64 (get_local 0)) 41 | (f64.add 42 | (f64.promote/f32 (get_local 1)) 43 | (f64.add 44 | (get_local 2) 45 | (f64.add 46 | (f64.convert_u/i32 (get_local 3)) 47 | (f64.add 48 | (f64.convert_s/i32 (get_local 4)) 49 | (f64.add 50 | (f64.promote/f32 (get_local 5)) 51 | (f64.add 52 | (f64.convert_u/i64 (get_local 6)) 53 | (f64.add 54 | (f64.convert_u/i64 (get_local 7)) 55 | (get_local 8) 56 | ) 57 | ) 58 | ) 59 | ) 60 | ) 61 | ) 62 | ) 63 | ) 64 | ) 65 | ) 66 | ) 67 | 68 | (assert_return (invoke "type-local-i32")) 69 | (assert_return (invoke "type-local-i64")) 70 | (assert_return (invoke "type-local-f32")) 71 | (assert_return (invoke "type-local-f64")) 72 | 73 | (assert_return (invoke "type-param-i32" (i32.const 2))) 74 | (assert_return (invoke "type-param-i64" (i64.const 3))) 75 | (assert_return (invoke "type-param-f32" (f32.const 4.4))) 76 | (assert_return (invoke "type-param-f64" (f64.const 5.5))) 77 | 78 | (assert_return 79 | (invoke "type-mixed" 80 | (i64.const 1) (f32.const 2.2) (f64.const 3.3) (i32.const 4) (i32.const 5) 81 | ) 82 | ) 83 | 84 | (assert_return 85 | (invoke "write" 86 | (i64.const 1) (f32.const 2) (f64.const 3.3) (i32.const 4) (i32.const 5) 87 | ) 88 | (i64.const 56) 89 | ) 90 | 91 | 92 | ;; Invalid typing of access to locals 93 | 94 | (assert_invalid 95 | (module (func $type-local-num-vs-num (result i64) (local i32) 96 | (set_local 0 (i32.const 0)) 97 | )) 98 | "type mismatch" 99 | ) 100 | (assert_invalid 101 | (module (func $type-local-num-vs-num (local f32) 102 | (i32.eqz (set_local 0 (f32.const 0))) 103 | )) 104 | "type mismatch" 105 | ) 106 | (assert_invalid 107 | (module (func $type-local-num-vs-num (local f64 i64) 108 | (f64.neg (set_local 1 (i64.const 0))) 109 | )) 110 | "type mismatch" 111 | ) 112 | 113 | (assert_invalid 114 | (module (func $type-local-arg-void-vs-num (local i32) (set_local 0 (nop)))) 115 | "type mismatch" 116 | ) 117 | (assert_invalid 118 | (module (func $type-local-arg-num-vs-num (local i32) (set_local 0 (f32.const 0)))) 119 | "type mismatch" 120 | ) 121 | (assert_invalid 122 | (module (func $type-local-arg-num-vs-num (local f32) (set_local 0 (f64.const 0)))) 123 | "type mismatch" 124 | ) 125 | (assert_invalid 126 | (module (func $type-local-arg-num-vs-num (local f64 i64) (set_local 1 (f64.const 0)))) 127 | "type mismatch" 128 | ) 129 | 130 | 131 | ;; Invalid typing of access to parameters 132 | 133 | (assert_invalid 134 | (module (func $type-param-num-vs-num (param i32) (result i64) (get_local 0))) 135 | "type mismatch" 136 | ) 137 | (assert_invalid 138 | (module (func $type-param-num-vs-num (param f32) (i32.eqz (get_local 0)))) 139 | "type mismatch" 140 | ) 141 | (assert_invalid 142 | (module (func $type-param-num-vs-num (param f64 i64) (f64.neg (get_local 1)))) 143 | "type mismatch" 144 | ) 145 | 146 | (assert_invalid 147 | (module (func $type-param-arg-void-vs-num (param i32) (set_local 0 (nop)))) 148 | "type mismatch" 149 | ) 150 | (assert_invalid 151 | (module (func $type-param-arg-num-vs-num (param i32) (set_local 0 (f32.const 0)))) 152 | "type mismatch" 153 | ) 154 | (assert_invalid 155 | (module (func $type-param-arg-num-vs-num (param f32) (set_local 0 (f64.const 0)))) 156 | "type mismatch" 157 | ) 158 | (assert_invalid 159 | (module (func $type-param-arg-num-vs-num (param f64 i64) (set_local 1 (f64.const 0)))) 160 | "type mismatch" 161 | ) 162 | 163 | 164 | ;; Invalid local index 165 | 166 | (assert_invalid 167 | (module (func $unbound-local (local i32 i64) (get_local 3))) 168 | "unknown local" 169 | ) 170 | (assert_invalid 171 | (module (func $large-local (local i32 i64) (get_local 14324343))) 172 | "unknown local" 173 | ) 174 | 175 | (assert_invalid 176 | (module (func $unbound-param (param i32 i64) (get_local 2))) 177 | "unknown local" 178 | ) 179 | (assert_invalid 180 | (module (func $large-param (local i32 i64) (get_local 714324343))) 181 | "unknown local" 182 | ) 183 | 184 | (assert_invalid 185 | (module (func $unbound-mixed (param i32) (local i32 i64) (get_local 3))) 186 | "unknown local" 187 | ) 188 | (assert_invalid 189 | (module (func $large-mixed (param i64) (local i32 i64) (get_local 214324343))) 190 | "unknown local" 191 | ) 192 | 193 | (assert_invalid 194 | (module (func $type-mixed-arg-num-vs-num (param f32) (local i32) (set_local 1 (f32.const 0)))) 195 | "type mismatch" 196 | ) 197 | (assert_invalid 198 | (module (func $type-mixed-arg-num-vs-num (param i64 i32) (local f32) (set_local 1 (f32.const 0)))) 199 | "type mismatch" 200 | ) 201 | (assert_invalid 202 | (module (func $type-mixed-arg-num-vs-num (param i64) (local f64 i64) (set_local 1 (i64.const 0)))) 203 | "type mismatch" 204 | ) 205 | 206 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/stack.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "fac-expr") (param $n i64) (result i64) 3 | (local $i i64) 4 | (local $res i64) 5 | (set_local $i (get_local $n)) 6 | (set_local $res (i64.const 1)) 7 | (block $done 8 | (loop $loop 9 | (if 10 | (i64.eq (get_local $i) (i64.const 0)) 11 | (then (br $done)) 12 | (else 13 | (set_local $res (i64.mul (get_local $i) (get_local $res))) 14 | (set_local $i (i64.sub (get_local $i) (i64.const 1))) 15 | ) 16 | ) 17 | (br $loop) 18 | ) 19 | ) 20 | (get_local $res) 21 | ) 22 | 23 | (func (export "fac-stack") (param $n i64) (result i64) 24 | (local $i i64) 25 | (local $res i64) 26 | (get_local $n) 27 | (set_local $i) 28 | (i64.const 1) 29 | (set_local $res) 30 | (block $done 31 | (loop $loop 32 | (get_local $i) 33 | (i64.const 0) 34 | (i64.eq) 35 | (if 36 | (then (br $done)) 37 | (else 38 | (get_local $i) 39 | (get_local $res) 40 | (i64.mul) 41 | (set_local $res) 42 | (get_local $i) 43 | (i64.const 1) 44 | (i64.sub) 45 | (set_local $i) 46 | ) 47 | ) 48 | (br $loop) 49 | ) 50 | ) 51 | (get_local $res) 52 | ) 53 | 54 | (func (export "fac-stack-raw") (param $n i64) (result i64) 55 | (local $i i64) 56 | (local $res i64) 57 | get_local $n 58 | set_local $i 59 | i64.const 1 60 | set_local $res 61 | block $done 62 | loop $loop 63 | get_local $i 64 | i64.const 0 65 | i64.eq 66 | if $body 67 | br $done 68 | else $body 69 | get_local $i 70 | get_local $res 71 | i64.mul 72 | set_local $res 73 | get_local $i 74 | i64.const 1 75 | i64.sub 76 | set_local $i 77 | end $body 78 | br $loop 79 | end $loop 80 | end $done 81 | get_local $res 82 | ) 83 | 84 | (func (export "fac-mixed") (param $n i64) (result i64) 85 | (local $i i64) 86 | (local $res i64) 87 | (set_local $i (get_local $n)) 88 | (set_local $res (i64.const 1)) 89 | (block $done 90 | (loop $loop 91 | (i64.eq (get_local $i) (i64.const 0)) 92 | (if 93 | (then (br $done)) 94 | (else 95 | (i64.mul (get_local $i) (get_local $res)) 96 | (set_local $res) 97 | (i64.sub (get_local $i) (i64.const 1)) 98 | (set_local $i) 99 | ) 100 | ) 101 | (br $loop) 102 | ) 103 | ) 104 | (get_local $res) 105 | ) 106 | 107 | (func (export "fac-mixed-raw") (param $n i64) (result i64) 108 | (local $i i64) 109 | (local $res i64) 110 | (set_local $i (get_local $n)) 111 | (set_local $res (i64.const 1)) 112 | block $done 113 | loop $loop 114 | (i64.eq (get_local $i) (i64.const 0)) 115 | if 116 | br $done 117 | else 118 | (i64.mul (get_local $i) (get_local $res)) 119 | set_local $res 120 | (i64.sub (get_local $i) (i64.const 1)) 121 | set_local $i 122 | end 123 | br $loop 124 | end 125 | end 126 | get_local $res 127 | ) 128 | ) 129 | 130 | (assert_return (invoke "fac-expr" (i64.const 25)) (i64.const 7034535277573963776)) 131 | (assert_return (invoke "fac-stack" (i64.const 25)) (i64.const 7034535277573963776)) 132 | (assert_return (invoke "fac-mixed" (i64.const 25)) (i64.const 7034535277573963776)) 133 | 134 | 135 | ;; Syntax of flat call_indirect 136 | 137 | (module 138 | (type $proc (func)) 139 | (table 1 anyfunc) 140 | 141 | (func 142 | (block i32.const 0 call_indirect) 143 | (loop i32.const 0 call_indirect) 144 | (if (i32.const 0) (then i32.const 0 call_indirect)) 145 | (if (i32.const 0) 146 | (then i32.const 0 call_indirect) 147 | (else i32.const 0 call_indirect) 148 | ) 149 | (block i32.const 0 call_indirect (type $proc)) 150 | (loop i32.const 0 call_indirect (type $proc)) 151 | (if (i32.const 0) (then i32.const 0 call_indirect (type $proc))) 152 | (if (i32.const 0) 153 | (then i32.const 0 call_indirect (type $proc)) 154 | (else i32.const 0 call_indirect (type $proc)) 155 | ) 156 | (block i32.const 0 i32.const 0 call_indirect (param i32)) 157 | (loop i32.const 0 i32.const 0 call_indirect (param i32)) 158 | (if (i32.const 0) (then i32.const 0 i32.const 0 call_indirect (param i32))) 159 | (if (i32.const 0) 160 | (then i32.const 0 i32.const 0 call_indirect (param i32)) 161 | (else i32.const 0 i32.const 0 call_indirect (param i32)) 162 | ) 163 | (block (result i32) i32.const 0 call_indirect (result i32)) (drop) 164 | (loop (result i32) i32.const 0 call_indirect (result i32)) (drop) 165 | (if (result i32) (i32.const 0) 166 | (then i32.const 0 call_indirect (result i32)) 167 | (else i32.const 0 call_indirect (result i32)) 168 | ) (drop) 169 | (block i32.const 0 call_indirect (type $proc) (param) (result)) 170 | (loop i32.const 0 call_indirect (type $proc) (param) (result)) 171 | (if (i32.const 0) 172 | (then i32.const 0 call_indirect (type $proc) (param) (result)) 173 | ) 174 | (if (i32.const 0) 175 | (then i32.const 0 call_indirect (type $proc) (param) (param) (result)) 176 | (else i32.const 0 call_indirect (type $proc) (param) (result) (result)) 177 | ) 178 | 179 | block i32.const 0 call_indirect end 180 | loop i32.const 0 call_indirect end 181 | i32.const 0 if i32.const 0 call_indirect end 182 | i32.const 0 if i32.const 0 call_indirect else i32.const 0 call_indirect end 183 | block i32.const 0 call_indirect (type $proc) end 184 | loop i32.const 0 call_indirect (type $proc) end 185 | i32.const 0 if i32.const 0 call_indirect (type $proc) end 186 | i32.const 0 187 | if 188 | i32.const 0 call_indirect (type $proc) 189 | else 190 | i32.const 0 call_indirect (type $proc) 191 | end 192 | block i32.const 0 i32.const 0 call_indirect (param i32) end 193 | loop i32.const 0 i32.const 0 call_indirect (param i32) end 194 | i32.const 0 if i32.const 0 i32.const 0 call_indirect (param i32) end 195 | i32.const 0 196 | if 197 | i32.const 0 i32.const 0 call_indirect (param i32) 198 | else 199 | i32.const 0 i32.const 0 call_indirect (param i32) 200 | end 201 | block (result i32) i32.const 0 call_indirect (result i32) end drop 202 | loop (result i32) i32.const 0 call_indirect (result i32) end drop 203 | i32.const 0 204 | if (result i32) 205 | i32.const 0 call_indirect (result i32) 206 | else 207 | i32.const 0 call_indirect (result i32) 208 | end drop 209 | block i32.const 0 call_indirect (type $proc) (param) (result) end 210 | loop i32.const 0 call_indirect (type $proc) (param) (result) end 211 | i32.const 0 if i32.const 0 call_indirect (type $proc) (param) (result) end 212 | i32.const 0 213 | if 214 | i32.const 0 call_indirect (type $proc) (param) (result) 215 | else 216 | i32.const 0 call_indirect (type $proc) (param) (param) (result) (result) 217 | end 218 | i32.const 0 call_indirect 219 | ) 220 | ) 221 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/start.wast: -------------------------------------------------------------------------------- 1 | (assert_invalid 2 | (module (func) (start 1)) 3 | "unknown function" 4 | ) 5 | 6 | (assert_invalid 7 | (module 8 | (func $main (result i32) (return (i32.const 0))) 9 | (start $main) 10 | ) 11 | "start function" 12 | ) 13 | (assert_invalid 14 | (module 15 | (func $main (param $a i32)) 16 | (start $main) 17 | ) 18 | "start function" 19 | ) 20 | 21 | (module 22 | (memory (data "A")) 23 | (func $inc 24 | (i32.store8 25 | (i32.const 0) 26 | (i32.add 27 | (i32.load8_u (i32.const 0)) 28 | (i32.const 1) 29 | ) 30 | ) 31 | ) 32 | (func $get (result i32) 33 | (return (i32.load8_u (i32.const 0))) 34 | ) 35 | (func $main 36 | (call $inc) 37 | (call $inc) 38 | (call $inc) 39 | ) 40 | 41 | (start $main) 42 | (export "inc" (func $inc)) 43 | (export "get" (func $get)) 44 | ) 45 | (assert_return (invoke "get") (i32.const 68)) 46 | (invoke "inc") 47 | (assert_return (invoke "get") (i32.const 69)) 48 | (invoke "inc") 49 | (assert_return (invoke "get") (i32.const 70)) 50 | 51 | (module 52 | (memory (data "A")) 53 | (func $inc 54 | (i32.store8 55 | (i32.const 0) 56 | (i32.add 57 | (i32.load8_u (i32.const 0)) 58 | (i32.const 1) 59 | ) 60 | ) 61 | ) 62 | (func $get (result i32) 63 | (return (i32.load8_u (i32.const 0))) 64 | ) 65 | (func $main 66 | (call $inc) 67 | (call $inc) 68 | (call $inc) 69 | ) 70 | (start 2) 71 | (export "inc" (func $inc)) 72 | (export "get" (func $get)) 73 | ) 74 | (assert_return (invoke "get") (i32.const 68)) 75 | (invoke "inc") 76 | (assert_return (invoke "get") (i32.const 69)) 77 | (invoke "inc") 78 | (assert_return (invoke "get") (i32.const 70)) 79 | 80 | (module 81 | (func $print_i32 (import "spectest" "print_i32") (param i32)) 82 | (func $main (call $print_i32 (i32.const 1))) 83 | (start 1) 84 | ) 85 | 86 | (module 87 | (func $print_i32 (import "spectest" "print_i32") (param i32)) 88 | (func $main (call $print_i32 (i32.const 2))) 89 | (start $main) 90 | ) 91 | 92 | (module 93 | (func $print (import "spectest" "print")) 94 | (start $print) 95 | ) 96 | 97 | (assert_trap 98 | (module (func $main (unreachable)) (start $main)) 99 | "unreachable" 100 | ) 101 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/store_retval.wast: -------------------------------------------------------------------------------- 1 | (assert_invalid 2 | (module (func (param i32) (result i32) (set_local 0 (i32.const 1)))) 3 | "type mismatch" 4 | ) 5 | (assert_invalid 6 | (module (func (param i64) (result i64) (set_local 0 (i64.const 1)))) 7 | "type mismatch" 8 | ) 9 | (assert_invalid 10 | (module (func (param f32) (result f32) (set_local 0 (f32.const 1)))) 11 | "type mismatch" 12 | ) 13 | (assert_invalid 14 | (module (func (param f64) (result f64) (set_local 0 (f64.const 1)))) 15 | "type mismatch" 16 | ) 17 | 18 | (assert_invalid 19 | (module (memory 1) (func (param i32) (result i32) (i32.store (i32.const 0) (i32.const 1)))) 20 | "type mismatch" 21 | ) 22 | (assert_invalid 23 | (module (memory 1) (func (param i64) (result i64) (i64.store (i32.const 0) (i64.const 1)))) 24 | "type mismatch" 25 | ) 26 | (assert_invalid 27 | (module (memory 1) (func (param f32) (result f32) (f32.store (i32.const 0) (f32.const 1)))) 28 | "type mismatch" 29 | ) 30 | (assert_invalid 31 | (module (memory 1) (func (param f64) (result f64) (f64.store (i32.const 0) (f64.const 1)))) 32 | "type mismatch" 33 | ) 34 | 35 | (assert_invalid 36 | (module (memory 1) (func (param i32) (result i32) (i32.store8 (i32.const 0) (i32.const 1)))) 37 | "type mismatch" 38 | ) 39 | (assert_invalid 40 | (module (memory 1) (func (param i32) (result i32) (i32.store16 (i32.const 0) (i32.const 1)))) 41 | "type mismatch" 42 | ) 43 | (assert_invalid 44 | (module (memory 1) (func (param i64) (result i64) (i64.store8 (i32.const 0) (i64.const 1)))) 45 | "type mismatch" 46 | ) 47 | (assert_invalid 48 | (module (memory 1) (func (param i64) (result i64) (i64.store16 (i32.const 0) (i64.const 1)))) 49 | "type mismatch" 50 | ) 51 | (assert_invalid 52 | (module (memory 1) (func (param i64) (result i64) (i64.store32 (i32.const 0) (i64.const 1)))) 53 | "type mismatch" 54 | ) 55 | 56 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/switch.wast: -------------------------------------------------------------------------------- 1 | (module 2 | ;; Statement switch 3 | (func (export "stmt") (param $i i32) (result i32) 4 | (local $j i32) 5 | (set_local $j (i32.const 100)) 6 | (block $switch 7 | (block $7 8 | (block $default 9 | (block $6 10 | (block $5 11 | (block $4 12 | (block $3 13 | (block $2 14 | (block $1 15 | (block $0 16 | (br_table $0 $1 $2 $3 $4 $5 $6 $7 $default 17 | (get_local $i) 18 | ) 19 | ) ;; 0 20 | (return (get_local $i)) 21 | ) ;; 1 22 | (nop) 23 | ;; fallthrough 24 | ) ;; 2 25 | ;; fallthrough 26 | ) ;; 3 27 | (set_local $j (i32.sub (i32.const 0) (get_local $i))) 28 | (br $switch) 29 | ) ;; 4 30 | (br $switch) 31 | ) ;; 5 32 | (set_local $j (i32.const 101)) 33 | (br $switch) 34 | ) ;; 6 35 | (set_local $j (i32.const 101)) 36 | ;; fallthrough 37 | ) ;; default 38 | (set_local $j (i32.const 102)) 39 | ) ;; 7 40 | ;; fallthrough 41 | ) 42 | (return (get_local $j)) 43 | ) 44 | 45 | ;; Expression switch 46 | (func (export "expr") (param $i i64) (result i64) 47 | (local $j i64) 48 | (set_local $j (i64.const 100)) 49 | (return 50 | (block $switch (result i64) 51 | (block $7 52 | (block $default 53 | (block $4 54 | (block $5 55 | (block $6 56 | (block $3 57 | (block $2 58 | (block $1 59 | (block $0 60 | (br_table $0 $1 $2 $3 $4 $5 $6 $7 $default 61 | (i32.wrap/i64 (get_local $i)) 62 | ) 63 | ) ;; 0 64 | (return (get_local $i)) 65 | ) ;; 1 66 | (nop) 67 | ;; fallthrough 68 | ) ;; 2 69 | ;; fallthrough 70 | ) ;; 3 71 | (br $switch (i64.sub (i64.const 0) (get_local $i))) 72 | ) ;; 6 73 | (set_local $j (i64.const 101)) 74 | ;; fallthrough 75 | ) ;; 4 76 | ;; fallthrough 77 | ) ;; 5 78 | ;; fallthrough 79 | ) ;; default 80 | (br $switch (get_local $j)) 81 | ) ;; 7 82 | (i64.const -5) 83 | ) 84 | ) 85 | ) 86 | 87 | ;; Argument switch 88 | (func (export "arg") (param $i i32) (result i32) 89 | (return 90 | (block $2 (result i32) 91 | (i32.add (i32.const 10) 92 | (block $1 (result i32) 93 | (i32.add (i32.const 100) 94 | (block $0 (result i32) 95 | (i32.add (i32.const 1000) 96 | (block $default (result i32) 97 | (br_table $0 $1 $2 $default 98 | (i32.mul (i32.const 2) (get_local $i)) 99 | (i32.and (i32.const 3) (get_local $i)) 100 | ) 101 | ) 102 | ) 103 | ) 104 | ) 105 | ) 106 | ) 107 | ) 108 | ) 109 | ) 110 | 111 | ;; Corner cases 112 | (func (export "corner") (result i32) 113 | (block 114 | (br_table 0 (i32.const 0)) 115 | ) 116 | (i32.const 1) 117 | ) 118 | ) 119 | 120 | (assert_return (invoke "stmt" (i32.const 0)) (i32.const 0)) 121 | (assert_return (invoke "stmt" (i32.const 1)) (i32.const -1)) 122 | (assert_return (invoke "stmt" (i32.const 2)) (i32.const -2)) 123 | (assert_return (invoke "stmt" (i32.const 3)) (i32.const -3)) 124 | (assert_return (invoke "stmt" (i32.const 4)) (i32.const 100)) 125 | (assert_return (invoke "stmt" (i32.const 5)) (i32.const 101)) 126 | (assert_return (invoke "stmt" (i32.const 6)) (i32.const 102)) 127 | (assert_return (invoke "stmt" (i32.const 7)) (i32.const 100)) 128 | (assert_return (invoke "stmt" (i32.const -10)) (i32.const 102)) 129 | 130 | (assert_return (invoke "expr" (i64.const 0)) (i64.const 0)) 131 | (assert_return (invoke "expr" (i64.const 1)) (i64.const -1)) 132 | (assert_return (invoke "expr" (i64.const 2)) (i64.const -2)) 133 | (assert_return (invoke "expr" (i64.const 3)) (i64.const -3)) 134 | (assert_return (invoke "expr" (i64.const 6)) (i64.const 101)) 135 | (assert_return (invoke "expr" (i64.const 7)) (i64.const -5)) 136 | (assert_return (invoke "expr" (i64.const -10)) (i64.const 100)) 137 | 138 | (assert_return (invoke "arg" (i32.const 0)) (i32.const 110)) 139 | (assert_return (invoke "arg" (i32.const 1)) (i32.const 12)) 140 | (assert_return (invoke "arg" (i32.const 2)) (i32.const 4)) 141 | (assert_return (invoke "arg" (i32.const 3)) (i32.const 1116)) 142 | (assert_return (invoke "arg" (i32.const 4)) (i32.const 118)) 143 | (assert_return (invoke "arg" (i32.const 5)) (i32.const 20)) 144 | (assert_return (invoke "arg" (i32.const 6)) (i32.const 12)) 145 | (assert_return (invoke "arg" (i32.const 7)) (i32.const 1124)) 146 | (assert_return (invoke "arg" (i32.const 8)) (i32.const 126)) 147 | 148 | (assert_return (invoke "corner") (i32.const 1)) 149 | 150 | (assert_invalid (module (func (br_table 3 (i32.const 0)))) "unknown label") 151 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/tee_local.wast: -------------------------------------------------------------------------------- 1 | ;; Test `tee_local` operator 2 | 3 | (module 4 | ;; Typing 5 | 6 | (func (export "type-local-i32") (result i32) (local i32) (tee_local 0 (i32.const 0))) 7 | (func (export "type-local-i64") (result i64) (local i64) (tee_local 0 (i64.const 0))) 8 | (func (export "type-local-f32") (result f32) (local f32) (tee_local 0 (f32.const 0))) 9 | (func (export "type-local-f64") (result f64) (local f64) (tee_local 0 (f64.const 0))) 10 | 11 | (func (export "type-param-i32") (param i32) (result i32) (tee_local 0 (i32.const 10))) 12 | (func (export "type-param-i64") (param i64) (result i64) (tee_local 0 (i64.const 11))) 13 | (func (export "type-param-f32") (param f32) (result f32) (tee_local 0 (f32.const 11.1))) 14 | (func (export "type-param-f64") (param f64) (result f64) (tee_local 0 (f64.const 12.2))) 15 | 16 | (func (export "type-mixed") (param i64 f32 f64 i32 i32) (local f32 i64 i64 f64) 17 | (drop (i64.eqz (tee_local 0 (i64.const 0)))) 18 | (drop (f32.neg (tee_local 1 (f32.const 0)))) 19 | (drop (f64.neg (tee_local 2 (f64.const 0)))) 20 | (drop (i32.eqz (tee_local 3 (i32.const 0)))) 21 | (drop (i32.eqz (tee_local 4 (i32.const 0)))) 22 | (drop (f32.neg (tee_local 5 (f32.const 0)))) 23 | (drop (i64.eqz (tee_local 6 (i64.const 0)))) 24 | (drop (i64.eqz (tee_local 7 (i64.const 0)))) 25 | (drop (f64.neg (tee_local 8 (f64.const 0)))) 26 | ) 27 | 28 | ;; Writing 29 | 30 | (func (export "write") (param i64 f32 f64 i32 i32) (result i64) (local f32 i64 i64 f64) 31 | (drop (tee_local 1 (f32.const -0.3))) 32 | (drop (tee_local 3 (i32.const 40))) 33 | (drop (tee_local 4 (i32.const -7))) 34 | (drop (tee_local 5 (f32.const 5.5))) 35 | (drop (tee_local 6 (i64.const 6))) 36 | (drop (tee_local 8 (f64.const 8))) 37 | (i64.trunc_s/f64 38 | (f64.add 39 | (f64.convert_u/i64 (get_local 0)) 40 | (f64.add 41 | (f64.promote/f32 (get_local 1)) 42 | (f64.add 43 | (get_local 2) 44 | (f64.add 45 | (f64.convert_u/i32 (get_local 3)) 46 | (f64.add 47 | (f64.convert_s/i32 (get_local 4)) 48 | (f64.add 49 | (f64.promote/f32 (get_local 5)) 50 | (f64.add 51 | (f64.convert_u/i64 (get_local 6)) 52 | (f64.add 53 | (f64.convert_u/i64 (get_local 7)) 54 | (get_local 8) 55 | ) 56 | ) 57 | ) 58 | ) 59 | ) 60 | ) 61 | ) 62 | ) 63 | ) 64 | ) 65 | 66 | ;; Result 67 | 68 | (func (export "result") (param i64 f32 f64 i32 i32) (result f64) 69 | (local f32 i64 i64 f64) 70 | (f64.add 71 | (f64.convert_u/i64 (tee_local 0 (i64.const 1))) 72 | (f64.add 73 | (f64.promote/f32 (tee_local 1 (f32.const 2))) 74 | (f64.add 75 | (tee_local 2 (f64.const 3.3)) 76 | (f64.add 77 | (f64.convert_u/i32 (tee_local 3 (i32.const 4))) 78 | (f64.add 79 | (f64.convert_s/i32 (tee_local 4 (i32.const 5))) 80 | (f64.add 81 | (f64.promote/f32 (tee_local 5 (f32.const 5.5))) 82 | (f64.add 83 | (f64.convert_u/i64 (tee_local 6 (i64.const 6))) 84 | (f64.add 85 | (f64.convert_u/i64 (tee_local 7 (i64.const 0))) 86 | (tee_local 8 (f64.const 8)) 87 | ) 88 | ) 89 | ) 90 | ) 91 | ) 92 | ) 93 | ) 94 | ) 95 | ) 96 | ) 97 | 98 | (assert_return (invoke "type-local-i32") (i32.const 0)) 99 | (assert_return (invoke "type-local-i64") (i64.const 0)) 100 | (assert_return (invoke "type-local-f32") (f32.const 0)) 101 | (assert_return (invoke "type-local-f64") (f64.const 0)) 102 | 103 | (assert_return (invoke "type-param-i32" (i32.const 2)) (i32.const 10)) 104 | (assert_return (invoke "type-param-i64" (i64.const 3)) (i64.const 11)) 105 | (assert_return (invoke "type-param-f32" (f32.const 4.4)) (f32.const 11.1)) 106 | (assert_return (invoke "type-param-f64" (f64.const 5.5)) (f64.const 12.2)) 107 | 108 | (assert_return 109 | (invoke "type-mixed" 110 | (i64.const 1) (f32.const 2.2) (f64.const 3.3) (i32.const 4) (i32.const 5) 111 | ) 112 | ) 113 | 114 | (assert_return 115 | (invoke "write" 116 | (i64.const 1) (f32.const 2) (f64.const 3.3) (i32.const 4) (i32.const 5) 117 | ) 118 | (i64.const 56) 119 | ) 120 | 121 | (assert_return 122 | (invoke "result" 123 | (i64.const -1) (f32.const -2) (f64.const -3.3) (i32.const -4) (i32.const -5) 124 | ) 125 | (f64.const 34.8) 126 | ) 127 | 128 | 129 | ;; Invalid typing of access to locals 130 | 131 | (assert_invalid 132 | (module (func $type-local-num-vs-num (result i64) (local i32) (tee_local 0 (i32.const 0)))) 133 | "type mismatch" 134 | ) 135 | (assert_invalid 136 | (module (func $type-local-num-vs-num (local f32) (i32.eqz (tee_local 0 (f32.const 0))))) 137 | "type mismatch" 138 | ) 139 | (assert_invalid 140 | (module (func $type-local-num-vs-num (local f64 i64) (f64.neg (tee_local 1 (i64.const 0))))) 141 | "type mismatch" 142 | ) 143 | 144 | (assert_invalid 145 | (module (func $type-local-arg-void-vs-num (local i32) (tee_local 0 (nop)))) 146 | "type mismatch" 147 | ) 148 | (assert_invalid 149 | (module (func $type-local-arg-num-vs-num (local i32) (tee_local 0 (f32.const 0)))) 150 | "type mismatch" 151 | ) 152 | (assert_invalid 153 | (module (func $type-local-arg-num-vs-num (local f32) (tee_local 0 (f64.const 0)))) 154 | "type mismatch" 155 | ) 156 | (assert_invalid 157 | (module (func $type-local-arg-num-vs-num (local f64 i64) (tee_local 1 (f64.const 0)))) 158 | "type mismatch" 159 | ) 160 | 161 | 162 | ;; Invalid typing of access to parameters 163 | 164 | (assert_invalid 165 | (module (func $type-param-num-vs-num (param i32) (result i64) (get_local 0))) 166 | "type mismatch" 167 | ) 168 | (assert_invalid 169 | (module (func $type-param-num-vs-num (param f32) (i32.eqz (get_local 0)))) 170 | "type mismatch" 171 | ) 172 | (assert_invalid 173 | (module (func $type-param-num-vs-num (param f64 i64) (f64.neg (get_local 1)))) 174 | "type mismatch" 175 | ) 176 | 177 | (assert_invalid 178 | (module (func $type-param-arg-void-vs-num (param i32) (tee_local 0 (nop)))) 179 | "type mismatch" 180 | ) 181 | (assert_invalid 182 | (module (func $type-param-arg-num-vs-num (param i32) (tee_local 0 (f32.const 0)))) 183 | "type mismatch" 184 | ) 185 | (assert_invalid 186 | (module (func $type-param-arg-num-vs-num (param f32) (tee_local 0 (f64.const 0)))) 187 | "type mismatch" 188 | ) 189 | (assert_invalid 190 | (module (func $type-param-arg-num-vs-num (param f64 i64) (tee_local 1 (f64.const 0)))) 191 | "type mismatch" 192 | ) 193 | 194 | 195 | ;; Invalid local index 196 | 197 | (assert_invalid 198 | (module (func $unbound-local (local i32 i64) (get_local 3))) 199 | "unknown local" 200 | ) 201 | (assert_invalid 202 | (module (func $large-local (local i32 i64) (get_local 14324343))) 203 | "unknown local" 204 | ) 205 | 206 | (assert_invalid 207 | (module (func $unbound-param (param i32 i64) (get_local 2))) 208 | "unknown local" 209 | ) 210 | (assert_invalid 211 | (module (func $large-param (local i32 i64) (get_local 714324343))) 212 | "unknown local" 213 | ) 214 | 215 | (assert_invalid 216 | (module (func $unbound-mixed (param i32) (local i32 i64) (get_local 3))) 217 | "unknown local" 218 | ) 219 | (assert_invalid 220 | (module (func $large-mixed (param i64) (local i32 i64) (get_local 214324343))) 221 | "unknown local" 222 | ) 223 | 224 | (assert_invalid 225 | (module (func $type-mixed-arg-num-vs-num (param f32) (local i32) (tee_local 1 (f32.const 0)))) 226 | "type mismatch" 227 | ) 228 | (assert_invalid 229 | (module (func $type-mixed-arg-num-vs-num (param i64 i32) (local f32) (tee_local 1 (f32.const 0)))) 230 | "type mismatch" 231 | ) 232 | (assert_invalid 233 | (module (func $type-mixed-arg-num-vs-num (param i64) (local f64 i64) (tee_local 1 (i64.const 0)))) 234 | "type mismatch" 235 | ) 236 | 237 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/token.wast: -------------------------------------------------------------------------------- 1 | ;; Test tokenization 2 | 3 | (assert_malformed 4 | (module quote "(func (drop (i32.const0)))") 5 | "unknown operator" 6 | ) 7 | (assert_malformed 8 | (module quote "(func br 0drop)") 9 | "unknown operator" 10 | ) 11 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/traps.wast: -------------------------------------------------------------------------------- 1 | ;; Test that traps are preserved even in instructions which might otherwise 2 | ;; be dead-code-eliminated. These functions all perform an operation and 3 | ;; discard its return value. 4 | 5 | (module 6 | (func (export "no_dce.i32.div_s") (param $x i32) (param $y i32) 7 | (drop (i32.div_s (get_local $x) (get_local $y)))) 8 | (func (export "no_dce.i32.div_u") (param $x i32) (param $y i32) 9 | (drop (i32.div_u (get_local $x) (get_local $y)))) 10 | (func (export "no_dce.i64.div_s") (param $x i64) (param $y i64) 11 | (drop (i64.div_s (get_local $x) (get_local $y)))) 12 | (func (export "no_dce.i64.div_u") (param $x i64) (param $y i64) 13 | (drop (i64.div_u (get_local $x) (get_local $y)))) 14 | ) 15 | 16 | (assert_trap (invoke "no_dce.i32.div_s" (i32.const 1) (i32.const 0)) "integer divide by zero") 17 | (assert_trap (invoke "no_dce.i32.div_u" (i32.const 1) (i32.const 0)) "integer divide by zero") 18 | (assert_trap (invoke "no_dce.i64.div_s" (i64.const 1) (i64.const 0)) "integer divide by zero") 19 | (assert_trap (invoke "no_dce.i64.div_u" (i64.const 1) (i64.const 0)) "integer divide by zero") 20 | (assert_trap (invoke "no_dce.i32.div_s" (i32.const 0x80000000) (i32.const -1)) "integer overflow") 21 | (assert_trap (invoke "no_dce.i64.div_s" (i64.const 0x8000000000000000) (i64.const -1)) "integer overflow") 22 | 23 | (module 24 | (func (export "no_dce.i32.rem_s") (param $x i32) (param $y i32) 25 | (drop (i32.rem_s (get_local $x) (get_local $y)))) 26 | (func (export "no_dce.i32.rem_u") (param $x i32) (param $y i32) 27 | (drop (i32.rem_u (get_local $x) (get_local $y)))) 28 | (func (export "no_dce.i64.rem_s") (param $x i64) (param $y i64) 29 | (drop (i64.rem_s (get_local $x) (get_local $y)))) 30 | (func (export "no_dce.i64.rem_u") (param $x i64) (param $y i64) 31 | (drop (i64.rem_u (get_local $x) (get_local $y)))) 32 | ) 33 | 34 | (assert_trap (invoke "no_dce.i32.rem_s" (i32.const 1) (i32.const 0)) "integer divide by zero") 35 | (assert_trap (invoke "no_dce.i32.rem_u" (i32.const 1) (i32.const 0)) "integer divide by zero") 36 | (assert_trap (invoke "no_dce.i64.rem_s" (i64.const 1) (i64.const 0)) "integer divide by zero") 37 | (assert_trap (invoke "no_dce.i64.rem_u" (i64.const 1) (i64.const 0)) "integer divide by zero") 38 | 39 | (module 40 | (func (export "no_dce.i32.trunc_s_f32") (param $x f32) (drop (i32.trunc_s/f32 (get_local $x)))) 41 | (func (export "no_dce.i32.trunc_u_f32") (param $x f32) (drop (i32.trunc_u/f32 (get_local $x)))) 42 | (func (export "no_dce.i32.trunc_s_f64") (param $x f64) (drop (i32.trunc_s/f64 (get_local $x)))) 43 | (func (export "no_dce.i32.trunc_u_f64") (param $x f64) (drop (i32.trunc_u/f64 (get_local $x)))) 44 | (func (export "no_dce.i64.trunc_s_f32") (param $x f32) (drop (i64.trunc_s/f32 (get_local $x)))) 45 | (func (export "no_dce.i64.trunc_u_f32") (param $x f32) (drop (i64.trunc_u/f32 (get_local $x)))) 46 | (func (export "no_dce.i64.trunc_s_f64") (param $x f64) (drop (i64.trunc_s/f64 (get_local $x)))) 47 | (func (export "no_dce.i64.trunc_u_f64") (param $x f64) (drop (i64.trunc_u/f64 (get_local $x)))) 48 | ) 49 | 50 | (assert_trap (invoke "no_dce.i32.trunc_s_f32" (f32.const nan)) "invalid conversion to integer") 51 | (assert_trap (invoke "no_dce.i32.trunc_u_f32" (f32.const nan)) "invalid conversion to integer") 52 | (assert_trap (invoke "no_dce.i32.trunc_s_f64" (f64.const nan)) "invalid conversion to integer") 53 | (assert_trap (invoke "no_dce.i32.trunc_u_f64" (f64.const nan)) "invalid conversion to integer") 54 | (assert_trap (invoke "no_dce.i64.trunc_s_f32" (f32.const nan)) "invalid conversion to integer") 55 | (assert_trap (invoke "no_dce.i64.trunc_u_f32" (f32.const nan)) "invalid conversion to integer") 56 | (assert_trap (invoke "no_dce.i64.trunc_s_f64" (f64.const nan)) "invalid conversion to integer") 57 | (assert_trap (invoke "no_dce.i64.trunc_u_f64" (f64.const nan)) "invalid conversion to integer") 58 | 59 | (module 60 | (memory 1) 61 | 62 | (func (export "no_dce.i32.load") (param $i i32) (drop (i32.load (get_local $i)))) 63 | (func (export "no_dce.i32.load16_s") (param $i i32) (drop (i32.load16_s (get_local $i)))) 64 | (func (export "no_dce.i32.load16_u") (param $i i32) (drop (i32.load16_u (get_local $i)))) 65 | (func (export "no_dce.i32.load8_s") (param $i i32) (drop (i32.load8_s (get_local $i)))) 66 | (func (export "no_dce.i32.load8_u") (param $i i32) (drop (i32.load8_u (get_local $i)))) 67 | (func (export "no_dce.i64.load") (param $i i32) (drop (i64.load (get_local $i)))) 68 | (func (export "no_dce.i64.load32_s") (param $i i32) (drop (i64.load32_s (get_local $i)))) 69 | (func (export "no_dce.i64.load32_u") (param $i i32) (drop (i64.load32_u (get_local $i)))) 70 | (func (export "no_dce.i64.load16_s") (param $i i32) (drop (i64.load16_s (get_local $i)))) 71 | (func (export "no_dce.i64.load16_u") (param $i i32) (drop (i64.load16_u (get_local $i)))) 72 | (func (export "no_dce.i64.load8_s") (param $i i32) (drop (i64.load8_s (get_local $i)))) 73 | (func (export "no_dce.i64.load8_u") (param $i i32) (drop (i64.load8_u (get_local $i)))) 74 | (func (export "no_dce.f32.load") (param $i i32) (drop (f32.load (get_local $i)))) 75 | (func (export "no_dce.f64.load") (param $i i32) (drop (f64.load (get_local $i)))) 76 | ) 77 | 78 | (assert_trap (invoke "no_dce.i32.load" (i32.const 65536)) "out of bounds memory access") 79 | (assert_trap (invoke "no_dce.i32.load16_s" (i32.const 65536)) "out of bounds memory access") 80 | (assert_trap (invoke "no_dce.i32.load16_u" (i32.const 65536)) "out of bounds memory access") 81 | (assert_trap (invoke "no_dce.i32.load8_s" (i32.const 65536)) "out of bounds memory access") 82 | (assert_trap (invoke "no_dce.i32.load8_u" (i32.const 65536)) "out of bounds memory access") 83 | (assert_trap (invoke "no_dce.i64.load" (i32.const 65536)) "out of bounds memory access") 84 | (assert_trap (invoke "no_dce.i64.load32_s" (i32.const 65536)) "out of bounds memory access") 85 | (assert_trap (invoke "no_dce.i64.load32_u" (i32.const 65536)) "out of bounds memory access") 86 | (assert_trap (invoke "no_dce.i64.load16_s" (i32.const 65536)) "out of bounds memory access") 87 | (assert_trap (invoke "no_dce.i64.load16_u" (i32.const 65536)) "out of bounds memory access") 88 | (assert_trap (invoke "no_dce.i64.load8_s" (i32.const 65536)) "out of bounds memory access") 89 | (assert_trap (invoke "no_dce.i64.load8_u" (i32.const 65536)) "out of bounds memory access") 90 | (assert_trap (invoke "no_dce.f32.load" (i32.const 65536)) "out of bounds memory access") 91 | (assert_trap (invoke "no_dce.f64.load" (i32.const 65536)) "out of bounds memory access") 92 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/type.wast: -------------------------------------------------------------------------------- 1 | ;; Test type definitions 2 | 3 | (module 4 | (type (func)) 5 | (type $t (func)) 6 | 7 | (type (func (param i32))) 8 | (type (func (param $x i32))) 9 | (type (func (result i32))) 10 | (type (func (param i32) (result i32))) 11 | (type (func (param $x i32) (result i32))) 12 | 13 | (type (func (param f32 f64))) 14 | ;; (type (func (result i64 f32))) 15 | ;; (type (func (param i32 i64) (result f32 f64))) 16 | 17 | (type (func (param f32) (param f64))) 18 | (type (func (param $x f32) (param f64))) 19 | (type (func (param f32) (param $y f64))) 20 | (type (func (param $x f32) (param $y f64))) 21 | ;; (type (func (result i64) (result f32))) 22 | ;; (type (func (param i32) (param i64) (result f32) (result f64))) 23 | ;; (type (func (param $x i32) (param $y i64) (result f32) (result f64))) 24 | 25 | (type (func (param f32 f64) (param $x i32) (param f64 i32 i32))) 26 | ;; (type (func (result i64 i64 f32) (result f32 i32))) 27 | ;; (type 28 | ;; (func (param i32 i32) (param i64 i32) (result f32 f64) (result f64 i32)) 29 | ;; ) 30 | 31 | (type (func (param) (param $x f32) (param) (param) (param f64 i32) (param))) 32 | ;; (type 33 | ;; (func (result) (result) (result i64 i64) (result) (result f32) (result)) 34 | ;; ) 35 | ;; (type 36 | ;; (func 37 | ;; (param i32 i32) (param i64 i32) (param) (param $x i32) (param) 38 | ;; (result) (result f32 f64) (result f64 i32) (result) 39 | ;; ) 40 | ;; ) 41 | ) 42 | 43 | (assert_malformed 44 | (module quote "(type (func (result i32) (param i32)))") 45 | "result before parameter" 46 | ) 47 | (assert_malformed 48 | (module quote "(type (func (result $x i32)))") 49 | "unexpected token" 50 | ) 51 | 52 | (assert_invalid 53 | (module (type (func (result i32 i32)))) 54 | "invalid result arity" 55 | ) 56 | (assert_invalid 57 | (module (type (func (result i32) (result i32)))) 58 | "invalid result arity" 59 | ) 60 | -------------------------------------------------------------------------------- /greenwasm-spectest/testsuite/update-testsuite.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | repos='spec threads simd exception-handling gc bulk-memory-operations tail-call nontrapping-float-to-int-conversions multi-value host-bindings sign-extension-ops mutable-global' 7 | 8 | log_and_run() { 9 | echo ">>" $* 10 | if ! $*; then 11 | echo "sub-command failed: $*" 12 | exit 13 | fi 14 | } 15 | 16 | try_log_and_run() { 17 | echo ">>" $* 18 | $* 19 | } 20 | 21 | pushdir() { 22 | pushd $1 >/dev/null || exit 23 | } 24 | 25 | popdir() { 26 | popd >/dev/null || exit 27 | } 28 | 29 | update_repo() { 30 | local repo=$1 31 | pushdir repos 32 | if [ -d ${repo} ]; then 33 | log_and_run git -C ${repo} fetch origin 34 | log_and_run git -C ${repo} reset origin/master --hard 35 | else 36 | log_and_run git clone https://github.com/WebAssembly/${repo} 37 | fi 38 | 39 | # Add upstream spec as "spec" remote. 40 | if [ "${repo}" != "spec" ]; then 41 | pushdir ${repo} 42 | if ! git remote | grep spec >/dev/null; then 43 | log_and_run git remote add spec https://github.com/WebAssembly/spec 44 | fi 45 | 46 | log_and_run git fetch spec 47 | popdir 48 | fi 49 | popdir 50 | } 51 | 52 | merge_with_spec() { 53 | local repo=$1 54 | 55 | [ "${repo}" == "spec" ] && return 56 | 57 | pushdir repos/${repo} 58 | # Create and checkout "try-merge" branch. 59 | if ! git branch | grep try-merge >/dev/null; then 60 | log_and_run git branch try-merge origin/master 61 | fi 62 | log_and_run git checkout try-merge 63 | 64 | # Attempt to merge with spec/master. 65 | log_and_run git reset origin/master --hard 66 | try_log_and_run git merge -q spec/master -m "merged" 67 | if [ $? -ne 0 ]; then 68 | git merge --abort 69 | popdir 70 | return 1 71 | fi 72 | popdir 73 | return 0 74 | } 75 | 76 | 77 | echo -e "update repos\n" > commit_message 78 | 79 | failed_repos= 80 | 81 | for repo in ${repos}; do 82 | echo "++ updating ${repo}" 83 | update_repo ${repo} 84 | 85 | if ! merge_with_spec ${repo}; then 86 | echo -e "!! error merging ${repo}, skipping\n" 87 | failed_repos="${failed_repos} ${repo}" 88 | continue 89 | fi 90 | 91 | if [ "${repo}" = "spec" ]; then 92 | wast_dir=. 93 | log_and_run cp repos/${repo}/test/core/*.wast ${wast_dir} 94 | else 95 | wast_dir=proposals/${repo} 96 | mkdir -p ${wast_dir} 97 | 98 | # Don't add tests from propsoal that are the same as spec. 99 | pushdir repos/${repo} 100 | for new in test/core/*.wast; do 101 | old=../../repos/spec/${new} 102 | if [[ ! -f ${old} ]] || ! diff ${old} ${new} >/dev/null; then 103 | log_and_run cp ${new} ../../${wast_dir} 104 | fi 105 | done 106 | popdir 107 | fi 108 | 109 | # Check whether any files were updated. 110 | if [ $(git status -s ${wast_dir}/*.wast | wc -l) -ne 0 ]; then 111 | log_and_run git add ${wast_dir}/*.wast 112 | 113 | repo_sha=$(git -C repos/${repo} log --max-count=1 --pretty=oneline | sed -e 's/ .*//') 114 | echo " ${repo}: ${repo_sha}" >> commit_message 115 | fi 116 | 117 | echo -e "-- ${repo}\n" 118 | done 119 | 120 | git commit -a -F commit_message 121 | # git push 122 | 123 | echo "done" 124 | 125 | if [ -n "${failed_repos}" ]; then 126 | echo "!! failed to update repos: ${failed_repos}" 127 | fi 128 | -------------------------------------------------------------------------------- /greenwasm-structure/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "greenwasm-structure" 3 | version = "0.3.0" 4 | authors = ["Marvin Löbel "] 5 | license = "MIT/Apache-2.0" 6 | 7 | documentation = "https://docs.rs/greenwasm-structure" 8 | description = "An implementation of the structure section from the Webassembly spec." 9 | readme = "README.md" 10 | repository = "https://github.com/Kimundi/greenwasm" 11 | categories = ["wasm", "data-structures"] 12 | keywords = ["AST", "structure"] 13 | 14 | workspace = ".." 15 | 16 | [dependencies.smallvec] 17 | version = "0.6.4" 18 | features = ["union"] 19 | 20 | [badges] 21 | appveyor = { repository = "Kimundi/greenwasm" } 22 | travis-ci = { repository = "Kimundi/greenwasm" } 23 | 24 | is-it-maintained-issue-resolution = { repository = "Kimundi/greenwasm" } 25 | is-it-maintained-open-issues = { repository = "Kimundi/greenwasm" } 26 | 27 | maintenance = { status = "experimental" } 28 | -------------------------------------------------------------------------------- /greenwasm-structure/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 The Rust Project Developers 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /greenwasm-structure/README.md: -------------------------------------------------------------------------------- 1 | # greenwasm-structure 2 | An implementation of the _Structure_ section from the Webassembly spec in Rust. 3 | 4 | Contains Typedefs for Wasm Types, Instructions and Modules. 5 | 6 | ## License 7 | 8 | Licensed under either of 9 | 10 | * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) 11 | * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) 12 | 13 | at your option. 14 | 15 | ### Contribution 16 | 17 | Unless you explicitly state otherwise, any contribution intentionally submitted 18 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any 19 | additional terms or conditions. 20 | -------------------------------------------------------------------------------- /greenwasm-structure/src/instructions.rs: -------------------------------------------------------------------------------- 1 | use super::types::U32; 2 | use super::types::I32; 3 | use super::types::I64; 4 | use super::types::F32; 5 | use super::types::F64; 6 | use super::types::ResultType; 7 | use super::types::Wec; 8 | 9 | use super::modules::LocalIdx; 10 | use super::modules::GlobalIdx; 11 | use super::modules::LabelIdx; 12 | use super::modules::FuncIdx; 13 | use super::modules::TypeIdx; 14 | 15 | #[derive(Copy, Clone, Debug, PartialEq)] 16 | pub struct Memarg { 17 | pub offset: U32, 18 | pub align: U32, 19 | } 20 | 21 | #[derive(Debug, PartialEq, Clone)] 22 | pub struct Expr { 23 | pub body: Vec, 24 | } 25 | 26 | #[derive(Debug, PartialEq, Clone)] 27 | pub enum Instr { 28 | // numeric instructions 29 | I32Const(I32), 30 | I64Const(I64), 31 | F32Const(F32), 32 | F64Const(F64), 33 | 34 | I32Clz, 35 | I32Ctz, 36 | I32Popcnt, 37 | 38 | I64Clz, 39 | I64Ctz, 40 | I64Popcnt, 41 | 42 | F32Abs, 43 | F32Neg, 44 | F32Sqrt, 45 | F32Ceil, 46 | F32Floor, 47 | F32Trunc, 48 | F32Nearest, 49 | 50 | F64Abs, 51 | F64Neg, 52 | F64Sqrt, 53 | F64Ceil, 54 | F64Floor, 55 | F64Trunc, 56 | F64Nearest, 57 | 58 | I32Add, 59 | I32Sub, 60 | I32Mul, 61 | I32DivU, 62 | I32DivS, 63 | I32RemU, 64 | I32RemS, 65 | I32And, 66 | I32Or, 67 | I32Xor, 68 | I32Shl, 69 | I32ShrU, 70 | I32ShrS, 71 | I32Rotl, 72 | I32Rotr, 73 | 74 | I64Add, 75 | I64Sub, 76 | I64Mul, 77 | I64DivU, 78 | I64DivS, 79 | I64RemU, 80 | I64RemS, 81 | I64And, 82 | I64Or, 83 | I64Xor, 84 | I64Shl, 85 | I64ShrU, 86 | I64ShrS, 87 | I64Rotl, 88 | I64Rotr, 89 | 90 | F32Add, 91 | F32Sub, 92 | F32Mul, 93 | F32Div, 94 | F32Min, 95 | F32Max, 96 | F32CopySign, 97 | 98 | F64Add, 99 | F64Sub, 100 | F64Mul, 101 | F64Div, 102 | F64Min, 103 | F64Max, 104 | F64CopySign, 105 | 106 | I32EqZ, 107 | I64EqZ, 108 | 109 | I32Eq, 110 | I32Ne, 111 | I32LtU, 112 | I32LtS, 113 | I32GtU, 114 | I32GtS, 115 | I32LeU, 116 | I32LeS, 117 | I32GeU, 118 | I32GeS, 119 | 120 | I64Eq, 121 | I64Ne, 122 | I64LtU, 123 | I64LtS, 124 | I64GtU, 125 | I64GtS, 126 | I64LeU, 127 | I64LeS, 128 | I64GeU, 129 | I64GeS, 130 | 131 | F32Eq, 132 | F32Ne, 133 | F32Lt, 134 | F32Gt, 135 | F32Le, 136 | F32Ge, 137 | 138 | F64Eq, 139 | F64Ne, 140 | F64Lt, 141 | F64Gt, 142 | F64Le, 143 | F64Ge, 144 | 145 | I32WrapI64, 146 | I64ExtendUI32, 147 | I64ExtendSI32, 148 | 149 | I32TruncUF32, 150 | I32TruncUF64, 151 | I32TruncSF32, 152 | I32TruncSF64, 153 | I64TruncUF32, 154 | I64TruncUF64, 155 | I64TruncSF32, 156 | I64TruncSF64, 157 | 158 | F32DemoteF64, 159 | F64PromoteF32, 160 | 161 | F32ConvertUI32, 162 | F64ConvertUI32, 163 | F32ConvertSI32, 164 | F64ConvertSI32, 165 | F32ConvertUI64, 166 | F64ConvertUI64, 167 | F32ConvertSI64, 168 | F64ConvertSI64, 169 | 170 | I32ReinterpretF32, 171 | I64ReinterpretF64, 172 | F32ReinterpretI32, 173 | F64ReinterpretI64, 174 | 175 | // parametric instructions 176 | Drop, 177 | Select, 178 | 179 | // variable instructions 180 | GetLocal(LocalIdx), 181 | SetLocal(LocalIdx), 182 | TeeLocal(LocalIdx), 183 | GetGlobal(GlobalIdx), 184 | SetGlobal(GlobalIdx), 185 | 186 | // memory instructions 187 | I32Load(Memarg), 188 | I64Load(Memarg), 189 | F32Load(Memarg), 190 | F64Load(Memarg), 191 | 192 | I32Store(Memarg), 193 | I64Store(Memarg), 194 | F32Store(Memarg), 195 | F64Store(Memarg), 196 | 197 | I32Load8U(Memarg), 198 | I32Load8S(Memarg), 199 | I64Load8U(Memarg), 200 | I64Load8S(Memarg), 201 | 202 | I32Load16U(Memarg), 203 | I32Load16S(Memarg), 204 | I64Load16U(Memarg), 205 | I64Load16S(Memarg), 206 | 207 | I64Load32U(Memarg), 208 | I64Load32S(Memarg), 209 | 210 | I32Store8(Memarg), 211 | I64Store8(Memarg), 212 | I32Store16(Memarg), 213 | I64Store16(Memarg), 214 | I64Store32(Memarg), 215 | 216 | CurrentMemory, 217 | GrowMemory, 218 | 219 | // control instructions 220 | Nop, 221 | Unreachable, 222 | Block(ResultType, Vec), 223 | Loop(ResultType, Vec), 224 | IfElse(ResultType, Vec, Vec), 225 | Br(LabelIdx), 226 | BrIf(LabelIdx), 227 | BrTable(Wec, LabelIdx), 228 | Return, 229 | Call(FuncIdx), 230 | CallIndirect(TypeIdx), 231 | } 232 | -------------------------------------------------------------------------------- /greenwasm-structure/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(slice_patterns)] 2 | #![feature(macro_at_most_once_rep)] 3 | 4 | pub mod types; 5 | pub mod instructions; 6 | pub mod modules; 7 | -------------------------------------------------------------------------------- /greenwasm-structure/src/modules.rs: -------------------------------------------------------------------------------- 1 | use super::types::Wec; 2 | use super::types::FuncType; 3 | use super::types::ValType; 4 | use super::types::TableType; 5 | use super::types::MemType; 6 | use super::types::GlobalType; 7 | use super::types::Byte; 8 | use super::types::Name; 9 | use super::types::U32; 10 | 11 | use super::instructions::Expr; 12 | 13 | #[derive(Debug, PartialEq)] 14 | pub struct Module { 15 | pub types: Wec, 16 | pub funcs: Wec, 17 | pub tables: Wec, 18 | pub mems: Wec, 19 | pub globals: Wec, 20 | pub elem: Wec, 21 | pub data: Wec, 22 | pub start: Option, 23 | pub imports: Wec, 24 | pub exports: Wec, 25 | } 26 | 27 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd)] 28 | pub struct TypeIdx(pub U32); 29 | impl Into for TypeIdx { fn into(self) -> usize { self.0 as usize } } 30 | impl From for TypeIdx { fn from(a: usize) -> Self { TypeIdx(a as u32) } } 31 | 32 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd)] 33 | pub struct FuncIdx(pub U32); 34 | impl Into for FuncIdx { fn into(self) -> usize { self.0 as usize } } 35 | impl From for FuncIdx { fn from(a: usize) -> Self { FuncIdx(a as u32) } } 36 | 37 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd)] 38 | pub struct TableIdx(pub U32); 39 | impl Into for TableIdx { fn into(self) -> usize { self.0 as usize } } 40 | impl From for TableIdx { fn from(a: usize) -> Self { TableIdx(a as u32) } } 41 | 42 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd)] 43 | pub struct MemIdx(pub U32); 44 | impl Into for MemIdx { fn into(self) -> usize { self.0 as usize } } 45 | impl From for MemIdx { fn from(a: usize) -> Self { MemIdx(a as u32) } } 46 | 47 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd)] 48 | pub struct GlobalIdx(pub U32); 49 | impl Into for GlobalIdx { fn into(self) -> usize { self.0 as usize } } 50 | impl From for GlobalIdx { fn from(a: usize) -> Self { GlobalIdx(a as u32) } } 51 | 52 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd)] 53 | pub struct LocalIdx(pub U32); 54 | impl Into for LocalIdx { fn into(self) -> usize { self.0 as usize } } 55 | impl From for LocalIdx { fn from(a: usize) -> Self { LocalIdx(a as u32) } } 56 | 57 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd)] 58 | pub struct LabelIdx(pub U32); 59 | impl Into for LabelIdx { fn into(self) -> usize { self.0 as usize } } 60 | impl From for LabelIdx { fn from(a: usize) -> Self { LabelIdx(a as u32) } } 61 | 62 | 63 | #[derive(Debug, PartialEq, Clone)] 64 | pub struct Func { 65 | pub type_: TypeIdx, 66 | pub locals: Wec, 67 | pub body: Expr, 68 | } 69 | 70 | #[derive(Debug, PartialEq)] 71 | pub struct Table { 72 | pub type_: TableType, 73 | } 74 | 75 | #[derive(Debug, PartialEq)] 76 | pub struct Mem { 77 | pub type_: MemType, 78 | } 79 | 80 | #[derive(Debug, PartialEq)] 81 | pub struct Global { 82 | pub type_: GlobalType, 83 | pub init: Expr, 84 | } 85 | 86 | #[derive(Debug, PartialEq)] 87 | pub struct Elem { 88 | pub table: TableIdx, 89 | pub offset: Expr, 90 | pub init: Wec, 91 | } 92 | 93 | #[derive(Debug, PartialEq)] 94 | pub struct Data { 95 | pub data: MemIdx, 96 | pub offset: Expr, 97 | pub init: Wec, 98 | } 99 | 100 | #[derive(Debug, PartialEq)] 101 | pub struct Start { 102 | pub func: FuncIdx, 103 | } 104 | 105 | #[derive(Debug, PartialEq)] 106 | pub struct Export { 107 | pub name: Name, 108 | pub desc: ExportDesc, 109 | } 110 | 111 | #[derive(Debug, PartialEq)] 112 | pub enum ExportDesc { 113 | Func(FuncIdx), 114 | Table(TableIdx), 115 | Mem(MemIdx), 116 | Global(GlobalIdx), 117 | } 118 | 119 | #[derive(Debug, PartialEq)] 120 | pub struct Import { 121 | pub module: Name, 122 | pub name: Name, 123 | pub desc: ImportDesc, 124 | } 125 | 126 | #[derive(Debug, PartialEq)] 127 | pub enum ImportDesc { 128 | Func(TypeIdx), 129 | Table(TableType), 130 | Mem(MemType), 131 | Global(GlobalType), 132 | } 133 | -------------------------------------------------------------------------------- /greenwasm-structure/src/types.rs: -------------------------------------------------------------------------------- 1 | //! Types according to the _structure_ section of the spec 2 | 3 | // 2.1.3 Vectors 4 | 5 | /// Vectors may have at most 2^32 - 1 elements, presumably 6 | /// to ensure their size can be expressed as a u32. 7 | pub const WEC_MAX_SIZE: usize = ::std::u32::MAX as usize; 8 | 9 | /// A vec(A) according to the spec. 10 | /// 11 | /// Constructing this type checks the invariant that it has 12 | /// a size <= WEC_MAX_SIZE. 13 | /// 14 | /// Called Wec to prevent confusion with Rusts Vec type. 15 | #[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd)] 16 | pub struct Wec { 17 | inner: Vec 18 | } 19 | impl From> for Wec { 20 | fn from(inner: Vec) -> Self { 21 | assert!(inner.len() <= WEC_MAX_SIZE); 22 | Wec { inner } 23 | } 24 | } 25 | impl Into> for Wec { 26 | fn into(self) -> Vec { 27 | self.inner 28 | } 29 | } 30 | impl ::std::ops::Deref for Wec { 31 | type Target = [A]; 32 | 33 | fn deref(&self) -> &Self::Target { 34 | &self.inner 35 | } 36 | } 37 | impl ::std::ops::DerefMut for Wec { 38 | fn deref_mut(&mut self) -> &mut Self::Target { 39 | &mut self.inner 40 | } 41 | } 42 | impl<'a, A> IntoIterator for &'a Wec { 43 | type Item = &'a A; 44 | type IntoIter = <&'a Vec as IntoIterator>::IntoIter; 45 | 46 | fn into_iter(self) -> Self::IntoIter { 47 | self.inner.iter() 48 | } 49 | } 50 | impl IntoIterator for Wec { 51 | type Item = A; 52 | type IntoIter = as IntoIterator>::IntoIter; 53 | 54 | fn into_iter(self) -> Self::IntoIter { 55 | self.inner.into_iter() 56 | } 57 | } 58 | impl ::std::iter::FromIterator for Wec { 59 | fn from_iter(iter: T) -> Self 60 | where T: IntoIterator 61 | { 62 | Vec::from_iter(iter).into() 63 | } 64 | } 65 | impl Default for Wec { 66 | fn default() -> Self { 67 | Vec::default().into() 68 | } 69 | } 70 | impl Wec { 71 | pub fn safe_append A>(&mut self, n: usize, mut f: F) { 72 | let l = self.len(); 73 | self.inner.reserve(l + n); 74 | for _ in 0..n { 75 | self.inner.push(f()); 76 | } 77 | } 78 | } 79 | 80 | // 2.2 Values 81 | // 2.2.1 Bytes 82 | 83 | pub type Byte = u8; 84 | 85 | // 2.2.2 Integers 86 | 87 | pub type U8 = u8; 88 | pub type S8 = i8; 89 | pub type I8 = U8; 90 | 91 | pub type U16 = u16; 92 | pub type S16 = i16; 93 | pub type I16 = U16; 94 | 95 | pub type U32 = u32; 96 | pub type S32 = i32; 97 | pub type I32 = U32; 98 | 99 | pub type U64 = u64; 100 | pub type S64 = i64; 101 | pub type I64 = U64; 102 | 103 | pub type F32 = f32; 104 | pub type F64 = f64; 105 | 106 | /// A Name according to the spec. 107 | /// 108 | /// Constructing this type checks the invariant that it has 109 | /// a size <= WEC_MAX_SIZE. 110 | #[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd)] 111 | pub struct Name { 112 | inner: String 113 | } 114 | impl From for Name { 115 | fn from(inner: String) -> Self { 116 | assert!(inner.len() <= WEC_MAX_SIZE); 117 | Name { inner } 118 | } 119 | } 120 | impl<'a> From<&'a str> for Name { 121 | fn from(inner: &'a str) -> Self { 122 | assert!(inner.len() <= WEC_MAX_SIZE); 123 | Name { inner: inner.into() } 124 | } 125 | } 126 | impl Into for Name { 127 | fn into(self) -> String { 128 | self.inner 129 | } 130 | } 131 | impl ::std::ops::Deref for Name { 132 | type Target = String; 133 | 134 | fn deref(&self) -> &Self::Target { 135 | &self.inner 136 | } 137 | } 138 | pub type Codepoint = char; 139 | 140 | #[derive(Copy, Clone, Eq, PartialEq, Debug)] 141 | pub enum ValType { 142 | I32, 143 | I64, 144 | F32, 145 | F64, 146 | } 147 | 148 | // TODO. What does the [] notation in the grammar spec mean exactly? 149 | // Eg, `resulttype​::=​[valtype?]​` 150 | // ... 151 | // Later answer: Obviously that it is a list with 0 or 1 element, 152 | // as opposed to a missing or not missing element. 153 | 154 | /// A ResultType is a list of 0 or 1 elements 155 | #[derive(Copy, Clone, Eq, PartialEq)] 156 | pub struct ResultType { 157 | results: Option 158 | } 159 | impl ::std::ops::Deref for ResultType { 160 | type Target = [ValType]; 161 | 162 | fn deref(&self) -> &Self::Target { 163 | self.results.as_ref().map(::std::slice::from_ref).unwrap_or(&[]) 164 | } 165 | } 166 | impl From for ResultType { 167 | fn from(t: ValType) -> Self { 168 | ResultType { 169 | results: Some(t) 170 | } 171 | } 172 | } 173 | impl From> for ResultType { 174 | fn from(t: Option) -> Self { 175 | ResultType { 176 | results: t 177 | } 178 | } 179 | } 180 | use std::fmt::Debug; 181 | impl Debug for ResultType { 182 | fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::result::Result<(), ::std::fmt::Error> { 183 | let x: &[_] = self; 184 | x.fmt(f) 185 | } 186 | } 187 | 188 | #[derive(Clone, Debug, PartialEq)] 189 | pub struct FuncType { 190 | pub args: Wec, 191 | pub results: Wec, 192 | } 193 | 194 | #[derive(Copy, Clone, Debug, PartialEq)] 195 | pub struct Limits { 196 | pub min: U32, 197 | pub max: Option, 198 | } 199 | 200 | #[derive(Copy, Clone, Debug, PartialEq)] 201 | pub struct MemType { 202 | pub limits: Limits, 203 | } 204 | 205 | #[derive(Copy, Clone, Debug, PartialEq)] 206 | pub struct TableType { 207 | pub limits: Limits, 208 | pub elemtype: ElemType, 209 | } 210 | 211 | #[derive(Copy, Clone, Eq, PartialEq, Debug)] 212 | pub enum ElemType { 213 | AnyFunc, 214 | } 215 | 216 | #[derive(Copy, Clone, Debug, PartialEq)] 217 | pub struct GlobalType { 218 | pub mutability: Mut, 219 | pub valtype: ValType, 220 | } 221 | 222 | #[derive(Copy, Clone, Eq, PartialEq, Debug)] 223 | pub enum Mut { 224 | Const, 225 | Var, 226 | } 227 | 228 | #[derive(Clone, Debug, PartialEq)] 229 | pub enum ExternType { 230 | Func(FuncType), 231 | Table(TableType), 232 | Mem(MemType), 233 | Global(GlobalType), 234 | } 235 | -------------------------------------------------------------------------------- /greenwasm-validation/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "greenwasm-validation" 3 | version = "0.3.0" 4 | authors = ["Marvin Löbel "] 5 | license = "MIT/Apache-2.0" 6 | 7 | documentation = "https://docs.rs/greenwasm-validation" 8 | description = "An implementation of the validation section from the Webassembly spec." 9 | readme = "README.md" 10 | repository = "https://github.com/Kimundi/greenwasm" 11 | categories = ["wasm"] 12 | keywords = ["validation"] 13 | 14 | workspace = ".." 15 | 16 | [dependencies.greenwasm-structure] 17 | version = "0.3.0" 18 | path = "../greenwasm-structure" 19 | 20 | [badges] 21 | appveyor = { repository = "Kimundi/greenwasm" } 22 | travis-ci = { repository = "Kimundi/greenwasm" } 23 | 24 | is-it-maintained-issue-resolution = { repository = "Kimundi/greenwasm" } 25 | is-it-maintained-open-issues = { repository = "Kimundi/greenwasm" } 26 | 27 | maintenance = { status = "experimental" } 28 | -------------------------------------------------------------------------------- /greenwasm-validation/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 The Rust Project Developers 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /greenwasm-validation/README.md: -------------------------------------------------------------------------------- 1 | # greenwasm-validation 2 | An implementation of the _Validation_ section from the Webassembly spec in Rust. 3 | 4 | Contains a validator for a Wasm Module. 5 | 6 | ## License 7 | 8 | Licensed under either of 9 | 10 | * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) 11 | * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) 12 | 13 | at your option. 14 | 15 | ### Contribution 16 | 17 | Unless you explicitly state otherwise, any contribution intentionally submitted 18 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any 19 | additional terms or conditions. 20 | -------------------------------------------------------------------------------- /src/bin/fuzz_generator.rs: -------------------------------------------------------------------------------- 1 | #![feature(nll)] 2 | 3 | extern crate binaryen; 4 | 5 | use binaryen::tools::*; 6 | 7 | fn main() { 8 | if let (Some(ref seed), Some(ref out)) = (::std::env::args().nth(1), ::std::env::args().nth(2)) { 9 | let seed = std::fs::read(&seed).unwrap(); 10 | let module = translate_to_fuzz_mvp(&seed); 11 | let module = module.write(); 12 | std::fs::write(out, &module).unwrap(); 13 | println!("Wrote wasm of size {}", module.len()); 14 | } else { 15 | println!("Usage: prog "); 16 | ::std::process::exit(1); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/bin/fuzz_launcher.rs: -------------------------------------------------------------------------------- 1 | #![feature(nll)] 2 | extern crate greenwasm; 3 | 4 | use greenwasm::structure::types::*; 5 | use greenwasm::binary_format::*; 6 | use greenwasm::validation::*; 7 | use greenwasm::execution::modules::*; 8 | use greenwasm::execution::runtime_structure::*; 9 | use greenwasm::execution::modules::instantiation::*; 10 | use greenwasm::binary_format; 11 | 12 | fn main() { 13 | let details = ::std::env::args().nth(2) == Some("--details".to_string()); 14 | 15 | if let Some(ref path) = ::std::env::args().nth(1) { 16 | if let Err(e) = ::std::panic::catch_unwind(|| run(path, details).unwrap()) { 17 | let msg = if let Some(s) = e.downcast_ref::() { 18 | &s[..] 19 | } else if let Some(s) = e.downcast_ref::<&'static str>() { 20 | s 21 | } else { 22 | "Unknown panic type" 23 | }; 24 | 25 | println!("Process raised a panic:\n{}", msg); 26 | ::std::process::exit(2); 27 | } 28 | } else { 29 | println!("Usage: prog [--details]"); 30 | ::std::process::exit(1); 31 | } 32 | } 33 | 34 | #[derive(Debug)] 35 | enum FuzzError { 36 | IoError(std::io::Error), 37 | ParseError(binary_format::NomErrorKind), 38 | ValidationError(ValidationError), 39 | InstantiationError(InstantiationError), 40 | } 41 | 42 | fn run(path: &str, details: bool) -> ::std::result::Result<(), FuzzError> { 43 | let file = std::fs::read(&path) 44 | .map_err(FuzzError::IoError)?; 45 | 46 | println!("Parsing..."); 47 | let (module, _custom_sections) = parse_binary_format(&file).map_err(|e| { 48 | if !details { 49 | match e { 50 | ParseError::NomError(e) => { 51 | e.into_error_kind() 52 | } 53 | } 54 | } else { 55 | unimplemented!() 56 | } 57 | }) 58 | .map_err(FuzzError::ParseError)?; 59 | 60 | println!("Validation..."); 61 | let validated_module = validate_module(module) 62 | .map_err(FuzzError::ValidationError)?; 63 | 64 | println!("Instantiation..."); 65 | let mut store = Default::default(); 66 | let mut stack = Stack::new(); 67 | 68 | let moduleaddr = instantiation::instantiate_module(&mut store, &mut stack, &validated_module, &[]) 69 | .map_err(FuzzError::InstantiationError)?; 70 | 71 | println!("Invocation of exports..."); 72 | 73 | assert!(validated_module.start.is_none()); 74 | 75 | let moduleinst = &store.modules[moduleaddr]; 76 | 77 | let mut hanglimitinit = None; 78 | let mut export_addrs = vec![]; 79 | for e in &moduleinst.exports { 80 | //println!("{:?}", e); 81 | if **e.name == "hangLimitInitializer" { 82 | hanglimitinit = Some(if let ExternVal::Func(faddr) = e.value { faddr } else { panic!() }); 83 | } 84 | if e.name.ends_with("_invoker") { 85 | export_addrs.push(if let ExternVal::Func(faddr) = e.value { faddr } else { panic!() }); 86 | } 87 | } 88 | if let Some(hanglimitinit) = hanglimitinit { 89 | invocation::invoke(&mut store, &mut stack, hanglimitinit, &[]).unwrap(); 90 | 91 | for faddr in export_addrs { 92 | let fty = store.funcs[faddr].type_(); 93 | let mut vals = vec![]; 94 | for ty in &fty.args { 95 | match ty { 96 | ValType::I32 => vals.push(Val::I32(0)), 97 | ValType::I64 => vals.push(Val::I64(0)), 98 | ValType::F32 => vals.push(Val::F32(0.0)), 99 | ValType::F64 => vals.push(Val::F64(0.0)), 100 | } 101 | } 102 | 103 | invocation::invoke(&mut store, &mut stack, faddr, &vals).unwrap(); 104 | } 105 | } 106 | 107 | Ok(()) 108 | } 109 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Implementation based on the wasm-core-1 W3C standard 2 | 3 | pub extern crate greenwasm_structure as structure; 4 | pub extern crate greenwasm_validation as validation; 5 | pub extern crate greenwasm_binary_format as binary_format; 6 | pub extern crate greenwasm_execution as execution; 7 | -------------------------------------------------------------------------------- /tests/function_space.wat: -------------------------------------------------------------------------------- 1 | (module 2 | (type $t0 (func (param i32) (result i32))) 3 | (type $t1 (func (param f32))) 4 | (type $t2 (func)) 5 | (import "foo" "bar" (func $foo.bar (type $t1))) 6 | (func $f1 (type $t2) 7 | (nop)) 8 | (table $T0 0 1 anyfunc) 9 | (memory $M0 1 1) 10 | (start 1)) 11 | -------------------------------------------------------------------------------- /tests/wasm_files.rs: -------------------------------------------------------------------------------- 1 | extern crate greenwasm; 2 | 3 | use greenwasm::structure::types::*; 4 | use greenwasm::structure::modules::*; 5 | use greenwasm::structure::instructions::Instr::*; 6 | use greenwasm::structure::instructions::*; 7 | use greenwasm::binary_format::parse_binary_format; 8 | use greenwasm::validation::validate_module; 9 | use greenwasm::execution::modules::instantiation::instantiate_module; 10 | use greenwasm::execution::modules::allocation::*; 11 | use greenwasm::execution::runtime_structure::*; 12 | 13 | fn diff_print(value_is: &T, value_should: &T) -> String { 14 | let value_is = format!("{:#?}", value_is); 15 | let value_should = format!("{:#?}", value_should); 16 | 17 | let a = value_is.as_bytes(); 18 | let b = value_should.as_bytes(); 19 | 20 | let mut i = 0; 21 | let mut j = 0; 22 | for (&a, &b) in a.iter().zip(b.iter()) { 23 | if a == b { 24 | i += 1; 25 | if a == b'\n' { 26 | j = i; 27 | } 28 | } else { 29 | break; 30 | } 31 | } 32 | 33 | let value_is = &value_is[j..]; 34 | let value_should = &value_should[j..]; 35 | 36 | let p = if j != 0 { "...\n" } else { "" }; 37 | 38 | format!("Is:\n{}{}\nShould:\n{}{}", p, value_is, p, value_should) 39 | } 40 | 41 | macro_rules! test_file { 42 | (@ $name:ident, $path:expr, $args:expr, $imports:expr, $module:expr) => ( 43 | #[test] 44 | fn $name() { 45 | let file = std::fs::read($path).unwrap(); 46 | let (module, _custom_sections) = parse_binary_format(&file).unwrap(); 47 | if let Some(ref_module) = $module { 48 | assert!(module == ref_module, "{}", diff_print(&module, &ref_module)); 49 | } 50 | 51 | let validated_module = validate_module(module).unwrap(); 52 | 53 | println!("Is valid with {:?}", validated_module.import_export_mapping()); 54 | 55 | let args = $args; 56 | let mut store = Default::default(); 57 | let mut stack = Stack::new(); 58 | 59 | fn apply<'a, T, F: FnOnce(&'a T, &mut Store<'a>) -> Vec>(args: &'a T, store: &mut Store<'a>, f: F) -> Vec { 60 | f(args, store) 61 | } 62 | 63 | let imports = apply(&args, &mut store, $imports); 64 | 65 | let instance = instantiate_module(&mut store, &mut stack, &validated_module, &imports).unwrap(); 66 | 67 | println!("Is instantiated with addr {:?}", instance); 68 | 69 | } 70 | ); 71 | ($name:ident, $path:expr, $args:expr, $imports:expr) => ( 72 | test_file!(@ $name, $path, $args, $imports, None); 73 | ); 74 | ($name:ident, $path:expr, $args:expr, $imports:expr, $module:expr) => ( 75 | test_file!(@ $name, $path, $args, $imports, Some($module)); 76 | ) 77 | } 78 | 79 | test_file!(factorial, "tests/wasm_files/factorial.wasm", (), |_, _| vec![], Module { 80 | types: vec![ 81 | FuncType { 82 | args: vec![ValType::F64].into(), 83 | results: vec![ValType::F64].into(), 84 | }, 85 | ].into(), 86 | funcs: vec![ 87 | Func { 88 | type_: TypeIdx(0), 89 | locals: vec![].into(), 90 | body: Expr { 91 | body: vec![ 92 | GetLocal(LocalIdx(0)), 93 | F64Const(1.0), 94 | F64Lt, 95 | IfElse(ValType::F64.into(), vec![ 96 | F64Const(1.0), 97 | ], vec![ 98 | GetLocal(LocalIdx(0)), 99 | GetLocal(LocalIdx(0)), 100 | F64Const(1.0), 101 | F64Sub, 102 | Call(FuncIdx(0)), 103 | F64Mul, 104 | ]) 105 | ] 106 | }, 107 | }, 108 | ].into(), 109 | tables: vec![].into(), 110 | mems: vec![].into(), 111 | globals: vec![].into(), 112 | elem: vec![].into(), 113 | data: vec![].into(), 114 | start: None, 115 | imports: vec![].into(), 116 | exports: vec![ 117 | Export { 118 | name: "fac".into(), 119 | desc: ExportDesc::Func(FuncIdx(0)), 120 | }, 121 | ].into(), 122 | }); 123 | 124 | test_file!(stuff, "tests/wasm_files/stuff.wasm", vec![ 125 | FuncType { args: vec![ValType::F32].into(), results: vec![].into() } 126 | ], |args, store| { 127 | let addr = alloc_host_function(store, HostFunc { id: 0 }, &args[0]); 128 | 129 | vec![ExternVal::Func(addr)] 130 | }, Module { 131 | types: vec![ 132 | FuncType { 133 | args: vec![ValType::I32].into(), 134 | results: vec![ValType::I32].into(), 135 | }, 136 | FuncType { 137 | args: vec![ValType::F32].into(), 138 | results: vec![].into(), 139 | }, 140 | FuncType { 141 | args: vec![].into(), 142 | results: vec![].into(), 143 | }, 144 | ].into(), 145 | funcs: vec![ 146 | Func { 147 | type_: TypeIdx(2), 148 | locals: vec![].into(), 149 | body: Expr { 150 | body: vec![ 151 | ] 152 | }, 153 | }, 154 | Func { 155 | type_: TypeIdx(1), 156 | locals: vec![].into(), 157 | body: Expr { 158 | body: vec![ 159 | I32Const(42), 160 | Drop, 161 | ] 162 | }, 163 | }, 164 | ].into(), 165 | tables: vec![ 166 | Table { 167 | type_: TableType { 168 | limits: Limits { 169 | min: 0, 170 | max: Some(1), 171 | }, 172 | elemtype: ElemType::AnyFunc, 173 | } 174 | }, 175 | ].into(), 176 | mems: vec![ 177 | Mem { 178 | type_: MemType { 179 | limits: Limits { 180 | min: 1, 181 | max: Some(1), 182 | } 183 | } 184 | } 185 | ].into(), 186 | globals: vec![].into(), 187 | elem: vec![].into(), 188 | data: vec![ 189 | Data { 190 | data: MemIdx(0), 191 | offset: Expr { 192 | body: vec![ 193 | I32Const(0), 194 | ] 195 | }, 196 | init: vec![ 197 | b'h', 198 | b'i', 199 | ].into(), 200 | }, 201 | ].into(), 202 | start: Some(Start{ func: FuncIdx(1) }), 203 | imports: vec![ 204 | Import { 205 | module: "foo".into(), 206 | name: "bar".into(), 207 | desc: ImportDesc::Func(TypeIdx(1)), 208 | }, 209 | ].into(), 210 | exports: vec![ 211 | Export { 212 | name: "e".into(), 213 | desc: ExportDesc::Func(FuncIdx(1)), 214 | }, 215 | ].into(), 216 | }); 217 | 218 | test_file!(fuzz0, "tests/wasm_files/fuzz0.wasm", (), |_, _| vec![]); 219 | test_file!(pong, "tests/wasm_files/pong.wasm", (), |_, _| vec![]); 220 | test_file!(function_space, "tests/wasm_files/function_space.wasm", vec![ 221 | FuncType { args: vec![ValType::F32].into(), results: vec![].into() } 222 | ], |args, store| { 223 | let addr = alloc_host_function(store, HostFunc { id: 0 }, &args[0]); 224 | 225 | vec![ExternVal::Func(addr)] 226 | }); 227 | test_file!(parser_abort, "tests/wasm_files/parser_abort.wasm", (), |_, _| vec![]); 228 | -------------------------------------------------------------------------------- /tests/wasm_files/factorial.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kimundi/greenwasm/9afe805aa534c752dd1c62b8978a305a9bc2f640/tests/wasm_files/factorial.wasm -------------------------------------------------------------------------------- /tests/wasm_files/function_space.wasm: -------------------------------------------------------------------------------- 1 | asm ``}` foobarp 2 |  namefoo.barf1 -------------------------------------------------------------------------------- /tests/wasm_files/fuzz0.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kimundi/greenwasm/9afe805aa534c752dd1c62b8978a305a9bc2f640/tests/wasm_files/fuzz0.wasm -------------------------------------------------------------------------------- /tests/wasm_files/parser_abort.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kimundi/greenwasm/9afe805aa534c752dd1c62b8978a305a9bc2f640/tests/wasm_files/parser_abort.wasm -------------------------------------------------------------------------------- /tests/wasm_files/pong.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kimundi/greenwasm/9afe805aa534c752dd1c62b8978a305a9bc2f640/tests/wasm_files/pong.wasm -------------------------------------------------------------------------------- /tests/wasm_files/stuff.wasm: -------------------------------------------------------------------------------- 1 | asm ``}` foobarpe 2 | 3 |  A* A hiname  --------------------------------------------------------------------------------