Merge branch 'master' into c-api-cargo-singlepass-feature

This commit is contained in:
Yaron Wittenstein
2019-08-22 11:02:57 +03:00
194 changed files with 28331 additions and 5684 deletions

View File

@ -51,7 +51,7 @@ build_script:
- cargo build --release --manifest-path lib/runtime-c-api/Cargo.toml
test_script:
- cargo test --manifest-path lib/spectests/Cargo.toml --features clif
- cargo test --manifest-path lib/spectests/Cargo.toml --release --features clif -- --nocapture
before_deploy:
- appveyor PushArtifact target\release\wasmer_runtime_c_api.dll

View File

@ -357,6 +357,8 @@ jobs:
VERSION=$(cat ./artifacts/version)
# VERSION_TAG=${CIRCLE_TAG}
VERSION_TAG=$(cat ./artifacts/git_version)
LATEST_VERSION_PUBLISHED_ON_CRATES=$(curl -s https://raw.githubusercontent.com/rust-lang/crates.io-index/master/wa/sm/wasmer-runtime | tail -n 1 | sed 's/.*"vers":"\([^"]*\)".*/\1/')
if ( [ $VERSION_TAG -ne $LATEST_VERSION_PUBLISHED_ON_CRATES ] ) then { echo "Could not detect version published to crates.io; make sure we've published the crates before publishing the Wasmer binary"; exit 1; } else { true; } fi
rm ./artifacts/version
rm ./artifacts/git_version
# VERSION_TAG=$(git describe --exact-match --tags)

View File

@ -5,7 +5,20 @@ All PRs to the Wasmer repository must add to this file.
Blocks of changes will separated by version increments.
## **[Unreleased]**
Special thanks to @YaronWittenstein @penberg for their contributions.
- [#650](https://github.com/wasmerio/wasmer/issues/650) Implement `wasi::path_rename`, improve WASI FS public api, and allow open files to exist even when the underlying file is deleted
- [#643](https://github.com/wasmerio/wasmer/issues/643) Implement `wasi::path_symlink` and improve WASI FS public api IO error reporting
- [#608](https://github.com/wasmerio/wasmer/issues/608) Implement wasi syscalls `fd_allocate`, `fd_sync`, `fd_pread`, `path_link`, `path_filestat_set_times`; update WASI fs API in a WIP way; reduce coupling of WASI code to host filesystem; make debug messages from WASI more readable; improve rights-checking when calling syscalls; implement reference counting on inodes; misc bug fixes and improvements
- [#616](https://github.com/wasmerio/wasmer/issues/616) Create the import object separately from instance instantiation in `runtime-c-api`
- [#620](https://github.com/wasmerio/wasmer/issues/620) Replace one `throw()` with `noexcept` in llvm backend
- [#618](https://github.com/wasmerio/wasmer/issues/618) Implement `InternalEvent::Breakpoint` in the llvm backend to allow metering in llvm
- [#615](https://github.com/wasmerio/wasmer/issues/615) Eliminate `FunctionEnvironment` construction in `feed_event()` speeding up to 70% of compilation in clif
- [#609](https://github.com/wasmerio/wasmer/issues/609) Update dependencies
- [#602](https://github.com/wasmerio/wasmer/issues/602) C api extract instance context from instance
- [#590](https://github.com/wasmerio/wasmer/issues/590) Error visibility changes in wasmer-c-api
- [#589](https://github.com/wasmerio/wasmer/issues/589) Make `wasmer_byte_array` fields `public` in wasmer-c-api
## 0.6.0 - 2019-07-31
- [#603](https://github.com/wasmerio/wasmer/pull/603) Update Wapm-cli, bump version numbers

33
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,33 @@
# How to Contribute to Wasmer
Thank you for your interest in contributing to Wasmer. This document outlines some recommendations on how to contribute.
## Issues & Feature Requests
Please use the issue template and provide a failing example if possible to help us recreate the issue.
## Pull Requests
For large changes, please try reaching the Wasmer using Github Issues or Spectrum Chat to ensure we can accept the change once it is ready.
We recommend trying the following commands before sending a pull request to ensure code quality:
- `cargo fmt --all` Ensures all code is correctly formatted.
- Run `cargo test` in the crates that you are modifying.
- Run `cargo build --all` (nightly) or `cargo build --all --exclude wasmer-singlepass-backend`
A comprehensive CI test suite will be run by a Wasmer team member after the PR has been created.
### Common Build Issues
**LLVM Dependency**
The LLVM backend requires LLVM to be installed to compile.
So, you may run into the following error:
```
Didn't find usable system-wide LLVM.
No suitable version of LLVM was found system-wide or pointed
```
**Singlepass Nightly Only**
The singlepass crate depends on nightly so you may need to add the `+nightly` cargo flag to compile this crate.
`error[E0554]: #![feature] may not be used on the stable release channel`

134
Cargo.lock generated
View File

@ -2,7 +2,7 @@
# It is not intended for manual editing.
[[package]]
name = "aho-corasick"
version = "0.7.4"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -66,7 +66,7 @@ name = "backtrace-sys"
version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -77,7 +77,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -97,7 +97,7 @@ dependencies = [
"peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -109,7 +109,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "blake2b_simd"
version = "0.5.5"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -144,7 +144,7 @@ name = "capstone-sys"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -152,7 +152,7 @@ name = "cargo_toml"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -171,7 +171,7 @@ dependencies = [
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -180,7 +180,7 @@ dependencies = [
[[package]]
name = "cc"
version = "1.0.37"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -243,7 +243,7 @@ name = "cmake"
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -324,7 +324,7 @@ dependencies = [
"rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
"tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -388,7 +388,7 @@ dependencies = [
"csv-core 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -453,7 +453,7 @@ dependencies = [
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -590,7 +590,7 @@ name = "indexmap"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -603,7 +603,7 @@ dependencies = [
"inkwell_internal_macros 0.1.0 (git+https://github.com/wasmerio/inkwell?branch=llvm8-0)",
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
"llvm-sys 80.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -658,7 +658,7 @@ name = "libloading"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -667,10 +667,10 @@ name = "llvm-sys"
version = "80.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -730,7 +730,7 @@ version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -956,7 +956,7 @@ version = "6.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1005,23 +1005,19 @@ dependencies = [
[[package]]
name = "regex"
version = "1.2.0"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
"aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex-syntax"
version = "0.6.10"
version = "0.6.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ucd-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "remove_dir_all"
@ -1101,7 +1097,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.98"
version = "1.0.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1113,15 +1109,15 @@ version = "0.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_bytes"
version = "0.11.1"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1141,7 +1137,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1301,7 +1297,7 @@ name = "tinytemplate"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1310,7 +1306,7 @@ name = "toml"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1318,7 +1314,7 @@ name = "toml"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1326,11 +1322,6 @@ name = "typenum"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ucd-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-segmentation"
version = "1.3.0"
@ -1351,11 +1342,6 @@ name = "unicode-xid"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "utf8-ranges"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "vec_map"
version = "0.8.1"
@ -1373,10 +1359,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "wabt"
version = "0.9.0"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1387,7 +1373,7 @@ name = "wabt-sys"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"cmake 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1411,7 +1397,7 @@ dependencies = [
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-clif-backend 0.6.0",
"wasmer-dev-utils 0.6.0",
"wasmer-emscripten 0.6.0",
@ -1437,9 +1423,9 @@ dependencies = [
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_bytes 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_bytes 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-clif-fork-frontend 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1498,7 +1484,7 @@ name = "wasmer-emscripten-tests"
version = "0.6.0"
dependencies = [
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-clif-backend 0.6.0",
"wasmer-dev-utils 0.6.0",
"wasmer-emscripten 0.6.0",
@ -1520,17 +1506,17 @@ name = "wasmer-llvm-backend"
version = "0.6.0"
dependencies = [
"capstone 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"goblin 0.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
"inkwell 0.1.0 (git+https://github.com/wasmerio/inkwell?branch=llvm8-0)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-runtime-core 0.6.0",
"wasmparser 0.35.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1541,7 +1527,7 @@ name = "wasmer-middleware-common"
version = "0.6.0"
dependencies = [
"criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-clif-backend 0.6.0",
"wasmer-llvm-backend 0.6.0",
"wasmer-runtime-core 0.6.0",
@ -1556,7 +1542,7 @@ dependencies = [
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-clif-backend 0.6.0",
"wasmer-llvm-backend 0.6.0",
"wasmer-runtime-core 0.6.0",
@ -1578,8 +1564,8 @@ name = "wasmer-runtime-core"
version = "0.6.0"
dependencies = [
"bincode 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"blake2b_simd 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"blake2b_simd 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"colored 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1592,9 +1578,9 @@ dependencies = [
"page_size 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_bytes 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_bytes 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmparser 0.35.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1621,7 +1607,8 @@ dependencies = [
name = "wasmer-spectests"
version = "0.6.0"
dependencies = [
"wabt 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-clif-backend 0.6.0",
"wasmer-llvm-backend 0.6.0",
"wasmer-runtime-core 0.6.0",
@ -1637,6 +1624,7 @@ dependencies = [
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-runtime-core 0.6.0",
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1661,7 +1649,7 @@ dependencies = [
"bindgen 0.51.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cmake 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-runtime-core 0.6.0",
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1738,7 +1726,7 @@ dependencies = [
]
[metadata]
"checksum aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "36b7aa1ccb7d7ea3f437cf025a2ab1c47cc6c1bc9fc84918ff449def12f5e282"
"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08abcc3b4e9339e33a3d0a5ed15d84a687350c05689d825e0f6655eef9e76a94"
"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
@ -1750,7 +1738,7 @@ dependencies = [
"checksum bincode 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9f04a5e50dc80b3d5d35320889053637d15011aed5e66b66b37ae798c65da6f7"
"checksum bindgen 0.51.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18270cdd7065ec045a6bb4bdcd5144d14a78b3aedb3bc5111e688773ac8b9ad0"
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
"checksum blake2b_simd 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "627892644fc13118fa3fc40f66723bb45b6b1fb086afcb772f9284cba5db09d5"
"checksum blake2b_simd 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "461f4b879a8eb70c1debf7d0788a9a5ff15f1ea9d25925fea264ef4258bed6b2"
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
"checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101"
"checksum capstone 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "031ba51c39151a1d6336ec859646153187204b0147c7b3f6fe2de636f1b8dbb3"
@ -1758,7 +1746,7 @@ dependencies = [
"checksum cargo_toml 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "097f5ce64ba566a83d9d914fd005de1e5937fdd57d8c5d99a7593040955d75a9"
"checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427"
"checksum cbindgen 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0e7e19db9a3892c88c74cbbdcd218196068a928f1b60e736c448b13a1e81f277"
"checksum cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "39f75544d7bbaf57560d2168f28fd649ff9c76153874db88bdbdfd839b1a7e7d"
"checksum cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "b548a4ee81fccb95919d4e22cfea83c7693ebfd78f0495493178db20b3139da7"
"checksum cexpr 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7fa24eb00d5ffab90eaeaf1092ac85c04c64aaf358ea6f84505b8116d24c6af"
"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
"checksum cgmath 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "64a4b57c8f4e3a2e9ac07e0f6abc9c24b6fc9e1b54c3478cfb598f3d0023e51c"
@ -1853,8 +1841,8 @@ dependencies = [
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
"checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6b23da8dfd98a84bd7e08700190a5d9f7d2d38abd4369dd1dae651bc40bfd2cc"
"checksum regex-syntax 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5485bf1523a9ed51c4964273f22f63f24e31632adb5dad134f488f86a3875c"
"checksum regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88c3d9193984285d544df4a30c23a4e62ead42edf70a4452ceb76dac1ce05c26"
"checksum regex-syntax 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b143cceb2ca5e56d5671988ef8b15615733e7ee16cd348e064333b251b89343f"
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
"checksum rgb 0.8.13 (registry+https://github.com/rust-lang/crates.io-index)" = "4f089652ca87f5a82a62935ec6172a534066c7b97be003cc8f702ee9a7a59c92"
"checksum rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f4dccf6f4891ebcc0c39f9b6eb1a83b9bf5d747cb439ec6fba4f3b977038af"
@ -1866,9 +1854,9 @@ dependencies = [
"checksum scroll_derive 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1aa96c45e7f5a91cb7fabe7b279f02fea7126239fc40b732316e8b6a2d0fcb"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)" = "7fe5626ac617da2f2d9c48af5515a21d5a480dbd151e01bb1c355e26a3e68113"
"checksum serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)" = "fec2851eb56d010dc9a21b89ca53ee75e6528bab60c11e89d38390904982da9f"
"checksum serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d733da87e79faaac25616e33d26299a41143fd4cd42746cbb0e91d8feea243fd"
"checksum serde_bytes 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aaff47db6ef8771cca5d88febef2f22f47f645420e51226374049f68c6b08569"
"checksum serde_bytes 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "45af0182ff64abaeea290235eb67da3825a576c5d53e642c4d5b652e12e6effc"
"checksum serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)" = "01e69e1b8a631f245467ee275b8c757b818653c6d704cdbcaeb56b56767b529c"
"checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d"
"checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
@ -1893,16 +1881,14 @@ dependencies = [
"checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
"checksum toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b8c96d7873fa7ef8bdeb3a9cda3ac48389b4154f32b9803b4bc26220b677b039"
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
"checksum ucd-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa9b3b49edd3468c0e6565d85783f51af95212b6fa3986a5500954f00b460874"
"checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9"
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum wabt 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d07edd40d190ddcbd0113c2150ccb214f47a02ff36958630ba0e5b8138ece1c1"
"checksum wabt 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "94b5f5d6984ca42df66280baa8a15ac188a173ddaf4580b574a98931c01920e7"
"checksum wabt-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b064c81821100adb4b71923cecfc67fef083db21c3bbd454b0162c7ffe63eeaa"
"checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1"
"checksum wasmer-clif-fork-frontend 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bd6bec1587a3b11222f4ff129fd119785713c41de413f54f99d3c03743812f4"

View File

@ -22,7 +22,7 @@ include = [
byteorder = "1.3.2"
errno = "0.2.4"
structopt = "0.2.18"
wabt = "0.9.0"
wabt = "0.9.1"
wasmer-clif-backend = { path = "lib/clif-backend" }
wasmer-singlepass-backend = { path = "lib/singlepass-backend", optional = true }
wasmer-middleware-common = { path = "lib/middleware-common" }
@ -60,7 +60,7 @@ members = [
]
[build-dependencies]
wabt = "0.9.0"
wabt = "0.9.1"
glob = "0.3.0"
rustc_version = "0.2.3"

View File

@ -7,7 +7,7 @@ generate-spectests:
generate-emtests:
WASM_EMSCRIPTEN_GENERATE_EMTESTS=1 cargo build -p wasmer-emscripten-tests --release
generate-wasitests:
generate-wasitests: wasitests-setup
WASM_WASI_GENERATE_WASITESTS=1 cargo build -p wasmer-wasi-tests --release -vv \
&& echo "formatting" \
&& cargo fmt
@ -21,13 +21,13 @@ generate: generate-spectests generate-emtests generate-wasitests
# Spectests
spectests-singlepass:
cargo test --manifest-path lib/spectests/Cargo.toml --release --features singlepass
cargo test --manifest-path lib/spectests/Cargo.toml --release --features singlepass -- --nocapture
spectests-cranelift:
cargo test --manifest-path lib/spectests/Cargo.toml --release --features clif
cargo test --manifest-path lib/spectests/Cargo.toml --release --features clif -- --nocapture
spectests-llvm:
cargo test --manifest-path lib/spectests/Cargo.toml --release --features llvm
cargo test --manifest-path lib/spectests/Cargo.toml --release --features llvm -- --nocapture
spectests: spectests-singlepass spectests-cranelift spectests-llvm
@ -62,13 +62,17 @@ middleware: middleware-singlepass middleware-cranelift middleware-llvm
# Wasitests
wasitests-singlepass:
wasitests-setup:
rm -rf lib/wasi-tests/wasitests/test_fs/temp
mkdir -p lib/wasi-tests/wasitests/test_fs/temp
wasitests-singlepass: wasitests-setup
cargo test --manifest-path lib/wasi-tests/Cargo.toml --release --features singlepass -- --test-threads=1
wasitests-cranelift:
wasitests-cranelift: wasitests-setup
cargo test --manifest-path lib/wasi-tests/Cargo.toml --release --features clif -- --test-threads=1
wasitests-llvm:
wasitests-llvm: wasitests-setup
cargo test --manifest-path lib/wasi-tests/Cargo.toml --release --features llvm -- --test-threads=1
wasitests-unit:
@ -144,7 +148,7 @@ release-llvm:
bench-singlepass:
cargo bench --all --no-default-features --features "backend-singlepass"
bench-clif:
cargo bench --all --no-default-features --features "backend-clif"
cargo bench --all --no-default-features --features "backend-cranelift"
bench-llvm:
cargo bench --all --no-default-features --features "backend-llvm"
@ -152,7 +156,7 @@ bench-llvm:
compile-bench-singlepass:
cargo bench --all --no-run --no-default-features --features "backend-singlepass"
compile-bench-clif:
cargo bench --all --no-run --no-default-features --features "backend-clif"
cargo bench --all --no-run --no-default-features --features "backend-cranelift"
compile-bench-llvm:
cargo bench --all --no-run --no-default-features --features "backend-llvm"

View File

@ -1,6 +1,6 @@
<p align="center">
<a href="https://wasmer.io" target="_blank" rel="noopener noreferrer">
<img width="400" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/logo.png" alt="Wasmer logo">
<img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/logo.png" alt="Wasmer logo">
</a>
</p>

View File

@ -0,0 +1,11 @@
extern "C" {
fn it_works() -> i32;
}
#[no_mangle]
pub fn plugin_entrypoint(n: i32) -> i32 {
let result = unsafe { it_works() };
result + n
}
fn main() {}

Binary file not shown.

View File

@ -35,6 +35,11 @@ dim="\e[2m"
# Warning: Remove this on the public repo
RELEASES_URL="https://github.com/wasmerio/wasmer/releases"
WASMER_VERBOSE="verbose"
if [ -z "$WASMER_INSTALL_LOG" ]; then
WASMER_INSTALL_LOG="$WASMER_VERBOSE"
fi
wasmer_download_json() {
url="$2"
@ -66,9 +71,19 @@ wasmer_download_file() {
# echo "Fetching $url.."
if test -x "$(command -v curl)"; then
code=$(curl --progress-bar -w '%{http_code}' -L "$url" -o "$destination")
if [ "$WASMER_INSTALL_LOG" == "$WASMER_VERBOSE" ]; then
code=$(curl --progress-bar -w '%{http_code}' -L "$url" -o "$destination")
printf "\033[K\n\033[1A"
else
code=$(curl -s -w '%{http_code}' -L "$url" -o "$destination")
fi
elif test -x "$(command -v wget)"; then
code=$(wget --show-progress --progress=bar:force:noscroll -q -O "$destination" --server-response "$url" 2>&1 | awk '/^ HTTP/{print $2}' | tail -1)
if [ "$WASMER_INSTALL_LOG" == "$WASMER_VERBOSE" ]; then
code=$(wget --show-progress --progress=bar:force:noscroll -q -O "$destination" --server-response "$url" 2>&1 | awk '/^ HTTP/{print $2}' | tail -1)
printf "\033[K\n\033[1A";
else
code=$(wget --quiet -O "$destination" --server-response "$url" 2>&1 | awk '/^ HTTP/{print $2}' | tail -1)
fi
else
printf "$red> Neither curl nor wget was available to perform http requests.$reset\n"
exit 1
@ -130,7 +145,7 @@ wasmer_detect_profile() {
wasmer_link() {
printf "$cyan> Adding to bash profile...$reset\n"
WASMER_PROFILE="$(wasmer_detect_profile)"
LOAD_STR="\n# Wasmer\nexport WASMER_DIR=\"$INSTALL_DIRECTORY\"\n[ -s \"\$WASMER_DIR/wasmer.sh\" ] && source \"\$WASMER_DIR/wasmer.sh\" # This loads wasmer\n"
LOAD_STR="\n# Wasmer\nexport WASMER_DIR=\"$INSTALL_DIRECTORY\"\n[ -s \"\$WASMER_DIR/wasmer.sh\" ] && source \"\$WASMER_DIR/wasmer.sh\"\n"
SOURCE_STR="# Wasmer config\nexport WASMER_DIR=\"$INSTALL_DIRECTORY\"\nexport WASMER_CACHE_DIR=\"\$WASMER_DIR/cache\"\nexport PATH=\"\$WASMER_DIR/bin:\$WASMER_DIR/globals/wapm_packages/.bin:\$PATH\"\n"
# We create the wasmer.sh file
@ -152,19 +167,22 @@ wasmer_link() {
# fi
fi
printf "\033[1A$cyan> Adding to bash profile... ✓$reset\n"
printf "${dim}Note: We've added the following to your $WASMER_PROFILE\n"
echo "If this isn't the profile of your current shell then please add the following to your correct profile:"
printf "$LOAD_STR$reset\n"
if [ "$WASMER_INSTALL_LOG" == "$WASMER_VERBOSE" ]; then
printf "${dim}Note: We've added the following to your $WASMER_PROFILE\n"
echo "If you have a different profile please add the following:"
printf "$LOAD_STR$reset\n"
fi
version=`$INSTALL_DIRECTORY/bin/wasmer --version` || (
printf "$red> wasmer was installed, but doesn't seem to be working :($reset\n"
exit 1;
)
printf "$green> Successfully installed $version!\n\n${reset}If you want to have the command available now please execute:\nsource $INSTALL_DIRECTORY/wasmer.sh$reset\n"
printf "\nOtherwise, wasmer and wapm will be available the next time you open the terminal.\n"
echo "Note: during the alpha release of wapm, telemetry is enabled by default; if you would like to opt out, run \`wapm config set telemetry.enabled false\`."
echo "If you notice anything wrong or have any issues, please file a bug at https://github.com/wasmerio/wapm-cli :)"
printf "$green> Successfully installed $version!\n"
if [ "$WASMER_INSTALL_LOG" == "$WASMER_VERBOSE" ]; then
printf "${reset}${dim}wasmer & wapm will be available the next time you open the terminal.\n"
printf "${reset}${dim}If you want to have the commands available now please execute:\n${reset}source $INSTALL_DIRECTORY/wasmer.sh$reset\n"
fi
fi
}
@ -230,33 +248,36 @@ initOS() {
wasmer_install() {
magenta1="${reset}\033[34;1m"
magenta2="${reset}\033[34m"
magenta3="${reset}\033[34;2m"
magenta2=""
magenta3=""
if which wasmer >/dev/null; then
printf "${reset}Updating wasmer$reset\n"
printf "${reset}Updating Wasmer and WAPM$reset\n"
else
printf "${reset}Installing Wasmer!$reset\n"
printf "
${magenta1} ${magenta2} ${magenta3}###${reset}
${magenta1} ${magenta2} ${magenta3}#####${reset}
${magenta1} ${magenta2}### ${magenta3}######${reset}
${magenta1} ${magenta2}###### ${magenta3}#############${reset}
${magenta1}# ${magenta2}####### ${magenta3}##############${reset}
${magenta1}##### ${magenta2}#############${magenta3}#########${reset}
${magenta1}######${magenta2}###############${magenta3}#######${reset}
${magenta1}############${magenta2}#########${magenta3}#######${reset}
${magenta1}##############${magenta2}#######${magenta3}#######${reset}
${magenta1}##############${magenta2}#######${magenta3}#######${reset}
${magenta1}##############${magenta2}#######${magenta3}#######${reset}
${magenta1}##############${magenta2}#######${magenta3} ###${reset}
${magenta1}##############${magenta2}#######
${magenta1}###########${magenta2} ###
${magenta1}########${magenta2}
${magenta1}####${reset}
printf "${reset}Installing Wasmer and WAPM!$reset\n"
if [ "$WASMER_INSTALL_LOG" == "$WASMER_VERBOSE" ]; then
printf "
${magenta1} ww
${magenta1} wwwww
${magenta1} ww wwwwww w
${magenta1} wwwww wwwwwwwww
${magenta1}ww wwwwww w wwwwwww
${magenta1}wwwww wwwwwwwwww wwwww
${magenta1}wwwwww w wwwwwww wwwww
${magenta1}wwwwwwwwwwwwww wwwww wwwww
${magenta1}wwwwwwwwwwwwwww wwwww wwwww
${magenta1}wwwwwwwwwwwwwww wwwww wwwww
${magenta1}wwwwwwwwwwwwwww wwwww wwwww
${magenta1}wwwwwwwwwwwwwww wwwww wwww
${magenta1}wwwwwwwwwwwwwww wwwww
${magenta1} wwwwwwwwwwww wwww
${magenta1} wwwwwwww
${magenta1} wwww
${reset}
"
fi
fi
# if [ -d "$INSTALL_DIRECTORY" ]; then
# if which wasmer; then
# local latest_url
@ -419,7 +440,7 @@ wasmer_download() {
printf "$cyan> Downloading $WASMER_RELEASE_TAG release...$reset\n"
wasmer_download_file "$BINARY_URL" "$DOWNLOAD_FILE"
# echo -en "\b\b"
printf "\033[2A$cyan> Downloading $WASMER_RELEASE_TAG release... ✓$reset\033[K\n"
printf "\033[1A$cyan> Downloading $WASMER_RELEASE_TAG release... ✓$reset\n"
printf "\033[K\n\033[1A"
# printf "\033[1A$cyan> Downloaded$reset\033[K\n"
# echo "Setting executable permissions."
@ -431,9 +452,12 @@ wasmer_download() {
# echo "Moving executable to $INSTALL_DIRECTORY/$INSTALL_NAME"
printf "$cyan> Unpacking contents...$reset\n"
mkdir -p $INSTALL_DIRECTORY
# Untar the wasmer contents in the install directory
tar -C $INSTALL_DIRECTORY -zxvf $DOWNLOAD_FILE
tar -C $INSTALL_DIRECTORY -zxf $DOWNLOAD_FILE
printf "\033[1A$cyan> Unpacking contents... ✓$reset\n"
}
wasmer_verify_or_quit() {

View File

@ -24,12 +24,12 @@ rayon = "1.1.0"
# Dependencies for caching.
[dependencies.serde]
version = "1.0.98"
version = "1.0.99"
features = ["rc"]
[dependencies.serde_derive]
version = "1.0.98"
[dependencies.serde_bytes]
version = "0.11.1"
version = "0.11.2"
[dependencies.serde-bench]
version = "0.0.7"

View File

@ -33,7 +33,7 @@ use wasmer_runtime_core::{
use wasmparser::Type as WpType;
pub struct CraneliftModuleCodeGenerator {
isa: Box<isa::TargetIsa>,
isa: Box<dyn isa::TargetIsa>,
signatures: Option<Arc<Map<SigIndex, FuncSig>>>,
pub clif_signatures: Map<SigIndex, ir::Signature>,
function_signatures: Option<Arc<Map<FuncIndex, SigIndex>>>,

View File

@ -1,6 +1,8 @@
#![deny(
dead_code,
nonstandard_style,
unused_imports,
unused_mut,
unused_variables,
unused_unsafe,
unreachable_patterns
@ -26,7 +28,7 @@ extern crate serde_derive;
extern crate rayon;
extern crate serde;
fn get_isa() -> Box<isa::TargetIsa> {
fn get_isa() -> Box<dyn isa::TargetIsa> {
let flags = {
let mut builder = settings::builder();
builder.set("opt_level", "best").unwrap();

View File

@ -76,8 +76,7 @@ pub extern "C" fn nearbyintf64(x: f64) -> f64 {
}
}
/// A declaration for the stack probe function in Rust's standard library, for
/// catching callstack overflow.
extern "C" {
pub fn __rust_probestack();
}
// FIXME: Is there a replacement on AArch64?
#[cfg(all(target_os = "linux", target_arch = "aarch64"))]
#[no_mangle]
pub extern "C" fn __rust_probestack() {}

View File

@ -88,7 +88,7 @@ impl FuncResolverBuilder {
}
pub fn new(
isa: &isa::TargetIsa,
isa: &dyn isa::TargetIsa,
function_bodies: Map<LocalFuncIndex, ir::Function>,
info: &ModuleInfo,
) -> CompileResult<(Self, HandlerData)> {

View File

@ -138,6 +138,14 @@ pub unsafe fn do_unwind(signum: i32, siginfo: *const c_void, ucontext: *const c_
longjmp(jmp_buf as *mut ::nix::libc::c_void, signum)
}
#[cfg(all(target_os = "linux", target_arch = "aarch64"))]
unsafe fn get_faulting_addr_and_ip(
_siginfo: *const c_void,
_ucontext: *const c_void,
) -> (*const c_void, *const c_void) {
(::std::ptr::null(), ::std::ptr::null())
}
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
unsafe fn get_faulting_addr_and_ip(
siginfo: *const c_void,
@ -230,5 +238,6 @@ unsafe fn get_faulting_addr_and_ip(
#[cfg(not(any(
all(target_os = "macos", target_arch = "x86_64"),
all(target_os = "linux", target_arch = "x86_64"),
all(target_os = "linux", target_arch = "aarch64"),
)))]
compile_error!("This crate doesn't yet support compiling on operating systems other than linux and macos and architectures other than x86_64");

View File

@ -66,7 +66,7 @@ impl Trampolines {
}
}
pub fn new(isa: &isa::TargetIsa, module: &ModuleInfo) -> Self {
pub fn new(isa: &dyn isa::TargetIsa, module: &ModuleInfo) -> Self {
let func_index_iter = module
.exports
.values()

View File

@ -16,7 +16,7 @@ wasmer-llvm-backend = { path = "../llvm-backend", version = "0.6.0", optional =
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.6.0", optional = true }
[dev-dependencies]
wabt = "0.9.0"
wabt = "0.9.1"
wasmer-dev-utils = { path = "../dev-utils", version = "0.6.0"}
[build-dependencies]

View File

@ -42,7 +42,7 @@ macro_rules! assert_emscripten_output {
// let module = compile(&wasm_bytes[..])
// .map_err(|err| format!("Can't create the WebAssembly module: {}", err)).unwrap(); // NOTE: Need to figure what the unwrap is for ??
let mut emscripten_globals = EmscriptenGlobals::new(&module);
let mut emscripten_globals = EmscriptenGlobals::new(&module).expect("globals are valid");
let import_object = generate_emscripten_env(&mut emscripten_globals);
let mut instance = module.instantiate(&import_object)

View File

@ -159,7 +159,7 @@ pub fn _gai_strerror(ctx: &mut Ctx, ecode: i32) -> i32 {
.unwrap()
};
for (i, byte) in bytes.iter().enumerate() {
writer[i].set(*byte as i8);
writer[i].set(*byte as _);
}
string_on_guest.offset() as _
@ -283,7 +283,7 @@ pub fn _getaddrinfo(
.deref(ctx.memory(0), 0, str_size as _)
.unwrap();
for (i, b) in canonname_bytes.into_iter().enumerate() {
guest_canonname_writer[i].set(*b as i8)
guest_canonname_writer[i].set(*b as _)
}
guest_canonname

View File

@ -37,7 +37,7 @@ pub fn execvp(ctx: &mut Ctx, command_name_offset: u32, argv_offset: u32) -> i32
// construct raw pointers and hand them to `execvp`
let command_pointer = command_name_string.as_ptr() as *const i8;
let args_pointer = argv.as_ptr();
unsafe { libc_execvp(command_pointer, args_pointer) }
unsafe { libc_execvp(command_pointer as *const _, args_pointer as *const *const _) }
}
/// execl

View File

@ -23,7 +23,7 @@ pub fn printf(ctx: &mut Ctx, memory_offset: i32, extra: i32) -> i32 {
pub fn chroot(ctx: &mut Ctx, name_ptr: i32) -> i32 {
debug!("emscripten::chroot");
let name = emscripten_memory_pointer!(ctx.memory(0), name_ptr) as *const i8;
unsafe { _chroot(name) }
unsafe { _chroot(name as *const _) }
}
/// getpwuid

View File

@ -1,6 +1,8 @@
#![deny(
dead_code,
nonstandard_style,
unused_imports,
unused_mut,
unused_variables,
unused_unsafe,
unreachable_patterns
@ -14,7 +16,7 @@ use std::collections::HashMap;
use std::path::PathBuf;
use std::{f64, ffi::c_void};
use wasmer_runtime_core::{
error::CallResult,
error::{CallError, CallResult, ResolveError},
export::Export,
func,
global::Global,
@ -371,10 +373,11 @@ pub fn run_emscripten_instance(
0 => {
instance.call(func_name, &[])?;
}
_ => panic!(
"The emscripten main function has received an incorrect number of params {}",
num_params
),
_ => {
return Err(CallError::Resolve(ResolveError::ExportWrongType {
name: "main".to_string(),
}))
}
};
}
@ -402,11 +405,18 @@ fn store_module_arguments(ctx: &mut Ctx, args: Vec<&str>) -> (u32, u32) {
(argc as u32 - 1, argv_offset)
}
pub fn emscripten_set_up_memory(memory: &Memory, globals: &EmscriptenGlobalsData) {
pub fn emscripten_set_up_memory(
memory: &Memory,
globals: &EmscriptenGlobalsData,
) -> Result<(), String> {
let dynamictop_ptr = globals.dynamictop_ptr;
let dynamic_base = globals.dynamic_base;
if (dynamictop_ptr / 4) as usize >= memory.view::<u32>().len() {
return Err("dynamictop_ptr beyond memory len".to_string());
}
memory.view::<u32>()[(dynamictop_ptr / 4) as usize].set(dynamic_base);
Ok(())
}
pub struct EmscriptenGlobalsData {
@ -434,7 +444,7 @@ pub struct EmscriptenGlobals {
}
impl EmscriptenGlobals {
pub fn new(module: &Module /*, static_bump: u32 */) -> Self {
pub fn new(module: &Module /*, static_bump: u32 */) -> Result<Self, String> {
let mut use_old_abort_on_cannot_grow_memory = false;
for (
index,
@ -456,8 +466,8 @@ impl EmscriptenGlobals {
}
}
let (table_min, table_max) = get_emscripten_table_size(&module);
let (memory_min, memory_max, shared) = get_emscripten_memory_size(&module);
let (table_min, table_max) = get_emscripten_table_size(&module)?;
let (memory_min, memory_max, shared) = get_emscripten_memory_size(&module)?;
// Memory initialization
let memory_type = MemoryDescriptor {
@ -486,7 +496,7 @@ impl EmscriptenGlobals {
static_top += 16;
let (dynamic_base, dynamictop_ptr) =
get_emscripten_metadata(&module).unwrap_or_else(|| {
get_emscripten_metadata(&module)?.unwrap_or_else(|| {
let dynamictop_ptr = static_alloc(&mut static_top, 4);
(
align_memory(align_memory(static_top) + TOTAL_STACK),
@ -510,7 +520,7 @@ impl EmscriptenGlobals {
}
};
emscripten_set_up_memory(&memory, &data);
emscripten_set_up_memory(&memory, &data)?;
let mut null_func_names = vec![];
for (
@ -528,14 +538,14 @@ impl EmscriptenGlobals {
}
}
Self {
Ok(Self {
data,
memory,
table,
memory_min,
memory_max,
null_func_names,
}
})
}
}

View File

@ -54,7 +54,7 @@ pub fn killpg(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
pub fn pathconf(ctx: &mut Ctx, path_ptr: i32, name: i32) -> i32 {
debug!("emscripten::pathconf");
let path = emscripten_memory_pointer!(ctx.memory(0), path_ptr) as *const i8;
unsafe { libc::pathconf(path, name).try_into().unwrap() }
unsafe { libc::pathconf(path as *const _, name).try_into().unwrap() }
}
#[cfg(not(unix))]

View File

@ -97,7 +97,7 @@ pub fn ___syscall6(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int
pub fn ___syscall12(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall12 (chdir) {}", _which);
let path_ptr = varargs.get_str(ctx);
let real_path_owned = get_cstr_path(ctx, path_ptr);
let real_path_owned = get_cstr_path(ctx, path_ptr as *const _);
let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
} else {
@ -168,13 +168,13 @@ pub fn ___syscall38(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> i32 {
debug!("emscripten::___syscall38 (rename)");
let old_path = varargs.get_str(ctx);
let new_path = varargs.get_str(ctx);
let real_old_path_owned = get_cstr_path(ctx, old_path);
let real_old_path_owned = get_cstr_path(ctx, old_path as *const _);
let real_old_path = if let Some(ref rp) = real_old_path_owned {
rp.as_c_str().as_ptr()
} else {
old_path
};
let real_new_path_owned = get_cstr_path(ctx, new_path);
let real_new_path_owned = get_cstr_path(ctx, new_path as *const _);
let real_new_path = if let Some(ref rp) = real_new_path_owned {
rp.as_c_str().as_ptr()
} else {
@ -194,7 +194,7 @@ pub fn ___syscall38(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> i32 {
pub fn ___syscall40(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall40 (rmdir)");
let pathname_addr = varargs.get_str(ctx);
let real_path_owned = get_cstr_path(ctx, pathname_addr);
let real_path_owned = get_cstr_path(ctx, pathname_addr as *const _);
let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
} else {
@ -359,7 +359,7 @@ pub fn ___syscall183(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> i32
let buf_writer = buf_offset.deref(ctx.memory(0), 0, len as u32 + 1).unwrap();
for (i, byte) in path_string.bytes().enumerate() {
buf_writer[i].set(byte as i8);
buf_writer[i].set(byte as _);
}
buf_writer[len].set(0);
buf_offset.offset() as i32
@ -535,7 +535,7 @@ pub fn ___syscall195(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
let pathname_addr = varargs.get_str(ctx);
let buf: u32 = varargs.get(ctx);
let real_path_owned = get_cstr_path(ctx, pathname_addr);
let real_path_owned = get_cstr_path(ctx, pathname_addr as *const _);
let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
} else {

View File

@ -146,7 +146,7 @@ pub fn ___syscall5(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int
let pathname_addr = varargs.get_str(ctx);
let flags: i32 = varargs.get(ctx);
let mode: u32 = varargs.get(ctx);
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr);
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr as *const _);
let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
} else {
@ -198,13 +198,13 @@ pub fn ___syscall83(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int
let path1 = varargs.get_str(ctx);
let path2 = varargs.get_str(ctx);
let real_path1_owned = utils::get_cstr_path(ctx, path1);
let real_path1_owned = utils::get_cstr_path(ctx, path1 as *const _);
let real_path1 = if let Some(ref rp) = real_path1_owned {
rp.as_c_str().as_ptr()
} else {
path1
};
let real_path2_owned = utils::get_cstr_path(ctx, path2);
let real_path2_owned = utils::get_cstr_path(ctx, path2 as *const _);
let real_path2 = if let Some(ref rp) = real_path2_owned {
rp.as_c_str().as_ptr()
} else {
@ -227,7 +227,7 @@ pub fn ___syscall85(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> i32 {
let buf = varargs.get_str(ctx);
// let buf_addr: i32 = varargs.get(ctx);
let buf_size: i32 = varargs.get(ctx);
let real_path_owned = get_cstr_path(ctx, pathname_addr);
let real_path_owned = get_cstr_path(ctx, pathname_addr as *const _);
let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
} else {
@ -266,7 +266,7 @@ pub fn ___syscall194(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
pub fn ___syscall198(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall198 (lchown) {}", _which);
let path_ptr = varargs.get_str(ctx);
let real_path_owned = utils::get_cstr_path(ctx, path_ptr);
let real_path_owned = utils::get_cstr_path(ctx, path_ptr as *const _);
let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
} else {
@ -307,7 +307,7 @@ pub fn ___syscall212(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
debug!("emscripten::___syscall212 (chown) {}", _which);
let pathname_addr = varargs.get_str(ctx);
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr);
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr as *const _);
let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
} else {
@ -336,7 +336,7 @@ pub fn ___syscall219(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
pub fn ___syscall33(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall33 (access) {}", _which);
let path = varargs.get_str(ctx);
let real_path_owned = utils::get_cstr_path(ctx, path);
let real_path_owned = utils::get_cstr_path(ctx, path as *const _);
let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
} else {
@ -364,7 +364,7 @@ pub fn ___syscall34(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int
pub fn ___syscall39(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall39 (mkdir) {}", _which);
let pathname_addr = varargs.get_str(ctx);
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr);
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr as *const _);
let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
} else {
@ -986,7 +986,7 @@ pub fn ___syscall122(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
pub fn ___syscall196(ctx: &mut Ctx, _which: i32, mut varargs: VarArgs) -> i32 {
debug!("emscripten::___syscall196 (lstat64) {}", _which);
let path = varargs.get_str(ctx);
let real_path_owned = utils::get_cstr_path(ctx, path);
let real_path_owned = utils::get_cstr_path(ctx, path as *const _);
let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
} else {
@ -1063,7 +1063,7 @@ pub fn ___syscall220(ctx: &mut Ctx, _which: i32, mut varargs: VarArgs) -> i32 {
let upper_bound = std::cmp::min((*dirent).d_reclen, 255) as usize;
let mut i = 0;
while i < upper_bound {
*(dirp.add(pos + 11 + i) as *mut i8) = (*dirent).d_name[i];
*(dirp.add(pos + 11 + i) as *mut i8) = (*dirent).d_name[i] as _;
i += 1;
}
// We set the termination string char

View File

@ -33,29 +33,43 @@ pub fn is_emscripten_module(module: &Module) -> bool {
false
}
pub fn get_emscripten_table_size(module: &Module) -> (u32, Option<u32>) {
pub fn get_emscripten_table_size(module: &Module) -> Result<(u32, Option<u32>), String> {
if module.info().imported_tables.len() == 0 {
return Err("Emscripten requires at least one imported table".to_string());
}
let (_, table) = &module.info().imported_tables[ImportedTableIndex::new(0)];
(table.minimum, table.maximum)
Ok((table.minimum, table.maximum))
}
pub fn get_emscripten_memory_size(module: &Module) -> (Pages, Option<Pages>, bool) {
pub fn get_emscripten_memory_size(module: &Module) -> Result<(Pages, Option<Pages>, bool), String> {
if module.info().imported_memories.len() == 0 {
return Err("Emscripten requires at least one imported memory".to_string());
}
let (_, memory) = &module.info().imported_memories[ImportedMemoryIndex::new(0)];
(memory.minimum, memory.maximum, memory.shared)
Ok((memory.minimum, memory.maximum, memory.shared))
}
/// Reads values written by `-s EMIT_EMSCRIPTEN_METADATA=1`
/// Assumes values start from the end in this order:
/// Last export: Dynamic Base
/// Second-to-Last export: Dynamic top pointer
pub fn get_emscripten_metadata(module: &Module) -> Option<(u32, u32)> {
let max_idx = &module.info().globals.iter().map(|(k, _)| k).max()?;
let snd_max_idx = &module
pub fn get_emscripten_metadata(module: &Module) -> Result<Option<(u32, u32)>, String> {
let max_idx = match module.info().globals.iter().map(|(k, _)| k).max() {
Some(x) => x,
None => return Ok(None),
};
let snd_max_idx = match module
.info()
.globals
.iter()
.map(|(k, _)| k)
.filter(|k| k != max_idx)
.max()?;
.filter(|k| *k != max_idx)
.max()
{
Some(x) => x,
None => return Ok(None),
};
use wasmer_runtime_core::types::{GlobalInit, Initializer::Const, Value::I32};
if let (
@ -68,15 +82,23 @@ pub fn get_emscripten_metadata(module: &Module) -> Option<(u32, u32)> {
..
},
) = (
&module.info().globals[*max_idx],
&module.info().globals[*snd_max_idx],
&module.info().globals[max_idx],
&module.info().globals[snd_max_idx],
) {
Some((
align_memory(*dynamic_base as u32 - 32),
align_memory(*dynamictop_ptr as u32 - 32),
))
let dynamic_base = (*dynamic_base as u32).checked_sub(32).ok_or(format!(
"emscripten unexpected dynamic_base {}",
*dynamic_base as u32
))?;
let dynamictop_ptr = (*dynamictop_ptr as u32).checked_sub(32).ok_or(format!(
"emscripten unexpected dynamictop_ptr {}",
*dynamictop_ptr as u32
))?;
Ok(Some((
align_memory(dynamic_base),
align_memory(dynamictop_ptr),
)))
} else {
None
Ok(None)
}
}
@ -214,7 +236,8 @@ pub fn read_string_from_wasm(memory: &Memory, offset: u32) -> String {
pub fn get_cstr_path(ctx: &mut Ctx, path: *const i8) -> Option<std::ffi::CString> {
use std::collections::VecDeque;
let path_str = unsafe { std::ffi::CStr::from_ptr(path).to_str().unwrap() }.to_string();
let path_str =
unsafe { std::ffi::CStr::from_ptr(path as *const _).to_str().unwrap() }.to_string();
let data = get_emscripten_data(ctx);
let path = PathBuf::from(path_str);
let mut prefix_added = false;

View File

@ -11,7 +11,6 @@ wasmparser = "0.35.1"
smallvec = "0.6.10"
goblin = "0.0.24"
libc = "0.2.60"
nix = "0.14.1"
capstone = { version = "0.6.0", optional = true }
[dependencies.inkwell]
@ -20,18 +19,21 @@ branch = "llvm8-0"
default-features = false
features = ["llvm8-0", "target-x86"]
[target.'cfg(unix)'.dependencies]
nix = "0.14.1"
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3.7", features = ["memoryapi"] }
[build-dependencies]
cc = "1.0"
lazy_static = "1.3.0"
regex = "1.2.0"
regex = "1.2.1"
semver = "0.9"
rustc_version = "0.2.3"
[dev-dependencies]
wabt = "0.9.0"
wabt = "0.9.1"
[features]
debug = ["wasmer-runtime-core/debug"]

View File

@ -1,5 +1,5 @@
//! This file was mostly taken from the llvm-sys crate.
//! (https://bitbucket.org/tari/llvm-sys.rs/src/21ab524ec4df1450035df895209c3f8fbeb8775f/build.rs?at=default&fileviewer=file-view-default)
//! (https://bitbucket.org/tari/llvm-sys.rs/raw/94361c1083a88f439b9d24c59b2d2831517413d7/build.rs)
use lazy_static::lazy_static;
use regex::Regex;
@ -10,23 +10,54 @@ use std::io::{self, ErrorKind};
use std::path::PathBuf;
use std::process::Command;
// Version of the llvm-sys crate that we (through inkwell) depend on.
const LLVM_SYS_MAJOR_VERSION: &str = "80";
const LLVM_SYS_MINOR_VERSION: &str = "0";
// Environment variables that can guide compilation
//
// When adding new ones, they should also be added to main() to force a
// rebuild if they are changed.
lazy_static! {
/// A single path to search for LLVM in (containing bin/llvm-config)
static ref ENV_LLVM_PREFIX: String =
format!("LLVM_SYS_{}_PREFIX", LLVM_SYS_MAJOR_VERSION);
/// If exactly "YES", ignore the version blacklist
static ref ENV_IGNORE_BLACKLIST: String =
format!("LLVM_SYS_{}_IGNORE_BLACKLIST", LLVM_SYS_MAJOR_VERSION);
/// If set, enforce precise correspondence between crate and binary versions.
static ref ENV_STRICT_VERSIONING: String =
format!("LLVM_SYS_{}_STRICT_VERSIONING", LLVM_SYS_MAJOR_VERSION);
/// If set, do not attempt to strip irrelevant options for llvm-config --cflags
static ref ENV_NO_CLEAN_CXXFLAGS: String =
format!("LLVM_SYS_{}_NO_CLEAN_CXXFLAGS", LLVM_SYS_MAJOR_VERSION);
/// If set and targeting MSVC, force the debug runtime library
static ref ENV_USE_DEBUG_MSVCRT: String =
format!("LLVM_SYS_{}_USE_DEBUG_MSVCRT", LLVM_SYS_MAJOR_VERSION);
/// If set, always link against libffi
static ref ENV_FORCE_FFI: String =
format!("LLVM_SYS_{}_FFI_WORKAROUND", LLVM_SYS_MAJOR_VERSION);
}
lazy_static! {
/// LLVM version used by this version of the crate.
static ref CRATE_VERSION: Version = {
let crate_version = Version::parse(env!("CARGO_PKG_VERSION"))
.expect("Crate version is somehow not valid semver");
Version {
major: crate_version.major / 10,
minor: crate_version.major % 10,
.. crate_version
}
Version::new(LLVM_SYS_MAJOR_VERSION.parse::<u64>().unwrap() / 10,
LLVM_SYS_MINOR_VERSION.parse::<u64>().unwrap() % 10,
0)
};
static ref LLVM_CONFIG_BINARY_NAMES: Vec<String> = {
vec![
"llvm-config".into(),
// format!("llvm-config-{}", CRATE_VERSION.major),
// format!("llvm-config-{}.{}", CRATE_VERSION.major, CRATE_VERSION.minor),
format!("llvm-config-{}", CRATE_VERSION.major),
format!("llvm-config-{}.{}", CRATE_VERSION.major, CRATE_VERSION.minor),
]
};
@ -41,21 +72,7 @@ lazy_static! {
// Did the user give us a binary path to use? If yes, try
// to use that and fail if it doesn't work.
let binary_prefix_var = "LLVM_SYS_80_PREFIX";
let path = if let Some(path) = env::var_os(&binary_prefix_var) {
Some(path.to_str().unwrap().to_owned())
} else if let Ok(mut file) = std::fs::File::open(".llvmenv") {
use std::io::Read;
let mut s = String::new();
file.read_to_string(&mut s).unwrap();
s.truncate(s.len() - 4);
Some(s)
} else {
None
};
if let Some(path) = path {
if let Some(path) = env::var_os(&*ENV_LLVM_PREFIX) {
for binary_name in LLVM_CONFIG_BINARY_NAMES.iter() {
let mut pb: PathBuf = path.clone().into();
pb.push("bin");
@ -67,7 +84,7 @@ lazy_static! {
return pb;
} else {
println!("LLVM binaries specified by {} are the wrong version.
(Found {}, need {}.)", binary_prefix_var, ver, *CRATE_VERSION);
(Found {}, need {}.)", *ENV_LLVM_PREFIX, ver, *CRATE_VERSION);
}
}
}
@ -79,7 +96,7 @@ lazy_static! {
refer to the llvm-sys documentation for more information.
llvm-sys: https://crates.io/crates/llvm-sys
llvmenv: https://crates.io/crates/llvmenv", binary_prefix_var);
llvmenv: https://crates.io/crates/llvmenv", *ENV_LLVM_PREFIX);
panic!("Could not find a compatible version of LLVM");
};
}
@ -115,15 +132,55 @@ fn locate_system_llvm_config() -> Option<&'static str> {
None
}
/// Check whether the given version of LLVM is blacklisted,
/// returning `Some(reason)` if it is.
fn is_blacklisted_llvm(llvm_version: &Version) -> Option<&'static str> {
static BLACKLIST: &'static [(u64, u64, u64, &'static str)] = &[];
if let Some(x) = env::var_os(&*ENV_IGNORE_BLACKLIST) {
if &x == "YES" {
println!(
"cargo:warning=Ignoring blacklist entry for LLVM {}",
llvm_version
);
return None;
} else {
println!(
"cargo:warning={} is set but not exactly \"YES\"; blacklist is still honored.",
*ENV_IGNORE_BLACKLIST
);
}
}
for &(major, minor, patch, reason) in BLACKLIST.iter() {
let bad_version = Version {
major: major,
minor: minor,
patch: patch,
pre: vec![],
build: vec![],
};
if &bad_version == llvm_version {
return Some(reason);
}
}
None
}
/// Check whether the given LLVM version is compatible with this version of
/// the crate.
fn is_compatible_llvm(llvm_version: &Version) -> bool {
let strict = env::var_os(format!(
"LLVM_SYS_{}_STRICT_VERSIONING",
env!("CARGO_PKG_VERSION_MAJOR")
))
.is_some()
|| cfg!(feature = "strict-versioning");
if let Some(reason) = is_blacklisted_llvm(llvm_version) {
println!(
"Found LLVM {}, which is blacklisted: {}",
llvm_version, reason
);
return false;
}
let strict =
env::var_os(&*ENV_STRICT_VERSIONING).is_some() || cfg!(feature = "strict-versioning");
if strict {
llvm_version.major == CRATE_VERSION.major && llvm_version.minor == CRATE_VERSION.minor
} else {
@ -184,11 +241,7 @@ fn get_llvm_cxxflags() -> String {
// include flags that aren't understood by the default compiler we're
// using. Unless requested otherwise, clean CFLAGS of options that are
// known to be possibly-harmful.
let no_clean = env::var_os(format!(
"LLVM_SYS_{}_NO_CLEAN_CFLAGS",
env!("CARGO_PKG_VERSION_MAJOR")
))
.is_some();
let no_clean = env::var_os(&*ENV_NO_CLEAN_CXXFLAGS).is_some();
if no_clean || cfg!(target_env = "msvc") {
// MSVC doesn't accept -W... options, so don't try to strip them and
// possibly strip something that should be retained. Also do nothing if
@ -204,20 +257,43 @@ fn get_llvm_cxxflags() -> String {
.join(" ")
}
fn is_llvm_debug() -> bool {
// Has to be either Debug or Release
llvm_config("--build-mode").contains("Debug")
}
fn main() {
println!("cargo:rustc-link-lib=static=llvm-backend");
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=cpp/object_loader.cpp");
println!("cargo:rerun-if-changed=cpp/object_loader.hh");
println!("cargo:rerun-if-env-changed={}", &*ENV_LLVM_PREFIX);
println!("cargo:rerun-if-env-changed={}", &*ENV_IGNORE_BLACKLIST);
println!("cargo:rerun-if-env-changed={}", &*ENV_STRICT_VERSIONING);
println!("cargo:rerun-if-env-changed={}", &*ENV_NO_CLEAN_CXXFLAGS);
println!("cargo:rerun-if-env-changed={}", &*ENV_USE_DEBUG_MSVCRT);
println!("cargo:rerun-if-env-changed={}", &*ENV_FORCE_FFI);
std::env::set_var("CXXFLAGS", get_llvm_cxxflags());
cc::Build::new()
.cpp(true)
.file("cpp/object_loader.cpp")
.compile("llvm-backend");
println!("cargo:rustc-link-lib=static=llvm-backend");
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=cpp/object_loader.cpp");
println!("cargo:rerun-if-changed=cpp/object_loader.hh");
// Enable "nightly" cfg if the current compiler is nightly.
if rustc_version::version_meta().unwrap().channel == rustc_version::Channel::Nightly {
println!("cargo:rustc-cfg=nightly");
}
let use_debug_msvcrt = env::var_os(&*ENV_USE_DEBUG_MSVCRT).is_some();
if cfg!(target_env = "msvc") && (use_debug_msvcrt || is_llvm_debug()) {
println!("cargo:rustc-link-lib={}", "msvcrtd");
}
// Link libffi if the user requested this workaround.
// See https://bitbucket.org/tari/llvm-sys.rs/issues/12/
let force_ffi = env::var_os(&*ENV_FORCE_FFI).is_some();
if force_ffi {
println!("cargo:rustc-link-lib=dylib={}", "ffi");
}
}

View File

@ -10,6 +10,8 @@ use libc::c_char;
use std::{
any::Any,
ffi::{c_void, CString},
fs::File,
io::Write,
mem,
ops::Deref,
ptr::{self, NonNull},
@ -103,6 +105,11 @@ fn get_callbacks() -> Callbacks {
fn_name!("vm.memory.grow.static.local") => vmcalls::local_static_memory_grow as _,
fn_name!("vm.memory.size.static.local") => vmcalls::local_static_memory_size as _,
fn_name!("vm.memory.grow.dynamic.import") => vmcalls::imported_dynamic_memory_grow as _,
fn_name!("vm.memory.size.dynamic.import") => vmcalls::imported_dynamic_memory_size as _,
fn_name!("vm.memory.grow.static.import") => vmcalls::imported_static_memory_grow as _,
fn_name!("vm.memory.size.static.import") => vmcalls::imported_static_memory_size as _,
fn_name!("vm.exception.trap") => throw_trap as _,
fn_name!("vm.breakpoint") => throw_breakpoint as _,
@ -177,6 +184,14 @@ impl LLVMBackend {
.unwrap();
let mem_buf_slice = memory_buffer.as_slice();
if let Some(path) = unsafe { &crate::GLOBAL_OPTIONS.obj_file } {
let mut file = File::create(path).unwrap();
let mut pos = 0;
while pos < mem_buf_slice.len() {
pos += file.write(&mem_buf_slice[pos..]).unwrap();
}
}
let callbacks = get_callbacks();
let mut module: *mut LLVMModule = ptr::null_mut();

View File

@ -1151,7 +1151,9 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
builder.build_store(ptr_to_value, value);
}
GlobalCache::Const { value: _ } => {
unreachable!("cannot set non-mutable globals")
return Err(CodegenError {
message: "global is immutable".to_string(),
});
}
}
}
@ -4639,6 +4641,10 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
self.intrinsics.as_ref().unwrap(),
);
if let Some(path) = unsafe { &crate::GLOBAL_OPTIONS.pre_opt_ir } {
self.module.print_to_file(path).unwrap();
}
let pass_manager = PassManager::create(());
if cfg!(test) {
pass_manager.add_verifier_pass();
@ -4658,7 +4664,9 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
pass_manager.add_slp_vectorize_pass();
pass_manager.run_on(&self.module);
// self.module.print_to_stderr();
if let Some(path) = unsafe { &crate::GLOBAL_OPTIONS.post_opt_ir } {
self.module.print_to_file(path).unwrap();
}
let (backend, cache_gen) = LLVMBackend::new(self.module, self.intrinsics.take().unwrap());
Ok((backend, Box::new(cache_gen)))

View File

@ -1,4 +1,5 @@
use inkwell::{
attributes::{Attribute, AttributeLoc},
builder::Builder,
context::Context,
module::Module,
@ -310,7 +311,7 @@ impl Intrinsics {
i32_ty.fn_type(&[ctx_ptr_ty.as_basic_type_enum(), i32_ty_basic], false);
let ret_i1_take_i1_i1 = i1_ty.fn_type(&[i1_ty_basic, i1_ty_basic], false);
Self {
let intrinsics = Self {
ctlz_i32: module.add_function("llvm.ctlz.i32", ret_i32_take_i32_i1, None),
ctlz_i64: module.add_function("llvm.ctlz.i64", ret_i64_take_i64_i1, None),
@ -531,7 +532,39 @@ impl Intrinsics {
None,
),
ctx_ptr_ty,
}
};
let readonly =
context.create_enum_attribute(Attribute::get_named_enum_kind_id("readonly"), 0);
intrinsics
.memory_size_dynamic_local
.add_attribute(AttributeLoc::Function, readonly);
intrinsics
.memory_size_static_local
.add_attribute(AttributeLoc::Function, readonly);
intrinsics
.memory_size_shared_local
.add_attribute(AttributeLoc::Function, readonly);
intrinsics
.memory_size_dynamic_import
.add_attribute(AttributeLoc::Function, readonly);
intrinsics
.memory_size_static_import
.add_attribute(AttributeLoc::Function, readonly);
intrinsics
.memory_size_shared_import
.add_attribute(AttributeLoc::Function, readonly);
let noreturn =
context.create_enum_attribute(Attribute::get_named_enum_kind_id("noreturn"), 0);
intrinsics
.throw_trap
.add_attribute(AttributeLoc::Function, noreturn);
intrinsics
.throw_breakpoint
.add_attribute(AttributeLoc::Function, noreturn);
intrinsics
}
}

View File

@ -1,6 +1,8 @@
#![deny(
dead_code,
nonstandard_style,
unused_imports,
unused_mut,
unused_variables,
unused_unsafe,
unreachable_patterns
@ -16,6 +18,8 @@ mod state;
mod structs;
mod trampolines;
use std::path::PathBuf;
pub use code::LLVMFunctionCodeGenerator as FunctionCodeGenerator;
pub use code::LLVMModuleCodeGenerator as ModuleCodeGenerator;
@ -27,3 +31,22 @@ pub type LLVMCompiler = SimpleStreamingCompilerGen<
backend::LLVMBackend,
code::CodegenError,
>;
#[derive(Debug, Clone)]
/// LLVM backend flags.
pub struct LLVMOptions {
/// Emit LLVM IR before optimization pipeline.
pub pre_opt_ir: Option<PathBuf>,
/// Emit LLVM IR after optimization pipeline.
pub post_opt_ir: Option<PathBuf>,
/// Emit LLVM generated native code object file.
pub obj_file: Option<PathBuf>,
}
pub static mut GLOBAL_OPTIONS: LLVMOptions = LLVMOptions {
pre_opt_ir: None,
post_opt_ir: None,
obj_file: None,
};

View File

@ -14,7 +14,7 @@ wasmer-llvm-backend = { path = "../llvm-backend", version = "0.6.0", optional =
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.6.0", optional = true }
[dev-dependencies]
wabt = "0.9.0"
wabt = "0.9.1"
criterion = "0.2"
[features]

View File

@ -1,6 +1,8 @@
#![deny(
dead_code,
nonstandard_style,
unused_imports,
unused_mut,
unused_variables,
unused_unsafe,
unreachable_patterns

View File

@ -8,7 +8,7 @@ use std::ptr;
use std::slice;
thread_local! {
static LAST_ERROR: RefCell<Option<Box<Error>>> = RefCell::new(None);
static LAST_ERROR: RefCell<Option<Box<dyn Error>>> = RefCell::new(None);
}
pub fn update_last_error<E: Error + 'static>(err: E) {
@ -18,7 +18,7 @@ pub fn update_last_error<E: Error + 'static>(err: E) {
}
/// Retrieve the most recent error, clearing it in the process.
pub(crate) fn take_last_error() -> Option<Box<Error>> {
pub(crate) fn take_last_error() -> Option<Box<dyn Error>> {
LAST_ERROR.with(|prev| prev.borrow_mut().take())
}

View File

@ -555,7 +555,7 @@ void wasmer_module_destroy(wasmer_module_t *module);
/**
* Given:
* A prepared `wasmer svm` import-object
* A prepared `wasmer` import-object
* A compiled wasmer module
* Instantiates a wasmer instance
*/

View File

@ -438,7 +438,7 @@ wasmer_result_t wasmer_module_deserialize(wasmer_module_t **module,
void wasmer_module_destroy(wasmer_module_t *module);
/// Given:
/// A prepared `wasmer svm` import-object
/// A prepared `wasmer` import-object
/// A compiled wasmer module
/// Instantiates a wasmer instance
wasmer_result_t wasmer_module_import_instantiate(wasmer_instance_t **instance,

View File

@ -26,17 +26,17 @@ features = ["serde-1"]
# Dependencies for caching.
[dependencies.serde]
version = "1.0.98"
version = "1.0.99"
# This feature is required for serde to support serializing/deserializing reference counted pointers (e.g. Rc and Arc).
features = ["rc"]
[dependencies.serde_derive]
version = "1.0.98"
[dependencies.serde_bytes]
version = "0.11.1"
version = "0.11.2"
[dependencies.serde-bench]
version = "0.0.7"
[dependencies.blake2b_simd]
version = "0.5.5"
version = "0.5.6"
[dependencies.digest]
version = "0.8.1"
@ -47,7 +47,7 @@ winapi = { version = "0.3.7", features = ["memoryapi"] }
field-offset = "0.1.1"
[build-dependencies]
blake2b_simd = "0.5.5"
blake2b_simd = "0.5.6"
rustc_version = "0.2.3"
cc = "1.0"

View File

@ -55,11 +55,19 @@ pub struct LocalBacking {
}
impl LocalBacking {
pub(crate) fn new(module: &ModuleInner, imports: &ImportBacking, vmctx: *mut vm::Ctx) -> Self {
pub(crate) fn new(
module: &ModuleInner,
imports: &ImportBacking,
vmctx: *mut vm::Ctx,
) -> LinkResult<Self> {
let mut memories = Self::generate_memories(module);
let mut tables = Self::generate_tables(module);
let mut globals = Self::generate_globals(module, imports);
// Ensure all initializers are valid before running finalizers
Self::validate_memories(module, imports)?;
Self::validate_tables(module, imports, &mut tables)?;
let vm_memories = Self::finalize_memories(module, imports, &mut memories);
let vm_tables = Self::finalize_tables(module, imports, &mut tables, vmctx);
let vm_globals = Self::finalize_globals(&mut globals);
@ -67,7 +75,7 @@ impl LocalBacking {
let dynamic_sigindices = Self::generate_sigindices(&module.info);
let local_functions = Self::generate_local_functions(module);
Self {
Ok(Self {
memories,
tables,
globals,
@ -80,7 +88,7 @@ impl LocalBacking {
local_functions,
internals: Internals([0; INTERNALS_SIZE]),
}
})
}
fn generate_local_functions(module: &ModuleInner) -> BoxedMap<LocalFuncIndex, *const vm::Func> {
@ -117,6 +125,51 @@ impl LocalBacking {
memories.into_boxed_map()
}
/// Validate each locally-defined memory in the Module.
///
/// This involves copying in the data initializers.
fn validate_memories(module: &ModuleInner, imports: &ImportBacking) -> LinkResult<()> {
// Validate data size fits
for init in module.info.data_initializers.iter() {
let init_base = match init.base {
Initializer::Const(Value::I32(offset)) => offset as u32,
Initializer::Const(_) => panic!("a const initializer must be the i32 type"),
Initializer::GetGlobal(import_global_index) => {
if let Value::I32(x) = imports.globals[import_global_index].get() {
x as u32
} else {
panic!("unsupported global type for initializer")
}
}
} as usize;
// Validate data size fits
match init.memory_index.local_or_import(&module.info) {
LocalOrImport::Local(local_memory_index) => {
let memory_desc = module.info.memories[local_memory_index];
let data_top = init_base + init.data.len();
if memory_desc.minimum.bytes().0 < data_top || data_top < init_base {
return Err(vec![LinkError::Generic {
message: "data segment does not fit".to_string(),
}]);
}
}
LocalOrImport::Import(imported_memory_index) => {
// Write the initialization data to the memory that
// we think the imported memory is.
let local_memory = unsafe { &*imports.vm_memories[imported_memory_index] };
let data_top = init_base + init.data.len();
if local_memory.bound < data_top || data_top < init_base {
return Err(vec![LinkError::Generic {
message: "data segment does not fit".to_string(),
}]);
}
}
}
}
Ok(())
}
/// Initialize each locally-defined memory in the Module.
///
/// This involves copying in the data initializers.
@ -126,12 +179,8 @@ impl LocalBacking {
memories: &mut SliceMap<LocalMemoryIndex, Memory>,
) -> BoxedMap<LocalMemoryIndex, *mut vm::LocalMemory> {
// For each init that has some data...
for init in module
.info
.data_initializers
.iter()
.filter(|init| init.data.len() > 0)
{
// Initialize data
for init in module.info.data_initializers.iter() {
let init_base = match init.base {
Initializer::Const(Value::I32(offset)) => offset as u32,
Initializer::Const(_) => panic!("a const initializer must be the i32 type"),
@ -146,10 +195,6 @@ impl LocalBacking {
match init.memory_index.local_or_import(&module.info) {
LocalOrImport::Local(local_memory_index) => {
let memory_desc = module.info.memories[local_memory_index];
let data_top = init_base + init.data.len();
assert!(memory_desc.minimum.bytes().0 >= data_top);
let mem = &memories[local_memory_index];
for (mem_byte, data_byte) in mem.view()[init_base..init_base + init.data.len()]
.iter()
@ -161,15 +206,13 @@ impl LocalBacking {
LocalOrImport::Import(imported_memory_index) => {
// Write the initialization data to the memory that
// we think the imported memory is.
unsafe {
let memory_slice = unsafe {
let local_memory = &*imports.vm_memories[imported_memory_index];
let memory_slice =
slice::from_raw_parts_mut(local_memory.base, local_memory.bound);
slice::from_raw_parts_mut(local_memory.base, local_memory.bound)
};
let mem_init_view =
&mut memory_slice[init_base..init_base + init.data.len()];
mem_init_view.copy_from_slice(&init.data);
}
let mem_init_view = &mut memory_slice[init_base..init_base + init.data.len()];
mem_init_view.copy_from_slice(&init.data);
}
}
}
@ -192,6 +235,50 @@ impl LocalBacking {
tables.into_boxed_map()
}
/// This validates all of the locally-defined tables in the Module.
#[allow(clippy::cast_ptr_alignment)]
fn validate_tables(
module: &ModuleInner,
imports: &ImportBacking,
tables: &mut SliceMap<LocalTableIndex, Table>,
) -> LinkResult<()> {
for init in &module.info.elem_initializers {
let init_base = match init.base {
Initializer::Const(Value::I32(offset)) => offset as u32,
Initializer::Const(_) => panic!("a const initializer must be the i32 type"),
Initializer::GetGlobal(import_global_index) => {
if let Value::I32(x) = imports.globals[import_global_index].get() {
x as u32
} else {
panic!("unsupported global type for initializer")
}
}
} as usize;
match init.table_index.local_or_import(&module.info) {
LocalOrImport::Local(local_table_index) => {
let table = &tables[local_table_index];
if (table.size() as usize) < init_base + init.elements.len() {
return Err(vec![LinkError::Generic {
message: "elements segment does not fit".to_string(),
}]);
}
}
LocalOrImport::Import(import_table_index) => {
let table = &imports.tables[import_table_index];
if (table.size() as usize) < init_base + init.elements.len() {
return Err(vec![LinkError::Generic {
message: "elements segment does not fit".to_string(),
}]);
}
}
}
}
Ok(())
}
/// This initializes all of the locally-defined tables in the Module, e.g.
/// putting all the table elements (function pointers)
/// in the right places.
@ -218,13 +305,6 @@ impl LocalBacking {
match init.table_index.local_or_import(&module.info) {
LocalOrImport::Local(local_table_index) => {
let table = &tables[local_table_index];
if (table.size() as usize) < init_base + init.elements.len() {
let delta = (init_base + init.elements.len()) - table.size() as usize;
// Grow the table if it's too small.
table.grow(delta as u32).expect("couldn't grow table");
}
table.anyfunc_direct_access_mut(|elements| {
for (i, &func_index) in init.elements.iter().enumerate() {
let sig_index = module.info.func_assoc[func_index];
@ -258,12 +338,6 @@ impl LocalBacking {
LocalOrImport::Import(import_table_index) => {
let table = &imports.tables[import_table_index];
if (table.size() as usize) < init_base + init.elements.len() {
let delta = (init_base + init.elements.len()) - table.size() as usize;
// Grow the table if it's too small.
table.grow(delta as u32).expect("couldn't grow table");
}
table.anyfunc_direct_access_mut(|elements| {
for (i, &func_index) in init.elements.iter().enumerate() {
let sig_index = module.info.func_assoc[func_index];

View File

@ -18,7 +18,7 @@ use wasmparser::{self, WasmDecoder};
use wasmparser::{Operator, Type as WpType};
pub type BreakpointHandler =
Box<Fn(BreakpointInfo) -> Result<(), Box<dyn Any>> + Send + Sync + 'static>;
Box<dyn Fn(BreakpointInfo) -> Result<(), Box<dyn Any>> + Send + Sync + 'static>;
pub type BreakpointMap = Arc<HashMap<usize, BreakpointHandler>>;
#[derive(Debug)]
@ -232,7 +232,7 @@ impl<'a, 'b> EventSink<'a, 'b> {
}
pub struct MiddlewareChain {
chain: Vec<Box<GenericFunctionMiddleware>>,
chain: Vec<Box<dyn GenericFunctionMiddleware>>,
}
impl MiddlewareChain {

View File

@ -80,6 +80,9 @@ pub enum LinkError {
expected: GlobalDescriptor,
found: GlobalDescriptor,
},
Generic {
message: String,
},
}
impl PartialEq for LinkError {
@ -107,6 +110,9 @@ impl std::fmt::Display for LinkError {
LinkError::IncorrectTableDescriptor{namespace, name,expected,found} => {
write!(f, "Incorrect table descriptor, namespace: {}, name: {}, expected table descriptor: {:?}, found table descriptor: {:?}", namespace, name, expected, found)
},
LinkError::Generic { message } => {
write!(f, "{}", message)
},
}
}
}

View File

@ -35,7 +35,7 @@ type SetJmpBuffer = [i32; SETJMP_BUFFER_LEN];
struct UnwindInfo {
jmpbuf: SetJmpBuffer, // in
breakpoints: Option<BreakpointMap>,
payload: Option<Box<Any>>, // out
payload: Option<Box<dyn Any>>, // out
}
thread_local! {
@ -89,7 +89,7 @@ pub unsafe fn clear_wasm_interrupt() {
pub unsafe fn catch_unsafe_unwind<R, F: FnOnce() -> R>(
f: F,
breakpoints: Option<BreakpointMap>,
) -> Result<R, Box<Any>> {
) -> Result<R, Box<dyn Any>> {
let unwind = UNWIND.with(|x| x.get());
let old = (*unwind).take();
*unwind = Some(UnwindInfo {
@ -111,7 +111,7 @@ pub unsafe fn catch_unsafe_unwind<R, F: FnOnce() -> R>(
}
}
pub unsafe fn begin_unsafe_unwind(e: Box<Any>) -> ! {
pub unsafe fn begin_unsafe_unwind(e: Box<dyn Any>) -> ! {
let unwind = UNWIND.with(|x| x.get());
let inner = (*unwind)
.as_mut()

View File

@ -46,7 +46,7 @@ impl IsExport for Export {
/// ```
pub struct ImportObject {
map: Rc<RefCell<HashMap<String, Box<dyn LikeNamespace>>>>,
pub(crate) state_creator: Option<Rc<Fn() -> (*mut c_void, fn(*mut c_void))>>,
pub(crate) state_creator: Option<Rc<dyn Fn() -> (*mut c_void, fn(*mut c_void))>>,
pub allow_missing_functions: bool,
}

View File

@ -55,7 +55,7 @@ impl Instance {
Box::new(mem::MaybeUninit::<vm::Ctx>::zeroed());
let import_backing = ImportBacking::new(&module, &imports, vmctx.as_mut_ptr())?;
let backing = LocalBacking::new(&module, &import_backing, vmctx.as_mut_ptr());
let backing = LocalBacking::new(&module, &import_backing, vmctx.as_mut_ptr())?;
let mut inner = Box::pin(InstanceInner {
backing,
@ -500,6 +500,23 @@ impl LikeNamespace for Instance {
}
}
use std::rc::Rc;
impl LikeNamespace for Rc<Instance> {
fn get_export(&self, name: &str) -> Option<Export> {
let export_index = self.module.info.exports.get(name)?;
Some(self.inner.get_export_from_index(&self.module, export_index))
}
fn get_exports(&self) -> Vec<(String, Export)> {
unimplemented!("Use the exports method instead");
}
fn maybe_insert(&mut self, _name: &str, _export: Export) -> Option<()> {
None
}
}
#[must_use]
fn call_func_with_index(
info: &ModuleInfo,

View File

@ -1,6 +1,8 @@
#![deny(
dead_code,
nonstandard_style,
unused_imports,
unused_mut,
unused_variables,
unused_unsafe,
unreachable_patterns

View File

@ -1,263 +0,0 @@
//! This is mostly copied from https://docs.rs/integer-atomics/1.0.2/src/integer_atomics/atomic.rs.html
//! Many thanks to "main()" for writing this.
use std::cell::UnsafeCell;
use std::mem;
use std::num::Wrapping;
use std::ops::{Add, BitAnd, BitOr, BitXor, Sub};
use std::panic::RefUnwindSafe;
use std::sync::atomic::{AtomicUsize, Ordering};
pub trait IntCast:
Copy
+ Eq
+ Add<Output = Self>
+ BitAnd<Output = Self>
+ BitOr<Output = Self>
+ BitXor<Output = Self>
+ Sub<Output = Self>
{
type Public: PartialEq + Copy;
fn from(u: usize) -> Self;
fn to(self) -> usize;
fn new(p: Self::Public) -> Self;
fn unwrap(self) -> Self::Public;
}
macro_rules! intcast {
($($type:ident)+) => {
$(
impl IntCast for $type {
type Public = $type;
fn from(u: usize) -> Self {
u as $type
}
fn to(self) -> usize {
self as usize
}
fn new(p: $type) -> Self {
p
}
fn unwrap(self) -> $type {
self
}
}
)+
}
}
intcast! { u8 i8 u16 i16 u32 i32 u64 i64 }
#[repr(transparent)]
pub struct Atomic<T> {
v: UnsafeCell<Wrapping<T>>,
}
impl<T: Default + IntCast> Default for Atomic<T> {
fn default() -> Self {
Self::new(T::default().unwrap())
}
}
// TODO: impl Debug
unsafe impl<T> Sync for Atomic<T> {}
impl<T> RefUnwindSafe for Atomic<T> {}
fn inject<T>(a: usize, b: usize, offset: usize) -> usize {
let mask = ((1 << (mem::size_of::<T>() * 8)) - 1) << offset;
(a & !mask) | (b << offset)
}
// straight from libcore's atomic.rs
#[inline]
fn strongest_failure_ordering(order: Ordering) -> Ordering {
use self::Ordering::*;
match order {
Release => Relaxed,
Relaxed => Relaxed,
SeqCst => SeqCst,
Acquire => Acquire,
AcqRel => Acquire,
_ => unreachable!(),
}
}
impl<T: IntCast> Atomic<T> {
#[inline]
fn proxy(&self) -> (&AtomicUsize, usize) {
let ptr = self.v.get() as usize;
let aligned = ptr & !(mem::size_of::<usize>() - 1);
(
unsafe { &*(aligned as *const AtomicUsize) },
(ptr - aligned) * 8,
)
}
#[inline]
pub(super) fn new(v: T::Public) -> Self {
Atomic {
v: UnsafeCell::new(Wrapping(T::new(v))),
}
}
#[inline]
pub fn get_mut(&mut self) -> &mut T::Public {
unsafe { &mut *(self.v.get() as *mut T::Public) }
}
#[inline]
pub fn into_inner(self) -> T::Public {
self.v.into_inner().0.unwrap()
}
#[inline]
pub fn load(&self, order: Ordering) -> T::Public {
let (p, o) = self.proxy();
T::from(p.load(order) >> o).unwrap()
}
#[inline]
fn op<F: Fn(T) -> Option<T>>(&self, f: F, order: Ordering) -> T::Public {
self.op_new(f, order, strongest_failure_ordering(order))
}
#[inline]
fn op_new<F: Fn(T) -> Option<T>>(
&self,
f: F,
success: Ordering,
failure: Ordering,
) -> T::Public {
let (p, o) = self.proxy();
let mut old = p.load(Ordering::Relaxed);
loop {
let old_t = T::from(old >> o);
let new_t = match f(old_t) {
Some(x) => x,
None => return old_t.unwrap(),
};
match Self::op_weak(p, o, old, new_t, success, failure) {
Ok(()) => return T::from(old >> o).unwrap(),
Err(prev) => old = prev,
};
}
}
#[inline]
fn op_weak(
p: &AtomicUsize,
o: usize,
old: usize,
new_t: T,
success: Ordering,
failure: Ordering,
) -> Result<(), usize> {
let new = inject::<T>(old, new_t.to(), o);
p.compare_exchange_weak(old, new, success, failure)
.map(|_| ())
}
#[inline]
pub fn store(&self, val: T::Public, order: Ordering) {
self.op(|_| Some(T::new(val)), order);
}
#[inline]
pub fn swap(&self, val: T::Public, order: Ordering) -> T::Public {
self.op(|_| Some(T::new(val)), order)
}
#[inline]
pub fn compare_and_swap(
&self,
current: T::Public,
new: T::Public,
order: Ordering,
) -> T::Public {
self.op(
|x| {
if x == T::new(current) {
Some(T::new(new))
} else {
None
}
},
order,
)
}
#[inline]
pub fn compare_exchange(
&self,
current: T::Public,
new: T::Public,
success: Ordering,
failure: Ordering,
) -> Result<T::Public, T::Public> {
match self.op_new(
|x| {
if x == T::new(current) {
Some(T::new(new))
} else {
None
}
},
success,
failure,
) {
x if x == current => Ok(x),
x => Err(x),
}
}
#[inline]
pub fn compare_exchange_weak(
&self,
current: T::Public,
new: T::Public,
success: Ordering,
failure: Ordering,
) -> Result<T::Public, T::Public> {
let (p, o) = self.proxy();
let old = p.load(Ordering::Relaxed);
let old_t = T::from(old >> o).unwrap();
if old_t != current {
return Err(old_t);
}
Self::op_weak(p, o, old, T::new(new), success, failure)
.map(|()| current)
.map_err(|x| T::from(x >> o).unwrap())
}
#[inline]
pub fn fetch_add(&self, val: T::Public, order: Ordering) -> T::Public {
self.op(|x| Some(x + T::new(val)), order)
}
#[inline]
pub fn fetch_sub(&self, val: T::Public, order: Ordering) -> T::Public {
self.op(|x| Some(x - T::new(val)), order)
}
#[inline]
pub fn fetch_and(&self, val: T::Public, order: Ordering) -> T::Public {
self.op(|x| Some(x & T::new(val)), order)
}
#[inline]
pub fn fetch_or(&self, val: T::Public, order: Ordering) -> T::Public {
self.op(|x| Some(x | T::new(val)), order)
}
#[inline]
pub fn fetch_xor(&self, val: T::Public, order: Ordering) -> T::Public {
self.op(|x| Some(x ^ T::new(val)), order)
}
}

View File

@ -14,12 +14,10 @@ use std::{
rc::Rc,
};
pub use self::atomic::Atomic;
pub use self::dynamic::DynamicMemory;
pub use self::static_::{SharedStaticMemory, StaticMemory};
pub use self::view::{Atomically, MemoryView};
mod atomic;
mod dynamic;
pub mod ptr;
mod static_;
@ -73,6 +71,12 @@ impl Memory {
}
}
if desc.shared && desc.maximum.is_none() {
return Err(CreationError::InvalidDescriptor(
"Max number of pages is required for shared memory".to_string(),
));
}
let variant = if !desc.shared {
MemoryVariant::Unshared(UnsharedMemory::new(desc)?)
} else {
@ -325,4 +329,17 @@ mod memory_tests {
assert_eq!(unshared_memory.size(), Pages(10));
}
#[test]
fn test_invalid_descriptor_returns_error() {
let result = Memory::new(MemoryDescriptor {
minimum: Pages(10),
maximum: None,
shared: true,
});
assert!(
result.is_err(),
"Max number of pages is required for shared memory"
)
}
}

View File

@ -1,8 +1,44 @@
use super::atomic::{Atomic, IntCast};
use crate::types::ValueType;
use std::sync::atomic::{
AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicU16, AtomicU32, AtomicU64, AtomicU8,
};
use std::{cell::Cell, marker::PhantomData, ops::Deref, slice};
pub trait Atomic {
type Output;
}
impl Atomic for i8 {
type Output = AtomicI8;
}
impl Atomic for i16 {
type Output = AtomicI16;
}
impl Atomic for i32 {
type Output = AtomicI32;
}
impl Atomic for i64 {
type Output = AtomicI64;
}
impl Atomic for u8 {
type Output = AtomicU8;
}
impl Atomic for u16 {
type Output = AtomicU16;
}
impl Atomic for u32 {
type Output = AtomicU32;
}
impl Atomic for u64 {
type Output = AtomicU64;
}
impl Atomic for f32 {
type Output = AtomicU32;
}
impl Atomic for f64 {
type Output = AtomicU64;
}
pub trait Atomicity {}
pub struct Atomically;
impl Atomicity for Atomically {}
@ -28,10 +64,10 @@ where
}
}
impl<'a, T: IntCast> MemoryView<'a, T, NonAtomically> {
pub fn atomically(&self) -> MemoryView<'a, T, Atomically> {
impl<'a, T: Atomic> MemoryView<'a, T> {
pub fn atomically(&self) -> MemoryView<'a, T::Output, Atomically> {
MemoryView {
ptr: self.ptr,
ptr: self.ptr as *mut T::Output,
length: self.length,
_phantom: PhantomData,
}
@ -45,9 +81,9 @@ impl<'a, T> Deref for MemoryView<'a, T, NonAtomically> {
}
}
impl<'a, T: IntCast> Deref for MemoryView<'a, T, Atomically> {
type Target = [Atomic<T>];
fn deref(&self) -> &[Atomic<T>] {
unsafe { slice::from_raw_parts(self.ptr as *const Atomic<T>, self.length) }
impl<'a, T> Deref for MemoryView<'a, T, Atomically> {
type Target = [T];
fn deref(&self) -> &[T] {
unsafe { slice::from_raw_parts(self.ptr as *const T, self.length) }
}
}

View File

@ -92,13 +92,13 @@ pub fn read_module<
let mut namespace_builder = Some(StringTableBuilder::new());
let mut name_builder = Some(StringTableBuilder::new());
let mut func_count: usize = ::std::usize::MAX;
let mut func_count: usize = 0;
let mut mcg_info_fed = false;
loop {
use wasmparser::ParserState;
let state = parser.read();
match *state {
ParserState::EndWasm => break,
ParserState::Error(err) => Err(LoadError::Parse(err))?,
ParserState::TypeSectionEntry(ref ty) => {
info.write()
@ -197,9 +197,9 @@ pub fn read_module<
info.write().unwrap().start_func = Some(FuncIndex::new(start_index as usize));
}
ParserState::BeginFunctionBody { .. } => {
let id = func_count.wrapping_add(1);
func_count = id;
if func_count == 0 {
let id = func_count;
if !mcg_info_fed {
mcg_info_fed = true;
info.write().unwrap().namespace_table =
namespace_builder.take().unwrap().finish();
info.write().unwrap().name_table = name_builder.take().unwrap().finish();
@ -280,6 +280,7 @@ pub fn read_module<
.map_err(|x| LoadError::Codegen(x))?;
fcg.finalize()
.map_err(|x| LoadError::Codegen(format!("{:?}", x)))?;
func_count = func_count.wrapping_add(1);
}
ParserState::BeginActiveElementSectionEntry(table_index) => {
let table_index = TableIndex::new(table_index as usize);
@ -369,7 +370,21 @@ pub fn read_module<
info.write().unwrap().globals.push(global_init);
}
ParserState::EndWasm => {
// TODO Consolidate with BeginFunction body if possible
if !mcg_info_fed {
info.write().unwrap().namespace_table =
namespace_builder.take().unwrap().finish();
info.write().unwrap().name_table = name_builder.take().unwrap().finish();
mcg.feed_signatures(info.read().unwrap().signatures.clone())
.map_err(|x| LoadError::Codegen(format!("{:?}", x)))?;
mcg.feed_function_signatures(info.read().unwrap().func_assoc.clone())
.map_err(|x| LoadError::Codegen(format!("{:?}", x)))?;
mcg.check_precondition(&info.read().unwrap())
.map_err(|x| LoadError::Codegen(format!("{:?}", x)))?;
}
break;
}
_ => {}
}
}

View File

@ -261,14 +261,14 @@ impl Protect {
pub fn is_readable(self) -> bool {
match self {
Protect::Read | Protect::ReadWrite | Protect::ReadExec => true,
Protect::Read | Protect::ReadWrite | Protect::ReadExec | Protect::ReadWriteExec => true,
_ => false,
}
}
pub fn is_writable(self) -> bool {
match self {
Protect::ReadWrite => true,
Protect::ReadWrite | Protect::ReadWriteExec => true,
_ => false,
}
}
@ -297,10 +297,12 @@ impl Drop for RawFd {
/// Round `size` up to the nearest multiple of `page_size`.
fn round_up_to_page_size(size: usize, page_size: usize) -> usize {
assert!(page_size.is_power_of_two());
(size + (page_size - 1)) & !(page_size - 1)
}
/// Round `size` down to the nearest multiple of `page_size`.
fn round_down_to_page_size(size: usize, page_size: usize) -> usize {
assert!(page_size.is_power_of_two());
size & !(page_size - 1)
}

View File

@ -763,7 +763,7 @@ mod vm_ctx_tests {
x: u32,
y: bool,
str: String,
finalizer: Box<FnMut()>,
finalizer: Box<dyn FnMut()>,
}
impl Drop for TestData {

View File

@ -25,7 +25,7 @@ optional = true
[dev-dependencies]
tempfile = "3.1.0"
criterion = "0.2"
wabt = "0.9.0"
wabt = "0.9.1"
[dependencies.wasmer-llvm-backend]
path = "../llvm-backend"
@ -45,3 +45,7 @@ default-backend-cranelift = ["cranelift"]
[[bench]]
name = "nginx"
harness = false
[[bench]]
name = "many_instances"
harness = false

View File

@ -0,0 +1,84 @@
#[macro_use]
extern crate criterion;
use criterion::Criterion;
use tempfile::tempdir;
use wasmer_runtime::{
cache::{Cache, FileSystemCache, WasmHash},
compile, func, imports, instantiate, validate, ImportObject,
};
use wasmer_runtime_core::vm::Ctx;
fn it_works(_ctx: &mut Ctx) -> i32 {
5
}
static SIMPLE_WASM: &[u8] = include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/../../examples/no_abi_simple_plugin.wasm"
));
fn hashing_benchmark(c: &mut Criterion) {
c.bench_function("HASH", |b| b.iter(|| WasmHash::generate(SIMPLE_WASM)));
}
fn validate_benchmark(c: &mut Criterion) {
c.bench_function("validate", |b| b.iter(|| validate(SIMPLE_WASM)));
}
fn compile_benchmark(c: &mut Criterion) {
c.bench_function("compile", |b| b.iter(|| compile(SIMPLE_WASM)));
}
fn create_instance_benchmark(c: &mut Criterion) {
let imports = imports!(
"env" => {
"it_works" => func!(it_works),
},
);
c.bench_function("instantiate", move |b| {
b.iter(|| instantiate(&SIMPLE_WASM[..], &imports).unwrap())
});
}
fn create_instance_from_cache_benchmark(c: &mut Criterion) {
let imports = imports!(
"env" => {
"it_works" => func!(it_works),
},
);
let tempdir = tempdir().unwrap();
let mut cache = unsafe {
FileSystemCache::new(tempdir.path()).expect("unable to create file system cache")
};
let module = compile(SIMPLE_WASM).unwrap();
let hash = WasmHash::generate(SIMPLE_WASM);
cache
.store(hash, module)
.expect("unable to store into cache");
c.bench_function("instantiate from cache", move |b| {
b.iter(|| {
let module = cache.load(hash).unwrap();
module.instantiate(&imports).unwrap();
})
});
}
fn calling_fn_benchmark(c: &mut Criterion) {
let imports = imports!(
"env" => {
"it_works" => func!(it_works),
},
);
let instance = instantiate(SIMPLE_WASM, &imports).unwrap();
c.bench_function("calling fn", move |b| {
let entry_point = instance.func::<(i32), i32>("plugin_entrypoint").unwrap();
b.iter(|| entry_point.call(2).unwrap())
});
}
criterion_group! {
name = instance_bench;
config = Criterion::default().sample_size(20);
targets = compile_benchmark, validate_benchmark, hashing_benchmark, create_instance_from_cache_benchmark, calling_fn_benchmark, create_instance_benchmark,
}
criterion_main!(instance_bench);

View File

@ -1,6 +1,8 @@
#![deny(
dead_code,
nonstandard_style,
unused_imports,
unused_mut,
unused_variables,
unused_unsafe,
unreachable_patterns
@ -98,7 +100,7 @@ pub use wasmer_runtime_core::{compile_with, validate};
pub use wasmer_runtime_core::{func, imports};
pub mod memory {
pub use wasmer_runtime_core::memory::{Atomic, Atomically, Memory, MemoryView};
pub use wasmer_runtime_core::memory::{Atomically, Memory, MemoryView};
}
pub mod wasm {

View File

@ -148,7 +148,7 @@ pub struct X64FunctionCode {
breakpoints: Option<
HashMap<
AssemblyOffset,
Box<Fn(BreakpointInfo) -> Result<(), Box<dyn Any>> + Send + Sync + 'static>,
Box<dyn Fn(BreakpointInfo) -> Result<(), Box<dyn Any>> + Send + Sync + 'static>,
>,
>,
returns: SmallVec<[WpType; 1]>,
@ -294,7 +294,7 @@ impl RunnableModule for X64ExecutionContext {
})
}
unsafe fn do_early_trap(&self, data: Box<Any>) -> ! {
unsafe fn do_early_trap(&self, data: Box<dyn Any>) -> ! {
protect_unix::TRAP_EARLY_DATA.with(|x| x.set(Some(data)));
protect_unix::trigger_trap();
}
@ -404,22 +404,22 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, CodegenError>
mut self,
_: &ModuleInfo,
) -> Result<(X64ExecutionContext, Box<dyn CacheGen>), CodegenError> {
let (assembler, breakpoints) = match self.functions.last_mut() {
Some(x) => (x.assembler.take().unwrap(), x.breakpoints.take().unwrap()),
None => {
return Err(CodegenError {
message: "no function",
});
}
let (assembler, function_labels, breakpoints) = match self.functions.last_mut() {
Some(x) => (
x.assembler.take().unwrap(),
x.function_labels.take().unwrap(),
x.breakpoints.take().unwrap(),
),
None => (
self.assembler.take().unwrap(),
self.function_labels.take().unwrap(),
HashMap::new(),
),
};
let total_size = assembler.get_offset().0;
let output = assembler.finalize().unwrap();
let function_labels = if let Some(x) = self.functions.last() {
x.function_labels.as_ref().unwrap()
} else {
self.function_labels.as_ref().unwrap()
};
let mut out_labels: Vec<FuncPtr> = vec![];
let mut out_offsets: Vec<AssemblyOffset> = vec![];

View File

@ -1,6 +1,8 @@
#![deny(
dead_code,
nonstandard_style,
unused_imports,
unused_mut,
unused_variables,
unused_unsafe,
unreachable_patterns

View File

@ -6,19 +6,19 @@ license = "MIT"
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
repository = "https://github.com/wasmerio/wasmer"
edition = "2018"
build = "build/mod.rs"
[dependencies]
glob = "0.3.0"
wasmer-runtime-core = { path = "../runtime-core", version = "0.6.0" }
wasmer-clif-backend = { path = "../clif-backend", version = "0.6.0" }
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.6.0", optional = true }
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.6.0", optional = true }
[build-dependencies]
wabt = "0.9.0"
wabt = "0.9.1"
[dev-dependencies]
wabt = "0.9.0"
wabt = "0.9.1"
[features]
default = ["fast-tests"]

View File

@ -30,3 +30,98 @@ more](https://github.com/wasmerio/wasmer).
This crate allows to test the Wasmer runtime against the official
specification test suite.
This lib 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).
SIMD wast specs are also added here.
These files should be a direct copy of the original [WebAssembly spec tests](/test/core).
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.
## Version
The spectests were last updated at `WebAssembly/spec` commit `a221f2574d7106e92cf8abaf05d5bb1131b19d76`.
## Testcases
Currently supported command assertions:
- [x] `module` _fully implemented_
- [x] `assert_return` _fully implemented_
- [x] `assert_return_canonical_nan` _fully implemented_
- [x] `assert_return_arithmetic_nan` _fully implemented_
- [x] `assert_trap` _fully implemented_
- [x] `assert_invalid` _fully implemented_ (it should not require validation to be performed separate from compilation)
- [x] `assert_malformed` _fully implemented_
- [ ] `assert_uninstantiable` _not implemented, no usages found_
- [x] `assert_exhaustion` _fully implemented_
- [x] `register` _fully implemented_
- [x] `perform_action` _fully implemented_
### Covered spec tests
See `tests/excludes.txt` for current coverage.
### Specific non-supported cases
There are some cases that we decided to skip for now to accelerate the release schedule:
- `SKIP_CALL_INDIRECT_TYPE_MISMATCH`: we implemented traps in a fast way. We haven't yet covered the type mismatch on `call_indirect`. Specs affected:
- `call_indirect.wast`
- `SKIP_CALL_UNDEFINED_ELEMENT`
Tables are imported into every spec module, even for modules that don't expect it. We need to figure out a way to prevent importing of objects that are not explicitly imported into the module.
Currently `cranelift_wasm::ModuleEnvironment` does not provide `declare_table_import`, etc. so there is no meaningful way of fixing this yet.
- `call_indirect.wast`
- `SKIP_SHARED_TABLE` [elem.wast]
Currently sharing tables between instances/modules does not work. Below are some of the reasons it is hard to achieve:
- Rust naturally prevents such because of the possibility of race conditions
- `ImportObject` is just a wrapper, what we really care about is references to its content.
- `Instance::new` contains a mutation points, the part where after getting the object (memory or table) we push values to it
`table[table_element_index] = func_addr`
- Instance has its own created memories and tables and references to them must outlive `Instance::new()`
- Possible strategy:
```rust
// ImportObject should be passed by ref
Instance::new<'a>(..., &ImportObject);
// Add OwnedData to Instance struct
struct OwnedData;
// For parts where mutatation is really needed
fn get_mut(&import) -> &mut ImportObject {
unsafe { transmute::<&ImportObject, &mut ImportObject>(import) }
}
```
- `elem.wast`
- `SKIP_UNARY_OPERATION` [memory_grow.wast]
In some versions of MacOS this is failing (perhaps because of the chip).
More info here:
```
Executing function c82_l299_action_invoke
thread 'test_memory_grow::test_module_5' panicked at 'assertion failed: `(left == right)`
left: `Ok([I32(0)])`,
right: `Ok([I32(31)])`', /Users/distiller/project/target/release/build/wasmer-spectests-98805f54de053dd1/out/spectests.rs:32304:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
failures:
test_memory_grow::test_module_5
```
https://circleci.com/gh/wasmerio/wasmer/9556
### Development
To test locally, try the following commands:
```
RUST_BACKTRACE=1 cargo test --features clif -- --nocapture
RUST_BACKTRACE=1 cargo test --features llvm -- --nocapture
RUST_BACKTRACE=1 cargo +nightly test --features singlepass -- --nocapture
```

View File

@ -1,5 +0,0 @@
mod spectests;
fn main() -> std::io::Result<()> {
spectests::build()
}

View File

@ -1,831 +0,0 @@
//! This file will run at build time to autogenerate Rust tests based on
//! WebAssembly spec tests. It will convert the files indicated in TESTS
//! from "/spectests/{MODULE}.wast" to "/src/spectests/{MODULE}.rs".
use std::collections::HashMap;
use std::fs::File;
use std::path::PathBuf;
use std::{env, fs, io::Write};
use wabt::script::{Action, Command, CommandKind, ModuleBinary, ScriptParser, Value};
use wabt::{wasm2wat_with_features, Features};
static BANNER: &str = "// Rust test file autogenerated with cargo build (build/spectests.rs).
// Please do NOT modify it by hand, as it will be reset on next build.\n";
const TESTS: &[&str] = &[
"spectests/address.wast",
"spectests/align.wast",
"spectests/binary.wast",
"spectests/block.wast",
"spectests/br.wast",
"spectests/br_if.wast",
"spectests/br_table.wast",
"spectests/break_drop.wast",
"spectests/call.wast",
"spectests/call_indirect.wast",
"spectests/comments.wast",
"spectests/const_.wast",
"spectests/conversions.wast",
"spectests/custom.wast",
"spectests/data.wast",
"spectests/elem.wast",
"spectests/endianness.wast",
"spectests/exports.wast",
"spectests/f32_.wast",
"spectests/f32_bitwise.wast",
"spectests/f32_cmp.wast",
"spectests/f64_.wast",
"spectests/f64_bitwise.wast",
"spectests/f64_cmp.wast",
"spectests/fac.wast",
"spectests/float_exprs.wast",
"spectests/float_literals.wast",
"spectests/float_memory.wast",
"spectests/float_misc.wast",
"spectests/forward.wast",
"spectests/func.wast",
"spectests/func_ptrs.wast",
"spectests/get_local.wast",
"spectests/globals.wast",
"spectests/i32_.wast",
"spectests/i64_.wast",
"spectests/if_.wast",
"spectests/int_exprs.wast",
"spectests/int_literals.wast",
"spectests/labels.wast",
"spectests/left_to_right.wast",
"spectests/loop_.wast",
"spectests/memory.wast",
"spectests/memory_grow.wast",
"spectests/memory_redundancy.wast",
"spectests/memory_trap.wast",
"spectests/nop.wast",
"spectests/return_.wast",
"spectests/select.wast",
"spectests/set_local.wast",
"spectests/stack.wast",
"spectests/start.wast",
"spectests/store_retval.wast",
"spectests/switch.wast",
"spectests/tee_local.wast",
"spectests/token.wast",
"spectests/traps.wast",
"spectests/typecheck.wast",
"spectests/types.wast",
"spectests/unwind.wast",
#[cfg(feature = "llvm")]
"spectests/simd.wast",
#[cfg(feature = "llvm")]
"spectests/simd_binaryen.wast",
];
static COMMON: &'static str = r##"
use std::{{f32, f64}};
use wabt::{{wat2wasm_with_features, Error as WabtError}};
use wasmer_runtime_core::import::ImportObject;
use wasmer_runtime_core::types::Value;
use wasmer_runtime_core::{{Instance, module::Module}};
use wasmer_runtime_core::error::Result;
use wasmer_runtime_core::vm::Ctx;
use wasmer_runtime_core::backend::{Compiler, CompilerConfig, Features};
static IMPORT_MODULE: &str = r#"
(module
(type $t0 (func (param i32)))
(type $t1 (func))
(func $print_i32 (export "print_i32") (type $t0) (param $lhs i32))
(func $print (export "print") (type $t1))
(table $table (export "table") 10 20 anyfunc)
(memory $memory (export "memory") 1 2)
(global $global_i32 (export "global_i32") i32 (i32.const 666)))
"#;
fn wat2wasm<S: AsRef<[u8]>>(
source: S,
) -> std::result::Result<Vec<u8>, WabtError> {
let mut features = wabt::Features::new();
features.enable_simd();
wabt::wat2wasm_with_features(source, features)
}
#[cfg(feature = "clif")]
fn get_compiler() -> impl Compiler {
use wasmer_clif_backend::CraneliftCompiler;
CraneliftCompiler::new()
}
#[cfg(feature = "llvm")]
fn get_compiler() -> impl Compiler {
use wasmer_llvm_backend::LLVMCompiler;
LLVMCompiler::new()
}
#[cfg(feature = "singlepass")]
fn get_compiler() -> impl Compiler {
use wasmer_singlepass_backend::SinglePassCompiler;
SinglePassCompiler::new()
}
#[cfg(not(any(feature = "llvm", feature = "clif", feature = "singlepass")))]
fn get_compiler() -> impl Compiler {
panic!("compiler not specified, activate a compiler via features");
use wasmer_clif_backend::CraneliftCompiler;
CraneliftCompiler::new()
}
pub fn generate_imports(extra_imports: Vec<(String, Instance)>) -> ImportObject {
let mut features = wabt::Features::new();
features.enable_simd();
let wasm_binary = wat2wasm_with_features(IMPORT_MODULE.as_bytes(), features).expect("WAST not valid or malformed");
let module = wasmer_runtime_core::compile_with_config(&wasm_binary[..], &get_compiler(), CompilerConfig { features: Features { simd: true }, ..Default::default() })
.expect("WASM can't be compiled");
let instance = module
.instantiate(&ImportObject::new())
.expect("WASM can't be instantiated");
let mut imports = ImportObject::new();
imports.register("spectest", instance);
for (name, instance) in extra_imports {
imports.register(name, instance);
}
imports
}
/// Bit pattern of an f32 value:
/// 1-bit sign + 8-bit mantissa + 23-bit exponent = 32 bits
///
/// Bit pattern of an f64 value:
/// 1-bit sign + 11-bit mantissa + 52-bit exponent = 64 bits
///
/// NOTE: On some old platforms (PA-RISC, some MIPS) quiet NaNs (qNaN) have
/// their mantissa MSB unset and set for signaling NaNs (sNaN).
///
/// Links:
/// * https://en.wikipedia.org/wiki/Floating-point_arithmetic
/// * https://github.com/WebAssembly/spec/issues/286
/// * https://en.wikipedia.org/wiki/NaN
///
pub trait NaNCheck {
fn is_quiet_nan(&self) -> bool;
fn is_canonical_nan(&self) -> bool;
}
impl NaNCheck for f32 {
/// The MSB of the mantissa must be set for a NaN to be a quiet NaN.
fn is_quiet_nan(&self) -> bool {
let bit_mask = 0b1 << 22; // Used to check if 23rd bit is set, which is MSB of the mantissa
self.is_nan() && (self.to_bits() & bit_mask) == bit_mask
}
/// For a NaN to be canonical, its mantissa bits must all be unset
fn is_canonical_nan(&self) -> bool {
let bit_mask: u32 = 0b1____0000_0000____011_1111_1111_1111_1111_1111;
let masked_value = self.to_bits() ^ bit_mask;
masked_value == 0xFFFF_FFFF || masked_value == 0x7FFF_FFFF
}
}
impl NaNCheck for f64 {
/// The MSB of the mantissa must be set for a NaN to be a quiet NaN.
fn is_quiet_nan(&self) -> bool {
let bit_mask = 0b1 << 51; // Used to check if 52st bit is set, which is MSB of the mantissa
self.is_nan() && (self.to_bits() & bit_mask) == bit_mask
}
/// For a NaN to be canonical, its mantissa bits must all be unset
fn is_canonical_nan(&self) -> bool {
let bit_mask: u64 =
0b1____000_0000_0000____0111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111;
let masked_value = self.to_bits() ^ bit_mask;
masked_value == 0x7FFF_FFFF_FFFF_FFFF || masked_value == 0xFFF_FFFF_FFFF_FFFF
}
}
"##;
fn wabt2rust_type(v: &Value) -> String {
match v {
Value::I32(_v) => format!("i32"),
Value::I64(_v) => format!("i64"),
Value::F32(_v) => format!("f32"),
Value::F64(_v) => format!("f64"),
Value::V128(_v) => format!("u128"),
}
}
fn wabt2rust_type_destructure(v: &Value, placeholder: &str) -> String {
match v {
Value::I32(_v) => format!("Value::I32({})", placeholder),
Value::I64(_v) => format!("Value::I64({})", placeholder),
Value::F32(_v) => format!("Value::F32({})", placeholder),
Value::F64(_v) => format!("Value::F64({})", placeholder),
Value::V128(_v) => format!("Value::V128({})", placeholder),
}
}
fn is_nan(v: &Value) -> bool {
if let Value::F32(v) = v {
return v.is_nan();
} else if let Value::F64(v) = v {
return v.is_nan();
}
return false;
}
fn wabt2rust_value_bare(v: &Value) -> String {
match v {
Value::I32(v) => format!("{:?} as i32", v),
Value::I64(v) => format!("{:?} as i64", v),
Value::F32(v) => {
if v.is_infinite() {
if v.is_sign_negative() {
"f32::NEG_INFINITY".to_string()
} else {
"f32::INFINITY".to_string()
}
} else if v.is_nan() {
// Support for non-canonical NaNs
format!("f32::from_bits({:?})", v.to_bits())
} else {
format!("{:?}", v)
}
}
Value::F64(v) => {
if v.is_infinite() {
if v.is_sign_negative() {
"f64::NEG_INFINITY".to_string()
} else {
"f64::INFINITY".to_string()
}
} else if v.is_nan() {
format!("f64::from_bits({:?})", v.to_bits())
} else {
format!("{:?}", v)
}
}
Value::V128(v) => format!("{:?} as u128", v),
}
}
fn wabt2rust_value(v: &Value) -> String {
match v {
Value::I32(v) => format!("Value::I32({:?} as i32)", v),
Value::I64(v) => format!("Value::I64({:?} as i64)", v),
Value::F32(v) => {
if v.is_infinite() {
if v.is_sign_negative() {
"Value::F32(f32::NEG_INFINITY)".to_string()
} else {
"Value::F32(f32::INFINITY)".to_string()
}
} else if v.is_nan() {
// Support for non-canonical NaNs
format!("Value::F32(f32::from_bits({:?}))", v.to_bits())
} else {
format!("Value::F32(({:?}f32))", v)
}
}
Value::F64(v) => {
if v.is_infinite() {
if v.is_sign_negative() {
"Value::F64(f64::NEG_INFINITY)".to_string()
} else {
"Value::F64(f64::INFINITY)".to_string()
}
} else if v.is_nan() {
format!("Value::F64(f64::from_bits({:?}))", v.to_bits())
} else {
format!("Value::F64(({:?}f64))", v)
}
}
Value::V128(v) => format!("Value::V128({:?} as u128)", v),
}
}
struct WastTestGenerator {
last_module: i32,
last_line: u64,
command_no: i32,
script_parser: ScriptParser,
module_calls: HashMap<i32, Vec<String>>,
buffer: String,
modules_by_name: HashMap<String, i32>,
registered_modules: Vec<(i32, String)>,
}
impl WastTestGenerator {
fn new(path: &PathBuf) -> Self {
let filename = path.file_name().unwrap().to_str().unwrap();
let source = fs::read(&path).unwrap();
let mut features = wabt::Features::new();
features.enable_simd();
let script: ScriptParser =
ScriptParser::from_source_and_name_with_features(&source, filename, features)
.expect(&format!("Failed to parse script {}", &filename));
let buffer = String::new();
WastTestGenerator {
last_module: 0,
last_line: 0,
command_no: 0,
script_parser: script,
buffer: buffer,
module_calls: HashMap::new(),
modules_by_name: HashMap::new(),
registered_modules: Vec::new(),
}
}
fn is_fat_test(&self) -> bool {
self.command_no > 200
}
fn consume(&mut self) {
self.buffer.push_str(BANNER);
// self.buffer.push_str(&format!(
// "// Test based on spectests/{}
// #![allow(
// warnings,
// dead_code
// )]
// //use wabt::wat2wasm;
// use std::{{f32, f64}};
// use wasmer_runtime_core::types::Value;
// use wasmer_runtime_core::{{Instance, module::Module}};
// //use crate::spectests::_common::{{
// // generate_imports,
// // NaNCheck,
// //}};\n\n",
// self.filename
// ));
while let Some(Command { line, kind }) = &self.script_parser.next().unwrap() {
self.last_line = line.clone();
self.buffer
.push_str(&format!("\n// Line {}\n", self.last_line));
self.visit_command(&kind);
self.command_no = self.command_no + 1;
}
for n in 1..self.last_module + 1 {
self.flush_module_calls(n);
}
}
fn command_name(&self) -> String {
format!("c{}_l{}", self.command_no, self.last_line)
}
fn flush_module_calls(&mut self, module: i32) {
let calls: Vec<String> = self
.module_calls
.entry(module)
.or_insert(Vec::new())
.iter()
.map(|call_str| format!("{}(&mut instance);", call_str))
.collect();
if calls.len() > 0 {
self.buffer.push_str(
format!(
"\n#[test]
fn test_module_{}() {{
let mut instance = create_module_{}();
// We group the calls together
{}
}}\n",
module,
module,
calls.join("\n ")
)
.as_str(),
);
}
self.module_calls.remove(&module);
}
fn visit_module(&mut self, module: &ModuleBinary, name: &Option<String>) {
let wasm_binary: Vec<u8> = module.clone().into_vec();
let mut features = Features::new();
features.enable_simd();
let wast_string =
wasm2wat_with_features(wasm_binary, features).expect("Can't convert back to wasm");
let last_module = self.last_module;
self.flush_module_calls(last_module);
self.last_module = self.last_module + 1;
// self.module_calls.insert(self.last_module, vec![]);
self.buffer.push_str(
format!(
"fn create_module_{}() -> Instance {{
let module_str = \"{}\";
println!(\"{{}}\", module_str);
let wasm_binary = wat2wasm(module_str.as_bytes()).expect(\"WAST not valid or malformed\");
let module = wasmer_runtime_core::compile_with_config(&wasm_binary[..], &get_compiler(), CompilerConfig {{ features: Features {{ simd: true }}, ..Default::default() }}).expect(\"WASM can't be compiled\");
let mut extra_imports = Vec::new();
{}
module.instantiate(&generate_imports(extra_imports)).expect(\"WASM can't be instantiated\")
}}\n",
self.last_module,
// We do this to ident four spaces, so it looks aligned to the function body
wast_string
.replace("\n", "\n ")
.replace("\\", "\\\\")
.replace("\"", "\\\""),
self.registered_modules.iter().map(|(number, name)| format!("extra_imports.push((String::from(\"{}\"), create_module_{}()));", name, number)).fold(String::from(""), |acc, x| format!("{}{}\n", acc, x)),
)
.as_str(),
);
if let Some(name) = name {
self.record_named_module(name);
}
}
fn record_named_module(&mut self, name: &String) {
self.modules_by_name.insert(name.clone(), self.last_module);
}
fn visit_register_module(&mut self, name: &String, as_name: &String) {
self.registered_modules
.push((*self.modules_by_name.get(name).unwrap(), as_name.clone()));
}
fn visit_assert_invalid(&mut self, module: &ModuleBinary) {
let wasm_binary: Vec<u8> = module.clone().into_vec();
// let wast_string = wasm2wat(wasm_binary).expect("Can't convert back to wasm");
let command_name = self.command_name();
self.buffer.push_str(
format!(
"#[test]
fn {}_assert_invalid() {{
let wasm_binary = {:?};
let module = wasmer_runtime_core::compile_with_config(&wasm_binary, &get_compiler(), CompilerConfig {{ features: Features {{ simd: true }}, ..Default::default() }});
assert!(module.is_err(), \"WASM should not compile as is invalid\");
}}\n",
command_name,
wasm_binary,
// We do this to ident four spaces back
// String::from_utf8_lossy(&wasm_binary),
// wast_string.replace("\n", "\n "),
)
.as_str(),
);
}
// TODO: Refactor repetitive code
fn visit_assert_return_arithmetic_nan(&mut self, action: &Action) {
match action {
Action::Invoke {
module: _,
field,
args,
} => {
// let return_type = wabt2rust_type(&args[0]);
// let func_return = format!(" -> {}", return_type);
let assertion = String::from(
"assert!(match result {
Value::F32(fp) => fp.is_quiet_nan(),
Value::F64(fp) => fp.is_quiet_nan(),
_ => unimplemented!()
})",
);
// We map the arguments provided into the raw Arguments provided
// to libffi
// let args_types: Vec<String> = args.iter().map(wabt2rust_type).collect();
// args_types.push("&Instance".to_string());
let args_values: Vec<String> = args.iter().map(wabt2rust_value).collect();
// args_values.push("&result_object.instance".to_string());
let func_name = format!("{}_assert_return_arithmetic_nan", self.command_name());
self.buffer.push_str(
format!(
"fn {func_name}(instance: &mut Instance) {{
println!(\"Executing function {{}}\", \"{func_name}\");
let result = instance.call(\"{field}\", &[{args_values}]).unwrap().first().expect(\"Missing result in {func_name}\").clone();
{assertion}
}}\n",
func_name=func_name,
field=field,
args_values=args_values.join(", "),
assertion=assertion,
)
.as_str(),
);
// field=field,
// args_types=args_types.join(", "),
// func_return=func_return,
self.module_calls
.entry(self.last_module)
.or_insert(Vec::new())
.push(func_name);
// let mut module_calls = self.module_calls.get(&self.last_module).unwrap();
// module_calls.push(func_name);
}
_ => {}
};
}
// PROBLEM: Im assuming the return type from the first argument type
// and wabt does gives us the `expected` result
// TODO: Refactor repetitive code
fn visit_assert_return_canonical_nan(&mut self, action: &Action) {
match action {
Action::Invoke {
module: _,
field,
args,
} => {
let _return_type = match &field.as_str() {
&"f64.promote_f32" => String::from("f64"),
&"f32.promote_f64" => String::from("f32"),
_ => wabt2rust_type(&args[0]),
};
// let func_return = format!(" -> {}", return_type);
let assertion = String::from(
"assert!(match result {
Value::F32(fp) => fp.is_quiet_nan(),
Value::F64(fp) => fp.is_quiet_nan(),
_ => unimplemented!()
})",
);
// We map the arguments provided into the raw Arguments provided
// to libffi
// let args_types: Vec<String> = args.iter().map(wabt2rust_type).collect();
// args_types.push("&Instance".to_string());
let args_values: Vec<String> = args.iter().map(wabt2rust_value).collect();
// args_values.push("&result_object.instance".to_string());
let func_name = format!("{}_assert_return_canonical_nan", self.command_name());
self.buffer.push_str(
format!(
"fn {func_name}(instance: &mut Instance) {{
println!(\"Executing function {{}}\", \"{func_name}\");
let result = instance.call(\"{field}\", &[{args_values}]).unwrap().first().expect(\"Missing result in {func_name}\").clone();
{assertion}
}}\n",
func_name=func_name,
field=field,
args_values=args_values.join(", "),
assertion=assertion,
)
.as_str(),
);
self.module_calls
.entry(self.last_module)
.or_insert(Vec::new())
.push(func_name);
// let mut module_calls = self.module_calls.get(&self.last_module).unwrap();
// module_calls.push(func_name);
}
_ => {}
};
}
fn visit_assert_malformed(&mut self, module: &ModuleBinary) {
let wasm_binary: Vec<u8> = module.clone().into_vec();
let command_name = self.command_name();
// let wast_string = wasm2wat(wasm_binary).expect("Can't convert back to wasm");
self.buffer.push_str(
format!(
"#[test]
fn {}_assert_malformed() {{
let wasm_binary = {:?};
let compilation = wasmer_runtime_core::compile_with_config(&wasm_binary, &get_compiler(), CompilerConfig {{ features: Features {{ simd: true }}, ..Default::default() }});
assert!(compilation.is_err(), \"WASM should not compile as is malformed\");
}}\n",
command_name,
wasm_binary,
// We do this to ident four spaces back
// String::from_utf8_lossy(&wasm_binary),
// wast_string.replace("\n", "\n "),
)
.as_str(),
);
}
// TODO: Refactor repetitive code
fn visit_action(&mut self, action: &Action, expected: Option<&Vec<Value>>) -> Option<String> {
match action {
Action::Invoke {
module: _,
field,
args,
} => {
let (_func_return, assertion) = match expected {
Some(expected) => {
let func_return = if expected.len() > 0 {
format!(" -> {}", wabt2rust_type(&expected[0]))
} else {
"".to_string()
};
let expected_result = if expected.len() > 0 {
wabt2rust_value_bare(&expected[0])
} else {
"should not use this expect result".to_string()
};
let expected_vec_result = if expected.len() > 0 {
format!("Ok(vec![{}])", wabt2rust_value(&expected[0]))
} else {
"Ok(vec![])".to_string()
};
let return_type = if expected.len() > 0 {
wabt2rust_type(&expected[0])
} else {
"should not use this return type".to_string()
};
let return_type_destructure = if expected.len() > 0 {
wabt2rust_type_destructure(&expected[0], "result")
} else {
"should not use this result return type destructure".to_string()
};
let _expected_type_destructure = if expected.len() > 0 {
wabt2rust_type_destructure(&expected[0], "expected")
} else {
"should not use this expected return type destructure".to_string()
};
let assertion = if expected.len() > 0 && is_nan(&expected[0]) {
format!(
"let expected = {expected_result};
if let {return_type_destructure} = result.as_ref().unwrap().first().unwrap() {{
assert!((*result as {return_type}).is_nan());
assert_eq!((*result as {return_type}).is_sign_positive(), (expected as {return_type}).is_sign_positive());
}} else {{
panic!(\"Unexpected result type {{:?}}\", result);
}}",
expected_result=expected_result,
return_type=return_type,
return_type_destructure=return_type_destructure
)
} else {
format!("assert_eq!(result, {});", expected_vec_result)
};
(func_return, assertion)
}
None => ("".to_string(), "".to_string()),
};
// We map the arguments provided into the raw Arguments provided
// to libffi
// let mut args_types: Vec<String> = args.iter().map(wabt2rust_type).collect();
// args_types.push("&Instance".to_string());
let args_values: Vec<String> = args.iter().map(wabt2rust_value).collect();
// args_values.push("&result_object.instance".to_string());
let func_name = format!("{}_action_invoke", self.command_name());
self.buffer.push_str(
format!(
"fn {func_name}(instance: &mut Instance) -> Result<()> {{
println!(\"Executing function {{}}\", \"{func_name}\");
let result = instance.call(\"{field}\", &[{args_values}]);
{assertion}
result?;
Ok(())
}}\n",
func_name = func_name,
field = field,
args_values = args_values.join(", "),
assertion = assertion,
)
.as_str(),
);
Some(func_name)
// let mut module_calls = self.module_calls.get(&self.last_module).unwrap();
// module_calls.push(func_name);
}
_ => None,
}
}
fn visit_assert_return(&mut self, action: &Action, expected: &Vec<Value>) {
let action_fn_name = self.visit_action(action, Some(expected));
if action_fn_name.is_none() {
return;
}
self.module_calls
.entry(self.last_module)
.or_insert(Vec::new())
.push(action_fn_name.unwrap());
}
fn visit_perform_action(&mut self, action: &Action) {
let action_fn_name = self.visit_action(action, None);
if action_fn_name.is_none() {
return;
}
self.module_calls
.entry(self.last_module)
.or_insert(Vec::new())
.push(action_fn_name.unwrap());
}
fn visit_assert_trap(&mut self, action: &Action) {
let action_fn_name = self.visit_action(action, None);
if action_fn_name.is_none() {
return;
}
let trap_func_name = format!("{}_assert_trap", self.command_name());
self.buffer.push_str(
format!(
"
#[test]
fn {}() {{
let mut instance = create_module_{}();
let result = {}(&mut instance);
assert!(result.is_err());
}}\n",
trap_func_name,
self.last_module,
action_fn_name.unwrap(),
)
.as_str(),
);
// We don't group trap calls as they may cause memory faults
// on the instance memory. So we test them alone.
// self.module_calls
// .entry(self.last_module)
// .or_insert(Vec::new())
// .push(trap_func_name);
}
fn visit_command(&mut self, cmd: &CommandKind) {
match cmd {
CommandKind::Module { module, name } => {
self.visit_module(module, name);
}
CommandKind::AssertReturn { action, expected } => {
self.visit_assert_return(action, expected)
}
CommandKind::AssertReturnCanonicalNan { action } => {
self.visit_assert_return_canonical_nan(action);
}
CommandKind::AssertReturnArithmeticNan { action } => {
self.visit_assert_return_arithmetic_nan(action);
}
CommandKind::AssertTrap { action, message: _ } => {
self.visit_assert_trap(action);
}
CommandKind::AssertInvalid { module, message: _ } => {
self.visit_assert_invalid(module);
}
CommandKind::AssertMalformed { module, message: _ } => {
self.visit_assert_malformed(module);
}
CommandKind::AssertUninstantiable {
module: _,
message: _,
} => {
// Do nothing for now
}
CommandKind::AssertExhaustion {
action: _,
message: _,
} => {
// Do nothing for now
}
CommandKind::AssertUnlinkable {
module: _,
message: _,
} => {
// Do nothing for now
}
CommandKind::Register { name, as_name } => {
self.visit_register_module(name.as_ref().unwrap(), as_name);
}
CommandKind::PerformAction(action) => {
self.visit_perform_action(action);
}
}
}
fn finalize(&self) -> &String {
&self.buffer
}
}
fn generate_spectest(out: &mut File, test_name: &str, wast: &PathBuf) -> std::io::Result<()> {
let mut generator = WastTestGenerator::new(wast);
generator.consume();
let generated_script = generator.finalize();
if !generator.is_fat_test() {
out.write(format!("mod test_{} {{\nuse super::*;\n", test_name).as_bytes())?;
out.write(generated_script.as_bytes())?;
out.write("\n}\n".as_bytes())?;
}
Ok(())
}
pub fn build() -> std::io::Result<()> {
let mut out_file = File::create(format!("{}/spectests.rs", env::var("OUT_DIR").unwrap()))?;
out_file.write(COMMON.as_bytes())?;
for test in TESTS.iter() {
let mut wast_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
wast_path.push(test);
generate_spectest(
&mut out_file,
test.split("/").last().unwrap().split(".").next().unwrap(),
&wast_path,
)?
}
Ok(())
}

View File

@ -1,162 +0,0 @@
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).
These files should be a direct copy of the original [WebAssembly spec tests](/test/core).
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.
## Autogenerated Rust test cases
These files will serve as a base for autogenerating Rust testcases
when `WASM_GENERATE_SPECTESTS=1 cargo build` is executed
([src/build_spectests.rs](/src/build_spectests.rs)).
The resulting autogenerated spec tests live in the [src/spectests](/src/spectests).
## Testcases
Currently supported command assertions:
- [x] `module` _mostly implemented_ (it should support named modules `(module $Xx)`).
- [x] `assert_return` _mostly implemented_ (it should support calls to named modules `(invoke $Xx "call")`).
- [x] `assert_return_canonical_nan` _fully implemented_
- [x] `assert_return_arithmetic_nan` _fully implemented_
- [x] `assert_trap` _fully implemented_
- [x] `assert_invalid` _fully implemented_ (it should not require validation to be performed separate from compilation)
- [x] `assert_malformed` _fully implemented_
- [ ] `assert_uninstantiable` _not implemented yet_
- [ ] `assert_exhaustion` _not implemented yet_
- [x] `register` _fully implemented_
- [x] `perform_action` _partially implemented, only function invocations for now_
### Covered spec tests
The following spec tests are currently covered:
- [x] address.wast
- [x] align.wast
- [x] binary.wast
- [x] block.wast
- [x] br.wast
- [x] br_if.wast
- [x] br_table.wast
- [x] break-drop.wast
- [x] call.wast
- [x] call_indirect.wast
- [x] comments.wast
- [x] const.wast
- [x] conversions.wast
- [x] custom.wast
- [x] data.wast
- [ ] elem.wast
- [x] endianness.wast
- [x] exports.wast
- [x] f32.wast
- [x] f32_bitwise.wast
- [x] f32_cmp.wast
- [x] f64.wast
- [x] f64_bitwise.wast
- [x] f64_cmp.wast
- [x] fac.wast
- [x] float_exprs.wast
- [x] float_literals.wast
- [x] float_memory.wast
- [x] float_misc.wast
- [x] forward.wast
- [x] func.wast
- [x] func_ptrs.wast
- [x] get_local.wast
- [x] globals.wast
- [x] i32.wast
- [x] i64.wast
- [x] if.wast
- [ ] imports.wast
- [ ] inline-module.wast
- [x] int_exprs.wast
- [x] int_literals.wast
- [x] labels.wast
- [x] left-to-right.wast
- [ ] linking.wast
- [x] loop.wast
- [x] memory.wast
- [x] memory_grow.wast
- [x] memory_redundancy.wast
- [x] memory_trap.wast
- [x] names.wast
- [x] nop.wast
- [x] return.wast
- [x] select.wast
- [x] set_local.wast
- [x] simd.wast
- [ ] skip-stack-guard-page.wast
- [x] stack.wast
- [x] start.wast
- [x] store_retval.wast
- [x] switch.wast
- [x] tee_local.wast
- [x] token.wast
- [x] traps.wast
- [x] type.wast
- [x] typecheck.wast
- [ ] unreachable.wast
- [ ] unreached-invalid.wast
- [x] unwind.wast
- [ ] utf8-custom-section-id.wast
- [ ] utf8-import-field.wast
- [ ] utf8-import-module.wast
- [ ] utf8-invalid-encoding.wast
### Specific non-supported cases
There are some cases that we decided to skip for now to accelerate the release schedule:
- `SKIP_CALL_INDIRECT_TYPE_MISMATCH`: we implemented traps in a fast way. We haven't yet covered the type mismatch on `call_indirect`. Specs affected:
- `call_indirect.wast`
- `SKIP_CALL_UNDEFINED_ELEMENT`
Tables are imported into every spec module, even for modules that don't expect it. We need to figure out a way to prevent importing of objects that are not explicitly imported into the module.
Currently `cranelift_wasm::ModuleEnvironment` does not provide `declare_table_import`, etc. so there is no meaningful way of fixing this yet.
- `call_indirect.wast`
- `SKIP_SHARED_TABLE` [elem.wast]
Currently sharing tables between instances/modules does not work. Below are some of the reasons it is hard to achieve:
- Rust naturally prevents such because of the possibility of race conditions
- `ImportObject` is just a wrapper, what we really care about is references to its content.
- `Instance::new` contains a mutation points, the part where after getting the object (memory or table) we push values to it
`table[table_element_index] = func_addr`
- Instance has its own created memories and tables and references to them must outlive `Instance::new()`
- Possible strategy:
```rust
// ImportObject should be passed by ref
Instance::new<'a>(..., &ImportObject);
// Add OwnedData to Instance struct
struct OwnedData;
// For parts where mutatation is really needed
fn get_mut(&import) -> &mut ImportObject {
unsafe { transmute::<&ImportObject, &mut ImportObject>(import) }
}
```
- `elem.wast`
- `SKIP_UNARY_OPERATION` [memory_grow.wast]
In some versions of MacOS this is failing (perhaps because of the chip).
More info here:
```
Executing function c82_l299_action_invoke
thread 'test_memory_grow::test_module_5' panicked at 'assertion failed: `(left == right)`
left: `Ok([I32(0)])`,
right: `Ok([I32(31)])`', /Users/distiller/project/target/release/build/wasmer-spectests-98805f54de053dd1/out/spectests.rs:32304:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
failures:
test_memory_grow::test_module_5
```
https://circleci.com/gh/wasmerio/wasmer/9556

View File

@ -5,99 +5,99 @@
(data (i32.const 0) "abcdefghijklmnopqrstuvwxyz")
(func (export "8u_good1") (param $i i32) (result i32)
(i32.load8_u offset=0 (get_local $i)) ;; 97 'a'
(i32.load8_u offset=0 (local.get $i)) ;; 97 'a'
)
(func (export "8u_good2") (param $i i32) (result i32)
(i32.load8_u align=1 (get_local $i)) ;; 97 'a'
(i32.load8_u align=1 (local.get $i)) ;; 97 'a'
)
(func (export "8u_good3") (param $i i32) (result i32)
(i32.load8_u offset=1 align=1 (get_local $i)) ;; 98 'b'
(i32.load8_u offset=1 align=1 (local.get $i)) ;; 98 'b'
)
(func (export "8u_good4") (param $i i32) (result i32)
(i32.load8_u offset=2 align=1 (get_local $i)) ;; 99 'c'
(i32.load8_u offset=2 align=1 (local.get $i)) ;; 99 'c'
)
(func (export "8u_good5") (param $i i32) (result i32)
(i32.load8_u offset=25 align=1 (get_local $i)) ;; 122 'z'
(i32.load8_u offset=25 align=1 (local.get $i)) ;; 122 'z'
)
(func (export "8s_good1") (param $i i32) (result i32)
(i32.load8_s offset=0 (get_local $i)) ;; 97 'a'
(i32.load8_s offset=0 (local.get $i)) ;; 97 'a'
)
(func (export "8s_good2") (param $i i32) (result i32)
(i32.load8_s align=1 (get_local $i)) ;; 97 'a'
(i32.load8_s align=1 (local.get $i)) ;; 97 'a'
)
(func (export "8s_good3") (param $i i32) (result i32)
(i32.load8_s offset=1 align=1 (get_local $i)) ;; 98 'b'
(i32.load8_s offset=1 align=1 (local.get $i)) ;; 98 'b'
)
(func (export "8s_good4") (param $i i32) (result i32)
(i32.load8_s offset=2 align=1 (get_local $i)) ;; 99 'c'
(i32.load8_s offset=2 align=1 (local.get $i)) ;; 99 'c'
)
(func (export "8s_good5") (param $i i32) (result i32)
(i32.load8_s offset=25 align=1 (get_local $i)) ;; 122 'z'
(i32.load8_s offset=25 align=1 (local.get $i)) ;; 122 'z'
)
(func (export "16u_good1") (param $i i32) (result i32)
(i32.load16_u offset=0 (get_local $i)) ;; 25185 'ab'
(i32.load16_u offset=0 (local.get $i)) ;; 25185 'ab'
)
(func (export "16u_good2") (param $i i32) (result i32)
(i32.load16_u align=1 (get_local $i)) ;; 25185 'ab'
(i32.load16_u align=1 (local.get $i)) ;; 25185 'ab'
)
(func (export "16u_good3") (param $i i32) (result i32)
(i32.load16_u offset=1 align=1 (get_local $i)) ;; 25442 'bc'
(i32.load16_u offset=1 align=1 (local.get $i)) ;; 25442 'bc'
)
(func (export "16u_good4") (param $i i32) (result i32)
(i32.load16_u offset=2 align=2 (get_local $i)) ;; 25699 'cd'
(i32.load16_u offset=2 align=2 (local.get $i)) ;; 25699 'cd'
)
(func (export "16u_good5") (param $i i32) (result i32)
(i32.load16_u offset=25 align=2 (get_local $i)) ;; 122 'z\0'
(i32.load16_u offset=25 align=2 (local.get $i)) ;; 122 'z\0'
)
(func (export "16s_good1") (param $i i32) (result i32)
(i32.load16_s offset=0 (get_local $i)) ;; 25185 'ab'
(i32.load16_s offset=0 (local.get $i)) ;; 25185 'ab'
)
(func (export "16s_good2") (param $i i32) (result i32)
(i32.load16_s align=1 (get_local $i)) ;; 25185 'ab'
(i32.load16_s align=1 (local.get $i)) ;; 25185 'ab'
)
(func (export "16s_good3") (param $i i32) (result i32)
(i32.load16_s offset=1 align=1 (get_local $i)) ;; 25442 'bc'
(i32.load16_s offset=1 align=1 (local.get $i)) ;; 25442 'bc'
)
(func (export "16s_good4") (param $i i32) (result i32)
(i32.load16_s offset=2 align=2 (get_local $i)) ;; 25699 'cd'
(i32.load16_s offset=2 align=2 (local.get $i)) ;; 25699 'cd'
)
(func (export "16s_good5") (param $i i32) (result i32)
(i32.load16_s offset=25 align=2 (get_local $i)) ;; 122 'z\0'
(i32.load16_s offset=25 align=2 (local.get $i)) ;; 122 'z\0'
)
(func (export "32_good1") (param $i i32) (result i32)
(i32.load offset=0 (get_local $i)) ;; 1684234849 'abcd'
(i32.load offset=0 (local.get $i)) ;; 1684234849 'abcd'
)
(func (export "32_good2") (param $i i32) (result i32)
(i32.load align=1 (get_local $i)) ;; 1684234849 'abcd'
(i32.load align=1 (local.get $i)) ;; 1684234849 'abcd'
)
(func (export "32_good3") (param $i i32) (result i32)
(i32.load offset=1 align=1 (get_local $i)) ;; 1701077858 'bcde'
(i32.load offset=1 align=1 (local.get $i)) ;; 1701077858 'bcde'
)
(func (export "32_good4") (param $i i32) (result i32)
(i32.load offset=2 align=2 (get_local $i)) ;; 1717920867 'cdef'
(i32.load offset=2 align=2 (local.get $i)) ;; 1717920867 'cdef'
)
(func (export "32_good5") (param $i i32) (result i32)
(i32.load offset=25 align=4 (get_local $i)) ;; 122 'z\0\0\0'
(i32.load offset=25 align=4 (local.get $i)) ;; 122 'z\0\0\0'
)
(func (export "8u_bad") (param $i i32)
(drop (i32.load8_u offset=4294967295 (get_local $i)))
(drop (i32.load8_u offset=4294967295 (local.get $i)))
)
(func (export "8s_bad") (param $i i32)
(drop (i32.load8_s offset=4294967295 (get_local $i)))
(drop (i32.load8_s offset=4294967295 (local.get $i)))
)
(func (export "16u_bad") (param $i i32)
(drop (i32.load16_u offset=4294967295 (get_local $i)))
(drop (i32.load16_u offset=4294967295 (local.get $i)))
)
(func (export "16s_bad") (param $i i32)
(drop (i32.load16_s offset=4294967295 (get_local $i)))
(drop (i32.load16_s offset=4294967295 (local.get $i)))
)
(func (export "32_bad") (param $i i32)
(drop (i32.load offset=4294967295 (get_local $i)))
(drop (i32.load offset=4294967295 (local.get $i)))
)
)
@ -218,137 +218,137 @@
(data (i32.const 0) "abcdefghijklmnopqrstuvwxyz")
(func (export "8u_good1") (param $i i32) (result i64)
(i64.load8_u offset=0 (get_local $i)) ;; 97 'a'
(i64.load8_u offset=0 (local.get $i)) ;; 97 'a'
)
(func (export "8u_good2") (param $i i32) (result i64)
(i64.load8_u align=1 (get_local $i)) ;; 97 'a'
(i64.load8_u align=1 (local.get $i)) ;; 97 'a'
)
(func (export "8u_good3") (param $i i32) (result i64)
(i64.load8_u offset=1 align=1 (get_local $i)) ;; 98 'b'
(i64.load8_u offset=1 align=1 (local.get $i)) ;; 98 'b'
)
(func (export "8u_good4") (param $i i32) (result i64)
(i64.load8_u offset=2 align=1 (get_local $i)) ;; 99 'c'
(i64.load8_u offset=2 align=1 (local.get $i)) ;; 99 'c'
)
(func (export "8u_good5") (param $i i32) (result i64)
(i64.load8_u offset=25 align=1 (get_local $i)) ;; 122 'z'
(i64.load8_u offset=25 align=1 (local.get $i)) ;; 122 'z'
)
(func (export "8s_good1") (param $i i32) (result i64)
(i64.load8_s offset=0 (get_local $i)) ;; 97 'a'
(i64.load8_s offset=0 (local.get $i)) ;; 97 'a'
)
(func (export "8s_good2") (param $i i32) (result i64)
(i64.load8_s align=1 (get_local $i)) ;; 97 'a'
(i64.load8_s align=1 (local.get $i)) ;; 97 'a'
)
(func (export "8s_good3") (param $i i32) (result i64)
(i64.load8_s offset=1 align=1 (get_local $i)) ;; 98 'b'
(i64.load8_s offset=1 align=1 (local.get $i)) ;; 98 'b'
)
(func (export "8s_good4") (param $i i32) (result i64)
(i64.load8_s offset=2 align=1 (get_local $i)) ;; 99 'c'
(i64.load8_s offset=2 align=1 (local.get $i)) ;; 99 'c'
)
(func (export "8s_good5") (param $i i32) (result i64)
(i64.load8_s offset=25 align=1 (get_local $i)) ;; 122 'z'
(i64.load8_s offset=25 align=1 (local.get $i)) ;; 122 'z'
)
(func (export "16u_good1") (param $i i32) (result i64)
(i64.load16_u offset=0 (get_local $i)) ;; 25185 'ab'
(i64.load16_u offset=0 (local.get $i)) ;; 25185 'ab'
)
(func (export "16u_good2") (param $i i32) (result i64)
(i64.load16_u align=1 (get_local $i)) ;; 25185 'ab'
(i64.load16_u align=1 (local.get $i)) ;; 25185 'ab'
)
(func (export "16u_good3") (param $i i32) (result i64)
(i64.load16_u offset=1 align=1 (get_local $i)) ;; 25442 'bc'
(i64.load16_u offset=1 align=1 (local.get $i)) ;; 25442 'bc'
)
(func (export "16u_good4") (param $i i32) (result i64)
(i64.load16_u offset=2 align=2 (get_local $i)) ;; 25699 'cd'
(i64.load16_u offset=2 align=2 (local.get $i)) ;; 25699 'cd'
)
(func (export "16u_good5") (param $i i32) (result i64)
(i64.load16_u offset=25 align=2 (get_local $i)) ;; 122 'z\0'
(i64.load16_u offset=25 align=2 (local.get $i)) ;; 122 'z\0'
)
(func (export "16s_good1") (param $i i32) (result i64)
(i64.load16_s offset=0 (get_local $i)) ;; 25185 'ab'
(i64.load16_s offset=0 (local.get $i)) ;; 25185 'ab'
)
(func (export "16s_good2") (param $i i32) (result i64)
(i64.load16_s align=1 (get_local $i)) ;; 25185 'ab'
(i64.load16_s align=1 (local.get $i)) ;; 25185 'ab'
)
(func (export "16s_good3") (param $i i32) (result i64)
(i64.load16_s offset=1 align=1 (get_local $i)) ;; 25442 'bc'
(i64.load16_s offset=1 align=1 (local.get $i)) ;; 25442 'bc'
)
(func (export "16s_good4") (param $i i32) (result i64)
(i64.load16_s offset=2 align=2 (get_local $i)) ;; 25699 'cd'
(i64.load16_s offset=2 align=2 (local.get $i)) ;; 25699 'cd'
)
(func (export "16s_good5") (param $i i32) (result i64)
(i64.load16_s offset=25 align=2 (get_local $i)) ;; 122 'z\0'
(i64.load16_s offset=25 align=2 (local.get $i)) ;; 122 'z\0'
)
(func (export "32u_good1") (param $i i32) (result i64)
(i64.load32_u offset=0 (get_local $i)) ;; 1684234849 'abcd'
(i64.load32_u offset=0 (local.get $i)) ;; 1684234849 'abcd'
)
(func (export "32u_good2") (param $i i32) (result i64)
(i64.load32_u align=1 (get_local $i)) ;; 1684234849 'abcd'
(i64.load32_u align=1 (local.get $i)) ;; 1684234849 'abcd'
)
(func (export "32u_good3") (param $i i32) (result i64)
(i64.load32_u offset=1 align=1 (get_local $i)) ;; 1701077858 'bcde'
(i64.load32_u offset=1 align=1 (local.get $i)) ;; 1701077858 'bcde'
)
(func (export "32u_good4") (param $i i32) (result i64)
(i64.load32_u offset=2 align=2 (get_local $i)) ;; 1717920867 'cdef'
(i64.load32_u offset=2 align=2 (local.get $i)) ;; 1717920867 'cdef'
)
(func (export "32u_good5") (param $i i32) (result i64)
(i64.load32_u offset=25 align=4 (get_local $i)) ;; 122 'z\0\0\0'
(i64.load32_u offset=25 align=4 (local.get $i)) ;; 122 'z\0\0\0'
)
(func (export "32s_good1") (param $i i32) (result i64)
(i64.load32_s offset=0 (get_local $i)) ;; 1684234849 'abcd'
(i64.load32_s offset=0 (local.get $i)) ;; 1684234849 'abcd'
)
(func (export "32s_good2") (param $i i32) (result i64)
(i64.load32_s align=1 (get_local $i)) ;; 1684234849 'abcd'
(i64.load32_s align=1 (local.get $i)) ;; 1684234849 'abcd'
)
(func (export "32s_good3") (param $i i32) (result i64)
(i64.load32_s offset=1 align=1 (get_local $i)) ;; 1701077858 'bcde'
(i64.load32_s offset=1 align=1 (local.get $i)) ;; 1701077858 'bcde'
)
(func (export "32s_good4") (param $i i32) (result i64)
(i64.load32_s offset=2 align=2 (get_local $i)) ;; 1717920867 'cdef'
(i64.load32_s offset=2 align=2 (local.get $i)) ;; 1717920867 'cdef'
)
(func (export "32s_good5") (param $i i32) (result i64)
(i64.load32_s offset=25 align=4 (get_local $i)) ;; 122 'z\0\0\0'
(i64.load32_s offset=25 align=4 (local.get $i)) ;; 122 'z\0\0\0'
)
(func (export "64_good1") (param $i i32) (result i64)
(i64.load offset=0 (get_local $i)) ;; 0x6867666564636261 'abcdefgh'
(i64.load offset=0 (local.get $i)) ;; 0x6867666564636261 'abcdefgh'
)
(func (export "64_good2") (param $i i32) (result i64)
(i64.load align=1 (get_local $i)) ;; 0x6867666564636261 'abcdefgh'
(i64.load align=1 (local.get $i)) ;; 0x6867666564636261 'abcdefgh'
)
(func (export "64_good3") (param $i i32) (result i64)
(i64.load offset=1 align=1 (get_local $i)) ;; 0x6968676665646362 'bcdefghi'
(i64.load offset=1 align=1 (local.get $i)) ;; 0x6968676665646362 'bcdefghi'
)
(func (export "64_good4") (param $i i32) (result i64)
(i64.load offset=2 align=2 (get_local $i)) ;; 0x6a69686766656463 'cdefghij'
(i64.load offset=2 align=2 (local.get $i)) ;; 0x6a69686766656463 'cdefghij'
)
(func (export "64_good5") (param $i i32) (result i64)
(i64.load offset=25 align=8 (get_local $i)) ;; 122 'z\0\0\0\0\0\0\0'
(i64.load offset=25 align=8 (local.get $i)) ;; 122 'z\0\0\0\0\0\0\0'
)
(func (export "8u_bad") (param $i i32)
(drop (i64.load8_u offset=4294967295 (get_local $i)))
(drop (i64.load8_u offset=4294967295 (local.get $i)))
)
(func (export "8s_bad") (param $i i32)
(drop (i64.load8_s offset=4294967295 (get_local $i)))
(drop (i64.load8_s offset=4294967295 (local.get $i)))
)
(func (export "16u_bad") (param $i i32)
(drop (i64.load16_u offset=4294967295 (get_local $i)))
(drop (i64.load16_u offset=4294967295 (local.get $i)))
)
(func (export "16s_bad") (param $i i32)
(drop (i64.load16_s offset=4294967295 (get_local $i)))
(drop (i64.load16_s offset=4294967295 (local.get $i)))
)
(func (export "32u_bad") (param $i i32)
(drop (i64.load32_u offset=4294967295 (get_local $i)))
(drop (i64.load32_u offset=4294967295 (local.get $i)))
)
(func (export "32s_bad") (param $i i32)
(drop (i64.load32_s offset=4294967295 (get_local $i)))
(drop (i64.load32_s offset=4294967295 (local.get $i)))
)
(func (export "64_bad") (param $i i32)
(drop (i64.load offset=4294967295 (get_local $i)))
(drop (i64.load offset=4294967295 (local.get $i)))
)
)
@ -501,22 +501,22 @@
(data (i32.const 0) "\00\00\00\00\00\00\a0\7f\01\00\d0\7f")
(func (export "32_good1") (param $i i32) (result f32)
(f32.load offset=0 (get_local $i)) ;; 0.0 '\00\00\00\00'
(f32.load offset=0 (local.get $i)) ;; 0.0 '\00\00\00\00'
)
(func (export "32_good2") (param $i i32) (result f32)
(f32.load align=1 (get_local $i)) ;; 0.0 '\00\00\00\00'
(f32.load align=1 (local.get $i)) ;; 0.0 '\00\00\00\00'
)
(func (export "32_good3") (param $i i32) (result f32)
(f32.load offset=1 align=1 (get_local $i)) ;; 0.0 '\00\00\00\00'
(f32.load offset=1 align=1 (local.get $i)) ;; 0.0 '\00\00\00\00'
)
(func (export "32_good4") (param $i i32) (result f32)
(f32.load offset=2 align=2 (get_local $i)) ;; 0.0 '\00\00\00\00'
(f32.load offset=2 align=2 (local.get $i)) ;; 0.0 '\00\00\00\00'
)
(func (export "32_good5") (param $i i32) (result f32)
(f32.load offset=8 align=4 (get_local $i)) ;; nan:0x500001 '\01\00\d0\7f'
(f32.load offset=8 align=4 (local.get $i)) ;; nan:0x500001 '\01\00\d0\7f'
)
(func (export "32_bad") (param $i i32)
(drop (f32.load offset=4294967295 (get_local $i)))
(drop (f32.load offset=4294967295 (local.get $i)))
)
)
@ -548,22 +548,22 @@
(data (i32.const 0) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\f4\7f\01\00\00\00\00\00\fc\7f")
(func (export "64_good1") (param $i i32) (result f64)
(f64.load offset=0 (get_local $i)) ;; 0.0 '\00\00\00\00\00\00\00\00'
(f64.load offset=0 (local.get $i)) ;; 0.0 '\00\00\00\00\00\00\00\00'
)
(func (export "64_good2") (param $i i32) (result f64)
(f64.load align=1 (get_local $i)) ;; 0.0 '\00\00\00\00\00\00\00\00'
(f64.load align=1 (local.get $i)) ;; 0.0 '\00\00\00\00\00\00\00\00'
)
(func (export "64_good3") (param $i i32) (result f64)
(f64.load offset=1 align=1 (get_local $i)) ;; 0.0 '\00\00\00\00\00\00\00\00'
(f64.load offset=1 align=1 (local.get $i)) ;; 0.0 '\00\00\00\00\00\00\00\00'
)
(func (export "64_good4") (param $i i32) (result f64)
(f64.load offset=2 align=2 (get_local $i)) ;; 0.0 '\00\00\00\00\00\00\00\00'
(f64.load offset=2 align=2 (local.get $i)) ;; 0.0 '\00\00\00\00\00\00\00\00'
)
(func (export "64_good5") (param $i i32) (result f64)
(f64.load offset=18 align=8 (get_local $i)) ;; nan:0xc000000000001 '\01\00\00\00\00\00\fc\7f'
(f64.load offset=18 align=8 (local.get $i)) ;; nan:0xc000000000001 '\01\00\00\00\00\00\fc\7f'
)
(func (export "64_bad") (param $i i32)
(drop (f64.load offset=4294967295 (get_local $i)))
(drop (f64.load offset=4294967295 (local.get $i)))
)
)

View File

@ -360,59 +360,59 @@
)
(assert_invalid
(module (memory 0) (func (i32.load8_s align=2 (i32.const 0))))
(module (memory 0) (func (drop (i32.load8_s align=2 (i32.const 0)))))
"alignment must not be larger than natural"
)
(assert_invalid
(module (memory 0) (func (i32.load8_u align=2 (i32.const 0))))
(module (memory 0) (func (drop (i32.load8_u align=2 (i32.const 0)))))
"alignment must not be larger than natural"
)
(assert_invalid
(module (memory 0) (func (i32.load16_s align=4 (i32.const 0))))
(module (memory 0) (func (drop (i32.load16_s align=4 (i32.const 0)))))
"alignment must not be larger than natural"
)
(assert_invalid
(module (memory 0) (func (i32.load16_u align=4 (i32.const 0))))
(module (memory 0) (func (drop (i32.load16_u align=4 (i32.const 0)))))
"alignment must not be larger than natural"
)
(assert_invalid
(module (memory 0) (func (i32.load align=8 (i32.const 0))))
(module (memory 0) (func (drop (i32.load align=8 (i32.const 0)))))
"alignment must not be larger than natural"
)
(assert_invalid
(module (memory 0) (func (i64.load8_s align=2 (i32.const 0))))
(module (memory 0) (func (drop (i64.load8_s align=2 (i32.const 0)))))
"alignment must not be larger than natural"
)
(assert_invalid
(module (memory 0) (func (i64.load8_u align=2 (i32.const 0))))
(module (memory 0) (func (drop (i64.load8_u align=2 (i32.const 0)))))
"alignment must not be larger than natural"
)
(assert_invalid
(module (memory 0) (func (i64.load16_s align=4 (i32.const 0))))
(module (memory 0) (func (drop (i64.load16_s align=4 (i32.const 0)))))
"alignment must not be larger than natural"
)
(assert_invalid
(module (memory 0) (func (i64.load16_u align=4 (i32.const 0))))
(module (memory 0) (func (drop (i64.load16_u align=4 (i32.const 0)))))
"alignment must not be larger than natural"
)
(assert_invalid
(module (memory 0) (func (i64.load32_s align=8 (i32.const 0))))
(module (memory 0) (func (drop (i64.load32_s align=8 (i32.const 0)))))
"alignment must not be larger than natural"
)
(assert_invalid
(module (memory 0) (func (i64.load32_u align=8 (i32.const 0))))
(module (memory 0) (func (drop (i64.load32_u align=8 (i32.const 0)))))
"alignment must not be larger than natural"
)
(assert_invalid
(module (memory 0) (func (i64.load align=16 (i32.const 0))))
"alignment"
)
(assert_invalid
(module (memory 0) (func (f32.load align=8 (i32.const 0))))
(module (memory 0) (func (drop (i64.load align=16 (i32.const 0)))))
"alignment must not be larger than natural"
)
(assert_invalid
(module (memory 0) (func (f64.load align=16 (i32.const 0))))
(module (memory 0) (func (drop (f32.load align=8 (i32.const 0)))))
"alignment must not be larger than natural"
)
(assert_invalid
(module (memory 0) (func (drop (f64.load align=16 (i32.const 0)))))
"alignment must not be larger than natural"
)
@ -442,14 +442,14 @@
)
(assert_invalid
(module (memory 0) (func (i64.store align=16 (i32.const 0) (i64.const 0))))
"alignment"
"alignment must not be larger than natural"
)
(assert_invalid
(module (memory 0) (func (f32.store align=8 (i32.const 0) (f32.const 0))))
"alignment must not be larger than natural"
)
(assert_invalid
(module (memory 0) (func (f64.store align=16 (i32.const 0) (f32.const 0))))
(module (memory 0) (func (f64.store align=16 (i32.const 0) (f64.const 0))))
"alignment must not be larger than natural"
)
@ -462,63 +462,63 @@
(func (export "f32_align_switch") (param i32) (result f32)
(local f32 f32)
(set_local 1 (f32.const 10.0))
(local.set 1 (f32.const 10.0))
(block $4
(block $2
(block $1
(block $default
(block $0
(br_table $0 $default $1 $2 $4 (get_local 0))
(br_table $0 $default $1 $2 $4 (local.get 0))
) ;; 0
(f32.store (i32.const 0) (get_local 1))
(set_local 2 (f32.load (i32.const 0)))
(f32.store (i32.const 0) (local.get 1))
(local.set 2 (f32.load (i32.const 0)))
(br $4)
) ;; default
(f32.store align=1 (i32.const 0) (get_local 1))
(set_local 2 (f32.load align=1 (i32.const 0)))
(f32.store align=1 (i32.const 0) (local.get 1))
(local.set 2 (f32.load align=1 (i32.const 0)))
(br $4)
) ;; 1
(f32.store align=2 (i32.const 0) (get_local 1))
(set_local 2 (f32.load align=2 (i32.const 0)))
(f32.store align=2 (i32.const 0) (local.get 1))
(local.set 2 (f32.load align=2 (i32.const 0)))
(br $4)
) ;; 2
(f32.store align=4 (i32.const 0) (get_local 1))
(set_local 2 (f32.load align=4 (i32.const 0)))
(f32.store align=4 (i32.const 0) (local.get 1))
(local.set 2 (f32.load align=4 (i32.const 0)))
) ;; 4
(get_local 2)
(local.get 2)
)
(func (export "f64_align_switch") (param i32) (result f64)
(local f64 f64)
(set_local 1 (f64.const 10.0))
(local.set 1 (f64.const 10.0))
(block $8
(block $4
(block $2
(block $1
(block $default
(block $0
(br_table $0 $default $1 $2 $4 $8 (get_local 0))
(br_table $0 $default $1 $2 $4 $8 (local.get 0))
) ;; 0
(f64.store (i32.const 0) (get_local 1))
(set_local 2 (f64.load (i32.const 0)))
(f64.store (i32.const 0) (local.get 1))
(local.set 2 (f64.load (i32.const 0)))
(br $8)
) ;; default
(f64.store align=1 (i32.const 0) (get_local 1))
(set_local 2 (f64.load align=1 (i32.const 0)))
(f64.store align=1 (i32.const 0) (local.get 1))
(local.set 2 (f64.load align=1 (i32.const 0)))
(br $8)
) ;; 1
(f64.store align=2 (i32.const 0) (get_local 1))
(set_local 2 (f64.load align=2 (i32.const 0)))
(f64.store align=2 (i32.const 0) (local.get 1))
(local.set 2 (f64.load align=2 (i32.const 0)))
(br $8)
) ;; 2
(f64.store align=4 (i32.const 0) (get_local 1))
(set_local 2 (f64.load align=4 (i32.const 0)))
(f64.store align=4 (i32.const 0) (local.get 1))
(local.set 2 (f64.load align=4 (i32.const 0)))
(br $8)
) ;; 4
(f64.store align=8 (i32.const 0) (get_local 1))
(set_local 2 (f64.load align=8 (i32.const 0)))
(f64.store align=8 (i32.const 0) (local.get 1))
(local.set 2 (f64.load align=8 (i32.const 0)))
) ;; 8
(get_local 2)
(local.get 2)
)
;; $8s: i32/i64.load8_s, $8u: i32/i64.load8_u, $16s: i32/i64.load16_s, $16u: i32/i64.load16_u, $32: i32.load
@ -526,114 +526,114 @@
(func (export "i32_align_switch") (param i32 i32) (result i32)
(local i32 i32)
(set_local 2 (i32.const 10))
(local.set 2 (i32.const 10))
(block $32
(block $16u
(block $16s
(block $8u
(block $8s
(block $0
(br_table $0 $8s $8u $16s $16u $32 (get_local 0))
(br_table $0 $8s $8u $16s $16u $32 (local.get 0))
) ;; 0
(if (i32.eq (get_local 1) (i32.const 0))
(if (i32.eq (local.get 1) (i32.const 0))
(then
(i32.store8 (i32.const 0) (get_local 2))
(set_local 3 (i32.load8_s (i32.const 0)))
(i32.store8 (i32.const 0) (local.get 2))
(local.set 3 (i32.load8_s (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 1))
(if (i32.eq (local.get 1) (i32.const 1))
(then
(i32.store8 align=1 (i32.const 0) (get_local 2))
(set_local 3 (i32.load8_s align=1 (i32.const 0)))
(i32.store8 align=1 (i32.const 0) (local.get 2))
(local.set 3 (i32.load8_s align=1 (i32.const 0)))
)
)
(br $32)
) ;; 8s
(if (i32.eq (get_local 1) (i32.const 0))
(if (i32.eq (local.get 1) (i32.const 0))
(then
(i32.store8 (i32.const 0) (get_local 2))
(set_local 3 (i32.load8_u (i32.const 0)))
(i32.store8 (i32.const 0) (local.get 2))
(local.set 3 (i32.load8_u (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 1))
(if (i32.eq (local.get 1) (i32.const 1))
(then
(i32.store8 align=1 (i32.const 0) (get_local 2))
(set_local 3 (i32.load8_u align=1 (i32.const 0)))
(i32.store8 align=1 (i32.const 0) (local.get 2))
(local.set 3 (i32.load8_u align=1 (i32.const 0)))
)
)
(br $32)
) ;; 8u
(if (i32.eq (get_local 1) (i32.const 0))
(if (i32.eq (local.get 1) (i32.const 0))
(then
(i32.store16 (i32.const 0) (get_local 2))
(set_local 3 (i32.load16_s (i32.const 0)))
(i32.store16 (i32.const 0) (local.get 2))
(local.set 3 (i32.load16_s (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 1))
(if (i32.eq (local.get 1) (i32.const 1))
(then
(i32.store16 align=1 (i32.const 0) (get_local 2))
(set_local 3 (i32.load16_s align=1 (i32.const 0)))
(i32.store16 align=1 (i32.const 0) (local.get 2))
(local.set 3 (i32.load16_s align=1 (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 2))
(if (i32.eq (local.get 1) (i32.const 2))
(then
(i32.store16 align=2 (i32.const 0) (get_local 2))
(set_local 3 (i32.load16_s align=2 (i32.const 0)))
(i32.store16 align=2 (i32.const 0) (local.get 2))
(local.set 3 (i32.load16_s align=2 (i32.const 0)))
)
)
(br $32)
) ;; 16s
(if (i32.eq (get_local 1) (i32.const 0))
(if (i32.eq (local.get 1) (i32.const 0))
(then
(i32.store16 (i32.const 0) (get_local 2))
(set_local 3 (i32.load16_u (i32.const 0)))
(i32.store16 (i32.const 0) (local.get 2))
(local.set 3 (i32.load16_u (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 1))
(if (i32.eq (local.get 1) (i32.const 1))
(then
(i32.store16 align=1 (i32.const 0) (get_local 2))
(set_local 3 (i32.load16_u align=1 (i32.const 0)))
(i32.store16 align=1 (i32.const 0) (local.get 2))
(local.set 3 (i32.load16_u align=1 (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 2))
(if (i32.eq (local.get 1) (i32.const 2))
(then
(i32.store16 align=2 (i32.const 0) (get_local 2))
(set_local 3 (i32.load16_u align=2 (i32.const 0)))
(i32.store16 align=2 (i32.const 0) (local.get 2))
(local.set 3 (i32.load16_u align=2 (i32.const 0)))
)
)
(br $32)
) ;; 16u
(if (i32.eq (get_local 1) (i32.const 0))
(if (i32.eq (local.get 1) (i32.const 0))
(then
(i32.store (i32.const 0) (get_local 2))
(set_local 3 (i32.load (i32.const 0)))
(i32.store (i32.const 0) (local.get 2))
(local.set 3 (i32.load (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 1))
(if (i32.eq (local.get 1) (i32.const 1))
(then
(i32.store align=1 (i32.const 0) (get_local 2))
(set_local 3 (i32.load align=1 (i32.const 0)))
(i32.store align=1 (i32.const 0) (local.get 2))
(local.set 3 (i32.load align=1 (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 2))
(if (i32.eq (local.get 1) (i32.const 2))
(then
(i32.store align=2 (i32.const 0) (get_local 2))
(set_local 3 (i32.load align=2 (i32.const 0)))
(i32.store align=2 (i32.const 0) (local.get 2))
(local.set 3 (i32.load align=2 (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 4))
(if (i32.eq (local.get 1) (i32.const 4))
(then
(i32.store align=4 (i32.const 0) (get_local 2))
(set_local 3 (i32.load align=4 (i32.const 0)))
(i32.store align=4 (i32.const 0) (local.get 2))
(local.set 3 (i32.load align=4 (i32.const 0)))
)
)
) ;; 32
(get_local 3)
(local.get 3)
)
(func (export "i64_align_switch") (param i32 i32) (result i64)
(local i64 i64)
(set_local 2 (i64.const 10))
(local.set 2 (i64.const 10))
(block $64
(block $32u
(block $32s
@ -642,160 +642,160 @@
(block $8u
(block $8s
(block $0
(br_table $0 $8s $8u $16s $16u $32s $32u $64 (get_local 0))
(br_table $0 $8s $8u $16s $16u $32s $32u $64 (local.get 0))
) ;; 0
(if (i32.eq (get_local 1) (i32.const 0))
(if (i32.eq (local.get 1) (i32.const 0))
(then
(i64.store8 (i32.const 0) (get_local 2))
(set_local 3 (i64.load8_s (i32.const 0)))
(i64.store8 (i32.const 0) (local.get 2))
(local.set 3 (i64.load8_s (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 1))
(if (i32.eq (local.get 1) (i32.const 1))
(then
(i64.store8 align=1 (i32.const 0) (get_local 2))
(set_local 3 (i64.load8_s align=1 (i32.const 0)))
(i64.store8 align=1 (i32.const 0) (local.get 2))
(local.set 3 (i64.load8_s align=1 (i32.const 0)))
)
)
(br $64)
) ;; 8s
(if (i32.eq (get_local 1) (i32.const 0))
(if (i32.eq (local.get 1) (i32.const 0))
(then
(i64.store8 (i32.const 0) (get_local 2))
(set_local 3 (i64.load8_u (i32.const 0)))
(i64.store8 (i32.const 0) (local.get 2))
(local.set 3 (i64.load8_u (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 1))
(if (i32.eq (local.get 1) (i32.const 1))
(then
(i64.store8 align=1 (i32.const 0) (get_local 2))
(set_local 3 (i64.load8_u align=1 (i32.const 0)))
(i64.store8 align=1 (i32.const 0) (local.get 2))
(local.set 3 (i64.load8_u align=1 (i32.const 0)))
)
)
(br $64)
) ;; 8u
(if (i32.eq (get_local 1) (i32.const 0))
(if (i32.eq (local.get 1) (i32.const 0))
(then
(i64.store16 (i32.const 0) (get_local 2))
(set_local 3 (i64.load16_s (i32.const 0)))
(i64.store16 (i32.const 0) (local.get 2))
(local.set 3 (i64.load16_s (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 1))
(if (i32.eq (local.get 1) (i32.const 1))
(then
(i64.store16 align=1 (i32.const 0) (get_local 2))
(set_local 3 (i64.load16_s align=1 (i32.const 0)))
(i64.store16 align=1 (i32.const 0) (local.get 2))
(local.set 3 (i64.load16_s align=1 (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 2))
(if (i32.eq (local.get 1) (i32.const 2))
(then
(i64.store16 align=2 (i32.const 0) (get_local 2))
(set_local 3 (i64.load16_s align=2 (i32.const 0)))
(i64.store16 align=2 (i32.const 0) (local.get 2))
(local.set 3 (i64.load16_s align=2 (i32.const 0)))
)
)
(br $64)
) ;; 16s
(if (i32.eq (get_local 1) (i32.const 0))
(if (i32.eq (local.get 1) (i32.const 0))
(then
(i64.store16 (i32.const 0) (get_local 2))
(set_local 3 (i64.load16_u (i32.const 0)))
(i64.store16 (i32.const 0) (local.get 2))
(local.set 3 (i64.load16_u (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 1))
(if (i32.eq (local.get 1) (i32.const 1))
(then
(i64.store16 align=1 (i32.const 0) (get_local 2))
(set_local 3 (i64.load16_u align=1 (i32.const 0)))
(i64.store16 align=1 (i32.const 0) (local.get 2))
(local.set 3 (i64.load16_u align=1 (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 2))
(if (i32.eq (local.get 1) (i32.const 2))
(then
(i64.store16 align=2 (i32.const 0) (get_local 2))
(set_local 3 (i64.load16_u align=2 (i32.const 0)))
(i64.store16 align=2 (i32.const 0) (local.get 2))
(local.set 3 (i64.load16_u align=2 (i32.const 0)))
)
)
(br $64)
) ;; 16u
(if (i32.eq (get_local 1) (i32.const 0))
(if (i32.eq (local.get 1) (i32.const 0))
(then
(i64.store32 (i32.const 0) (get_local 2))
(set_local 3 (i64.load32_s (i32.const 0)))
(i64.store32 (i32.const 0) (local.get 2))
(local.set 3 (i64.load32_s (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 1))
(if (i32.eq (local.get 1) (i32.const 1))
(then
(i64.store32 align=1 (i32.const 0) (get_local 2))
(set_local 3 (i64.load32_s align=1 (i32.const 0)))
(i64.store32 align=1 (i32.const 0) (local.get 2))
(local.set 3 (i64.load32_s align=1 (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 2))
(if (i32.eq (local.get 1) (i32.const 2))
(then
(i64.store32 align=2 (i32.const 0) (get_local 2))
(set_local 3 (i64.load32_s align=2 (i32.const 0)))
(i64.store32 align=2 (i32.const 0) (local.get 2))
(local.set 3 (i64.load32_s align=2 (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 4))
(if (i32.eq (local.get 1) (i32.const 4))
(then
(i64.store32 align=4 (i32.const 0) (get_local 2))
(set_local 3 (i64.load32_s align=4 (i32.const 0)))
(i64.store32 align=4 (i32.const 0) (local.get 2))
(local.set 3 (i64.load32_s align=4 (i32.const 0)))
)
)
(br $64)
) ;; 32s
(if (i32.eq (get_local 1) (i32.const 0))
(if (i32.eq (local.get 1) (i32.const 0))
(then
(i64.store32 (i32.const 0) (get_local 2))
(set_local 3 (i64.load32_u (i32.const 0)))
(i64.store32 (i32.const 0) (local.get 2))
(local.set 3 (i64.load32_u (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 1))
(if (i32.eq (local.get 1) (i32.const 1))
(then
(i64.store32 align=1 (i32.const 0) (get_local 2))
(set_local 3 (i64.load32_u align=1 (i32.const 0)))
(i64.store32 align=1 (i32.const 0) (local.get 2))
(local.set 3 (i64.load32_u align=1 (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 2))
(if (i32.eq (local.get 1) (i32.const 2))
(then
(i64.store32 align=2 (i32.const 0) (get_local 2))
(set_local 3 (i64.load32_u align=2 (i32.const 0)))
(i64.store32 align=2 (i32.const 0) (local.get 2))
(local.set 3 (i64.load32_u align=2 (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 4))
(if (i32.eq (local.get 1) (i32.const 4))
(then
(i64.store32 align=4 (i32.const 0) (get_local 2))
(set_local 3 (i64.load32_u align=4 (i32.const 0)))
(i64.store32 align=4 (i32.const 0) (local.get 2))
(local.set 3 (i64.load32_u align=4 (i32.const 0)))
)
)
(br $64)
) ;; 32u
(if (i32.eq (get_local 1) (i32.const 0))
(if (i32.eq (local.get 1) (i32.const 0))
(then
(i64.store (i32.const 0) (get_local 2))
(set_local 3 (i64.load (i32.const 0)))
(i64.store (i32.const 0) (local.get 2))
(local.set 3 (i64.load (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 1))
(if (i32.eq (local.get 1) (i32.const 1))
(then
(i64.store align=1 (i32.const 0) (get_local 2))
(set_local 3 (i64.load align=1 (i32.const 0)))
(i64.store align=1 (i32.const 0) (local.get 2))
(local.set 3 (i64.load align=1 (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 2))
(if (i32.eq (local.get 1) (i32.const 2))
(then
(i64.store align=2 (i32.const 0) (get_local 2))
(set_local 3 (i64.load align=2 (i32.const 0)))
(i64.store align=2 (i32.const 0) (local.get 2))
(local.set 3 (i64.load align=2 (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 4))
(if (i32.eq (local.get 1) (i32.const 4))
(then
(i64.store align=4 (i32.const 0) (get_local 2))
(set_local 3 (i64.load align=4 (i32.const 0)))
(i64.store align=4 (i32.const 0) (local.get 2))
(local.set 3 (i64.load align=4 (i32.const 0)))
)
)
(if (i32.eq (get_local 1) (i32.const 8))
(if (i32.eq (local.get 1) (i32.const 8))
(then
(i64.store align=8 (i32.const 0) (get_local 2))
(set_local 3 (i64.load align=8 (i32.const 0)))
(i64.store align=8 (i32.const 0) (local.get 2))
(local.set 3 (i64.load align=8 (i32.const 0)))
)
)
) ;; 64
(get_local 3)
(local.get 3)
)
)
@ -849,18 +849,18 @@
(assert_return (invoke "i64_align_switch" (i32.const 6) (i32.const 4)) (i64.const 10))
(assert_return (invoke "i64_align_switch" (i32.const 6) (i32.const 8)) (i64.const 10))
;; ;; Test that an i64 store with 4-byte alignment that's 4 bytes out of bounds traps without storing anything
;; Test that an i64 store with 4-byte alignment that's 4 bytes out of bounds traps without storing anything
;; (module
;; (memory 1)
;; (func (export "store") (param i32 i64)
;; (i64.store align=4 (get_local 0) (get_local 1))
;; )
;; (func (export "load") (param i32) (result i32)
;; (i32.load (get_local 0))
;; )
;; )
(module
(memory 1)
(func (export "store") (param i32 i64)
(i64.store align=4 (local.get 0) (local.get 1))
)
(func (export "load") (param i32) (result i32)
(i32.load (local.get 0))
)
)
;; (assert_trap (invoke "store" (i32.const 65532) (i64.const -1)) "out of bounds memory access")
;; ;; No memory was changed
;; (assert_return (invoke "load" (i32.const 65532)) (i32.const 0))
(assert_trap (invoke "store" (i32.const 65532) (i64.const -1)) "out of bounds memory access")
;; No memory was changed
(assert_return (invoke "load" (i32.const 65532)) (i32.const 0))

View File

@ -0,0 +1,963 @@
;; Unsigned LEB128 can have non-minimal length
(module binary
"\00asm" "\01\00\00\00"
"\05\04\01" ;; Memory section with 1 entry
"\00\82\00" ;; no max, minimum 2
)
(module binary
"\00asm" "\01\00\00\00"
"\05\07\01" ;; Memory section with 1 entry
"\00\82\80\80\80\00" ;; no max, minimum 2
)
(module binary
"\00asm" "\01\00\00\00"
"\05\06\01" ;; Memory section with 1 entry
"\01\82\00" ;; minimum 2
"\82\00" ;; max 2
)
(module binary
"\00asm" "\01\00\00\00"
"\05\09\01" ;; Memory section with 1 entry
"\01\82\00" ;; minimum 2
"\82\80\80\80\00" ;; max 2
)
(module binary
"\00asm" "\01\00\00\00"
"\05\03\01" ;; Memory section with 1 entry
"\00\00" ;; no max, minimum 0
"\0b\07\01" ;; Data section with 1 entry
"\80\00" ;; Memory index 0, encoded with 2 bytes
"\41\00\0b\00" ;; (i32.const 0) with contents ""
)
(module binary
"\00asm" "\01\00\00\00"
"\04\04\01" ;; Table section with 1 entry
"\70\00\00" ;; no max, minimum 0, funcref
"\09\07\01" ;; Element section with 1 entry
"\80\00" ;; Table index 0, encoded with 2 bytes
"\41\00\0b\00" ;; (i32.const 0) with no elements
)
(module binary
"\00asm" "\01\00\00\00"
"\00" ;; custom section
"\8a\00" ;; section size 10, encoded with 2 bytes
"\01" ;; name byte count
"1" ;; name
"23456789" ;; sequence of bytes
)
(module binary
"\00asm" "\01\00\00\00"
"\00" ;; custom section
"\0b" ;; section size
"\88\00" ;; name byte count 8, encoded with 2 bytes
"12345678" ;; name
"9" ;; sequence of bytes
)
(module binary
"\00asm" "\01\00\00\00"
"\01\08\01" ;; type section
"\60" ;; func type
"\82\00" ;; num params 2, encoded with 2 bytes
"\7f\7e" ;; param type
"\01" ;; num results
"\7f" ;; result type
)
(module binary
"\00asm" "\01\00\00\00"
"\01\08\01" ;; type section
"\60" ;; func type
"\02" ;; num params
"\7f\7e" ;; param type
"\81\00" ;; num results 1, encoded with 2 bytes
"\7f" ;; result type
)
(module binary
"\00asm" "\01\00\00\00"
"\01\05\01" ;; type section
"\60\01\7f\00" ;; function type
"\02\17\01" ;; import section
"\88\00" ;; module name length 8, encoded with 2 bytes
"\73\70\65\63\74\65\73\74" ;; module name
"\09" ;; entity name length
"\70\72\69\6e\74\5f\69\33\32" ;; entity name
"\00" ;; import kind
"\00" ;; import signature index
)
(module binary
"\00asm" "\01\00\00\00"
"\01\05\01" ;; type section
"\60\01\7f\00" ;; function type
"\02\17\01" ;; import section
"\08" ;; module name length
"\73\70\65\63\74\65\73\74" ;; module name
"\89\00" ;; entity name length 9, encoded with 2 bytes
"\70\72\69\6e\74\5f\69\33\32" ;; entity name
"\00" ;; import kind
"\00" ;; import signature index
)
(module binary
"\00asm" "\01\00\00\00"
"\01\05\01" ;; type section
"\60\01\7f\00" ;; function type
"\02\17\01" ;; import section
"\08" ;; module name length
"\73\70\65\63\74\65\73\74" ;; module name
"\09" ;; entity name length 9
"\70\72\69\6e\74\5f\69\33\32" ;; entity name
"\00" ;; import kind
"\80\00" ;; import signature index, encoded with 2 bytes
)
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; function type
"\03\03\01" ;; function section
"\80\00" ;; function 0 signature index, encoded with 2 bytes
"\0a\04\01" ;; code section
"\02\00\0b" ;; function body
)
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; fun type
"\03\02\01\00" ;; function section
"\07\07\01" ;; export section
"\82\00" ;; string length 2, encoded with 2 bytes
"\66\31" ;; export name f1
"\00" ;; export kind
"\00" ;; export func index
"\0a\04\01" ;; code section
"\02\00\0b" ;; function body
)
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; fun type
"\03\02\01\00" ;; function section
"\07\07\01" ;; export section
"\02" ;; string length 2
"\66\31" ;; export name f1
"\00" ;; export kind
"\80\00" ;; export func index, encoded with 2 bytes
"\0a\04\01" ;; code section
"\02\00\0b" ;; function body
)
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; fun type
"\03\02\01\00" ;; function section
"\0a" ;; code section
"\05" ;; section size
"\81\00" ;; num functions, encoded with 2 bytes
"\02\00\0b" ;; function body
)
;; Signed LEB128 can have non-minimal length
(module binary
"\00asm" "\01\00\00\00"
"\06\07\01" ;; Global section with 1 entry
"\7f\00" ;; i32, immutable
"\41\80\00" ;; i32.const 0
"\0b" ;; end
)
(module binary
"\00asm" "\01\00\00\00"
"\06\07\01" ;; Global section with 1 entry
"\7f\00" ;; i32, immutable
"\41\ff\7f" ;; i32.const -1
"\0b" ;; end
)
(module binary
"\00asm" "\01\00\00\00"
"\06\0a\01" ;; Global section with 1 entry
"\7f\00" ;; i32, immutable
"\41\80\80\80\80\00" ;; i32.const 0
"\0b" ;; end
)
(module binary
"\00asm" "\01\00\00\00"
"\06\0a\01" ;; Global section with 1 entry
"\7f\00" ;; i32, immutable
"\41\ff\ff\ff\ff\7f" ;; i32.const -1
"\0b" ;; end
)
(module binary
"\00asm" "\01\00\00\00"
"\06\07\01" ;; Global section with 1 entry
"\7e\00" ;; i64, immutable
"\42\80\00" ;; i64.const 0 with unused bits set
"\0b" ;; end
)
(module binary
"\00asm" "\01\00\00\00"
"\06\07\01" ;; Global section with 1 entry
"\7e\00" ;; i64, immutable
"\42\ff\7f" ;; i64.const -1 with unused bits unset
"\0b" ;; end
)
(module binary
"\00asm" "\01\00\00\00"
"\06\0f\01" ;; Global section with 1 entry
"\7e\00" ;; i64, immutable
"\42\80\80\80\80\80\80\80\80\80\00" ;; i64.const 0 with unused bits set
"\0b" ;; end
)
(module binary
"\00asm" "\01\00\00\00"
"\06\0f\01" ;; Global section with 1 entry
"\7e\00" ;; i64, immutable
"\42\ff\ff\ff\ff\ff\ff\ff\ff\ff\7f" ;; i64.const -1 with unused bits unset
"\0b" ;; end
)
;; Unsigned LEB128 must not be overlong
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\05\08\01" ;; Memory section with 1 entry
"\00\82\80\80\80\80\00" ;; no max, minimum 2 with one byte too many
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\05\0a\01" ;; Memory section with 1 entry
"\01\82\00" ;; minimum 2
"\82\80\80\80\80\00" ;; max 2 with one byte too many
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\05\03\01" ;; Memory section with 1 entry
"\00\00" ;; no max, minimum 0
"\0b\0b\01" ;; Data section with 1 entry
"\80\80\80\80\80\00" ;; Memory index 0 with one byte too many
"\41\00\0b\00" ;; (i32.const 0) with contents ""
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\04\04\01" ;; Table section with 1 entry
"\70\00\00" ;; no max, minimum 0, funcref
"\09\0b\01" ;; Element section with 1 entry
"\80\80\80\80\80\00" ;; Table index 0 with one byte too many
"\41\00\0b\00" ;; (i32.const 0) with no elements
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\00" ;; custom section
"\83\80\80\80\80\00" ;; section size 3 with one byte too many
"\01" ;; name byte count
"1" ;; name
"2" ;; sequence of bytes
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\00" ;; custom section
"\0A" ;; section size
"\83\80\80\80\80\00" ;; name byte count 3 with one byte too many
"123" ;; name
"4" ;; sequence of bytes
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\0c\01" ;; type section
"\60" ;; func type
"\82\80\80\80\80\00" ;; num params 2 with one byte too many
"\7f\7e" ;; param type
"\01" ;; num result
"\7f" ;; result type
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\08\01" ;; type section
"\60" ;; func type
"\02" ;; num params
"\7f\7e" ;; param type
"\81\80\80\80\80\00" ;; num result 1 with one byte too many
"\7f" ;; result type
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\05\01" ;; type section
"\60\01\7f\00" ;; function type
"\02\1b\01" ;; import section
"\88\80\80\80\80\00" ;; module name length 8 with one byte too many
"\73\70\65\63\74\65\73\74" ;; module name
"\09" ;; entity name length
"\70\72\69\6e\74\5f\69\33\32" ;; entity name
"\00" ;; import kind
"\00" ;; import signature index
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\05\01" ;; type section
"\60\01\7f\00" ;; function type
"\02\1b\01" ;; import section
"\08" ;; module name length
"\73\70\65\63\74\65\73\74" ;; module name
"\89\80\80\80\80\00" ;; entity name length 9 with one byte too many
"\70\72\69\6e\74\5f\69\33\32" ;; entity name
"\00" ;; import kind
"\00" ;; import signature index
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\05\01" ;; type section
"\60\01\7f\00" ;; function type
"\02\1b\01" ;; import section
"\08" ;; module name length
"\73\70\65\63\74\65\73\74" ;; module name
"\09" ;; entity name length 9
"\70\72\69\6e\74\5f\69\33\32" ;; entity name
"\00" ;; import kind
"\80\80\80\80\80\00" ;; import signature index 0 with one byte too many
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; function type
"\03\03\01" ;; function section
"\80\80\80\80\80\00" ;; function 0 signature index with one byte too many
"\0a\04\01" ;; code section
"\02\00\0b" ;; function body
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; fun type
"\03\02\01\00" ;; function section
"\07\0b\01" ;; export section
"\82\80\80\80\80\00" ;; string length 2 with one byte too many
"\66\31" ;; export name f1
"\00" ;; export kind
"\00" ;; export func index
"\0a\04\01" ;; code section
"\02\00\0b" ;; function body
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; fun type
"\03\02\01\00" ;; function section
"\07\0b\01" ;; export section
"\02" ;; string length 2
"\66\31" ;; export name f1
"\00" ;; export kind
"\80\80\80\80\80\00" ;; export func index 0 with one byte too many
"\0a\04\01" ;; code section
"\02\00\0b" ;; function body
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; fun type
"\03\02\01\00" ;; function section
"\0a" ;; code section
"\05" ;; section size
"\81\80\80\80\80\00" ;; num functions 1 with one byte too many
"\02\00\0b" ;; function body
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01\60\00\00" ;; Type section
"\03\02\01\00" ;; Function section
"\05\03\01\00\01" ;; Memory section
"\0a\11\01" ;; Code section
;; function 0
"\0f\01\01" ;; local type count
"\7f" ;; i32
"\41\00" ;; i32.const 0
"\28" ;; i32.load
"\02" ;; alignment 2
"\82\80\80\80\80\00" ;; offset 2 with one byte too many
"\1a" ;; drop
"\0b" ;; end
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01\60\00\00" ;; Type section
"\03\02\01\00" ;; Function section
"\05\03\01\00\01" ;; Memory section
"\0a\11\01" ;; Code section
;; function 0
"\0f\01\01" ;; local type count
"\7f" ;; i32
"\41\00" ;; i32.const 0
"\28" ;; i32.load
"\82\80\80\80\80\00" ;; alignment 2 with one byte too many
"\00" ;; offset 0
"\1a" ;; drop
"\0b" ;; end
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01\60\00\00" ;; Type section
"\03\02\01\00" ;; Function section
"\05\03\01\00\01" ;; Memory section
"\0a\12\01" ;; Code section
;; function 0
"\10\01\01" ;; local type count
"\7f" ;; i32
"\41\00" ;; i32.const 0
"\41\03" ;; i32.const 3
"\36" ;; i32.store
"\82\80\80\80\80\00" ;; alignment 2 with one byte too many
"\03" ;; offset 3
"\0b" ;; end
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01\60\00\00" ;; Type section
"\03\02\01\00" ;; Function section
"\05\03\01\00\01" ;; Memory section
"\0a\12\01" ;; Code section
;; function 0
"\10\01\01" ;; local type count
"\7f" ;; i32
"\41\00" ;; i32.const 0
"\41\03" ;; i32.const 3
"\36" ;; i32.store
"\02" ;; alignment 2
"\82\80\80\80\80\00" ;; offset 2 with one byte too many
"\0b" ;; end
)
"integer representation too long"
)
;; Signed LEB128 must not be overlong
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\0b\01" ;; Global section with 1 entry
"\7f\00" ;; i32, immutable
"\41\80\80\80\80\80\00" ;; i32.const 0 with one byte too many
"\0b" ;; end
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\0b\01" ;; Global section with 1 entry
"\7f\00" ;; i32, immutable
"\41\ff\ff\ff\ff\ff\7f" ;; i32.const -1 with one byte too many
"\0b" ;; end
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\10\01" ;; Global section with 1 entry
"\7e\00" ;; i64, immutable
"\42\80\80\80\80\80\80\80\80\80\80\00" ;; i64.const 0 with one byte too many
"\0b" ;; end
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\10\01" ;; Global section with 1 entry
"\7e\00" ;; i64, immutable
"\42\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\7f" ;; i64.const -1 with one byte too many
"\0b" ;; end
)
"integer representation too long"
)
;; Unsigned LEB128s zero-extend
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\05\07\01" ;; Memory section with 1 entry
"\00\82\80\80\80\70" ;; no max, minimum 2 with unused bits set
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\05\07\01" ;; Memory section with 1 entry
"\00\82\80\80\80\40" ;; no max, minimum 2 with some unused bits set
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\05\09\01" ;; Memory section with 1 entry
"\01\82\00" ;; minimum 2
"\82\80\80\80\10" ;; max 2 with unused bits set
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\05\09\01" ;; Memory section with 1 entry
"\01\82\00" ;; minimum 2
"\82\80\80\80\40" ;; max 2 with some unused bits set
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\05\03\01" ;; Memory section with 1 entry
"\00\00" ;; no max, minimum 0
"\0b\0a\01" ;; Data section with 1 entry
"\80\80\80\80\10" ;; Memory index 0 with unused bits set
"\41\00\0b\00" ;; (i32.const 0) with contents ""
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\04\04\01" ;; Table section with 1 entry
"\70\00\00" ;; no max, minimum 0, funcref
"\09\0a\01" ;; Element section with 1 entry
"\80\80\80\80\10" ;; Table index 0 with unused bits set
"\41\00\0b\00" ;; (i32.const 0) with no elements
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\00" ;; custom section
"\83\80\80\80\10" ;; section size 3 with unused bits set
"\01" ;; name byte count
"1" ;; name
"2" ;; sequence of bytes
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\00" ;; custom section
"\09" ;; section size
"\83\80\80\80\40" ;; name byte count 3 with unused bits set
"123" ;; name
"4" ;; sequence of bytes
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\0b\01" ;; type section
"\60" ;; func type
"\82\80\80\80\10" ;; num params 2 with unused bits set
"\7f\7e" ;; param type
"\01" ;; num result
"\7f" ;; result type
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\0b\01" ;; type section
"\60" ;; func type
"\02" ;; num params
"\7f\7e" ;; param type
"\81\80\80\80\40" ;; num result 1 with unused bits set
"\7f" ;; result type
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\05\01" ;; type section
"\60\01\7f\00" ;; function type
"\02\1a\01" ;; import section
"\88\80\80\80\10" ;; module name length 8 with unused bits set
"\73\70\65\63\74\65\73\74" ;; module name
"\09" ;; entity name length
"\70\72\69\6e\74\5f\69\33\32" ;; entity name
"\00" ;; import kind
"\00" ;; import signature index
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\05\01" ;; type section
"\60\01\7f\00" ;; function type
"\02\1a\01" ;; import section
"\08" ;; module name length
"\73\70\65\63\74\65\73\74" ;; module name
"\89\80\80\80\40" ;; entity name length 9 with unused bits set
"\70\72\69\6e\74\5f\69\33\32" ;; entity name
"\00" ;; import kind
"\00" ;; import signature index
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\05\01" ;; type section
"\60\01\7f\00" ;; function type
"\02\1a\01" ;; import section
"\08" ;; module name length
"\73\70\65\63\74\65\73\74" ;; module name
"\09" ;; entity name length 9
"\70\72\69\6e\74\5f\69\33\32" ;; entity name
"\00" ;; import kind
"\80\80\80\80\10" ;; import signature index 0 with unused bits set
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; function type
"\03\06\01" ;; function section
"\80\80\80\80\10" ;; function 0 signature index with unused bits set
"\0a\04\01" ;; code section
"\02\00\0b" ;; function body
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; fun type
"\03\02\01\00" ;; function section
"\07\0a\01" ;; export section
"\82\80\80\80\10" ;; string length 2 with unused bits set
"\66\31" ;; export name f1
"\00" ;; export kind
"\00" ;; export func index
"\0a\04\01" ;; code section
"\02\00\0b" ;; function body
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; fun type
"\03\02\01\00" ;; function section
"\07\0a\01" ;; export section
"\02" ;; string length 2
"\66\31" ;; export name f1
"\00" ;; export kind
"\80\80\80\80\10" ;; export func index with unused bits set
"\0a\04\01" ;; code section
"\02\00\0b" ;; function body
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; fun type
"\03\02\01\00" ;; function section
"\0a" ;; code section
"\08" ;; section size
"\81\80\80\80\10" ;; num functions 1 with unused bits set
"\02\00\0b" ;; function body
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01\60\00\00" ;; Type section
"\03\02\01\00" ;; Function section
"\05\03\01\00\01" ;; Memory section
"\0a\10\01" ;; Code section
;; function 0
"\0e\01\01" ;; local type count
"\7f" ;; i32
"\41\00" ;; i32.const 0
"\28" ;; i32.load
"\02" ;; alignment 2
"\82\80\80\80\10" ;; offset 2 with unused bits set
"\1a" ;; drop
"\0b" ;; end
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01\60\00\00" ;; Type section
"\03\02\01\00" ;; Function section
"\05\03\01\00\01" ;; Memory section
"\0a\10\01" ;; Code section
;; function 0
"\0e\01\01" ;; local type count
"\7f" ;; i32
"\41\00" ;; i32.const 0
"\28" ;; i32.load
"\02" ;; alignment 2
"\82\80\80\80\40" ;; offset 2 with some unused bits set
"\1a" ;; drop
"\0b" ;; end
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01\60\00\00" ;; Type section
"\03\02\01\00" ;; Function section
"\05\03\01\00\01" ;; Memory section
"\0a\10\01" ;; Code section
"\0e\01\01" ;; local type count
"\7f" ;; i32
"\41\00" ;; i32.const 0
"\28" ;; i32.load
"\82\80\80\80\10" ;; alignment 2 with unused bits set
"\00" ;; offset 0
"\1a" ;; drop
"\0b" ;; end
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01\60\00\00" ;; Type section
"\03\02\01\00" ;; Function section
"\05\03\01\00\01" ;; Memory section
"\0a\10\01" ;; Code section
;; function 0
"\0e\01\01" ;; local type count
"\7f" ;; i32
"\41\00" ;; i32.const 0
"\28" ;; i32.load
"\82\80\80\80\40" ;; alignment 2 with some unused bits set
"\00" ;; offset 0
"\1a" ;; drop
"\0b" ;; end
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01\60\00\00" ;; Type section
"\03\02\01\00" ;; Function section
"\05\03\01\00\01" ;; Memory section
"\0a\11\01" ;; Code section
;; function 0
"\0f\01\01" ;; local type count
"\7f" ;; i32
"\41\00" ;; i32.const 0
"\41\03" ;; i32.const 3
"\36" ;; i32.store
"\82\80\80\80\10" ;; alignment 2 with unused bits set
"\03" ;; offset 3
"\0b" ;; end
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01\60\00\00" ;; Type section
"\03\02\01\00" ;; Function section
"\05\03\01\00\01" ;; Memory section
"\0a\11\01" ;; Code section
;; function 0
"\0f\01\01" ;; local type count
"\7f" ;; i32
"\41\00" ;; i32.const 0
"\41\03" ;; i32.const 3
"\36" ;; i32.store
"\82\80\80\80\40" ;; alignment 2 with some unused bits set
"\03" ;; offset 3
"\0b" ;; end
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01\60\00\00" ;; Type section
"\03\02\01\00" ;; Function section
"\05\03\01\00\01" ;; Memory section
"\0a\11\01" ;; Code section
;; function 0
"\0f\01\01" ;; local type count
"\7f" ;; i32
"\41\00" ;; i32.const 0
"\41\03" ;; i32.const 3
"\36" ;; i32.store
"\03" ;; alignment 2
"\82\80\80\80\10" ;; offset 2 with unused bits set
"\0b" ;; end
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01\60\00\00" ;; Type section
"\03\02\01\00" ;; Function section
"\05\03\01\00\01" ;; Memory section
"\0a\11\01" ;; Code section
;; function 0
"\0f\01\01" ;; local type count
"\7f" ;; i32
"\41\00" ;; i32.const 0
"\41\03" ;; i32.const 3
"\36" ;; i32.store
"\02" ;; alignment 2
"\82\80\80\80\40" ;; offset 2 with some unused bits set
"\0b" ;; end
)
"integer too large"
)
;; Signed LEB128s sign-extend
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\0a\01" ;; Global section with 1 entry
"\7f\00" ;; i32, immutable
"\41\80\80\80\80\70" ;; i32.const 0 with unused bits set
"\0b" ;; end
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\0a\01" ;; Global section with 1 entry
"\7f\00" ;; i32, immutable
"\41\ff\ff\ff\ff\0f" ;; i32.const -1 with unused bits unset
"\0b" ;; end
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\0a\01" ;; Global section with 1 entry
"\7f\00" ;; i32, immutable
"\41\80\80\80\80\1f" ;; i32.const 0 with some unused bits set
"\0b" ;; end
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\0a\01" ;; Global section with 1 entry
"\7f\00" ;; i32, immutable
"\41\ff\ff\ff\ff\4f" ;; i32.const -1 with some unused bits unset
"\0b" ;; end
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\0f\01" ;; Global section with 1 entry
"\7e\00" ;; i64, immutable
"\42\80\80\80\80\80\80\80\80\80\7e" ;; i64.const 0 with unused bits set
"\0b" ;; end
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\0f\01" ;; Global section with 1 entry
"\7e\00" ;; i64, immutable
"\42\ff\ff\ff\ff\ff\ff\ff\ff\ff\01" ;; i64.const -1 with unused bits unset
"\0b" ;; end
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\0f\01" ;; Global section with 1 entry
"\7e\00" ;; i64, immutable
"\42\80\80\80\80\80\80\80\80\80\02" ;; i64.const 0 with some unused bits set
"\0b" ;; end
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\0f\01" ;; Global section with 1 entry
"\7e\00" ;; i64, immutable
"\42\ff\ff\ff\ff\ff\ff\ff\ff\ff\41" ;; i64.const -1 with some unused bits unset
"\0b" ;; end
)
"integer too large"
)

View File

@ -33,6 +33,7 @@
;; Leading UTF-8 BOM.
(assert_malformed (module binary "\ef\bb\bf\00asm\01\00\00\00") "magic header not detected")
;; Malformed binary version.
(assert_malformed (module binary "\00asm") "unexpected end")
(assert_malformed (module binary "\00asm\01") "unexpected end")
(assert_malformed (module binary "\00asm\01\00\00") "unexpected end")
@ -43,250 +44,6 @@
(assert_malformed (module binary "\00asm\00\00\01\00") "unknown binary version")
(assert_malformed (module binary "\00asm\00\00\00\01") "unknown binary version")
;; Unsigned LEB128 can have non-minimal length
(module binary
"\00asm" "\01\00\00\00"
"\05\04\01" ;; Memory section with 1 entry
"\00\82\00" ;; no max, minimum 2
)
(module binary
"\00asm" "\01\00\00\00"
"\05\07\01" ;; Memory section with 1 entry
"\00\82\80\80\80\00" ;; no max, minimum 2
)
;; Signed LEB128 can have non-minimal length
(module binary
"\00asm" "\01\00\00\00"
"\06\07\01" ;; Global section with 1 entry
"\7f\00" ;; i32, immutable
"\41\80\00" ;; i32.const 0
"\0b" ;; end
)
(module binary
"\00asm" "\01\00\00\00"
"\06\07\01" ;; Global section with 1 entry
"\7f\00" ;; i32, immutable
"\41\ff\7f" ;; i32.const -1
"\0b" ;; end
)
(module binary
"\00asm" "\01\00\00\00"
"\06\0a\01" ;; Global section with 1 entry
"\7f\00" ;; i32, immutable
"\41\80\80\80\80\00" ;; i32.const 0
"\0b" ;; end
)
(module binary
"\00asm" "\01\00\00\00"
"\06\0a\01" ;; Global section with 1 entry
"\7f\00" ;; i32, immutable
"\41\ff\ff\ff\ff\7f" ;; i32.const -1
"\0b" ;; end
)
(module binary
"\00asm" "\01\00\00\00"
"\06\07\01" ;; Global section with 1 entry
"\7e\00" ;; i64, immutable
"\42\80\00" ;; i64.const 0 with unused bits set
"\0b" ;; end
)
(module binary
"\00asm" "\01\00\00\00"
"\06\07\01" ;; Global section with 1 entry
"\7e\00" ;; i64, immutable
"\42\ff\7f" ;; i64.const -1 with unused bits unset
"\0b" ;; end
)
(module binary
"\00asm" "\01\00\00\00"
"\06\0f\01" ;; Global section with 1 entry
"\7e\00" ;; i64, immutable
"\42\80\80\80\80\80\80\80\80\80\00" ;; i64.const 0 with unused bits set
"\0b" ;; end
)
(module binary
"\00asm" "\01\00\00\00"
"\06\0f\01" ;; Global section with 1 entry
"\7e\00" ;; i64, immutable
"\42\ff\ff\ff\ff\ff\ff\ff\ff\ff\7f" ;; i64.const -1 with unused bits unset
"\0b" ;; end
)
;; Data segment memory index can have non-minimal length
(module binary
"\00asm" "\01\00\00\00"
"\05\03\01" ;; Memory section with 1 entry
"\00\00" ;; no max, minimum 0
"\0b\07\01" ;; Data section with 1 entry
"\80\00" ;; Memory index 0, encoded with 2 bytes
"\41\00\0b\00" ;; (i32.const 0) with contents ""
)
;; Element segment table index can have non-minimal length
(module binary
"\00asm" "\01\00\00\00"
"\04\04\01" ;; Table section with 1 entry
"\70\00\00" ;; no max, minimum 0, anyfunc
"\09\07\01" ;; Element section with 1 entry
"\80\00" ;; Table index 0, encoded with 2 bytes
"\41\00\0b\00" ;; (i32.const 0) with no elements
)
;; Unsigned LEB128 must not be overlong
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\05\08\01" ;; Memory section with 1 entry
"\00\82\80\80\80\80\00" ;; no max, minimum 2 with one byte too many
)
"integer representation too long"
)
;; Signed LEB128 must not be overlong
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\0b\01" ;; Global section with 1 entry
"\7f\00" ;; i32, immutable
"\41\80\80\80\80\80\00" ;; i32.const 0 with one byte too many
"\0b" ;; end
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\0b\01" ;; Global section with 1 entry
"\7f\00" ;; i32, immutable
"\41\ff\ff\ff\ff\ff\7f" ;; i32.const -1 with one byte too many
"\0b" ;; end
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\10\01" ;; Global section with 1 entry
"\7e\00" ;; i64, immutable
"\42\80\80\80\80\80\80\80\80\80\80\00" ;; i64.const 0 with one byte too many
"\0b" ;; end
)
"integer representation too long"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\10\01" ;; Global section with 1 entry
"\7e\00" ;; i64, immutable
"\42\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\7f" ;; i64.const -1 with one byte too many
"\0b" ;; end
)
"integer representation too long"
)
;; Unsigned LEB128s zero-extend
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\05\07\01" ;; Memory section with 1 entry
"\00\82\80\80\80\70" ;; no max, minimum 2 with unused bits set
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\05\07\01" ;; Memory section with 1 entry
"\00\82\80\80\80\40" ;; no max, minimum 2 with some unused bits set
)
"integer too large"
)
;; Signed LEB128s sign-extend
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\0a\01" ;; Global section with 1 entry
"\7f\00" ;; i32, immutable
"\41\80\80\80\80\70" ;; i32.const 0 with unused bits set
"\0b" ;; end
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\0a\01" ;; Global section with 1 entry
"\7f\00" ;; i32, immutable
"\41\ff\ff\ff\ff\0f" ;; i32.const -1 with unused bits unset
"\0b" ;; end
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\0a\01" ;; Global section with 1 entry
"\7f\00" ;; i32, immutable
"\41\80\80\80\80\1f" ;; i32.const 0 with some unused bits set
"\0b" ;; end
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\0a\01" ;; Global section with 1 entry
"\7f\00" ;; i32, immutable
"\41\ff\ff\ff\ff\4f" ;; i32.const -1 with some unused bits unset
"\0b" ;; end
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\0f\01" ;; Global section with 1 entry
"\7e\00" ;; i64, immutable
"\42\80\80\80\80\80\80\80\80\80\7e" ;; i64.const 0 with unused bits set
"\0b" ;; end
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\0f\01" ;; Global section with 1 entry
"\7e\00" ;; i64, immutable
"\42\ff\ff\ff\ff\ff\ff\ff\ff\ff\01" ;; i64.const -1 with unused bits unset
"\0b" ;; end
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\0f\01" ;; Global section with 1 entry
"\7e\00" ;; i64, immutable
"\42\80\80\80\80\80\80\80\80\80\02" ;; i64.const 0 with some unused bits set
"\0b" ;; end
)
"integer too large"
)
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\0f\01" ;; Global section with 1 entry
"\7e\00" ;; i64, immutable
"\42\ff\ff\ff\ff\ff\ff\ff\ff\ff\41" ;; i64.const -1 with some unused bits unset
"\0b" ;; end
)
"integer too large"
)
;; call_indirect reserved byte equal to zero.
(assert_malformed
@ -588,3 +345,437 @@
)
"too many locals"
)
;; Local count can be 0.
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01\60\00\00" ;; Type section
"\03\02\01\00" ;; Function section
"\0a\0a\01" ;; Code section
;; function 0
"\08\03"
"\00\7f" ;; 0 i32
"\00\7e" ;; 0 i64
"\02\7d" ;; 2 f32
"\0b" ;; end
)
;; Function section has non-zero count, but code section is absent.
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01\60\00\00" ;; Type section
"\03\03\02\00\00" ;; Function section with 2 functions
)
"function and code section have inconsistent lengths"
)
;; Code section has non-zero count, but function section is absent.
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\0a\04\01\02\00\0b" ;; Code section with 1 empty function
)
"function and code section have inconsistent lengths"
)
;; Function section count > code section count
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01\60\00\00" ;; Type section
"\03\03\02\00\00" ;; Function section with 2 functions
"\0a\04\01\02\00\0b" ;; Code section with 1 empty function
)
"function and code section have inconsistent lengths"
)
;; Function section count < code section count
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01\60\00\00" ;; Type section
"\03\02\01\00" ;; Function section with 1 function
"\0a\07\02\02\00\0b\02\00\0b" ;; Code section with 2 empty functions
)
"function and code section have inconsistent lengths"
)
;; Function section has zero count, and code section is absent.
(module binary
"\00asm" "\01\00\00\00"
"\03\01\00" ;; Function section with 0 functions
)
;; Code section has zero count, and function section is absent.
(module binary
"\00asm" "\01\00\00\00"
"\0a\01\00" ;; Code section with 0 functions
)
;; Type count can be zero
(module binary
"\00asm" "\01\00\00\00"
"\01\01\00" ;; type count can be zero
)
;; 2 type declared, 1 given
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\07\02" ;; type section with inconsistent count (2 declared, 1 given)
"\60\00\00" ;; 1st type
;; "\60\00\00" ;; 2nd type (missed)
)
"unexpected end of section or function"
)
;; 1 type declared, 2 given
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\07\01" ;; type section with inconsistent count (1 declared, 2 given)
"\60\00\00" ;; 1st type
"\60\00\00" ;; 2nd type (redundant)
)
"section size mismatch"
)
;; Import count can be zero
(module binary
"\00asm" "\01\00\00\00"
"\01\05\01" ;; type section
"\60\01\7f\00" ;; type 0
"\02\01\00" ;; import count can be zero
)
;; 2 import declared, 1 given
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\05\01" ;; type section
"\60\01\7f\00" ;; type 0
"\02\16\02" ;; import section with inconsistent count (2 declared, 1 given)
;; 1st import
"\08" ;; string length
"\73\70\65\63\74\65\73\74" ;; spectest
"\09" ;; string length
"\70\72\69\6e\74\5f\69\33\32" ;; print_i32
"\00\00" ;; import kind, import signature index
;; 2nd import
;; (missed)
)
"unexpected end of section or function"
)
;; 1 import declared, 2 given
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\09\02" ;; type section
"\60\01\7f\00" ;; type 0
"\60\01\7d\00" ;; type 1
"\02\2b\01" ;; import section with inconsistent count (1 declared, 2 given)
;; 1st import
"\08" ;; string length
"\73\70\65\63\74\65\73\74" ;; spectest
"\09" ;; string length
"\70\72\69\6e\74\5f\69\33\32" ;; print_i32
"\00\00" ;; import kind, import signature index
;; 2nd import
;; (redundant)
"\08" ;; string length
"\73\70\65\63\74\65\73\74" ;; spectest
"\09" ;; string length
"\70\72\69\6e\74\5f\66\33\32" ;; print_f32
"\00\01" ;; import kind, import signature index
)
"section size mismatch"
)
;; Table count can be zero
(module binary
"\00asm" "\01\00\00\00"
"\04\01\00" ;; table count can be zero
)
;; 1 table declared, 0 given
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\04\01\01" ;; table section with inconsistent count (1 declared, 0 given)
;; "\70\01\00\00" ;; table entity
)
"unexpected end of section or function"
)
;; Memory count can be zero
(module binary
"\00asm" "\01\00\00\00"
"\05\01\00" ;; memory count can be zero
)
;; 1 memory declared, 0 given
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\05\01\01" ;; memory section with inconsistent count (1 declared, 0 given)
;; "\00\00" ;; memory 0 (missed)
)
"unexpected end of section or function"
)
;; Global count can be zero
(module binary
"\00asm" "\01\00\00\00"
"\06\01\00" ;; global count can be zero
)
;; 2 global declared, 1 given
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\06\02" ;; global section with inconsistent count (2 declared, 1 given)
"\7f\00\41\00\0b" ;; global 0
;; "\7f\00\41\00\0b" ;; global 1 (missed)
)
"unexpected end of section or function"
)
;; 1 global declared, 2 given
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\06\0b\01" ;; global section with inconsistent count (1 declared, 2 given)
"\7f\00\41\00\0b" ;; global 0
"\7f\00\41\00\0b" ;; global 1 (redundant)
)
"section size mismatch"
)
;; Export count can be 0
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; type 0
"\03\03\02\00\00" ;; func section
"\07\01\00" ;; export count can be zero
"\0a\07\02" ;; code section
"\02\00\0b" ;; function body 0
"\02\00\0b" ;; function body 1
)
;; 2 export declared, 1 given
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; type 0
"\03\03\02\00\00" ;; func section
"\07\06\02" ;; export section with inconsistent count (2 declared, 1 given)
"\02" ;; export 0
"\66\31" ;; export name
"\00\00" ;; export kind, export func index
;; "\02" ;; export 1 (missed)
;; "\66\32" ;; export name
;; "\00\01" ;; export kind, export func index
"\0a\07\02" ;; code section
"\02\00\0b" ;; function body 0
"\02\00\0b" ;; function body 1
)
"unexpected end of section or function"
)
;; 1 export declared, 2 given
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; type 0
"\03\03\02\00\00" ;; func section
"\07\0b\01" ;; export section with inconsistent count (1 declared, 2 given)
"\02" ;; export 0
"\66\31" ;; export name
"\00\00" ;; export kind, export func index
"\02" ;; export 1 (redundant)
"\66\32" ;; export name
"\00\01" ;; export kind, export func index
"\0a\07\02" ;; code section
"\02\00\0b" ;; function body 0
"\02\00\0b" ;; function body 1
)
"section size mismatch"
)
;; elem segment count can be zero
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; type 0
"\03\02\01\00" ;; func section
"\04\04\01" ;; table section
"\70\00\01" ;; table 0
"\09\01\00" ;; elem segment count can be zero
"\0a\04\01" ;; code section
"\02\00\0b" ;; function body
)
;; 2 elem segment declared, 1 given
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; type 0
"\03\02\01\00" ;; func section
"\04\04\01" ;; table section
"\70\00\01" ;; table 0
"\09\07\02" ;; elem with inconsistent segment count (2 declared, 1 given)
"\00\41\00\0b\01\00" ;; elem 0
;; "\00\41\00\0b\01\00" ;; elem 1 (missed)
"\0a\04\01" ;; code section
"\02\00\0b" ;; function body
)
"invalid value type"
)
;; 1 elem segment declared, 2 given
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; type 0
"\03\02\01\00" ;; func section
"\04\04\01" ;; table section
"\70\00\01" ;; table 0
"\09\0d\01" ;; elem with inconsistent segment count (1 declared, 2 given)
"\00\41\00\0b\01\00" ;; elem 0
"\00\41\00\0b\01\00" ;; elem 1 (redundant)
"\0a\04\01" ;; code section
"\02\00\0b" ;; function body
)
"section size mismatch"
)
;; data segment count can be zero
(module binary
"\00asm" "\01\00\00\00"
"\05\03\01" ;; memory section
"\00\01" ;; memory 0
"\0b\01\00" ;; data segment count can be zero
)
;; 2 data segment declared, 1 given
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\05\03\01" ;; memory section
"\00\01" ;; memory 0
"\0b\07\02" ;; data with inconsistent segment count (2 declared, 1 given)
"\00\41\00\0b\01\61" ;; data 0
;; "\00\41\01\0b\01\62" ;; data 1 (missed)
)
"unexpected end of section or function"
)
;; 1 data segment declared, 2 given
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\05\03\01" ;; memory section
"\00\01" ;; memory 0
"\0b\0d\01" ;; data with inconsistent segment count (1 declared, 2 given)
"\00\41\00\0b\01\61" ;; data 0
"\00\41\01\0b\01\62" ;; data 1 (redundant)
)
"section size mismatch"
)
;; data segment has 7 bytes declared, but 6 bytes given
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\05\03\01" ;; memory section
"\00\01" ;; memory 0
"\0b\0c\01" ;; data section
"\00\41\03\0b" ;; data segment 0
"\07" ;; data segment size with inconsistent lengths (7 declared, 6 given)
"\61\62\63\64\65\66" ;; 6 bytes given
)
"unexpected end of section or function"
)
;; data segment has 5 bytes declared, but 6 bytes given
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\05\03\01" ;; memory section
"\00\01" ;; memory 0
"\0b\0c\01" ;; data section
"\00\41\00\0b" ;; data segment 0
"\05" ;; data segment size with inconsistent lengths (5 declared, 6 given)
"\61\62\63\64\65\66" ;; 6 bytes given
)
"section size mismatch"
)
;; br_table target count can be zero
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; type 0
"\03\02\01\00" ;; func section
"\0a\11\01" ;; code section
"\0f\00" ;; func 0
"\02\40" ;; block 0
"\41\01" ;; condition of if 0
"\04\40" ;; if 0
"\41\01" ;; index of br_table element
"\0e\00" ;; br_table target count can be zero
"\02" ;; break depth for default
"\0b\0b\0b" ;; end
)
;; 2 br_table target declared, 1 given
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; type 0
"\03\02\01\00" ;; func section
"\0a\12\01" ;; code section
"\10\00" ;; func 0
"\02\40" ;; block 0
"\41\01" ;; condition of if 0
"\04\40" ;; if 0
"\41\01" ;; index of br_table element
"\0e\02" ;; br_table with inconsistent target count (2 declared, 1 given)
"\00" ;; break depth 0
;; "\01" ;; break depth 1 (missed)
"\02" ;; break depth for default
"\0b\0b\0b" ;; end
)
"unexpected end of section or function"
)
;; 1 br_table target declared, 2 given
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\01\04\01" ;; type section
"\60\00\00" ;; type 0
"\03\02\01\00" ;; func section
"\0a\12\01" ;; code section
"\11\00" ;; func 0
"\02\40" ;; block 0
"\41\01" ;; condition of if 0
"\04\40" ;; if 0
"\41\01" ;; index of br_table element
"\0e\01" ;; br_table with inconsistent target count (1 declared, 2 given)
"\00" ;; break depth 0
"\01" ;; break depth 1
"\02" ;; break depth for default
"\0b\0b\0b" ;; end
)
"invalid value type"
)

View File

@ -114,9 +114,9 @@
(block (result i32) (i32.const 2) (block (result i32) (i32.const 1)) (br_table 0 0))
)
(func $func (param i32 i32) (result i32) (get_local 0))
(func $func (param i32 i32) (result i32) (local.get 0))
(type $check (func (param i32 i32) (result i32)))
(table anyfunc (elem $func))
(table funcref (elem $func))
(func (export "as-call_indirect-first") (result i32)
(block (result i32)
(call_indirect (type $check)
@ -150,7 +150,7 @@
(memory.grow (block (result i32) (i32.const 1)))
)
(func $f (param i32) (result i32) (get_local 0))
(func $f (param i32) (result i32) (local.get 0))
(func (export "as-call-value") (result i32)
(call $f (block (result i32) (i32.const 1)))
@ -164,16 +164,16 @@
(func (export "as-br-value") (result i32)
(block (result i32) (br 0 (block (result i32) (i32.const 1))))
)
(func (export "as-set_local-value") (result i32)
(local i32) (set_local 0 (block (result i32) (i32.const 1))) (get_local 0)
(func (export "as-local.set-value") (result i32)
(local i32) (local.set 0 (block (result i32) (i32.const 1))) (local.get 0)
)
(func (export "as-tee_local-value") (result i32)
(local i32) (tee_local 0 (block (result i32) (i32.const 1)))
(func (export "as-local.tee-value") (result i32)
(local i32) (local.tee 0 (block (result i32) (i32.const 1)))
)
(global $a (mut i32) (i32.const 10))
(func (export "as-set_global-value") (result i32)
(set_global $a (block (result i32) (i32.const 1)))
(get_global $a)
(func (export "as-global.set-value") (result i32)
(global.set $a (block (result i32) (i32.const 1)))
(global.get $a)
)
(func (export "as-load-operand") (result i32)
@ -223,29 +223,29 @@
)
(func (export "break-inner") (result i32)
(local i32)
(set_local 0 (i32.const 0))
(set_local 0 (i32.add (get_local 0) (block (result i32) (block (result i32) (br 1 (i32.const 0x1))))))
(set_local 0 (i32.add (get_local 0) (block (result i32) (block (br 0)) (i32.const 0x2))))
(set_local 0
(i32.add (get_local 0) (block (result i32) (i32.ctz (br 0 (i32.const 0x4)))))
(local.set 0 (i32.const 0))
(local.set 0 (i32.add (local.get 0) (block (result i32) (block (result i32) (br 1 (i32.const 0x1))))))
(local.set 0 (i32.add (local.get 0) (block (result i32) (block (br 0)) (i32.const 0x2))))
(local.set 0
(i32.add (local.get 0) (block (result i32) (i32.ctz (br 0 (i32.const 0x4)))))
)
(set_local 0
(i32.add (get_local 0) (block (result i32) (i32.ctz (block (result i32) (br 1 (i32.const 0x8))))))
(local.set 0
(i32.add (local.get 0) (block (result i32) (i32.ctz (block (result i32) (br 1 (i32.const 0x8))))))
)
(get_local 0)
(local.get 0)
)
(func (export "effects") (result i32)
(local i32)
(block
(set_local 0 (i32.const 1))
(set_local 0 (i32.mul (get_local 0) (i32.const 3)))
(set_local 0 (i32.sub (get_local 0) (i32.const 5)))
(set_local 0 (i32.mul (get_local 0) (i32.const 7)))
(local.set 0 (i32.const 1))
(local.set 0 (i32.mul (local.get 0) (i32.const 3)))
(local.set 0 (i32.sub (local.get 0) (i32.const 5)))
(local.set 0 (i32.mul (local.get 0) (i32.const 7)))
(br 0)
(set_local 0 (i32.mul (get_local 0) (i32.const 100)))
(local.set 0 (i32.mul (local.get 0) (i32.const 100)))
)
(i32.eq (get_local 0) (i32.const -14))
(i32.eq (local.get 0) (i32.const -14))
)
)
@ -285,9 +285,9 @@
(assert_return (invoke "as-return-value") (i32.const 1))
(assert_return (invoke "as-drop-operand"))
(assert_return (invoke "as-br-value") (i32.const 1))
(assert_return (invoke "as-set_local-value") (i32.const 1))
(assert_return (invoke "as-tee_local-value") (i32.const 1))
(assert_return (invoke "as-set_global-value") (i32.const 1))
(assert_return (invoke "as-local.set-value") (i32.const 1))
(assert_return (invoke "as-local.tee-value") (i32.const 1))
(assert_return (invoke "as-global.set-value") (i32.const 1))
(assert_return (invoke "as-load-operand") (i32.const 1))
(assert_return (invoke "as-unary-operand") (i32.const 0))
@ -369,6 +369,34 @@
"type mismatch"
)
(assert_invalid
(module
(func $type-value-empty-in-block
(i32.const 0)
(block (block (result i32)) (drop))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-value-empty-in-loop
(i32.const 0)
(loop (block (result i32)) (drop))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-value-empty-in-then
(i32.const 0) (i32.const 0)
(if (then (block (result i32)) (drop)))
)
)
"type mismatch"
)
(assert_invalid
(module (func $type-value-void-vs-i32 (result i32)
(block (result i32) (nop))
@ -1081,6 +1109,7 @@
"type mismatch"
)
(assert_malformed
(module quote "(func block end $l)")
"mismatching label"

View File

@ -95,16 +95,16 @@
)
(func (export "as-if-then") (param i32 i32) (result i32)
(block (result i32)
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (br 1 (i32.const 3)))
(else (get_local 1))
(else (local.get 1))
)
)
)
(func (export "as-if-else") (param i32 i32) (result i32)
(block (result i32)
(if (result i32) (get_local 0)
(then (get_local 1))
(if (result i32) (local.get 0)
(then (local.get 1))
(else (br 1 (i32.const 4)))
)
)
@ -112,12 +112,12 @@
(func (export "as-select-first") (param i32 i32) (result i32)
(block (result i32)
(select (br 0 (i32.const 5)) (get_local 0) (get_local 1))
(select (br 0 (i32.const 5)) (local.get 0) (local.get 1))
)
)
(func (export "as-select-second") (param i32 i32) (result i32)
(block (result i32)
(select (get_local 0) (br 0 (i32.const 6)) (get_local 1))
(select (local.get 0) (br 0 (i32.const 6)) (local.get 1))
)
)
(func (export "as-select-cond") (result i32)
@ -144,7 +144,7 @@
)
(type $sig (func (param i32 i32 i32) (result i32)))
(table anyfunc (elem $f))
(table funcref (elem $f))
(func (export "as-call_indirect-func") (result i32)
(block (result i32)
(call_indirect (type $sig)
@ -178,15 +178,15 @@
)
)
(func (export "as-set_local-value") (result i32) (local f32)
(block (result i32) (set_local 0 (br 0 (i32.const 17))) (i32.const -1))
(func (export "as-local.set-value") (result i32) (local f32)
(block (result i32) (local.set 0 (br 0 (i32.const 17))) (i32.const -1))
)
(func (export "as-tee_local-value") (result i32) (local i32)
(block (result i32) (tee_local 0 (br 0 (i32.const 1))))
(func (export "as-local.tee-value") (result i32) (local i32)
(block (result i32) (local.tee 0 (br 0 (i32.const 1))))
)
(global $a (mut i32) (i32.const 10))
(func (export "as-set_global-value") (result i32)
(block (result i32) (set_global $a (br 0 (i32.const 1))))
(func (export "as-global.set-value") (result i32)
(block (result i32) (global.set $a (br 0 (i32.const 1))))
)
(memory 1)
@ -242,7 +242,7 @@
)
(func (export "as-convert-operand") (result i32)
(block (result i32) (i32.wrap/i64 (br 0 (i32.const 41))))
(block (result i32) (i32.wrap_i64 (br 0 (i32.const 41))))
)
(func (export "as-memory.grow-size") (result i32)
@ -383,9 +383,9 @@
(assert_return (invoke "as-call_indirect-mid") (i32.const 22))
(assert_return (invoke "as-call_indirect-last") (i32.const 23))
(assert_return (invoke "as-set_local-value") (i32.const 17))
(assert_return (invoke "as-tee_local-value") (i32.const 1))
(assert_return (invoke "as-set_global-value") (i32.const 1))
(assert_return (invoke "as-local.set-value") (i32.const 17))
(assert_return (invoke "as-local.tee-value") (i32.const 1))
(assert_return (invoke "as-global.set-value") (i32.const 1))
(assert_return (invoke "as-load-address") (f32.const 1.7))
(assert_return (invoke "as-loadN-address") (i64.const 30))
@ -442,6 +442,156 @@
"type mismatch"
)
(assert_invalid
(module
(func $type-arg-empty-in-br
(i32.const 0)
(block (result i32) (br 0 (br 0))) (i32.eqz) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-arg-empty-in-br_if
(i32.const 0)
(block (result i32) (br_if 0 (br 0) (i32.const 1))) (i32.eqz) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-arg-empty-in-br_table
(i32.const 0)
(block (result i32) (br_table 0 (br 0))) (i32.eqz) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-arg-empty-in-return
(block (result i32)
(return (br 0))
)
(i32.eqz) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-arg-empty-in-select
(block (result i32)
(select (br 0) (i32.const 1) (i32.const 2))
)
(i32.eqz) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-arg-empty-in-call
(block (result i32)
(call 1 (br 0))
)
(i32.eqz) (drop)
)
(func (param i32) (result i32) (local.get 0))
)
"type mismatch"
)
(assert_invalid
(module
(func $f (param i32) (result i32) (local.get 0))
(type $sig (func (param i32) (result i32)))
(table funcref (elem $f))
(func $type-arg-empty-in-call_indirect
(block (result i32)
(call_indirect (type $sig)
(br 0) (i32.const 0)
)
)
(i32.eqz) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-arg-empty-in-local.set
(local i32)
(block (result i32)
(local.set 0 (br 0)) (local.get 0)
)
(i32.eqz) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-arg-empty-in-local.tee
(local i32)
(block (result i32)
(local.tee 0 (br 0))
)
(i32.eqz) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(global $x (mut i32) (i32.const 0))
(func $type-arg-empty-in-global.set
(block (result i32)
(global.set $x (br 0)) (global.get $x)
)
(i32.eqz) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(memory 0)
(func $type-arg-empty-in-memory.grow
(block (result i32)
(memory.grow (br 0))
)
(i32.eqz) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(memory 1)
(func $type-arg-empty-in-load
(block (result i32)
(i32.load (br 0))
)
(i32.eqz) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(memory 1)
(func $type-arg-empty-in-store
(block (result i32)
(i32.store (br 0) (i32.const 0))
)
(i32.eqz) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module (func $unbound-label (br 1)))
"unknown label"

View File

@ -30,42 +30,42 @@
)
(func (export "as-block-first") (param i32) (result i32)
(block (br_if 0 (get_local 0)) (return (i32.const 2))) (i32.const 3)
(block (br_if 0 (local.get 0)) (return (i32.const 2))) (i32.const 3)
)
(func (export "as-block-mid") (param i32) (result i32)
(block (call $dummy) (br_if 0 (get_local 0)) (return (i32.const 2)))
(block (call $dummy) (br_if 0 (local.get 0)) (return (i32.const 2)))
(i32.const 3)
)
(func (export "as-block-last") (param i32)
(block (call $dummy) (call $dummy) (br_if 0 (get_local 0)))
(block (call $dummy) (call $dummy) (br_if 0 (local.get 0)))
)
(func (export "as-block-first-value") (param i32) (result i32)
(block (result i32)
(drop (br_if 0 (i32.const 10) (get_local 0))) (return (i32.const 11))
(drop (br_if 0 (i32.const 10) (local.get 0))) (return (i32.const 11))
)
)
(func (export "as-block-mid-value") (param i32) (result i32)
(block (result i32)
(call $dummy)
(drop (br_if 0 (i32.const 20) (get_local 0)))
(drop (br_if 0 (i32.const 20) (local.get 0)))
(return (i32.const 21))
)
)
(func (export "as-block-last-value") (param i32) (result i32)
(block (result i32)
(call $dummy) (call $dummy) (br_if 0 (i32.const 11) (get_local 0))
(call $dummy) (call $dummy) (br_if 0 (i32.const 11) (local.get 0))
)
)
(func (export "as-loop-first") (param i32) (result i32)
(block (loop (br_if 1 (get_local 0)) (return (i32.const 2)))) (i32.const 3)
(block (loop (br_if 1 (local.get 0)) (return (i32.const 2)))) (i32.const 3)
)
(func (export "as-loop-mid") (param i32) (result i32)
(block (loop (call $dummy) (br_if 1 (get_local 0)) (return (i32.const 2))))
(block (loop (call $dummy) (br_if 1 (local.get 0)) (return (i32.const 2))))
(i32.const 4)
)
(func (export "as-loop-last") (param i32)
(loop (call $dummy) (br_if 1 (get_local 0)))
(loop (call $dummy) (br_if 1 (local.get 0)))
)
(func (export "as-br-value") (result i32)
@ -83,7 +83,7 @@
)
(func (export "as-br_if-value-cond") (param i32) (result i32)
(block (result i32)
(drop (br_if 0 (i32.const 2) (br_if 0 (i32.const 1) (get_local 0))))
(drop (br_if 0 (i32.const 2) (br_if 0 (i32.const 1) (local.get 0))))
(i32.const 4)
)
)
@ -108,7 +108,7 @@
(func (export "as-if-cond") (param i32) (result i32)
(block (result i32)
(if (result i32)
(br_if 0 (i32.const 1) (get_local 0))
(br_if 0 (i32.const 1) (local.get 0))
(then (i32.const 2))
(else (i32.const 3))
)
@ -116,23 +116,23 @@
)
(func (export "as-if-then") (param i32 i32)
(block
(if (get_local 0) (then (br_if 1 (get_local 1))) (else (call $dummy)))
(if (local.get 0) (then (br_if 1 (local.get 1))) (else (call $dummy)))
)
)
(func (export "as-if-else") (param i32 i32)
(block
(if (get_local 0) (then (call $dummy)) (else (br_if 1 (get_local 1))))
(if (local.get 0) (then (call $dummy)) (else (br_if 1 (local.get 1))))
)
)
(func (export "as-select-first") (param i32) (result i32)
(block (result i32)
(select (br_if 0 (i32.const 3) (i32.const 10)) (i32.const 2) (get_local 0))
(select (br_if 0 (i32.const 3) (i32.const 10)) (i32.const 2) (local.get 0))
)
)
(func (export "as-select-second") (param i32) (result i32)
(block (result i32)
(select (i32.const 1) (br_if 0 (i32.const 3) (i32.const 10)) (get_local 0))
(select (i32.const 1) (br_if 0 (i32.const 3) (i32.const 10)) (local.get 0))
)
)
(func (export "as-select-cond") (result i32)
@ -164,9 +164,9 @@
)
)
(func $func (param i32 i32 i32) (result i32) (get_local 0))
(func $func (param i32 i32 i32) (result i32) (local.get 0))
(type $check (func (param i32 i32 i32) (result i32)))
(table anyfunc (elem $func))
(table funcref (elem $func))
(func (export "as-call_indirect-func") (result i32)
(block (result i32)
(call_indirect (type $check)
@ -198,27 +198,57 @@
)
)
(func (export "as-set_local-value") (param i32) (result i32)
(func (export "as-local.set-value") (param i32) (result i32)
(local i32)
(block (result i32)
(set_local 0 (br_if 0 (i32.const 17) (get_local 0)))
(local.set 0 (br_if 0 (i32.const 17) (local.get 0)))
(i32.const -1)
)
)
(func (export "as-tee_local-value") (param i32) (result i32)
(func (export "as-local.tee-value") (param i32) (result i32)
(block (result i32)
(tee_local 0 (br_if 0 (i32.const 1) (get_local 0)))
(local.tee 0 (br_if 0 (i32.const 1) (local.get 0)))
(return (i32.const -1))
)
)
(global $a (mut i32) (i32.const 10))
(func (export "as-set_global-value") (param i32) (result i32)
(func (export "as-global.set-value") (param i32) (result i32)
(block (result i32)
(set_global $a (br_if 0 (i32.const 1) (get_local 0)))
(global.set $a (br_if 0 (i32.const 1) (local.get 0)))
(return (i32.const -1))
)
)
(memory 1)
(func (export "as-load-address") (result i32)
(block (result i32) (i32.load (br_if 0 (i32.const 1) (i32.const 1))))
)
(func (export "as-loadN-address") (result i32)
(block (result i32) (i32.load8_s (br_if 0 (i32.const 30) (i32.const 1))))
)
(func (export "as-store-address") (result i32)
(block (result i32)
(i32.store (br_if 0 (i32.const 30) (i32.const 1)) (i32.const 7)) (i32.const -1)
)
)
(func (export "as-store-value") (result i32)
(block (result i32)
(i32.store (i32.const 2) (br_if 0 (i32.const 31) (i32.const 1))) (i32.const -1)
)
)
(func (export "as-storeN-address") (result i32)
(block (result i32)
(i32.store8 (br_if 0 (i32.const 32) (i32.const 1)) (i32.const 7)) (i32.const -1)
)
)
(func (export "as-storeN-value") (result i32)
(block (result i32)
(i32.store16 (i32.const 2) (br_if 0 (i32.const 33) (i32.const 1))) (i32.const -1)
)
)
(func (export "as-unary-operand") (result f64)
(block (result f64) (f64.neg (br_if 0 (f64.const 1.0) (i32.const 1))))
)
@ -228,8 +258,16 @@
(func (export "as-binary-right") (result i32)
(block (result i32) (i32.sub (i32.const 10) (br_if 0 (i32.const 1) (i32.const 1))))
)
(func (export "as-test-operand") (result i32)
(block (result i32) (i32.eqz (br_if 0 (i32.const 0) (i32.const 1))))
)
(func (export "as-compare-left") (result i32)
(block (result i32) (i32.le_u (br_if 0 (i32.const 1) (i32.const 1)) (i32.const 10)))
)
(func (export "as-compare-right") (result i32)
(block (result i32) (i32.ne (i32.const 10) (br_if 0 (i32.const 1) (i32.const 42))))
)
(memory 0)
(func (export "as-memory.grow-size") (result i32)
(block (result i32) (memory.grow (br_if 0 (i32.const 1) (i32.const 1))))
)
@ -242,7 +280,7 @@
(i32.add
(i32.const 4)
(block (result i32)
(drop (br_if 1 (i32.const 8) (get_local 0)))
(drop (br_if 1 (i32.const 8) (local.get 0)))
(i32.const 16)
)
)
@ -257,7 +295,7 @@
(drop (i32.const 2))
(br 0
(block (result i32)
(drop (br_if 1 (i32.const 8) (get_local 0))) (i32.const 4)
(drop (br_if 1 (i32.const 8) (local.get 0))) (i32.const 4)
)
)
(i32.const 16)
@ -272,7 +310,7 @@
(drop (i32.const 2))
(drop (br_if 0
(block (result i32)
(drop (br_if 1 (i32.const 8) (get_local 0))) (i32.const 4)
(drop (br_if 1 (i32.const 8) (local.get 0))) (i32.const 4)
)
(i32.const 1)
))
@ -289,7 +327,7 @@
(drop (br_if 0
(i32.const 4)
(block (result i32)
(drop (br_if 1 (i32.const 8) (get_local 0))) (i32.const 1)
(drop (br_if 1 (i32.const 8) (local.get 0))) (i32.const 1)
)
))
(i32.const 16)
@ -304,7 +342,7 @@
(drop (i32.const 2))
(br_table 0
(block (result i32)
(drop (br_if 1 (i32.const 8) (get_local 0))) (i32.const 4)
(drop (br_if 1 (i32.const 8) (local.get 0))) (i32.const 4)
)
(i32.const 1)
)
@ -321,7 +359,7 @@
(br_table 0
(i32.const 4)
(block (result i32)
(drop (br_if 1 (i32.const 8) (get_local 0))) (i32.const 1)
(drop (br_if 1 (i32.const 8) (local.get 0))) (i32.const 1)
)
)
(i32.const 16)
@ -401,18 +439,29 @@
(assert_return (invoke "as-call_indirect-mid") (i32.const 4))
(assert_return (invoke "as-call_indirect-last") (i32.const 4))
(assert_return (invoke "as-set_local-value" (i32.const 0)) (i32.const -1))
(assert_return (invoke "as-set_local-value" (i32.const 1)) (i32.const 17))
(assert_return (invoke "as-local.set-value" (i32.const 0)) (i32.const -1))
(assert_return (invoke "as-local.set-value" (i32.const 1)) (i32.const 17))
(assert_return (invoke "as-tee_local-value" (i32.const 0)) (i32.const -1))
(assert_return (invoke "as-tee_local-value" (i32.const 1)) (i32.const 1))
(assert_return (invoke "as-local.tee-value" (i32.const 0)) (i32.const -1))
(assert_return (invoke "as-local.tee-value" (i32.const 1)) (i32.const 1))
(assert_return (invoke "as-set_global-value" (i32.const 0)) (i32.const -1))
(assert_return (invoke "as-set_global-value" (i32.const 1)) (i32.const 1))
(assert_return (invoke "as-global.set-value" (i32.const 0)) (i32.const -1))
(assert_return (invoke "as-global.set-value" (i32.const 1)) (i32.const 1))
(assert_return (invoke "as-load-address") (i32.const 1))
(assert_return (invoke "as-loadN-address") (i32.const 30))
(assert_return (invoke "as-store-address") (i32.const 30))
(assert_return (invoke "as-store-value") (i32.const 31))
(assert_return (invoke "as-storeN-address") (i32.const 32))
(assert_return (invoke "as-storeN-value") (i32.const 33))
(assert_return (invoke "as-unary-operand") (f64.const 1.0))
(assert_return (invoke "as-binary-left") (i32.const 1))
(assert_return (invoke "as-binary-right") (i32.const 1))
(assert_return (invoke "as-test-operand") (i32.const 0))
(assert_return (invoke "as-compare-left") (i32.const 1))
(assert_return (invoke "as-compare-right") (i32.const 1))
(assert_return (invoke "as-memory.grow-size") (i32.const 1))
(assert_return (invoke "nested-block-value" (i32.const 0)) (i32.const 21))
@ -516,6 +565,12 @@
"type mismatch"
)
(assert_invalid
(module (func $type-cond-empty-vs-i32
(block (br_if 0))
))
"type mismatch"
)
(assert_invalid
(module (func $type-cond-void-vs-i32
(block (br_if 0 (nop)))
@ -547,6 +602,54 @@
"type mismatch"
)
(assert_invalid
(module
(func $type-1st-cond-empty-in-then
(block
(i32.const 0) (i32.const 0)
(if (result i32) (then (br_if 0)))
)
(i32.eqz) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-2nd-cond-empty-in-then
(block
(i32.const 0) (i32.const 0)
(if (result i32) (then (br_if 0 (i32.const 1))))
)
(i32.eqz) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-1st-cond-empty-in-return
(block (result i32)
(return (br_if 0))
)
(i32.eqz) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-2nd-cond-empty-in-return
(block (result i32)
(return (br_if 0 (i32.const 1)))
)
(i32.eqz) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module (func $unbound-label (br_if 1 (i32.const 1))))
"unknown label"
@ -559,3 +662,4 @@
(module (func $large-label (br_if 0x10000001 (i32.const 1))))
"unknown label"
)

View File

@ -31,19 +31,19 @@
)
(func (export "empty") (param i32) (result i32)
(block (br_table 0 (get_local 0)) (return (i32.const 21)))
(block (br_table 0 (local.get 0)) (return (i32.const 21)))
(i32.const 22)
)
(func (export "empty-value") (param i32) (result i32)
(block (result i32)
(br_table 0 (i32.const 33) (get_local 0)) (i32.const 31)
(br_table 0 (i32.const 33) (local.get 0)) (i32.const 31)
)
)
(func (export "singleton") (param i32) (result i32)
(block
(block
(br_table 1 0 (get_local 0))
(br_table 1 0 (local.get 0))
(return (i32.const 21))
)
(return (i32.const 20))
@ -55,7 +55,7 @@
(block (result i32)
(drop
(block (result i32)
(br_table 0 1 (i32.const 33) (get_local 0))
(br_table 0 1 (i32.const 33) (local.get 0))
(return (i32.const 31))
)
)
@ -69,7 +69,7 @@
(block
(block
(block
(br_table 3 2 1 0 4 (get_local 0))
(br_table 3 2 1 0 4 (local.get 0))
(return (i32.const 99))
)
(return (i32.const 100))
@ -85,23 +85,23 @@
(func (export "multiple-value") (param i32) (result i32)
(local i32)
(set_local 1 (block (result i32)
(set_local 1 (block (result i32)
(set_local 1 (block (result i32)
(set_local 1 (block (result i32)
(set_local 1 (block (result i32)
(br_table 3 2 1 0 4 (i32.const 200) (get_local 0))
(return (i32.add (get_local 1) (i32.const 99)))
(local.set 1 (block (result i32)
(local.set 1 (block (result i32)
(local.set 1 (block (result i32)
(local.set 1 (block (result i32)
(local.set 1 (block (result i32)
(br_table 3 2 1 0 4 (i32.const 200) (local.get 0))
(return (i32.add (local.get 1) (i32.const 99)))
))
(return (i32.add (get_local 1) (i32.const 10)))
(return (i32.add (local.get 1) (i32.const 10)))
))
(return (i32.add (get_local 1) (i32.const 11)))
(return (i32.add (local.get 1) (i32.const 11)))
))
(return (i32.add (get_local 1) (i32.const 12)))
(return (i32.add (local.get 1) (i32.const 12)))
))
(return (i32.add (get_local 1) (i32.const 13)))
(return (i32.add (local.get 1) (i32.const 13)))
))
(i32.add (get_local 1) (i32.const 14))
(i32.add (local.get 1) (i32.const 14))
)
(func (export "large") (param i32) (result i32)
@ -832,7 +832,7 @@
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
(get_local 0)
(local.get 0)
)
(return (i32.const -1))
)
@ -924,17 +924,17 @@
(func (export "as-if-then") (param i32 i32) (result i32)
(block (result i32)
(if (result i32)
(get_local 0)
(local.get 0)
(then (br_table 1 (i32.const 3) (i32.const 0)))
(else (get_local 1))
(else (local.get 1))
)
)
)
(func (export "as-if-else") (param i32 i32) (result i32)
(block (result i32)
(if (result i32)
(get_local 0)
(then (get_local 1))
(local.get 0)
(then (local.get 1))
(else (br_table 1 0 (i32.const 4) (i32.const 0)))
)
)
@ -943,14 +943,14 @@
(func (export "as-select-first") (param i32 i32) (result i32)
(block (result i32)
(select
(br_table 0 (i32.const 5) (i32.const 0)) (get_local 0) (get_local 1)
(br_table 0 (i32.const 5) (i32.const 0)) (local.get 0) (local.get 1)
)
)
)
(func (export "as-select-second") (param i32 i32) (result i32)
(block (result i32)
(select
(get_local 0) (br_table 0 (i32.const 6) (i32.const 1)) (get_local 1)
(local.get 0) (br_table 0 (i32.const 6) (i32.const 1)) (local.get 1)
)
)
)
@ -986,7 +986,7 @@
)
(type $sig (func (param i32 i32 i32) (result i32)))
(table anyfunc (elem $f))
(table funcref (elem $f))
(func (export "as-call_indirect-first") (result i32)
(block (result i32)
(call_indirect (type $sig)
@ -1020,24 +1020,24 @@
)
)
(func (export "as-set_local-value") (result i32)
(func (export "as-local.set-value") (result i32)
(local f32)
(block (result i32)
(set_local 0 (br_table 0 (i32.const 17) (i32.const 1)))
(local.set 0 (br_table 0 (i32.const 17) (i32.const 1)))
(i32.const -1)
)
)
(func (export "as-tee_local-value") (result i32)
(func (export "as-local.tee-value") (result i32)
(local i32)
(block (result i32)
(set_local 0 (br_table 0 (i32.const 1) (i32.const 1)))
(local.set 0 (br_table 0 (i32.const 1) (i32.const 1)))
(i32.const -1)
)
)
(global $a (mut i32) (i32.const 10))
(func (export "as-set_global-value") (result i32)
(func (export "as-global.set-value") (result i32)
(block (result i32)
(set_global $a (br_table 0 (i32.const 1) (i32.const 1)))
(global.set $a (br_table 0 (i32.const 1) (i32.const 1)))
(i32.const -1)
)
)
@ -1108,7 +1108,7 @@
(func (export "as-convert-operand") (result i32)
(block (result i32)
(i32.wrap/i64 (br_table 0 (i32.const 41) (i32.const 0)))
(i32.wrap_i64 (br_table 0 (i32.const 41) (i32.const 0)))
)
)
@ -1128,7 +1128,7 @@
(drop (i32.const 4))
(i32.add
(i32.const 8)
(br_table 0 1 2 (i32.const 16) (get_local 0))
(br_table 0 1 2 (i32.const 16) (local.get 0))
)
)
)
@ -1146,7 +1146,7 @@
(drop
(block (result i32)
(drop (i32.const 4))
(br 0 (br_table 2 1 0 (i32.const 8) (get_local 0)))
(br 0 (br_table 2 1 0 (i32.const 8) (local.get 0)))
)
)
(i32.const 16)
@ -1166,7 +1166,7 @@
(drop (i32.const 4))
(drop
(br_if 0
(br_table 0 1 2 (i32.const 8) (get_local 0))
(br_table 0 1 2 (i32.const 8) (local.get 0))
(i32.const 1)
)
)
@ -1186,7 +1186,7 @@
(block (result i32)
(drop (i32.const 2))
(drop
(br_if 0 (i32.const 4) (br_table 0 1 0 (i32.const 8) (get_local 0)))
(br_if 0 (i32.const 4) (br_table 0 1 0 (i32.const 8) (local.get 0)))
)
(i32.const 16)
)
@ -1203,7 +1203,7 @@
(drop
(block (result i32)
(drop (i32.const 4))
(br_table 0 (br_table 0 1 2 (i32.const 8) (get_local 0)) (i32.const 1))
(br_table 0 (br_table 0 1 2 (i32.const 8) (local.get 0)) (i32.const 1))
(i32.const 32)
)
)
@ -1219,7 +1219,7 @@
(i32.const 1)
(block (result i32)
(drop (i32.const 2))
(br_table 0 (i32.const 4) (br_table 0 1 0 (i32.const 8) (get_local 0)))
(br_table 0 (i32.const 4) (br_table 0 1 0 (i32.const 8) (local.get 0)))
(i32.const 16)
)
)
@ -1227,17 +1227,17 @@
)
(func (export "nested-br_table-loop-block") (param i32) (result i32)
(set_local 0
(local.set 0
(loop (result i32)
(block
(br_table 1 0 0 (get_local 0))
(br_table 1 0 0 (local.get 0))
)
(i32.const 0)
)
)
(loop (result i32)
(block
(br_table 0 1 1 (get_local 0))
(br_table 0 1 1 (local.get 0))
)
(i32.const 3)
)
@ -1355,9 +1355,9 @@
(assert_return (invoke "as-call_indirect-last") (i32.const 22))
(assert_return (invoke "as-call_indirect-func") (i32.const 23))
(assert_return (invoke "as-set_local-value") (i32.const 17))
(assert_return (invoke "as-tee_local-value") (i32.const 1))
(assert_return (invoke "as-set_global-value") (i32.const 1))
(assert_return (invoke "as-local.set-value") (i32.const 17))
(assert_return (invoke "as-local.tee-value") (i32.const 1))
(assert_return (invoke "as-global.set-value") (i32.const 1))
(assert_return (invoke "as-load-address") (f32.const 1.7))
(assert_return (invoke "as-loadN-address") (i64.const 30))
@ -1432,6 +1432,13 @@
"type mismatch"
)
(assert_invalid
(module (func $type-arg-empty-vs-num (result i32)
(block (br_table 0) (i32.const 1))
))
"type mismatch"
)
(assert_invalid
(module (func $type-arg-void-vs-num (result i32)
(block (result i32) (br_table 0 (nop) (i32.const 1)) (i32.const 1))
@ -1491,6 +1498,61 @@
"type mismatch"
)
(assert_invalid
(module (func $type-arg-void-vs-num (result i32)
(block (br_table 0 (i32.const 1)) (i32.const 1))
))
"type mismatch"
)
(assert_invalid
(module
(func $type-arg-index-empty-in-then
(block
(i32.const 0) (i32.const 0)
(if (result i32) (then (br_table 0)))
)
(i32.eqz) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-arg-value-empty-in-then
(block
(i32.const 0) (i32.const 0)
(if (result i32) (then (br_table 0 (i32.const 1))))
)
(i32.eqz) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-arg-index-empty-in-return
(block (result i32)
(return (br_table 0))
)
(i32.eqz) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-arg-value-empty-in-return
(block (result i32)
(return (br_table 0 (i32.const 1)))
)
(i32.eqz) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module (func $unbound-label
(block (br_table 2 1 (i32.const 1)))
@ -1528,3 +1590,4 @@
))
"unknown label"
)

View File

@ -7,15 +7,15 @@
(func $const-f32 (result f32) (f32.const 0xf32))
(func $const-f64 (result f64) (f64.const 0xf64))
(func $id-i32 (param i32) (result i32) (get_local 0))
(func $id-i64 (param i64) (result i64) (get_local 0))
(func $id-f32 (param f32) (result f32) (get_local 0))
(func $id-f64 (param f64) (result f64) (get_local 0))
(func $id-i32 (param i32) (result i32) (local.get 0))
(func $id-i64 (param i64) (result i64) (local.get 0))
(func $id-f32 (param f32) (result f32) (local.get 0))
(func $id-f64 (param f64) (result f64) (local.get 0))
(func $f32-i32 (param f32 i32) (result i32) (get_local 1))
(func $i32-i64 (param i32 i64) (result i64) (get_local 1))
(func $f64-f32 (param f64 f32) (result f32) (get_local 1))
(func $i64-f64 (param i64 f64) (result f64) (get_local 1))
(func $f32-i32 (param f32 i32) (result i32) (local.get 1))
(func $i32-i64 (param i32 i64) (result i64) (local.get 1))
(func $f64-f32 (param f64 f32) (result f32) (local.get 1))
(func $i64-f64 (param i64 f64) (result f64) (local.get 1))
;; Typing
@ -45,51 +45,51 @@
;; Recursion
(func $fac (export "fac") (param i64) (result i64)
(if (result i64) (i64.eqz (get_local 0))
(if (result i64) (i64.eqz (local.get 0))
(then (i64.const 1))
(else
(i64.mul
(get_local 0)
(call $fac (i64.sub (get_local 0) (i64.const 1)))
(local.get 0)
(call $fac (i64.sub (local.get 0) (i64.const 1)))
)
)
)
)
(func $fac-acc (export "fac-acc") (param i64 i64) (result i64)
(if (result i64) (i64.eqz (get_local 0))
(then (get_local 1))
(if (result i64) (i64.eqz (local.get 0))
(then (local.get 1))
(else
(call $fac-acc
(i64.sub (get_local 0) (i64.const 1))
(i64.mul (get_local 0) (get_local 1))
(i64.sub (local.get 0) (i64.const 1))
(i64.mul (local.get 0) (local.get 1))
)
)
)
)
(func $fib (export "fib") (param i64) (result i64)
(if (result i64) (i64.le_u (get_local 0) (i64.const 1))
(if (result i64) (i64.le_u (local.get 0) (i64.const 1))
(then (i64.const 1))
(else
(i64.add
(call $fib (i64.sub (get_local 0) (i64.const 2)))
(call $fib (i64.sub (get_local 0) (i64.const 1)))
(call $fib (i64.sub (local.get 0) (i64.const 2)))
(call $fib (i64.sub (local.get 0) (i64.const 1)))
)
)
)
)
(func $even (export "even") (param i64) (result i32)
(if (result i32) (i64.eqz (get_local 0))
(if (result i32) (i64.eqz (local.get 0))
(then (i32.const 44))
(else (call $odd (i64.sub (get_local 0) (i64.const 1))))
(else (call $odd (i64.sub (local.get 0) (i64.const 1))))
)
)
(func $odd (export "odd") (param i64) (result i32)
(if (result i32) (i64.eqz (get_local 0))
(if (result i32) (i64.eqz (local.get 0))
(then (i32.const 99))
(else (call $even (i64.sub (get_local 0) (i64.const 1))))
(else (call $even (i64.sub (local.get 0) (i64.const 1))))
)
)
@ -139,9 +139,9 @@
(block (result i32) (i32.const 2) (call $const-i32) (br_table 0 0))
)
(func $func (param i32 i32) (result i32) (get_local 0))
(func $func (param i32 i32) (result i32) (local.get 0))
(type $check (func (param i32 i32) (result i32)))
(table anyfunc (elem $func))
(table funcref (elem $func))
(func (export "as-call_indirect-first") (result i32)
(block (result i32)
(call_indirect (type $check)
@ -183,20 +183,48 @@
(func (export "as-br-value") (result i32)
(block (result i32) (br 0 (call $const-i32)))
)
(func (export "as-set_local-value") (result i32)
(local i32) (set_local 0 (call $const-i32)) (get_local 0)
(func (export "as-local.set-value") (result i32)
(local i32) (local.set 0 (call $const-i32)) (local.get 0)
)
(func (export "as-tee_local-value") (result i32)
(local i32) (tee_local 0 (call $const-i32))
(func (export "as-local.tee-value") (result i32)
(local i32) (local.tee 0 (call $const-i32))
)
(global $a (mut i32) (i32.const 10))
(func (export "as-set_global-value") (result i32)
(set_global $a (call $const-i32))
(get_global $a)
(func (export "as-global.set-value") (result i32)
(global.set $a (call $const-i32))
(global.get $a)
)
(func (export "as-load-operand") (result i32)
(i32.load (call $const-i32))
)
(func $dummy (param i32) (result i32) (local.get 0))
(func $du (param f32) (result f32) (local.get 0))
(func (export "as-unary-operand") (result f32)
(block (result f32) (f32.sqrt (call $du (f32.const 0x0p+0))))
)
(func (export "as-binary-left") (result i32)
(block (result i32) (i32.add (call $dummy (i32.const 1)) (i32.const 10)))
)
(func (export "as-binary-right") (result i32)
(block (result i32) (i32.sub (i32.const 10) (call $dummy (i32.const 1))))
)
(func (export "as-test-operand") (result i32)
(block (result i32) (i32.eqz (call $dummy (i32.const 1))))
)
(func (export "as-compare-left") (result i32)
(block (result i32) (i32.le_u (call $dummy (i32.const 1)) (i32.const 10)))
)
(func (export "as-compare-right") (result i32)
(block (result i32) (i32.ne (i32.const 10) (call $dummy (i32.const 1))))
)
(func (export "as-convert-operand") (result i64)
(block (result i64) (i64.extend_i32_s (call $dummy (i32.const 1))))
)
)
(assert_return (invoke "type-i32") (i32.const 0x132))
@ -267,11 +295,19 @@
(assert_return (invoke "as-return-value") (i32.const 0x132))
(assert_return (invoke "as-drop-operand"))
(assert_return (invoke "as-br-value") (i32.const 0x132))
(assert_return (invoke "as-set_local-value") (i32.const 0x132))
(assert_return (invoke "as-tee_local-value") (i32.const 0x132))
(assert_return (invoke "as-set_global-value") (i32.const 0x132))
(assert_return (invoke "as-local.set-value") (i32.const 0x132))
(assert_return (invoke "as-local.tee-value") (i32.const 0x132))
(assert_return (invoke "as-global.set-value") (i32.const 0x132))
(assert_return (invoke "as-load-operand") (i32.const 1))
(assert_return (invoke "as-unary-operand") (f32.const 0x0p+0))
(assert_return (invoke "as-binary-left") (i32.const 11))
(assert_return (invoke "as-binary-right") (i32.const 9))
(assert_return (invoke "as-test-operand") (i32.const 0))
(assert_return (invoke "as-compare-left") (i32.const 1))
(assert_return (invoke "as-compare-right") (i32.const 1))
(assert_return (invoke "as-convert-operand") (i64.const 1))
;; Invalid typing
(assert_invalid
@ -347,6 +383,61 @@
"type mismatch"
)
(assert_invalid
(module
(func $type-first-empty-in-block
(block (call 1))
)
(func (param i32))
)
"type mismatch"
)
(assert_invalid
(module
(func $type-second-empty-in-block
(block (call 1 (i32.const 0)))
)
(func (param i32 i32))
)
"type mismatch"
)
(assert_invalid
(module
(func $type-first-empty-in-loop
(loop (call 1))
)
(func (param i32))
)
"type mismatch"
)
(assert_invalid
(module
(func $type-second-empty-in-loop
(loop (call 1 (i32.const 0)))
)
(func (param i32 i32))
)
"type mismatch"
)
(assert_invalid
(module
(func $type-first-empty-in-then
(if (i32.const 0) (then (call 1)))
)
(func (param i32))
)
"type mismatch"
)
(assert_invalid
(module
(func $type-second-empty-in-then
(if (i32.const 0) (then (call 1 (i32.const 0))))
)
(func (param i32 i32))
)
"type mismatch"
)
;; Unbound function

View File

@ -25,22 +25,22 @@
(func $const-f32 (type $out-f32) (f32.const 0xf32))
(func $const-f64 (type $out-f64) (f64.const 0xf64))
(func $id-i32 (type $over-i32) (get_local 0))
(func $id-i64 (type $over-i64) (get_local 0))
(func $id-f32 (type $over-f32) (get_local 0))
(func $id-f64 (type $over-f64) (get_local 0))
(func $id-i32 (type $over-i32) (local.get 0))
(func $id-i64 (type $over-i64) (local.get 0))
(func $id-f32 (type $over-f32) (local.get 0))
(func $id-f64 (type $over-f64) (local.get 0))
(func $i32-i64 (type $i32-i64) (get_local 1))
(func $i64-f64 (type $i64-f64) (get_local 1))
(func $f32-i32 (type $f32-i32) (get_local 1))
(func $f64-f32 (type $f64-f32) (get_local 1))
(func $i32-i64 (type $i32-i64) (local.get 1))
(func $i64-f64 (type $i64-f64) (local.get 1))
(func $f32-i32 (type $f32-i32) (local.get 1))
(func $f64-f32 (type $f64-f32) (local.get 1))
(func $over-i32-duplicate (type $over-i32-duplicate) (get_local 0))
(func $over-i64-duplicate (type $over-i64-duplicate) (get_local 0))
(func $over-f32-duplicate (type $over-f32-duplicate) (get_local 0))
(func $over-f64-duplicate (type $over-f64-duplicate) (get_local 0))
(func $over-i32-duplicate (type $over-i32-duplicate) (local.get 0))
(func $over-i64-duplicate (type $over-i64-duplicate) (local.get 0))
(func $over-f32-duplicate (type $over-f32-duplicate) (local.get 0))
(func $over-f64-duplicate (type $over-f64-duplicate) (local.get 0))
(table anyfunc
(table funcref
(elem
$const-i32 $const-i64 $const-f32 $const-f64
$id-i32 $id-i64 $id-f32 $id-f64
@ -130,32 +130,32 @@
;; Dispatch
(func (export "dispatch") (param i32 i64) (result i64)
(call_indirect (type $over-i64) (get_local 1) (get_local 0))
(call_indirect (type $over-i64) (local.get 1) (local.get 0))
)
(func (export "dispatch-structural-i64") (param i32) (result i64)
(call_indirect (type $over-i64-duplicate) (i64.const 9) (get_local 0))
(call_indirect (type $over-i64-duplicate) (i64.const 9) (local.get 0))
)
(func (export "dispatch-structural-i32") (param i32) (result i32)
(call_indirect (type $over-i32-duplicate) (i32.const 9) (get_local 0))
(call_indirect (type $over-i32-duplicate) (i32.const 9) (local.get 0))
)
(func (export "dispatch-structural-f32") (param i32) (result f32)
(call_indirect (type $over-f32-duplicate) (f32.const 9.0) (get_local 0))
(call_indirect (type $over-f32-duplicate) (f32.const 9.0) (local.get 0))
)
(func (export "dispatch-structural-f64") (param i32) (result f64)
(call_indirect (type $over-f64-duplicate) (f64.const 9.0) (get_local 0))
(call_indirect (type $over-f64-duplicate) (f64.const 9.0) (local.get 0))
)
;; Recursion
(func $fac-i64 (export "fac-i64") (type $over-i64)
(if (result i64) (i64.eqz (get_local 0))
(if (result i64) (i64.eqz (local.get 0))
(then (i64.const 1))
(else
(i64.mul
(get_local 0)
(local.get 0)
(call_indirect (type $over-i64)
(i64.sub (get_local 0) (i64.const 1))
(i64.sub (local.get 0) (i64.const 1))
(i32.const 12)
)
)
@ -164,16 +164,16 @@
)
(func $fib-i64 (export "fib-i64") (type $over-i64)
(if (result i64) (i64.le_u (get_local 0) (i64.const 1))
(if (result i64) (i64.le_u (local.get 0) (i64.const 1))
(then (i64.const 1))
(else
(i64.add
(call_indirect (type $over-i64)
(i64.sub (get_local 0) (i64.const 2))
(i64.sub (local.get 0) (i64.const 2))
(i32.const 13)
)
(call_indirect (type $over-i64)
(i64.sub (get_local 0) (i64.const 1))
(i64.sub (local.get 0) (i64.const 1))
(i32.const 13)
)
)
@ -182,13 +182,13 @@
)
(func $fac-i32 (export "fac-i32") (type $over-i32)
(if (result i32) (i32.eqz (get_local 0))
(if (result i32) (i32.eqz (local.get 0))
(then (i32.const 1))
(else
(i32.mul
(get_local 0)
(local.get 0)
(call_indirect (type $over-i32)
(i32.sub (get_local 0) (i32.const 1))
(i32.sub (local.get 0) (i32.const 1))
(i32.const 23)
)
)
@ -197,13 +197,13 @@
)
(func $fac-f32 (export "fac-f32") (type $over-f32)
(if (result f32) (f32.eq (get_local 0) (f32.const 0.0))
(if (result f32) (f32.eq (local.get 0) (f32.const 0.0))
(then (f32.const 1.0))
(else
(f32.mul
(get_local 0)
(local.get 0)
(call_indirect (type $over-f32)
(f32.sub (get_local 0) (f32.const 1.0))
(f32.sub (local.get 0) (f32.const 1.0))
(i32.const 24)
)
)
@ -212,13 +212,13 @@
)
(func $fac-f64 (export "fac-f64") (type $over-f64)
(if (result f64) (f64.eq (get_local 0) (f64.const 0.0))
(if (result f64) (f64.eq (local.get 0) (f64.const 0.0))
(then (f64.const 1.0))
(else
(f64.mul
(get_local 0)
(local.get 0)
(call_indirect (type $over-f64)
(f64.sub (get_local 0) (f64.const 1.0))
(f64.sub (local.get 0) (f64.const 1.0))
(i32.const 25)
)
)
@ -227,16 +227,16 @@
)
(func $fib-i32 (export "fib-i32") (type $over-i32)
(if (result i32) (i32.le_u (get_local 0) (i32.const 1))
(if (result i32) (i32.le_u (local.get 0) (i32.const 1))
(then (i32.const 1))
(else
(i32.add
(call_indirect (type $over-i32)
(i32.sub (get_local 0) (i32.const 2))
(i32.sub (local.get 0) (i32.const 2))
(i32.const 26)
)
(call_indirect (type $over-i32)
(i32.sub (get_local 0) (i32.const 1))
(i32.sub (local.get 0) (i32.const 1))
(i32.const 26)
)
)
@ -245,16 +245,16 @@
)
(func $fib-f32 (export "fib-f32") (type $over-f32)
(if (result f32) (f32.le (get_local 0) (f32.const 1.0))
(if (result f32) (f32.le (local.get 0) (f32.const 1.0))
(then (f32.const 1.0))
(else
(f32.add
(call_indirect (type $over-f32)
(f32.sub (get_local 0) (f32.const 2.0))
(f32.sub (local.get 0) (f32.const 2.0))
(i32.const 27)
)
(call_indirect (type $over-f32)
(f32.sub (get_local 0) (f32.const 1.0))
(f32.sub (local.get 0) (f32.const 1.0))
(i32.const 27)
)
)
@ -263,16 +263,16 @@
)
(func $fib-f64 (export "fib-f64") (type $over-f64)
(if (result f64) (f64.le (get_local 0) (f64.const 1.0))
(if (result f64) (f64.le (local.get 0) (f64.const 1.0))
(then (f64.const 1.0))
(else
(f64.add
(call_indirect (type $over-f64)
(f64.sub (get_local 0) (f64.const 2.0))
(f64.sub (local.get 0) (f64.const 2.0))
(i32.const 28)
)
(call_indirect (type $over-f64)
(f64.sub (get_local 0) (f64.const 1.0))
(f64.sub (local.get 0) (f64.const 1.0))
(i32.const 28)
)
)
@ -281,22 +281,22 @@
)
(func $even (export "even") (param i32) (result i32)
(if (result i32) (i32.eqz (get_local 0))
(if (result i32) (i32.eqz (local.get 0))
(then (i32.const 44))
(else
(call_indirect (type $over-i32)
(i32.sub (get_local 0) (i32.const 1))
(i32.sub (local.get 0) (i32.const 1))
(i32.const 15)
)
)
)
)
(func $odd (export "odd") (param i32) (result i32)
(if (result i32) (i32.eqz (get_local 0))
(if (result i32) (i32.eqz (local.get 0))
(then (i32.const 99))
(else
(call_indirect (type $over-i32)
(i32.sub (get_local 0) (i32.const 1))
(i32.sub (local.get 0) (i32.const 1))
(i32.const 14)
)
)
@ -368,21 +368,80 @@
(func (export "as-br-value") (result f32)
(block (result f32) (br 0 (call_indirect (type $over-f32) (f32.const 1) (i32.const 6))))
)
(func (export "as-set_local-value") (result f64)
(local f64) (set_local 0 (call_indirect (type $over-f64) (f64.const 1) (i32.const 7))) (get_local 0)
(func (export "as-local.set-value") (result f64)
(local f64) (local.set 0 (call_indirect (type $over-f64) (f64.const 1) (i32.const 7))) (local.get 0)
)
(func (export "as-tee_local-value") (result f64)
(local f64) (tee_local 0 (call_indirect (type $over-f64) (f64.const 1) (i32.const 7)))
(func (export "as-local.tee-value") (result f64)
(local f64) (local.tee 0 (call_indirect (type $over-f64) (f64.const 1) (i32.const 7)))
)
(global $a (mut f64) (f64.const 10.0))
(func (export "as-set_global-value") (result f64)
(set_global $a (call_indirect (type $over-f64) (f64.const 1.0) (i32.const 7)))
(get_global $a)
(func (export "as-global.set-value") (result f64)
(global.set $a (call_indirect (type $over-f64) (f64.const 1.0) (i32.const 7)))
(global.get $a)
)
(func (export "as-load-operand") (result i32)
(i32.load (call_indirect (type $out-i32) (i32.const 0)))
)
(func (export "as-unary-operand") (result f32)
(block (result f32)
(f32.sqrt
(call_indirect (type $over-f32) (f32.const 0x0p+0) (i32.const 6))
)
)
)
(func (export "as-binary-left") (result i32)
(block (result i32)
(i32.add
(call_indirect (type $over-i32) (i32.const 1) (i32.const 4))
(i32.const 10)
)
)
)
(func (export "as-binary-right") (result i32)
(block (result i32)
(i32.sub
(i32.const 10)
(call_indirect (type $over-i32) (i32.const 1) (i32.const 4))
)
)
)
(func (export "as-test-operand") (result i32)
(block (result i32)
(i32.eqz
(call_indirect (type $over-i32) (i32.const 1) (i32.const 4))
)
)
)
(func (export "as-compare-left") (result i32)
(block (result i32)
(i32.le_u
(call_indirect (type $over-i32) (i32.const 1) (i32.const 4))
(i32.const 10)
)
)
)
(func (export "as-compare-right") (result i32)
(block (result i32)
(i32.ne
(i32.const 10)
(call_indirect (type $over-i32) (i32.const 1) (i32.const 4))
)
)
)
(func (export "as-convert-operand") (result i64)
(block (result i64)
(i64.extend_i32_s
(call_indirect (type $over-i32) (i32.const 1) (i32.const 4))
)
)
)
)
(assert_return (invoke "type-i32") (i32.const 0x132))
@ -407,51 +466,39 @@
(assert_return (invoke "dispatch" (i32.const 12) (i64.const 5)) (i64.const 120))
(assert_return (invoke "dispatch" (i32.const 13) (i64.const 5)) (i64.const 8))
(assert_return (invoke "dispatch" (i32.const 20) (i64.const 2)) (i64.const 2))
;; SKIP_CALL_INDIRECT_TYPE_MISMATCH
;; (assert_trap (invoke "dispatch" (i32.const 0) (i64.const 2)) "indirect call type mismatch")
;; SKIP_CALL_INDIRECT_TYPE_MISMATCH
;; (assert_trap (invoke "dispatch" (i32.const 15) (i64.const 2)) "indirect call type mismatch")
;; SKIP_CALL_UNDEFINED_ELEMENT
;; (assert_trap (invoke "dispatch" (i32.const 29) (i64.const 2)) "undefined element")
;; (assert_trap (invoke "dispatch" (i32.const -1) (i64.const 2)) "undefined element")
;; (assert_trap (invoke "dispatch" (i32.const 1213432423) (i64.const 2)) "undefined element")
(assert_trap (invoke "dispatch" (i32.const 0) (i64.const 2)) "indirect call type mismatch")
(assert_trap (invoke "dispatch" (i32.const 15) (i64.const 2)) "indirect call type mismatch")
(assert_trap (invoke "dispatch" (i32.const 29) (i64.const 2)) "undefined element")
(assert_trap (invoke "dispatch" (i32.const -1) (i64.const 2)) "undefined element")
(assert_trap (invoke "dispatch" (i32.const 1213432423) (i64.const 2)) "undefined element")
(assert_return (invoke "dispatch-structural-i64" (i32.const 5)) (i64.const 9))
(assert_return (invoke "dispatch-structural-i64" (i32.const 12)) (i64.const 362880))
(assert_return (invoke "dispatch-structural-i64" (i32.const 13)) (i64.const 55))
(assert_return (invoke "dispatch-structural-i64" (i32.const 20)) (i64.const 9))
;; SKIP_CALL_INDIRECT_TYPE_MISMATCH
;; (assert_trap (invoke "dispatch-structural-i64" (i32.const 11)) "indirect call type mismatch")
;; SKIP_CALL_INDIRECT_TYPE_MISMATCH
;; (assert_trap (invoke "dispatch-structural-i64" (i32.const 22)) "indirect call type mismatch")
(assert_trap (invoke "dispatch-structural-i64" (i32.const 11)) "indirect call type mismatch")
(assert_trap (invoke "dispatch-structural-i64" (i32.const 22)) "indirect call type mismatch")
(assert_return (invoke "dispatch-structural-i32" (i32.const 4)) (i32.const 9))
(assert_return (invoke "dispatch-structural-i32" (i32.const 23)) (i32.const 362880))
(assert_return (invoke "dispatch-structural-i32" (i32.const 26)) (i32.const 55))
(assert_return (invoke "dispatch-structural-i32" (i32.const 19)) (i32.const 9))
;; SKIP_CALL_INDIRECT_TYPE_MISMATCH
;; (assert_trap (invoke "dispatch-structural-i32" (i32.const 9)) "indirect call type mismatch")
;; SKIP_CALL_INDIRECT_TYPE_MISMATCH
;; (assert_trap (invoke "dispatch-structural-i32" (i32.const 21)) "indirect call type mismatch")
(assert_trap (invoke "dispatch-structural-i32" (i32.const 9)) "indirect call type mismatch")
(assert_trap (invoke "dispatch-structural-i32" (i32.const 21)) "indirect call type mismatch")
(assert_return (invoke "dispatch-structural-f32" (i32.const 6)) (f32.const 9.0))
(assert_return (invoke "dispatch-structural-f32" (i32.const 24)) (f32.const 362880.0))
(assert_return (invoke "dispatch-structural-f32" (i32.const 27)) (f32.const 55.0))
(assert_return (invoke "dispatch-structural-f32" (i32.const 21)) (f32.const 9.0))
;; SKIP_CALL_INDIRECT_TYPE_MISMATCH
;; (assert_trap (invoke "dispatch-structural-f32" (i32.const 8)) "indirect call type mismatch")
;; SKIP_CALL_INDIRECT_TYPE_MISMATCH
;; (assert_trap (invoke "dispatch-structural-f32" (i32.const 19)) "indirect call type mismatch")
(assert_trap (invoke "dispatch-structural-f32" (i32.const 8)) "indirect call type mismatch")
(assert_trap (invoke "dispatch-structural-f32" (i32.const 19)) "indirect call type mismatch")
(assert_return (invoke "dispatch-structural-f64" (i32.const 7)) (f64.const 9.0))
(assert_return (invoke "dispatch-structural-f64" (i32.const 25)) (f64.const 362880.0))
(assert_return (invoke "dispatch-structural-f64" (i32.const 28)) (f64.const 55.0))
(assert_return (invoke "dispatch-structural-f64" (i32.const 22)) (f64.const 9.0))
;; SKIP_CALL_INDIRECT_TYPE_MISMATCH
;; (assert_trap (invoke "dispatch-structural-f64" (i32.const 10)) "indirect call type mismatch")
;; SKIP_CALL_INDIRECT_TYPE_MISMATCH
;; (assert_trap (invoke "dispatch-structural-f64" (i32.const 18)) "indirect call type mismatch")
(assert_trap (invoke "dispatch-structural-f64" (i32.const 10)) "indirect call type mismatch")
(assert_trap (invoke "dispatch-structural-f64" (i32.const 18)) "indirect call type mismatch")
(assert_return (invoke "fac-i64" (i64.const 0)) (i64.const 1))
(assert_return (invoke "fac-i64" (i64.const 1)) (i64.const 1))
@ -528,17 +575,25 @@
(assert_return (invoke "as-return-value") (i32.const 1))
(assert_return (invoke "as-drop-operand"))
(assert_return (invoke "as-br-value") (f32.const 1))
(assert_return (invoke "as-set_local-value") (f64.const 1))
(assert_return (invoke "as-tee_local-value") (f64.const 1))
(assert_return (invoke "as-set_global-value") (f64.const 1.0))
(assert_return (invoke "as-local.set-value") (f64.const 1))
(assert_return (invoke "as-local.tee-value") (f64.const 1))
(assert_return (invoke "as-global.set-value") (f64.const 1.0))
(assert_return (invoke "as-load-operand") (i32.const 1))
(assert_return (invoke "as-unary-operand") (f32.const 0x0p+0))
(assert_return (invoke "as-binary-left") (i32.const 11))
(assert_return (invoke "as-binary-right") (i32.const 9))
(assert_return (invoke "as-test-operand") (i32.const 0))
(assert_return (invoke "as-compare-left") (i32.const 1))
(assert_return (invoke "as-compare-right") (i32.const 1))
(assert_return (invoke "as-convert-operand") (i64.const 1))
;; Invalid syntax
(assert_malformed
(module quote
"(type $sig (func (param i32) (result i32)))"
"(table 0 anyfunc)"
"(table 0 funcref)"
"(func (result i32)"
" (call_indirect (type $sig) (result i32) (param i32)"
" (i32.const 0) (i32.const 0)"
@ -550,7 +605,7 @@
(assert_malformed
(module quote
"(type $sig (func (param i32) (result i32)))"
"(table 0 anyfunc)"
"(table 0 funcref)"
"(func (result i32)"
" (call_indirect (param i32) (type $sig) (result i32)"
" (i32.const 0) (i32.const 0)"
@ -562,7 +617,7 @@
(assert_malformed
(module quote
"(type $sig (func (param i32) (result i32)))"
"(table 0 anyfunc)"
"(table 0 funcref)"
"(func (result i32)"
" (call_indirect (param i32) (result i32) (type $sig)"
" (i32.const 0) (i32.const 0)"
@ -574,7 +629,7 @@
(assert_malformed
(module quote
"(type $sig (func (param i32) (result i32)))"
"(table 0 anyfunc)"
"(table 0 funcref)"
"(func (result i32)"
" (call_indirect (result i32) (type $sig) (param i32)"
" (i32.const 0) (i32.const 0)"
@ -586,7 +641,7 @@
(assert_malformed
(module quote
"(type $sig (func (param i32) (result i32)))"
"(table 0 anyfunc)"
"(table 0 funcref)"
"(func (result i32)"
" (call_indirect (result i32) (param i32) (type $sig)"
" (i32.const 0) (i32.const 0)"
@ -597,7 +652,7 @@
)
(assert_malformed
(module quote
"(table 0 anyfunc)"
"(table 0 funcref)"
"(func (result i32)"
" (call_indirect (result i32) (param i32) (i32.const 0) (i32.const 0))"
")"
@ -607,7 +662,7 @@
(assert_malformed
(module quote
"(table 0 anyfunc)"
"(table 0 funcref)"
"(func (call_indirect (param $x i32) (i32.const 0) (i32.const 0)))"
)
"unexpected token"
@ -615,7 +670,7 @@
(assert_malformed
(module quote
"(type $sig (func))"
"(table 0 anyfunc)"
"(table 0 funcref)"
"(func (result i32)"
" (call_indirect (type $sig) (result i32) (i32.const 0))"
")"
@ -625,7 +680,7 @@
(assert_malformed
(module quote
"(type $sig (func (param i32) (result i32)))"
"(table 0 anyfunc)"
"(table 0 funcref)"
"(func (result i32)"
" (call_indirect (type $sig) (result i32) (i32.const 0))"
")"
@ -635,7 +690,7 @@
(assert_malformed
(module quote
"(type $sig (func (param i32) (result i32)))"
"(table 0 anyfunc)"
"(table 0 funcref)"
"(func"
" (call_indirect (type $sig) (param i32) (i32.const 0) (i32.const 0))"
")"
@ -645,7 +700,7 @@
(assert_malformed
(module quote
"(type $sig (func (param i32 i32) (result i32)))"
"(table 0 anyfunc)"
"(table 0 funcref)"
"(func (result i32)"
" (call_indirect (type $sig) (param i32) (result i32)"
" (i32.const 0) (i32.const 0)"
@ -668,7 +723,7 @@
(assert_invalid
(module
(type (func))
(table 0 anyfunc)
(table 0 funcref)
(func $type-void-vs-num (i32.eqz (call_indirect (type 0) (i32.const 0))))
)
"type mismatch"
@ -676,7 +731,7 @@
(assert_invalid
(module
(type (func (result i64)))
(table 0 anyfunc)
(table 0 funcref)
(func $type-num-vs-num (i32.eqz (call_indirect (type 0) (i32.const 0))))
)
"type mismatch"
@ -685,7 +740,7 @@
(assert_invalid
(module
(type (func (param i32)))
(table 0 anyfunc)
(table 0 funcref)
(func $arity-0-vs-1 (call_indirect (type 0) (i32.const 0)))
)
"type mismatch"
@ -693,7 +748,7 @@
(assert_invalid
(module
(type (func (param f64 i32)))
(table 0 anyfunc)
(table 0 funcref)
(func $arity-0-vs-2 (call_indirect (type 0) (i32.const 0)))
)
"type mismatch"
@ -701,7 +756,7 @@
(assert_invalid
(module
(type (func))
(table 0 anyfunc)
(table 0 funcref)
(func $arity-1-vs-0 (call_indirect (type 0) (i32.const 1) (i32.const 0)))
)
"type mismatch"
@ -709,7 +764,7 @@
(assert_invalid
(module
(type (func))
(table 0 anyfunc)
(table 0 funcref)
(func $arity-2-vs-0
(call_indirect (type 0) (f64.const 2) (i32.const 1) (i32.const 0))
)
@ -720,7 +775,7 @@
(assert_invalid
(module
(type (func (param i32)))
(table 0 anyfunc)
(table 0 funcref)
(func $type-func-void-vs-i32 (call_indirect (type 0) (i32.const 1) (nop)))
)
"type mismatch"
@ -728,7 +783,7 @@
(assert_invalid
(module
(type (func (param i32)))
(table 0 anyfunc)
(table 0 funcref)
(func $type-func-num-vs-i32 (call_indirect (type 0) (i32.const 0) (i64.const 1)))
)
"type mismatch"
@ -737,7 +792,7 @@
(assert_invalid
(module
(type (func (param i32 i32)))
(table 0 anyfunc)
(table 0 funcref)
(func $type-first-void-vs-num
(call_indirect (type 0) (nop) (i32.const 1) (i32.const 0))
)
@ -747,7 +802,7 @@
(assert_invalid
(module
(type (func (param i32 i32)))
(table 0 anyfunc)
(table 0 funcref)
(func $type-second-void-vs-num
(call_indirect (type 0) (i32.const 1) (nop) (i32.const 0))
)
@ -757,7 +812,7 @@
(assert_invalid
(module
(type (func (param i32 f64)))
(table 0 anyfunc)
(table 0 funcref)
(func $type-first-num-vs-num
(call_indirect (type 0) (f64.const 1) (i32.const 1) (i32.const 0))
)
@ -767,7 +822,7 @@
(assert_invalid
(module
(type (func (param f64 i32)))
(table 0 anyfunc)
(table 0 funcref)
(func $type-second-num-vs-num
(call_indirect (type 0) (i32.const 1) (f64.const 1) (i32.const 0))
)
@ -775,19 +830,104 @@
"type mismatch"
)
(assert_invalid
(module
(func $f (param i32))
(type $sig (func (param i32)))
(table funcref (elem $f))
(func $type-first-empty-in-block
(block
(call_indirect (type $sig) (i32.const 0))
)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $f (param i32 i32))
(type $sig (func (param i32 i32)))
(table funcref (elem $f))
(func $type-second-empty-in-block
(block
(call_indirect (type $sig) (i32.const 0) (i32.const 0))
)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $f (param i32))
(type $sig (func (param i32)))
(table funcref (elem $f))
(func $type-first-empty-in-loop
(loop
(call_indirect (type $sig) (i32.const 0))
)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $f (param i32 i32))
(type $sig (func (param i32 i32)))
(table funcref (elem $f))
(func $type-second-empty-in-loop
(loop
(call_indirect (type $sig) (i32.const 0) (i32.const 0))
)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $f (param i32))
(type $sig (func (param i32)))
(table funcref (elem $f))
(func $type-first-empty-in-then
(i32.const 0) (i32.const 0)
(if
(then
(call_indirect (type $sig) (i32.const 0))
)
)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $f (param i32 i32))
(type $sig (func (param i32 i32)))
(table funcref (elem $f))
(func $type-second-empty-in-then
(i32.const 0) (i32.const 0)
(if
(then
(call_indirect (type $sig) (i32.const 0) (i32.const 0))
)
)
)
)
"type mismatch"
)
;; Unbound type
(assert_invalid
(module
(table 0 anyfunc)
(table 0 funcref)
(func $unbound-type (call_indirect (type 1) (i32.const 0)))
)
"unknown type"
)
(assert_invalid
(module
(table 0 anyfunc)
(table 0 funcref)
(func $large-type (call_indirect (type 1012321300) (i32.const 0)))
)
"unknown type"
@ -797,6 +937,6 @@
;; Unbound function in table
(assert_invalid
(module (table anyfunc (elem 0 0)))
(module (table funcref (elem 0 0)))
"unknown function 0"
)

Binary file not shown.

802
lib/spectests/spectests/const.wast vendored Normal file
View File

@ -0,0 +1,802 @@
;; Test t.const instructions
;; Syntax error
(module (func (i32.const 0xffffffff) drop))
(module (func (i32.const -0x80000000) drop))
(assert_malformed
(module quote "(func (i32.const 0x100000000) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (i32.const -0x80000001) drop)")
"constant out of range"
)
(module (func (i32.const 4294967295) drop))
(module (func (i32.const -2147483648) drop))
(assert_malformed
(module quote "(func (i32.const 4294967296) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (i32.const -2147483649) drop)")
"constant out of range"
)
(module (func (i64.const 0xffffffffffffffff) drop))
(module (func (i64.const -0x8000000000000000) drop))
(assert_malformed
(module quote "(func (i64.const 0x10000000000000000) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (i64.const -0x8000000000000001) drop)")
"constant out of range"
)
(module (func (i64.const 18446744073709551615) drop))
(module (func (i64.const -9223372036854775808) drop))
(assert_malformed
(module quote "(func (i64.const 18446744073709551616) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (i64.const -9223372036854775809) drop)")
"constant out of range"
)
(module (func (f32.const 0x1p127) drop))
(module (func (f32.const -0x1p127) drop))
(module (func (f32.const 0x1.fffffep127) drop))
(module (func (f32.const -0x1.fffffep127) drop))
(module (func (f32.const 0x1.fffffe7p127) drop))
(module (func (f32.const -0x1.fffffe7p127) drop))
(module (func (f32.const 0x1.fffffefffffff8000000p127) drop))
(module (func (f32.const -0x1.fffffefffffff8000000p127) drop))
(module (func (f32.const 0x1.fffffefffffffffffffp127) drop))
(module (func (f32.const -0x1.fffffefffffffffffffp127) drop))
(assert_malformed
(module quote "(func (f32.const 0x1p128) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f32.const -0x1p128) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f32.const 0x1.ffffffp127) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f32.const -0x1.ffffffp127) drop)")
"constant out of range"
)
(module (func (f32.const 1e38) drop))
(module (func (f32.const -1e38) drop))
(assert_malformed
(module quote "(func (f32.const 1e39) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f32.const -1e39) drop)")
"constant out of range"
)
(module (func (f32.const 340282356779733623858607532500980858880) drop))
(module (func (f32.const -340282356779733623858607532500980858880) drop))
(assert_malformed
(module quote "(func (f32.const 340282356779733661637539395458142568448) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f32.const -340282356779733661637539395458142568448) drop)")
"constant out of range"
)
(module (func (f64.const 0x1p1023) drop))
(module (func (f64.const -0x1p1023) drop))
(module (func (f64.const 0x1.fffffffffffffp1023) drop))
(module (func (f64.const -0x1.fffffffffffffp1023) drop))
(module (func (f64.const 0x1.fffffffffffff7p1023) drop))
(module (func (f64.const -0x1.fffffffffffff7p1023) drop))
(module (func (f64.const 0x1.fffffffffffff7ffffffp1023) drop))
(module (func (f64.const -0x1.fffffffffffff7ffffffp1023) drop))
(assert_malformed
(module quote "(func (f64.const 0x1p1024) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f64.const -0x1p1024) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f64.const 0x1.fffffffffffff8p1023) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f64.const -0x1.fffffffffffff8p1023) drop)")
"constant out of range"
)
(module (func (f64.const 1e308) drop))
(module (func (f64.const -1e308) drop))
(assert_malformed
(module quote "(func (f64.const 1e309) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f64.const -1e309) drop)")
"constant out of range"
)
(module (func (f64.const 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368) drop))
(module (func (f64.const -179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368) drop))
(assert_malformed
(module quote "(func (f64.const 269653970229347356221791135597556535197105851288767494898376215204735891170042808140884337949150317257310688430271573696351481990334196274152701320055306275479074865864826923114368235135583993416113802762682700913456874855354834422248712838998185022412196739306217084753107265771378949821875606039276187287552) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f64.const -269653970229347356221791135597556535197105851288767494898376215204735891170042808140884337949150317257310688430271573696351481990334196274152701320055306275479074865864826923114368235135583993416113802762682700913456874855354834422248712838998185022412196739306217084753107265771378949821875606039276187287552) drop)")
"constant out of range"
)
(module (func (f32.const nan:0x1) drop))
(module (func (f64.const nan:0x1) drop))
(module (func (f32.const nan:0x7f_ffff) drop))
(module (func (f64.const nan:0xf_ffff_ffff_ffff) drop))
(assert_malformed
(module quote "(func (f32.const nan:1) drop)")
"unknown operator"
)
(assert_malformed
(module quote "(func (f64.const nan:1) drop)")
"unknown operator"
)
(assert_malformed
(module quote "(func (f32.const nan:0x0) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f64.const nan:0x0) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f32.const nan:0x80_0000) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f64.const nan:0x10_0000_0000_0000) drop)")
"constant out of range"
)
;; Rounding behaviour
;; f32, small exponent
(module (func (export "f") (result f32) (f32.const +0x1.00000100000000000p-50)))
(assert_return (invoke "f") (f32.const +0x1.000000p-50))
(module (func (export "f") (result f32) (f32.const -0x1.00000100000000000p-50)))
(assert_return (invoke "f") (f32.const -0x1.000000p-50))
(module (func (export "f") (result f32) (f32.const +0x1.00000100000000001p-50)))
(assert_return (invoke "f") (f32.const +0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const -0x1.00000100000000001p-50)))
(assert_return (invoke "f") (f32.const -0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const +0x1.000001fffffffffffp-50)))
(assert_return (invoke "f") (f32.const +0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const -0x1.000001fffffffffffp-50)))
(assert_return (invoke "f") (f32.const -0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const +0x1.00000200000000000p-50)))
(assert_return (invoke "f") (f32.const +0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const -0x1.00000200000000000p-50)))
(assert_return (invoke "f") (f32.const -0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const +0x1.00000200000000001p-50)))
(assert_return (invoke "f") (f32.const +0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const -0x1.00000200000000001p-50)))
(assert_return (invoke "f") (f32.const -0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const +0x1.000002fffffffffffp-50)))
(assert_return (invoke "f") (f32.const +0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const -0x1.000002fffffffffffp-50)))
(assert_return (invoke "f") (f32.const -0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const +0x1.00000300000000000p-50)))
(assert_return (invoke "f") (f32.const +0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const -0x1.00000300000000000p-50)))
(assert_return (invoke "f") (f32.const -0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const +0x1.00000300000000001p-50)))
(assert_return (invoke "f") (f32.const +0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const -0x1.00000300000000001p-50)))
(assert_return (invoke "f") (f32.const -0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const +0x1.000003fffffffffffp-50)))
(assert_return (invoke "f") (f32.const +0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const -0x1.000003fffffffffffp-50)))
(assert_return (invoke "f") (f32.const -0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const +0x1.00000400000000000p-50)))
(assert_return (invoke "f") (f32.const +0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const -0x1.00000400000000000p-50)))
(assert_return (invoke "f") (f32.const -0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const +0x1.00000400000000001p-50)))
(assert_return (invoke "f") (f32.const +0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const -0x1.00000400000000001p-50)))
(assert_return (invoke "f") (f32.const -0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const +0x1.000004fffffffffffp-50)))
(assert_return (invoke "f") (f32.const +0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const -0x1.000004fffffffffffp-50)))
(assert_return (invoke "f") (f32.const -0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const +0x1.00000500000000000p-50)))
(assert_return (invoke "f") (f32.const +0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const -0x1.00000500000000000p-50)))
(assert_return (invoke "f") (f32.const -0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const +0x1.00000500000000001p-50)))
(assert_return (invoke "f") (f32.const +0x1.000006p-50))
(module (func (export "f") (result f32) (f32.const -0x1.00000500000000001p-50)))
(assert_return (invoke "f") (f32.const -0x1.000006p-50))
(module (func (export "f") (result f32) (f32.const +0x4000.004000000p-64)))
(assert_return (invoke "f") (f32.const +0x1.000000p-50))
(module (func (export "f") (result f32) (f32.const -0x4000.004000000p-64)))
(assert_return (invoke "f") (f32.const -0x1.000000p-50))
(module (func (export "f") (result f32) (f32.const +0x4000.004000001p-64)))
(assert_return (invoke "f") (f32.const +0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const -0x4000.004000001p-64)))
(assert_return (invoke "f") (f32.const -0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const +0x4000.007ffffffp-64)))
(assert_return (invoke "f") (f32.const +0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const -0x4000.007ffffffp-64)))
(assert_return (invoke "f") (f32.const -0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const +0x4000.008000000p-64)))
(assert_return (invoke "f") (f32.const +0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const -0x4000.008000000p-64)))
(assert_return (invoke "f") (f32.const -0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const +0x4000.008000001p-64)))
(assert_return (invoke "f") (f32.const +0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const -0x4000.008000001p-64)))
(assert_return (invoke "f") (f32.const -0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const +0x4000.00bffffffp-64)))
(assert_return (invoke "f") (f32.const +0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const -0x4000.00bffffffp-64)))
(assert_return (invoke "f") (f32.const -0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const +0x4000.00c000000p-64)))
(assert_return (invoke "f") (f32.const +0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const -0x4000.00c000000p-64)))
(assert_return (invoke "f") (f32.const -0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const +0x4000.00c000001p-64)))
(assert_return (invoke "f") (f32.const +0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const -0x4000.00c000001p-64)))
(assert_return (invoke "f") (f32.const -0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const +0x4000.00fffffffp-64)))
(assert_return (invoke "f") (f32.const +0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const -0x4000.00fffffffp-64)))
(assert_return (invoke "f") (f32.const -0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const +0x4000.010000001p-64)))
(assert_return (invoke "f") (f32.const +0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const -0x4000.010000001p-64)))
(assert_return (invoke "f") (f32.const -0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const +0x4000.013ffffffp-64)))
(assert_return (invoke "f") (f32.const +0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const -0x4000.013ffffffp-64)))
(assert_return (invoke "f") (f32.const -0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const +0x4000.014000001p-64)))
(assert_return (invoke "f") (f32.const +0x1.000006p-50))
(module (func (export "f") (result f32) (f32.const -0x4000.014000001p-64)))
(assert_return (invoke "f") (f32.const -0x1.000006p-50))
(module (func (export "f") (result f32) (f32.const +8.8817847263968443573e-16)))
(assert_return (invoke "f") (f32.const +0x1.000000p-50))
(module (func (export "f") (result f32) (f32.const -8.8817847263968443573e-16)))
(assert_return (invoke "f") (f32.const -0x1.000000p-50))
(module (func (export "f") (result f32) (f32.const +8.8817847263968443574e-16)))
(assert_return (invoke "f") (f32.const +0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const -8.8817847263968443574e-16)))
(assert_return (invoke "f") (f32.const -0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const +8.8817857851880284252e-16)))
(assert_return (invoke "f") (f32.const +0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const -8.8817857851880284252e-16)))
(assert_return (invoke "f") (f32.const -0x1.000002p-50))
(module (func (export "f") (result f32) (f32.const +8.8817857851880284253e-16)))
(assert_return (invoke "f") (f32.const +0x1.000004p-50))
(module (func (export "f") (result f32) (f32.const -8.8817857851880284253e-16)))
(assert_return (invoke "f") (f32.const -0x1.000004p-50))
;; f32, large exponent
(module (func (export "f") (result f32) (f32.const +0x1.00000100000000000p+50)))
(assert_return (invoke "f") (f32.const +0x1.000000p+50))
(module (func (export "f") (result f32) (f32.const -0x1.00000100000000000p+50)))
(assert_return (invoke "f") (f32.const -0x1.000000p+50))
(module (func (export "f") (result f32) (f32.const +0x1.00000100000000001p+50)))
(assert_return (invoke "f") (f32.const +0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const -0x1.00000100000000001p+50)))
(assert_return (invoke "f") (f32.const -0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const +0x1.000001fffffffffffp+50)))
(assert_return (invoke "f") (f32.const +0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const -0x1.000001fffffffffffp+50)))
(assert_return (invoke "f") (f32.const -0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const +0x1.00000200000000000p+50)))
(assert_return (invoke "f") (f32.const +0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const -0x1.00000200000000000p+50)))
(assert_return (invoke "f") (f32.const -0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const +0x1.00000200000000001p+50)))
(assert_return (invoke "f") (f32.const +0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const -0x1.00000200000000001p+50)))
(assert_return (invoke "f") (f32.const -0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const +0x1.000002fffffffffffp+50)))
(assert_return (invoke "f") (f32.const +0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const -0x1.000002fffffffffffp+50)))
(assert_return (invoke "f") (f32.const -0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const +0x1.00000300000000000p+50)))
(assert_return (invoke "f") (f32.const +0x1.000004p+50))
(module (func (export "f") (result f32) (f32.const -0x1.00000300000000000p+50)))
(assert_return (invoke "f") (f32.const -0x1.000004p+50))
(module (func (export "f") (result f32) (f32.const +0x1.00000300000000001p+50)))
(assert_return (invoke "f") (f32.const +0x1.000004p+50))
(module (func (export "f") (result f32) (f32.const -0x1.00000300000000001p+50)))
(assert_return (invoke "f") (f32.const -0x1.000004p+50))
(module (func (export "f") (result f32) (f32.const +0x1.000003fffffffffffp+50)))
(assert_return (invoke "f") (f32.const +0x1.000004p+50))
(module (func (export "f") (result f32) (f32.const -0x1.000003fffffffffffp+50)))
(assert_return (invoke "f") (f32.const -0x1.000004p+50))
(module (func (export "f") (result f32) (f32.const +0x1.00000400000000000p+50)))
(assert_return (invoke "f") (f32.const +0x1.000004p+50))
(module (func (export "f") (result f32) (f32.const -0x1.00000400000000000p+50)))
(assert_return (invoke "f") (f32.const -0x1.000004p+50))
(module (func (export "f") (result f32) (f32.const +0x1.00000400000000001p+50)))
(assert_return (invoke "f") (f32.const +0x1.000004p+50))
(module (func (export "f") (result f32) (f32.const -0x1.00000400000000001p+50)))
(assert_return (invoke "f") (f32.const -0x1.000004p+50))
(module (func (export "f") (result f32) (f32.const +0x1.000004fffffffffffp+50)))
(assert_return (invoke "f") (f32.const +0x1.000004p+50))
(module (func (export "f") (result f32) (f32.const -0x1.000004fffffffffffp+50)))
(assert_return (invoke "f") (f32.const -0x1.000004p+50))
(module (func (export "f") (result f32) (f32.const +0x1.00000500000000000p+50)))
(assert_return (invoke "f") (f32.const +0x1.000004p+50))
(module (func (export "f") (result f32) (f32.const -0x1.00000500000000000p+50)))
(assert_return (invoke "f") (f32.const -0x1.000004p+50))
(module (func (export "f") (result f32) (f32.const +0x1.00000500000000001p+50)))
(assert_return (invoke "f") (f32.const +0x1.000006p+50))
(module (func (export "f") (result f32) (f32.const -0x1.00000500000000001p+50)))
(assert_return (invoke "f") (f32.const -0x1.000006p+50))
(module (func (export "f") (result f32) (f32.const +0x4000004000000)))
(assert_return (invoke "f") (f32.const +0x1.000000p+50))
(module (func (export "f") (result f32) (f32.const -0x4000004000000)))
(assert_return (invoke "f") (f32.const -0x1.000000p+50))
(module (func (export "f") (result f32) (f32.const +0x4000004000001)))
(assert_return (invoke "f") (f32.const +0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const -0x4000004000001)))
(assert_return (invoke "f") (f32.const -0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const +0x4000007ffffff)))
(assert_return (invoke "f") (f32.const +0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const -0x4000007ffffff)))
(assert_return (invoke "f") (f32.const -0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const +0x4000008000000)))
(assert_return (invoke "f") (f32.const +0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const -0x4000008000000)))
(assert_return (invoke "f") (f32.const -0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const +0x4000008000001)))
(assert_return (invoke "f") (f32.const +0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const -0x4000008000001)))
(assert_return (invoke "f") (f32.const -0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const +0x400000bffffff)))
(assert_return (invoke "f") (f32.const +0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const -0x400000bffffff)))
(assert_return (invoke "f") (f32.const -0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const +0x400000c000000)))
(assert_return (invoke "f") (f32.const +0x1.000004p+50))
(module (func (export "f") (result f32) (f32.const -0x400000c000000)))
(assert_return (invoke "f") (f32.const -0x1.000004p+50))
(module (func (export "f") (result f32) (f32.const +1125899973951488)))
(assert_return (invoke "f") (f32.const +0x1.000000p+50))
(module (func (export "f") (result f32) (f32.const -1125899973951488)))
(assert_return (invoke "f") (f32.const -0x1.000000p+50))
(module (func (export "f") (result f32) (f32.const +1125899973951489)))
(assert_return (invoke "f") (f32.const +0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const -1125899973951489)))
(assert_return (invoke "f") (f32.const -0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const +1125900108169215)))
(assert_return (invoke "f") (f32.const +0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const -1125900108169215)))
(assert_return (invoke "f") (f32.const -0x1.000002p+50))
(module (func (export "f") (result f32) (f32.const +1125900108169216)))
(assert_return (invoke "f") (f32.const +0x1.000004p+50))
(module (func (export "f") (result f32) (f32.const -1125900108169216)))
(assert_return (invoke "f") (f32.const -0x1.000004p+50))
;; f32, subnormal
(module (func (export "f") (result f32) (f32.const +0x0.00000100000000000p-126)))
(assert_return (invoke "f") (f32.const +0x0.000000p-126))
(module (func (export "f") (result f32) (f32.const -0x0.00000100000000000p-126)))
(assert_return (invoke "f") (f32.const -0x0.000000p-126))
(module (func (export "f") (result f32) (f32.const +0x0.00000100000000001p-126)))
(assert_return (invoke "f") (f32.const +0x0.000002p-126))
(module (func (export "f") (result f32) (f32.const -0x0.00000100000000001p-126)))
(assert_return (invoke "f") (f32.const -0x0.000002p-126))
(module (func (export "f") (result f32) (f32.const +0x0.000001fffffffffffp-126)))
(assert_return (invoke "f") (f32.const +0x0.000002p-126))
(module (func (export "f") (result f32) (f32.const -0x0.000001fffffffffffp-126)))
(assert_return (invoke "f") (f32.const -0x0.000002p-126))
(module (func (export "f") (result f32) (f32.const +0x0.00000200000000000p-126)))
(assert_return (invoke "f") (f32.const +0x0.000002p-126))
(module (func (export "f") (result f32) (f32.const -0x0.00000200000000000p-126)))
(assert_return (invoke "f") (f32.const -0x0.000002p-126))
(module (func (export "f") (result f32) (f32.const +0x0.00000200000000001p-126)))
(assert_return (invoke "f") (f32.const +0x0.000002p-126))
(module (func (export "f") (result f32) (f32.const -0x0.00000200000000001p-126)))
(assert_return (invoke "f") (f32.const -0x0.000002p-126))
(module (func (export "f") (result f32) (f32.const +0x0.000002fffffffffffp-126)))
(assert_return (invoke "f") (f32.const +0x0.000002p-126))
(module (func (export "f") (result f32) (f32.const -0x0.000002fffffffffffp-126)))
(assert_return (invoke "f") (f32.const -0x0.000002p-126))
(module (func (export "f") (result f32) (f32.const +0x0.00000300000000000p-126)))
(assert_return (invoke "f") (f32.const +0x0.000004p-126))
(module (func (export "f") (result f32) (f32.const -0x0.00000300000000000p-126)))
(assert_return (invoke "f") (f32.const -0x0.000004p-126))
(module (func (export "f") (result f32) (f32.const +0x0.00000300000000001p-126)))
(assert_return (invoke "f") (f32.const +0x0.000004p-126))
(module (func (export "f") (result f32) (f32.const -0x0.00000300000000001p-126)))
(assert_return (invoke "f") (f32.const -0x0.000004p-126))
(module (func (export "f") (result f32) (f32.const +0x0.000003fffffffffffp-126)))
(assert_return (invoke "f") (f32.const +0x0.000004p-126))
(module (func (export "f") (result f32) (f32.const -0x0.000003fffffffffffp-126)))
(assert_return (invoke "f") (f32.const -0x0.000004p-126))
(module (func (export "f") (result f32) (f32.const +0x0.00000400000000000p-126)))
(assert_return (invoke "f") (f32.const +0x0.000004p-126))
(module (func (export "f") (result f32) (f32.const -0x0.00000400000000000p-126)))
(assert_return (invoke "f") (f32.const -0x0.000004p-126))
(module (func (export "f") (result f32) (f32.const +0x0.00000400000000001p-126)))
(assert_return (invoke "f") (f32.const +0x0.000004p-126))
(module (func (export "f") (result f32) (f32.const -0x0.00000400000000001p-126)))
(assert_return (invoke "f") (f32.const -0x0.000004p-126))
(module (func (export "f") (result f32) (f32.const +0x0.000004fffffffffffp-126)))
(assert_return (invoke "f") (f32.const +0x0.000004p-126))
(module (func (export "f") (result f32) (f32.const -0x0.000004fffffffffffp-126)))
(assert_return (invoke "f") (f32.const -0x0.000004p-126))
(module (func (export "f") (result f32) (f32.const +0x0.00000500000000000p-126)))
(assert_return (invoke "f") (f32.const +0x0.000004p-126))
(module (func (export "f") (result f32) (f32.const -0x0.00000500000000000p-126)))
(assert_return (invoke "f") (f32.const -0x0.000004p-126))
(module (func (export "f") (result f32) (f32.const +0x0.00000500000000001p-126)))
(assert_return (invoke "f") (f32.const +0x0.000006p-126))
(module (func (export "f") (result f32) (f32.const -0x0.00000500000000001p-126)))
(assert_return (invoke "f") (f32.const -0x0.000006p-126))
;; f32, round down at limit to infinity
(module (func (export "f") (result f32) (f32.const +0x1.fffffe8p127)))
(assert_return (invoke "f") (f32.const +0x1.fffffep127))
(module (func (export "f") (result f32) (f32.const -0x1.fffffe8p127)))
(assert_return (invoke "f") (f32.const -0x1.fffffep127))
(module (func (export "f") (result f32) (f32.const +0x1.fffffefffffff8p127)))
(assert_return (invoke "f") (f32.const +0x1.fffffep127))
(module (func (export "f") (result f32) (f32.const -0x1.fffffefffffff8p127)))
(assert_return (invoke "f") (f32.const -0x1.fffffep127))
(module (func (export "f") (result f32) (f32.const +0x1.fffffefffffffffffp127)))
(assert_return (invoke "f") (f32.const +0x1.fffffep127))
(module (func (export "f") (result f32) (f32.const -0x1.fffffefffffffffffp127)))
(assert_return (invoke "f") (f32.const -0x1.fffffep127))
;; f64, small exponent
(module (func (export "f") (result f64) (f64.const +0x1.000000000000080000000000p-600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000000p-600))
(module (func (export "f") (result f64) (f64.const -0x1.000000000000080000000000p-600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000000p-600))
(module (func (export "f") (result f64) (f64.const +0x1.000000000000080000000001p-600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p-600))
(module (func (export "f") (result f64) (f64.const -0x1.000000000000080000000001p-600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p-600))
(module (func (export "f") (result f64) (f64.const +0x1.0000000000000fffffffffffp-600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p-600))
(module (func (export "f") (result f64) (f64.const -0x1.0000000000000fffffffffffp-600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p-600))
(module (func (export "f") (result f64) (f64.const +0x1.000000000000100000000000p-600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p-600))
(module (func (export "f") (result f64) (f64.const -0x1.000000000000100000000000p-600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p-600))
(module (func (export "f") (result f64) (f64.const +0x1.000000000000100000000001p-600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p-600))
(module (func (export "f") (result f64) (f64.const -0x1.000000000000100000000001p-600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p-600))
(module (func (export "f") (result f64) (f64.const +0x1.00000000000017ffffffffffp-600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p-600))
(module (func (export "f") (result f64) (f64.const -0x1.00000000000017ffffffffffp-600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p-600))
(module (func (export "f") (result f64) (f64.const +0x1.000000000000180000000000p-600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const -0x1.000000000000180000000000p-600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const +0x1.000000000000180000000001p-600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const -0x1.000000000000180000000001p-600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const +0x1.0000000000001fffffffffffp-600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const -0x1.0000000000001fffffffffffp-600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const +0x1.000000000000200000000000p-600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const -0x1.000000000000200000000000p-600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const +0x1.000000000000200000000001p-600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const -0x1.000000000000200000000001p-600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const +0x1.00000000000027ffffffffffp-600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const -0x1.00000000000027ffffffffffp-600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const +0x1.000000000000280000000001p-600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000003p-600))
(module (func (export "f") (result f64) (f64.const -0x1.000000000000280000000001p-600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000003p-600))
(module (func (export "f") (result f64) (f64.const +0x8000000.000000400000000000p-627)))
(assert_return (invoke "f") (f64.const +0x1.0000000000000p-600))
(module (func (export "f") (result f64) (f64.const -0x8000000.000000400000000000p-627)))
(assert_return (invoke "f") (f64.const -0x1.0000000000000p-600))
(module (func (export "f") (result f64) (f64.const +0x8000000.000000400000000001p-627)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p-600))
(module (func (export "f") (result f64) (f64.const -0x8000000.000000400000000001p-627)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p-600))
(module (func (export "f") (result f64) (f64.const +0x8000000.0000007fffffffffffp-627)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p-600))
(module (func (export "f") (result f64) (f64.const -0x8000000.0000007fffffffffffp-627)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p-600))
(module (func (export "f") (result f64) (f64.const +0x8000000.000000800000000000p-627)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p-600))
(module (func (export "f") (result f64) (f64.const -0x8000000.000000800000000000p-627)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p-600))
(module (func (export "f") (result f64) (f64.const +0x8000000.000000800000000001p-627)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p-600))
(module (func (export "f") (result f64) (f64.const -0x8000000.000000800000000001p-627)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p-600))
(module (func (export "f") (result f64) (f64.const +0x8000000.000000bfffffffffffp-627)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p-600))
(module (func (export "f") (result f64) (f64.const -0x8000000.000000bfffffffffffp-627)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p-600))
(module (func (export "f") (result f64) (f64.const +0x8000000.000000c00000000000p-627)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const -0x8000000.000000c00000000000p-627)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const +0x8000000.000000c00000000001p-627)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const -0x8000000.000000c00000000001p-627)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const +0x8000000.000000ffffffffffffp-627)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const -0x8000000.000000ffffffffffffp-627)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const +0x8000000.000001000000000000p-627)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const -0x8000000.000001000000000000p-627)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const +0x8000000.000001000000000001p-627)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const -0x8000000.000001000000000001p-627)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const +0x8000000.0000013fffffffffffp-627)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const -0x8000000.0000013fffffffffffp-627)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p-600))
(module (func (export "f") (result f64) (f64.const +0x8000000.000001400000000001p-627)))
(assert_return (invoke "f") (f64.const +0x1.0000000000003p-600))
(module (func (export "f") (result f64) (f64.const -0x8000000.000001400000000001p-627)))
(assert_return (invoke "f") (f64.const -0x1.0000000000003p-600))
(module (func (export "f") (result f64) (f64.const +5.3575430359313371995e+300)))
(assert_return (invoke "f") (f64.const +0x1.0000000000000p+999))
(module (func (export "f") (result f64) (f64.const -5.3575430359313371995e+300)))
(assert_return (invoke "f") (f64.const -0x1.0000000000000p+999))
(module (func (export "f") (result f64) (f64.const +5.3575430359313371996e+300)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p+999))
(module (func (export "f") (result f64) (f64.const -5.3575430359313371996e+300)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p+999))
(module (func (export "f") (result f64) (f64.const +5.3575430359313383891e+300)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p+999))
(module (func (export "f") (result f64) (f64.const -5.3575430359313383891e+300)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p+999))
(module (func (export "f") (result f64) (f64.const +5.3575430359313383892e+300)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p+999))
(module (func (export "f") (result f64) (f64.const -5.3575430359313383892e+300)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p+999))
;; f64, large exponent
(module (func (export "f") (result f64) (f64.const +0x1.000000000000080000000000p+600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000000p+600))
(module (func (export "f") (result f64) (f64.const -0x1.000000000000080000000000p+600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000000p+600))
(module (func (export "f") (result f64) (f64.const +0x1.000000000000080000000001p+600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p+600))
(module (func (export "f") (result f64) (f64.const -0x1.000000000000080000000001p+600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p+600))
(module (func (export "f") (result f64) (f64.const +0x1.0000000000000fffffffffffp+600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p+600))
(module (func (export "f") (result f64) (f64.const -0x1.0000000000000fffffffffffp+600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p+600))
(module (func (export "f") (result f64) (f64.const +0x1.000000000000100000000000p+600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p+600))
(module (func (export "f") (result f64) (f64.const -0x1.000000000000100000000000p+600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p+600))
(module (func (export "f") (result f64) (f64.const +0x1.000000000000100000000001p+600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p+600))
(module (func (export "f") (result f64) (f64.const -0x1.000000000000100000000001p+600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p+600))
(module (func (export "f") (result f64) (f64.const +0x1.00000000000017ffffffffffp+600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p+600))
(module (func (export "f") (result f64) (f64.const -0x1.00000000000017ffffffffffp+600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p+600))
(module (func (export "f") (result f64) (f64.const +0x1.000000000000180000000000p+600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p+600))
(module (func (export "f") (result f64) (f64.const -0x1.000000000000180000000000p+600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p+600))
(module (func (export "f") (result f64) (f64.const +0x1.000000000000180000000001p+600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p+600))
(module (func (export "f") (result f64) (f64.const -0x1.000000000000180000000001p+600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p+600))
(module (func (export "f") (result f64) (f64.const +0x1.0000000000001fffffffffffp+600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p+600))
(module (func (export "f") (result f64) (f64.const -0x1.0000000000001fffffffffffp+600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p+600))
(module (func (export "f") (result f64) (f64.const +0x1.000000000000200000000000p+600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p+600))
(module (func (export "f") (result f64) (f64.const -0x1.000000000000200000000000p+600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p+600))
(module (func (export "f") (result f64) (f64.const +0x1.000000000000200000000001p+600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p+600))
(module (func (export "f") (result f64) (f64.const -0x1.000000000000200000000001p+600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p+600))
(module (func (export "f") (result f64) (f64.const +0x1.00000000000027ffffffffffp+600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p+600))
(module (func (export "f") (result f64) (f64.const -0x1.00000000000027ffffffffffp+600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p+600))
(module (func (export "f") (result f64) (f64.const +0x1.000000000000280000000000p+600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p+600))
(module (func (export "f") (result f64) (f64.const -0x1.000000000000280000000000p+600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p+600))
(module (func (export "f") (result f64) (f64.const +0x1.000000000000280000000001p+600)))
(assert_return (invoke "f") (f64.const +0x1.0000000000003p+600))
(module (func (export "f") (result f64) (f64.const -0x1.000000000000280000000001p+600)))
(assert_return (invoke "f") (f64.const -0x1.0000000000003p+600))
(module (func (export "f") (result f64) (f64.const +0x2000000000000100000000000)))
(assert_return (invoke "f") (f64.const +0x1.0000000000000p+97))
(module (func (export "f") (result f64) (f64.const -0x2000000000000100000000000)))
(assert_return (invoke "f") (f64.const -0x1.0000000000000p+97))
(module (func (export "f") (result f64) (f64.const +0x2000000000000100000000001)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p+97))
(module (func (export "f") (result f64) (f64.const -0x2000000000000100000000001)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p+97))
(module (func (export "f") (result f64) (f64.const +0x20000000000001fffffffffff)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p+97))
(module (func (export "f") (result f64) (f64.const -0x20000000000001fffffffffff)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p+97))
(module (func (export "f") (result f64) (f64.const +0x2000000000000200000000000)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p+97))
(module (func (export "f") (result f64) (f64.const -0x2000000000000200000000000)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p+97))
(module (func (export "f") (result f64) (f64.const +0x2000000000000200000000001)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p+97))
(module (func (export "f") (result f64) (f64.const -0x2000000000000200000000001)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p+97))
(module (func (export "f") (result f64) (f64.const +0x20000000000002fffffffffff)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p+97))
(module (func (export "f") (result f64) (f64.const -0x20000000000002fffffffffff)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p+97))
(module (func (export "f") (result f64) (f64.const +0x2000000000000300000000000)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p+97))
(module (func (export "f") (result f64) (f64.const -0x2000000000000300000000000)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p+97))
(module (func (export "f") (result f64) (f64.const +0x2000000000000300000000001)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p+97))
(module (func (export "f") (result f64) (f64.const -0x2000000000000300000000001)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p+97))
(module (func (export "f") (result f64) (f64.const +0x20000000000003fffffffffff)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p+97))
(module (func (export "f") (result f64) (f64.const -0x20000000000003fffffffffff)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p+97))
(module (func (export "f") (result f64) (f64.const +0x2000000000000400000000000)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p+97))
(module (func (export "f") (result f64) (f64.const -0x2000000000000400000000000)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p+97))
(module (func (export "f") (result f64) (f64.const +0x2000000000000400000000001)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p+97))
(module (func (export "f") (result f64) (f64.const -0x2000000000000400000000001)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p+97))
(module (func (export "f") (result f64) (f64.const +0x20000000000004fffffffffff)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p+97))
(module (func (export "f") (result f64) (f64.const -0x20000000000004fffffffffff)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p+97))
(module (func (export "f") (result f64) (f64.const +0x2000000000000500000000000)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p+97))
(module (func (export "f") (result f64) (f64.const -0x2000000000000500000000000)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p+97))
(module (func (export "f") (result f64) (f64.const +0x2000000000000500000000001)))
(assert_return (invoke "f") (f64.const +0x1.0000000000003p+97))
(module (func (export "f") (result f64) (f64.const -0x2000000000000500000000001)))
(assert_return (invoke "f") (f64.const -0x1.0000000000003p+97))
(module (func (export "f") (result f64) (f64.const +1152921504606847104)))
(assert_return (invoke "f") (f64.const +0x1.0000000000000p+60))
(module (func (export "f") (result f64) (f64.const -1152921504606847104)))
(assert_return (invoke "f") (f64.const -0x1.0000000000000p+60))
(module (func (export "f") (result f64) (f64.const +1152921504606847105)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p+60))
(module (func (export "f") (result f64) (f64.const -1152921504606847105)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p+60))
(module (func (export "f") (result f64) (f64.const +1152921504606847359)))
(assert_return (invoke "f") (f64.const +0x1.0000000000001p+60))
(module (func (export "f") (result f64) (f64.const -1152921504606847359)))
(assert_return (invoke "f") (f64.const -0x1.0000000000001p+60))
(module (func (export "f") (result f64) (f64.const +1152921504606847360)))
(assert_return (invoke "f") (f64.const +0x1.0000000000002p+60))
(module (func (export "f") (result f64) (f64.const -1152921504606847360)))
(assert_return (invoke "f") (f64.const -0x1.0000000000002p+60))
;; f64, subnormal
(module (func (export "f") (result f64) (f64.const +0x0.000000000000080000000000p-1022)))
(assert_return (invoke "f") (f64.const +0x0.0000000000000p-1022))
(module (func (export "f") (result f64) (f64.const -0x0.000000000000080000000000p-1022)))
(assert_return (invoke "f") (f64.const -0x0.0000000000000p-1022))
(module (func (export "f") (result f64) (f64.const +0x0.000000000000080000000001p-1022)))
(assert_return (invoke "f") (f64.const +0x0.0000000000001p-1022))
(module (func (export "f") (result f64) (f64.const -0x0.000000000000080000000001p-1022)))
(assert_return (invoke "f") (f64.const -0x0.0000000000001p-1022))
(module (func (export "f") (result f64) (f64.const +0x0.0000000000000fffffffffffp-1022)))
(assert_return (invoke "f") (f64.const +0x0.0000000000001p-1022))
(module (func (export "f") (result f64) (f64.const -0x0.0000000000000fffffffffffp-1022)))
(assert_return (invoke "f") (f64.const -0x0.0000000000001p-1022))
(module (func (export "f") (result f64) (f64.const +0x0.000000000000100000000000p-1022)))
(assert_return (invoke "f") (f64.const +0x0.0000000000001p-1022))
(module (func (export "f") (result f64) (f64.const -0x0.000000000000100000000000p-1022)))
(assert_return (invoke "f") (f64.const -0x0.0000000000001p-1022))
(module (func (export "f") (result f64) (f64.const +0x0.000000000000100000000001p-1022)))
(assert_return (invoke "f") (f64.const +0x0.0000000000001p-1022))
(module (func (export "f") (result f64) (f64.const -0x0.000000000000100000000001p-1022)))
(assert_return (invoke "f") (f64.const -0x0.0000000000001p-1022))
(module (func (export "f") (result f64) (f64.const +0x0.00000000000017ffffffffffp-1022)))
(assert_return (invoke "f") (f64.const +0x0.0000000000001p-1022))
(module (func (export "f") (result f64) (f64.const -0x0.00000000000017ffffffffffp-1022)))
(assert_return (invoke "f") (f64.const -0x0.0000000000001p-1022))
(module (func (export "f") (result f64) (f64.const +0x0.000000000000180000000000p-1022)))
(assert_return (invoke "f") (f64.const +0x0.0000000000002p-1022))
(module (func (export "f") (result f64) (f64.const -0x0.000000000000180000000000p-1022)))
(assert_return (invoke "f") (f64.const -0x0.0000000000002p-1022))
(module (func (export "f") (result f64) (f64.const +0x0.000000000000180000000001p-1022)))
(assert_return (invoke "f") (f64.const +0x0.0000000000002p-1022))
(module (func (export "f") (result f64) (f64.const -0x0.000000000000180000000001p-1022)))
(assert_return (invoke "f") (f64.const -0x0.0000000000002p-1022))
(module (func (export "f") (result f64) (f64.const +0x0.0000000000001fffffffffffp-1022)))
(assert_return (invoke "f") (f64.const +0x0.0000000000002p-1022))
(module (func (export "f") (result f64) (f64.const -0x0.0000000000001fffffffffffp-1022)))
(assert_return (invoke "f") (f64.const -0x0.0000000000002p-1022))
(module (func (export "f") (result f64) (f64.const +0x0.000000000000200000000000p-1022)))
(assert_return (invoke "f") (f64.const +0x0.0000000000002p-1022))
(module (func (export "f") (result f64) (f64.const -0x0.000000000000200000000000p-1022)))
(assert_return (invoke "f") (f64.const -0x0.0000000000002p-1022))
(module (func (export "f") (result f64) (f64.const +0x0.000000000000200000000001p-1022)))
(assert_return (invoke "f") (f64.const +0x0.0000000000002p-1022))
(module (func (export "f") (result f64) (f64.const -0x0.000000000000200000000001p-1022)))
(assert_return (invoke "f") (f64.const -0x0.0000000000002p-1022))
(module (func (export "f") (result f64) (f64.const +0x0.00000000000027ffffffffffp-1022)))
(assert_return (invoke "f") (f64.const +0x0.0000000000002p-1022))
(module (func (export "f") (result f64) (f64.const -0x0.00000000000027ffffffffffp-1022)))
(assert_return (invoke "f") (f64.const -0x0.0000000000002p-1022))
(module (func (export "f") (result f64) (f64.const +0x0.000000000000280000000000p-1022)))
(assert_return (invoke "f") (f64.const +0x0.0000000000002p-1022))
(module (func (export "f") (result f64) (f64.const -0x0.000000000000280000000000p-1022)))
(assert_return (invoke "f") (f64.const -0x0.0000000000002p-1022))
(module (func (export "f") (result f64) (f64.const +0x1.000000000000280000000001p-1022)))
(assert_return (invoke "f") (f64.const +0x1.0000000000003p-1022))
(module (func (export "f") (result f64) (f64.const -0x1.000000000000280000000001p-1022)))
(assert_return (invoke "f") (f64.const -0x1.0000000000003p-1022))
;; f64, round down at limit to infinity
(module (func (export "f") (result f64) (f64.const +0x1.fffffffffffff4p1023)))
(assert_return (invoke "f") (f64.const +0x1.fffffffffffffp1023))
(module (func (export "f") (result f64) (f64.const -0x1.fffffffffffff4p1023)))
(assert_return (invoke "f") (f64.const -0x1.fffffffffffffp1023))
(module (func (export "f") (result f64) (f64.const +0x1.fffffffffffff7ffffffp1023)))
(assert_return (invoke "f") (f64.const +0x1.fffffffffffffp1023))
(module (func (export "f") (result f64) (f64.const -0x1.fffffffffffff7ffffffp1023)))
(assert_return (invoke "f") (f64.const -0x1.fffffffffffffp1023))

View File

@ -1,137 +0,0 @@
;; Test t.const instructions
;; Syntax error
(module (func (i32.const 0xffffffff) drop))
(module (func (i32.const -0x80000000) drop))
(assert_malformed
(module quote "(func (i32.const 0x100000000) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (i32.const -0x80000001) drop)")
"constant out of range"
)
(module (func (i32.const 4294967295) drop))
(module (func (i32.const -2147483648) drop))
(assert_malformed
(module quote "(func (i32.const 4294967296) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (i32.const -2147483649) drop)")
"constant out of range"
)
(module (func (i64.const 0xffffffffffffffff) drop))
(module (func (i64.const -0x8000000000000000) drop))
(assert_malformed
(module quote "(func (i64.const 0x10000000000000000) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (i64.const -0x8000000000000001) drop)")
"constant out of range"
)
(module (func (i64.const 18446744073709551615) drop))
(module (func (i64.const -9223372036854775808) drop))
(assert_malformed
(module quote "(func (i64.const 18446744073709551616) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (i64.const -9223372036854775809) drop)")
"constant out of range"
)
(module (func (f32.const 0x1p127) drop))
(module (func (f32.const -0x1p127) drop))
(module (func (f32.const 0x1.fffffep127) drop))
(module (func (f32.const -0x1.fffffep127) drop))
(module (func (f32.const 0x1.fffffe7p127) drop))
(module (func (f32.const -0x1.fffffe7p127) drop))
(assert_malformed
(module quote "(func (f32.const 0x1p128) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f32.const -0x1p128) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f32.const 0x1.ffffffp127) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f32.const -0x1.ffffffp127) drop)")
"constant out of range"
)
(module (func (f32.const 1e38) drop))
(module (func (f32.const -1e38) drop))
(assert_malformed
(module quote "(func (f32.const 1e39) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f32.const -1e39) drop)")
"constant out of range"
)
(module (func (f32.const 340282356779733623858607532500980858880) drop))
(module (func (f32.const -340282356779733623858607532500980858880) drop))
(assert_malformed
(module quote "(func (f32.const 340282356779733661637539395458142568448) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f32.const -340282356779733661637539395458142568448) drop)")
"constant out of range"
)
(module (func (f64.const 0x1p1023) drop))
(module (func (f64.const -0x1p1023) drop))
(module (func (f64.const 0x1.fffffffffffffp1023) drop))
(module (func (f64.const -0x1.fffffffffffffp1023) drop))
(module (func (f64.const 0x1.fffffffffffff7p1023) drop))
(module (func (f64.const -0x1.fffffffffffff7p1023) drop))
(assert_malformed
(module quote "(func (f64.const 0x1p1024) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f64.const -0x1p1024) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f64.const 0x1.fffffffffffff8p1023) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f64.const -0x1.fffffffffffff8p1023) drop)")
"constant out of range"
)
(module (func (f64.const 1e308) drop))
(module (func (f64.const -1e308) drop))
(assert_malformed
(module quote "(func (f64.const 1e309) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f64.const -1e309) drop)")
"constant out of range"
)
(module (func (f64.const 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368) drop))
(module (func (f64.const -179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368) drop))
(assert_malformed
(module quote "(func (f64.const 269653970229347356221791135597556535197105851288767494898376215204735891170042808140884337949150317257310688430271573696351481990334196274152701320055306275479074865864826923114368235135583993416113802762682700913456874855354834422248712838998185022412196739306217084753107265771378949821875606039276187287552) drop)")
"constant out of range"
)
(assert_malformed
(module quote "(func (f64.const -269653970229347356221791135597556535197105851288767494898376215204735891170042808140884337949150317257310688430271573696351481990334196274152701320055306275479074865864826923114368235135583993416113802762682700913456874855354834422248712838998185022412196739306217084753107265771378949821875606039276187287552) drop)")
"constant out of range"
)

View File

@ -1,44 +1,44 @@
(module
(func (export "i64.extend_s_i32") (param $x i32) (result i64) (i64.extend_s/i32 (get_local $x)))
(func (export "i64.extend_u_i32") (param $x i32) (result i64) (i64.extend_u/i32 (get_local $x)))
(func (export "i32.wrap_i64") (param $x i64) (result i32) (i32.wrap/i64 (get_local $x)))
(func (export "i32.trunc_s_f32") (param $x f32) (result i32) (i32.trunc_s/f32 (get_local $x)))
(func (export "i32.trunc_u_f32") (param $x f32) (result i32) (i32.trunc_u/f32 (get_local $x)))
(func (export "i32.trunc_s_f64") (param $x f64) (result i32) (i32.trunc_s/f64 (get_local $x)))
(func (export "i32.trunc_u_f64") (param $x f64) (result i32) (i32.trunc_u/f64 (get_local $x)))
(func (export "i64.trunc_s_f32") (param $x f32) (result i64) (i64.trunc_s/f32 (get_local $x)))
(func (export "i64.trunc_u_f32") (param $x f32) (result i64) (i64.trunc_u/f32 (get_local $x)))
(func (export "i64.trunc_s_f64") (param $x f64) (result i64) (i64.trunc_s/f64 (get_local $x)))
(func (export "i64.trunc_u_f64") (param $x f64) (result i64) (i64.trunc_u/f64 (get_local $x)))
(func (export "f32.convert_s_i32") (param $x i32) (result f32) (f32.convert_s/i32 (get_local $x)))
(func (export "f32.convert_s_i64") (param $x i64) (result f32) (f32.convert_s/i64 (get_local $x)))
(func (export "f64.convert_s_i32") (param $x i32) (result f64) (f64.convert_s/i32 (get_local $x)))
(func (export "f64.convert_s_i64") (param $x i64) (result f64) (f64.convert_s/i64 (get_local $x)))
(func (export "f32.convert_u_i32") (param $x i32) (result f32) (f32.convert_u/i32 (get_local $x)))
(func (export "f32.convert_u_i64") (param $x i64) (result f32) (f32.convert_u/i64 (get_local $x)))
(func (export "f64.convert_u_i32") (param $x i32) (result f64) (f64.convert_u/i32 (get_local $x)))
(func (export "f64.convert_u_i64") (param $x i64) (result f64) (f64.convert_u/i64 (get_local $x)))
(func (export "f64.promote_f32") (param $x f32) (result f64) (f64.promote/f32 (get_local $x)))
(func (export "f32.demote_f64") (param $x f64) (result f32) (f32.demote/f64 (get_local $x)))
(func (export "f32.reinterpret_i32") (param $x i32) (result f32) (f32.reinterpret/i32 (get_local $x)))
(func (export "f64.reinterpret_i64") (param $x i64) (result f64) (f64.reinterpret/i64 (get_local $x)))
(func (export "i32.reinterpret_f32") (param $x f32) (result i32) (i32.reinterpret/f32 (get_local $x)))
(func (export "i64.reinterpret_f64") (param $x f64) (result i64) (i64.reinterpret/f64 (get_local $x)))
(func (export "i64.extend_i32_s") (param $x i32) (result i64) (i64.extend_i32_s (local.get $x)))
(func (export "i64.extend_i32_u") (param $x i32) (result i64) (i64.extend_i32_u (local.get $x)))
(func (export "i32.wrap_i64") (param $x i64) (result i32) (i32.wrap_i64 (local.get $x)))
(func (export "i32.trunc_f32_s") (param $x f32) (result i32) (i32.trunc_f32_s (local.get $x)))
(func (export "i32.trunc_f32_u") (param $x f32) (result i32) (i32.trunc_f32_u (local.get $x)))
(func (export "i32.trunc_f64_s") (param $x f64) (result i32) (i32.trunc_f64_s (local.get $x)))
(func (export "i32.trunc_f64_u") (param $x f64) (result i32) (i32.trunc_f64_u (local.get $x)))
(func (export "i64.trunc_f32_s") (param $x f32) (result i64) (i64.trunc_f32_s (local.get $x)))
(func (export "i64.trunc_f32_u") (param $x f32) (result i64) (i64.trunc_f32_u (local.get $x)))
(func (export "i64.trunc_f64_s") (param $x f64) (result i64) (i64.trunc_f64_s (local.get $x)))
(func (export "i64.trunc_f64_u") (param $x f64) (result i64) (i64.trunc_f64_u (local.get $x)))
(func (export "f32.convert_i32_s") (param $x i32) (result f32) (f32.convert_i32_s (local.get $x)))
(func (export "f32.convert_i64_s") (param $x i64) (result f32) (f32.convert_i64_s (local.get $x)))
(func (export "f64.convert_i32_s") (param $x i32) (result f64) (f64.convert_i32_s (local.get $x)))
(func (export "f64.convert_i64_s") (param $x i64) (result f64) (f64.convert_i64_s (local.get $x)))
(func (export "f32.convert_i32_u") (param $x i32) (result f32) (f32.convert_i32_u (local.get $x)))
(func (export "f32.convert_i64_u") (param $x i64) (result f32) (f32.convert_i64_u (local.get $x)))
(func (export "f64.convert_i32_u") (param $x i32) (result f64) (f64.convert_i32_u (local.get $x)))
(func (export "f64.convert_i64_u") (param $x i64) (result f64) (f64.convert_i64_u (local.get $x)))
(func (export "f64.promote_f32") (param $x f32) (result f64) (f64.promote_f32 (local.get $x)))
(func (export "f32.demote_f64") (param $x f64) (result f32) (f32.demote_f64 (local.get $x)))
(func (export "f32.reinterpret_i32") (param $x i32) (result f32) (f32.reinterpret_i32 (local.get $x)))
(func (export "f64.reinterpret_i64") (param $x i64) (result f64) (f64.reinterpret_i64 (local.get $x)))
(func (export "i32.reinterpret_f32") (param $x f32) (result i32) (i32.reinterpret_f32 (local.get $x)))
(func (export "i64.reinterpret_f64") (param $x f64) (result i64) (i64.reinterpret_f64 (local.get $x)))
)
(assert_return (invoke "i64.extend_s_i32" (i32.const 0)) (i64.const 0))
(assert_return (invoke "i64.extend_s_i32" (i32.const 10000)) (i64.const 10000))
(assert_return (invoke "i64.extend_s_i32" (i32.const -10000)) (i64.const -10000))
(assert_return (invoke "i64.extend_s_i32" (i32.const -1)) (i64.const -1))
(assert_return (invoke "i64.extend_s_i32" (i32.const 0x7fffffff)) (i64.const 0x000000007fffffff))
(assert_return (invoke "i64.extend_s_i32" (i32.const 0x80000000)) (i64.const 0xffffffff80000000))
(assert_return (invoke "i64.extend_i32_s" (i32.const 0)) (i64.const 0))
(assert_return (invoke "i64.extend_i32_s" (i32.const 10000)) (i64.const 10000))
(assert_return (invoke "i64.extend_i32_s" (i32.const -10000)) (i64.const -10000))
(assert_return (invoke "i64.extend_i32_s" (i32.const -1)) (i64.const -1))
(assert_return (invoke "i64.extend_i32_s" (i32.const 0x7fffffff)) (i64.const 0x000000007fffffff))
(assert_return (invoke "i64.extend_i32_s" (i32.const 0x80000000)) (i64.const 0xffffffff80000000))
(assert_return (invoke "i64.extend_u_i32" (i32.const 0)) (i64.const 0))
(assert_return (invoke "i64.extend_u_i32" (i32.const 10000)) (i64.const 10000))
(assert_return (invoke "i64.extend_u_i32" (i32.const -10000)) (i64.const 0x00000000ffffd8f0))
(assert_return (invoke "i64.extend_u_i32" (i32.const -1)) (i64.const 0xffffffff))
(assert_return (invoke "i64.extend_u_i32" (i32.const 0x7fffffff)) (i64.const 0x000000007fffffff))
(assert_return (invoke "i64.extend_u_i32" (i32.const 0x80000000)) (i64.const 0x0000000080000000))
(assert_return (invoke "i64.extend_i32_u" (i32.const 0)) (i64.const 0))
(assert_return (invoke "i64.extend_i32_u" (i32.const 10000)) (i64.const 10000))
(assert_return (invoke "i64.extend_i32_u" (i32.const -10000)) (i64.const 0x00000000ffffd8f0))
(assert_return (invoke "i64.extend_i32_u" (i32.const -1)) (i64.const 0xffffffff))
(assert_return (invoke "i64.extend_i32_u" (i32.const 0x7fffffff)) (i64.const 0x000000007fffffff))
(assert_return (invoke "i64.extend_i32_u" (i32.const 0x80000000)) (i64.const 0x0000000080000000))
(assert_return (invoke "i32.wrap_i64" (i64.const -1)) (i32.const -1))
(assert_return (invoke "i32.wrap_i64" (i64.const -100000)) (i32.const -100000))
@ -53,282 +53,292 @@
(assert_return (invoke "i32.wrap_i64" (i64.const 0x0000000100000000)) (i32.const 0x00000000))
(assert_return (invoke "i32.wrap_i64" (i64.const 0x0000000100000001)) (i32.const 0x00000001))
(assert_return (invoke "i32.trunc_s_f32" (f32.const 0.0)) (i32.const 0))
(assert_return (invoke "i32.trunc_s_f32" (f32.const -0.0)) (i32.const 0))
(assert_return (invoke "i32.trunc_s_f32" (f32.const 0x1p-149)) (i32.const 0))
(assert_return (invoke "i32.trunc_s_f32" (f32.const -0x1p-149)) (i32.const 0))
(assert_return (invoke "i32.trunc_s_f32" (f32.const 1.0)) (i32.const 1))
(assert_return (invoke "i32.trunc_s_f32" (f32.const 0x1.19999ap+0)) (i32.const 1))
(assert_return (invoke "i32.trunc_s_f32" (f32.const 1.5)) (i32.const 1))
(assert_return (invoke "i32.trunc_s_f32" (f32.const -1.0)) (i32.const -1))
(assert_return (invoke "i32.trunc_s_f32" (f32.const -0x1.19999ap+0)) (i32.const -1))
(assert_return (invoke "i32.trunc_s_f32" (f32.const -1.5)) (i32.const -1))
(assert_return (invoke "i32.trunc_s_f32" (f32.const -1.9)) (i32.const -1))
(assert_return (invoke "i32.trunc_s_f32" (f32.const -2.0)) (i32.const -2))
(assert_return (invoke "i32.trunc_s_f32" (f32.const 2147483520.0)) (i32.const 2147483520))
(assert_return (invoke "i32.trunc_s_f32" (f32.const -2147483648.0)) (i32.const -2147483648))
(assert_trap (invoke "i32.trunc_s_f32" (f32.const 2147483648.0)) "integer overflow")
(assert_trap (invoke "i32.trunc_s_f32" (f32.const -2147483904.0)) "integer overflow")
(assert_trap (invoke "i32.trunc_s_f32" (f32.const inf)) "integer overflow")
(assert_trap (invoke "i32.trunc_s_f32" (f32.const -inf)) "integer overflow")
(assert_trap (invoke "i32.trunc_s_f32" (f32.const nan)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_s_f32" (f32.const nan:0x200000)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_s_f32" (f32.const -nan)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_s_f32" (f32.const -nan:0x200000)) "invalid conversion to integer")
(assert_return (invoke "i32.trunc_f32_s" (f32.const 0.0)) (i32.const 0))
(assert_return (invoke "i32.trunc_f32_s" (f32.const -0.0)) (i32.const 0))
(assert_return (invoke "i32.trunc_f32_s" (f32.const 0x1p-149)) (i32.const 0))
(assert_return (invoke "i32.trunc_f32_s" (f32.const -0x1p-149)) (i32.const 0))
(assert_return (invoke "i32.trunc_f32_s" (f32.const 1.0)) (i32.const 1))
(assert_return (invoke "i32.trunc_f32_s" (f32.const 0x1.19999ap+0)) (i32.const 1))
(assert_return (invoke "i32.trunc_f32_s" (f32.const 1.5)) (i32.const 1))
(assert_return (invoke "i32.trunc_f32_s" (f32.const -1.0)) (i32.const -1))
(assert_return (invoke "i32.trunc_f32_s" (f32.const -0x1.19999ap+0)) (i32.const -1))
(assert_return (invoke "i32.trunc_f32_s" (f32.const -1.5)) (i32.const -1))
(assert_return (invoke "i32.trunc_f32_s" (f32.const -1.9)) (i32.const -1))
(assert_return (invoke "i32.trunc_f32_s" (f32.const -2.0)) (i32.const -2))
(assert_return (invoke "i32.trunc_f32_s" (f32.const 2147483520.0)) (i32.const 2147483520))
(assert_return (invoke "i32.trunc_f32_s" (f32.const -2147483648.0)) (i32.const -2147483648))
(assert_trap (invoke "i32.trunc_f32_s" (f32.const 2147483648.0)) "integer overflow")
(assert_trap (invoke "i32.trunc_f32_s" (f32.const -2147483904.0)) "integer overflow")
(assert_trap (invoke "i32.trunc_f32_s" (f32.const inf)) "integer overflow")
(assert_trap (invoke "i32.trunc_f32_s" (f32.const -inf)) "integer overflow")
(assert_trap (invoke "i32.trunc_f32_s" (f32.const nan)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_f32_s" (f32.const nan:0x200000)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_f32_s" (f32.const -nan)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_f32_s" (f32.const -nan:0x200000)) "invalid conversion to integer")
(assert_return (invoke "i32.trunc_u_f32" (f32.const 0.0)) (i32.const 0))
(assert_return (invoke "i32.trunc_u_f32" (f32.const -0.0)) (i32.const 0))
(assert_return (invoke "i32.trunc_u_f32" (f32.const 0x1p-149)) (i32.const 0))
(assert_return (invoke "i32.trunc_u_f32" (f32.const -0x1p-149)) (i32.const 0))
(assert_return (invoke "i32.trunc_u_f32" (f32.const 1.0)) (i32.const 1))
(assert_return (invoke "i32.trunc_u_f32" (f32.const 0x1.19999ap+0)) (i32.const 1))
(assert_return (invoke "i32.trunc_u_f32" (f32.const 1.5)) (i32.const 1))
(assert_return (invoke "i32.trunc_u_f32" (f32.const 1.9)) (i32.const 1))
(assert_return (invoke "i32.trunc_u_f32" (f32.const 2.0)) (i32.const 2))
(assert_return (invoke "i32.trunc_u_f32" (f32.const 2147483648)) (i32.const -2147483648)) ;; 0x1.00000p+31 -> 8000 0000
(assert_return (invoke "i32.trunc_u_f32" (f32.const 4294967040.0)) (i32.const -256))
(assert_return (invoke "i32.trunc_u_f32" (f32.const -0x1.ccccccp-1)) (i32.const 0))
(assert_return (invoke "i32.trunc_u_f32" (f32.const -0x1.fffffep-1)) (i32.const 0))
(assert_trap (invoke "i32.trunc_u_f32" (f32.const 4294967296.0)) "integer overflow")
(assert_trap (invoke "i32.trunc_u_f32" (f32.const -1.0)) "integer overflow")
(assert_trap (invoke "i32.trunc_u_f32" (f32.const inf)) "integer overflow")
(assert_trap (invoke "i32.trunc_u_f32" (f32.const -inf)) "integer overflow")
(assert_trap (invoke "i32.trunc_u_f32" (f32.const nan)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_u_f32" (f32.const nan:0x200000)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_u_f32" (f32.const -nan)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_u_f32" (f32.const -nan:0x200000)) "invalid conversion to integer")
(assert_return (invoke "i32.trunc_f32_u" (f32.const 0.0)) (i32.const 0))
(assert_return (invoke "i32.trunc_f32_u" (f32.const -0.0)) (i32.const 0))
(assert_return (invoke "i32.trunc_f32_u" (f32.const 0x1p-149)) (i32.const 0))
(assert_return (invoke "i32.trunc_f32_u" (f32.const -0x1p-149)) (i32.const 0))
(assert_return (invoke "i32.trunc_f32_u" (f32.const 1.0)) (i32.const 1))
(assert_return (invoke "i32.trunc_f32_u" (f32.const 0x1.19999ap+0)) (i32.const 1))
(assert_return (invoke "i32.trunc_f32_u" (f32.const 1.5)) (i32.const 1))
(assert_return (invoke "i32.trunc_f32_u" (f32.const 1.9)) (i32.const 1))
(assert_return (invoke "i32.trunc_f32_u" (f32.const 2.0)) (i32.const 2))
(assert_return (invoke "i32.trunc_f32_u" (f32.const 2147483648)) (i32.const -2147483648)) ;; 0x1.00000p+31 -> 8000 0000
(assert_return (invoke "i32.trunc_f32_u" (f32.const 4294967040.0)) (i32.const -256))
(assert_return (invoke "i32.trunc_f32_u" (f32.const -0x1.ccccccp-1)) (i32.const 0))
(assert_return (invoke "i32.trunc_f32_u" (f32.const -0x1.fffffep-1)) (i32.const 0))
(assert_trap (invoke "i32.trunc_f32_u" (f32.const 4294967296.0)) "integer overflow")
(assert_trap (invoke "i32.trunc_f32_u" (f32.const -1.0)) "integer overflow")
(assert_trap (invoke "i32.trunc_f32_u" (f32.const inf)) "integer overflow")
(assert_trap (invoke "i32.trunc_f32_u" (f32.const -inf)) "integer overflow")
(assert_trap (invoke "i32.trunc_f32_u" (f32.const nan)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_f32_u" (f32.const nan:0x200000)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_f32_u" (f32.const -nan)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_f32_u" (f32.const -nan:0x200000)) "invalid conversion to integer")
(assert_return (invoke "i32.trunc_s_f64" (f64.const 0.0)) (i32.const 0))
(assert_return (invoke "i32.trunc_s_f64" (f64.const -0.0)) (i32.const 0))
(assert_return (invoke "i32.trunc_s_f64" (f64.const 0x0.0000000000001p-1022)) (i32.const 0))
(assert_return (invoke "i32.trunc_s_f64" (f64.const -0x0.0000000000001p-1022)) (i32.const 0))
(assert_return (invoke "i32.trunc_s_f64" (f64.const 1.0)) (i32.const 1))
(assert_return (invoke "i32.trunc_s_f64" (f64.const 0x1.199999999999ap+0)) (i32.const 1))
(assert_return (invoke "i32.trunc_s_f64" (f64.const 1.5)) (i32.const 1))
(assert_return (invoke "i32.trunc_s_f64" (f64.const -1.0)) (i32.const -1))
(assert_return (invoke "i32.trunc_s_f64" (f64.const -0x1.199999999999ap+0)) (i32.const -1))
(assert_return (invoke "i32.trunc_s_f64" (f64.const -1.5)) (i32.const -1))
(assert_return (invoke "i32.trunc_s_f64" (f64.const -1.9)) (i32.const -1))
(assert_return (invoke "i32.trunc_s_f64" (f64.const -2.0)) (i32.const -2))
(assert_return (invoke "i32.trunc_s_f64" (f64.const 2147483647.0)) (i32.const 2147483647))
(assert_return (invoke "i32.trunc_s_f64" (f64.const -2147483648.0)) (i32.const -2147483648))
(assert_trap (invoke "i32.trunc_s_f64" (f64.const 2147483648.0)) "integer overflow")
(assert_trap (invoke "i32.trunc_s_f64" (f64.const -2147483649.0)) "integer overflow")
(assert_trap (invoke "i32.trunc_s_f64" (f64.const inf)) "integer overflow")
(assert_trap (invoke "i32.trunc_s_f64" (f64.const -inf)) "integer overflow")
(assert_trap (invoke "i32.trunc_s_f64" (f64.const nan)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_s_f64" (f64.const nan:0x4000000000000)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_s_f64" (f64.const -nan)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_s_f64" (f64.const -nan:0x4000000000000)) "invalid conversion to integer")
(assert_return (invoke "i32.trunc_f64_s" (f64.const 0.0)) (i32.const 0))
(assert_return (invoke "i32.trunc_f64_s" (f64.const -0.0)) (i32.const 0))
(assert_return (invoke "i32.trunc_f64_s" (f64.const 0x0.0000000000001p-1022)) (i32.const 0))
(assert_return (invoke "i32.trunc_f64_s" (f64.const -0x0.0000000000001p-1022)) (i32.const 0))
(assert_return (invoke "i32.trunc_f64_s" (f64.const 1.0)) (i32.const 1))
(assert_return (invoke "i32.trunc_f64_s" (f64.const 0x1.199999999999ap+0)) (i32.const 1))
(assert_return (invoke "i32.trunc_f64_s" (f64.const 1.5)) (i32.const 1))
(assert_return (invoke "i32.trunc_f64_s" (f64.const -1.0)) (i32.const -1))
(assert_return (invoke "i32.trunc_f64_s" (f64.const -0x1.199999999999ap+0)) (i32.const -1))
(assert_return (invoke "i32.trunc_f64_s" (f64.const -1.5)) (i32.const -1))
(assert_return (invoke "i32.trunc_f64_s" (f64.const -1.9)) (i32.const -1))
(assert_return (invoke "i32.trunc_f64_s" (f64.const -2.0)) (i32.const -2))
(assert_return (invoke "i32.trunc_f64_s" (f64.const 2147483647.0)) (i32.const 2147483647))
(assert_return (invoke "i32.trunc_f64_s" (f64.const -2147483648.0)) (i32.const -2147483648))
(assert_trap (invoke "i32.trunc_f64_s" (f64.const 2147483648.0)) "integer overflow")
(assert_trap (invoke "i32.trunc_f64_s" (f64.const -2147483649.0)) "integer overflow")
(assert_trap (invoke "i32.trunc_f64_s" (f64.const inf)) "integer overflow")
(assert_trap (invoke "i32.trunc_f64_s" (f64.const -inf)) "integer overflow")
(assert_trap (invoke "i32.trunc_f64_s" (f64.const nan)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_f64_s" (f64.const nan:0x4000000000000)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_f64_s" (f64.const -nan)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_f64_s" (f64.const -nan:0x4000000000000)) "invalid conversion to integer")
(assert_return (invoke "i32.trunc_u_f64" (f64.const 0.0)) (i32.const 0))
(assert_return (invoke "i32.trunc_u_f64" (f64.const -0.0)) (i32.const 0))
(assert_return (invoke "i32.trunc_u_f64" (f64.const 0x0.0000000000001p-1022)) (i32.const 0))
(assert_return (invoke "i32.trunc_u_f64" (f64.const -0x0.0000000000001p-1022)) (i32.const 0))
(assert_return (invoke "i32.trunc_u_f64" (f64.const 1.0)) (i32.const 1))
(assert_return (invoke "i32.trunc_u_f64" (f64.const 0x1.199999999999ap+0)) (i32.const 1))
(assert_return (invoke "i32.trunc_u_f64" (f64.const 1.5)) (i32.const 1))
(assert_return (invoke "i32.trunc_u_f64" (f64.const 1.9)) (i32.const 1))
(assert_return (invoke "i32.trunc_u_f64" (f64.const 2.0)) (i32.const 2))
(assert_return (invoke "i32.trunc_u_f64" (f64.const 2147483648)) (i32.const -2147483648)) ;; 0x1.00000p+31 -> 8000 0000
(assert_return (invoke "i32.trunc_u_f64" (f64.const 4294967295.0)) (i32.const -1))
(assert_return (invoke "i32.trunc_u_f64" (f64.const -0x1.ccccccccccccdp-1)) (i32.const 0))
(assert_return (invoke "i32.trunc_u_f64" (f64.const -0x1.fffffffffffffp-1)) (i32.const 0))
(assert_return (invoke "i32.trunc_u_f64" (f64.const 1e8)) (i32.const 100000000))
(assert_trap (invoke "i32.trunc_u_f64" (f64.const 4294967296.0)) "integer overflow")
(assert_trap (invoke "i32.trunc_u_f64" (f64.const -1.0)) "integer overflow")
(assert_trap (invoke "i32.trunc_u_f64" (f64.const 1e16)) "integer overflow")
(assert_trap (invoke "i32.trunc_u_f64" (f64.const 1e30)) "integer overflow")
(assert_trap (invoke "i32.trunc_u_f64" (f64.const 9223372036854775808)) "integer overflow")
(assert_trap (invoke "i32.trunc_u_f64" (f64.const inf)) "integer overflow")
(assert_trap (invoke "i32.trunc_u_f64" (f64.const -inf)) "integer overflow")
(assert_trap (invoke "i32.trunc_u_f64" (f64.const nan)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_u_f64" (f64.const nan:0x4000000000000)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_u_f64" (f64.const -nan)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_u_f64" (f64.const -nan:0x4000000000000)) "invalid conversion to integer")
(assert_return (invoke "i32.trunc_f64_u" (f64.const 0.0)) (i32.const 0))
(assert_return (invoke "i32.trunc_f64_u" (f64.const -0.0)) (i32.const 0))
(assert_return (invoke "i32.trunc_f64_u" (f64.const 0x0.0000000000001p-1022)) (i32.const 0))
(assert_return (invoke "i32.trunc_f64_u" (f64.const -0x0.0000000000001p-1022)) (i32.const 0))
(assert_return (invoke "i32.trunc_f64_u" (f64.const 1.0)) (i32.const 1))
(assert_return (invoke "i32.trunc_f64_u" (f64.const 0x1.199999999999ap+0)) (i32.const 1))
(assert_return (invoke "i32.trunc_f64_u" (f64.const 1.5)) (i32.const 1))
(assert_return (invoke "i32.trunc_f64_u" (f64.const 1.9)) (i32.const 1))
(assert_return (invoke "i32.trunc_f64_u" (f64.const 2.0)) (i32.const 2))
(assert_return (invoke "i32.trunc_f64_u" (f64.const 2147483648)) (i32.const -2147483648)) ;; 0x1.00000p+31 -> 8000 0000
(assert_return (invoke "i32.trunc_f64_u" (f64.const 4294967295.0)) (i32.const -1))
(assert_return (invoke "i32.trunc_f64_u" (f64.const -0x1.ccccccccccccdp-1)) (i32.const 0))
(assert_return (invoke "i32.trunc_f64_u" (f64.const -0x1.fffffffffffffp-1)) (i32.const 0))
(assert_return (invoke "i32.trunc_f64_u" (f64.const 1e8)) (i32.const 100000000))
(assert_trap (invoke "i32.trunc_f64_u" (f64.const 4294967296.0)) "integer overflow")
(assert_trap (invoke "i32.trunc_f64_u" (f64.const -1.0)) "integer overflow")
(assert_trap (invoke "i32.trunc_f64_u" (f64.const 1e16)) "integer overflow")
(assert_trap (invoke "i32.trunc_f64_u" (f64.const 1e30)) "integer overflow")
(assert_trap (invoke "i32.trunc_f64_u" (f64.const 9223372036854775808)) "integer overflow")
(assert_trap (invoke "i32.trunc_f64_u" (f64.const inf)) "integer overflow")
(assert_trap (invoke "i32.trunc_f64_u" (f64.const -inf)) "integer overflow")
(assert_trap (invoke "i32.trunc_f64_u" (f64.const nan)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_f64_u" (f64.const nan:0x4000000000000)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_f64_u" (f64.const -nan)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_f64_u" (f64.const -nan:0x4000000000000)) "invalid conversion to integer")
(assert_return (invoke "i64.trunc_s_f32" (f32.const 0.0)) (i64.const 0))
(assert_return (invoke "i64.trunc_s_f32" (f32.const -0.0)) (i64.const 0))
(assert_return (invoke "i64.trunc_s_f32" (f32.const 0x1p-149)) (i64.const 0))
(assert_return (invoke "i64.trunc_s_f32" (f32.const -0x1p-149)) (i64.const 0))
(assert_return (invoke "i64.trunc_s_f32" (f32.const 1.0)) (i64.const 1))
(assert_return (invoke "i64.trunc_s_f32" (f32.const 0x1.19999ap+0)) (i64.const 1))
(assert_return (invoke "i64.trunc_s_f32" (f32.const 1.5)) (i64.const 1))
(assert_return (invoke "i64.trunc_s_f32" (f32.const -1.0)) (i64.const -1))
(assert_return (invoke "i64.trunc_s_f32" (f32.const -0x1.19999ap+0)) (i64.const -1))
(assert_return (invoke "i64.trunc_s_f32" (f32.const -1.5)) (i64.const -1))
(assert_return (invoke "i64.trunc_s_f32" (f32.const -1.9)) (i64.const -1))
(assert_return (invoke "i64.trunc_s_f32" (f32.const -2.0)) (i64.const -2))
(assert_return (invoke "i64.trunc_s_f32" (f32.const 4294967296)) (i64.const 4294967296)) ;; 0x1.00000p+32 -> 1 0000 0000
(assert_return (invoke "i64.trunc_s_f32" (f32.const -4294967296)) (i64.const -4294967296)) ;; -0x1.00000p+32 -> ffff ffff 0000 0000
(assert_return (invoke "i64.trunc_s_f32" (f32.const 9223371487098961920.0)) (i64.const 9223371487098961920))
(assert_return (invoke "i64.trunc_s_f32" (f32.const -9223372036854775808.0)) (i64.const -9223372036854775808))
(assert_trap (invoke "i64.trunc_s_f32" (f32.const 9223372036854775808.0)) "integer overflow")
(assert_trap (invoke "i64.trunc_s_f32" (f32.const -9223373136366403584.0)) "integer overflow")
(assert_trap (invoke "i64.trunc_s_f32" (f32.const inf)) "integer overflow")
(assert_trap (invoke "i64.trunc_s_f32" (f32.const -inf)) "integer overflow")
(assert_trap (invoke "i64.trunc_s_f32" (f32.const nan)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_s_f32" (f32.const nan:0x200000)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_s_f32" (f32.const -nan)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_s_f32" (f32.const -nan:0x200000)) "invalid conversion to integer")
(assert_return (invoke "i64.trunc_f32_s" (f32.const 0.0)) (i64.const 0))
(assert_return (invoke "i64.trunc_f32_s" (f32.const -0.0)) (i64.const 0))
(assert_return (invoke "i64.trunc_f32_s" (f32.const 0x1p-149)) (i64.const 0))
(assert_return (invoke "i64.trunc_f32_s" (f32.const -0x1p-149)) (i64.const 0))
(assert_return (invoke "i64.trunc_f32_s" (f32.const 1.0)) (i64.const 1))
(assert_return (invoke "i64.trunc_f32_s" (f32.const 0x1.19999ap+0)) (i64.const 1))
(assert_return (invoke "i64.trunc_f32_s" (f32.const 1.5)) (i64.const 1))
(assert_return (invoke "i64.trunc_f32_s" (f32.const -1.0)) (i64.const -1))
(assert_return (invoke "i64.trunc_f32_s" (f32.const -0x1.19999ap+0)) (i64.const -1))
(assert_return (invoke "i64.trunc_f32_s" (f32.const -1.5)) (i64.const -1))
(assert_return (invoke "i64.trunc_f32_s" (f32.const -1.9)) (i64.const -1))
(assert_return (invoke "i64.trunc_f32_s" (f32.const -2.0)) (i64.const -2))
(assert_return (invoke "i64.trunc_f32_s" (f32.const 4294967296)) (i64.const 4294967296)) ;; 0x1.00000p+32 -> 1 0000 0000
(assert_return (invoke "i64.trunc_f32_s" (f32.const -4294967296)) (i64.const -4294967296)) ;; -0x1.00000p+32 -> ffff ffff 0000 0000
(assert_return (invoke "i64.trunc_f32_s" (f32.const 9223371487098961920.0)) (i64.const 9223371487098961920))
(assert_return (invoke "i64.trunc_f32_s" (f32.const -9223372036854775808.0)) (i64.const -9223372036854775808))
(assert_trap (invoke "i64.trunc_f32_s" (f32.const 9223372036854775808.0)) "integer overflow")
(assert_trap (invoke "i64.trunc_f32_s" (f32.const -9223373136366403584.0)) "integer overflow")
(assert_trap (invoke "i64.trunc_f32_s" (f32.const inf)) "integer overflow")
(assert_trap (invoke "i64.trunc_f32_s" (f32.const -inf)) "integer overflow")
(assert_trap (invoke "i64.trunc_f32_s" (f32.const nan)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_f32_s" (f32.const nan:0x200000)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_f32_s" (f32.const -nan)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_f32_s" (f32.const -nan:0x200000)) "invalid conversion to integer")
(assert_return (invoke "i64.trunc_u_f32" (f32.const 0.0)) (i64.const 0))
(assert_return (invoke "i64.trunc_u_f32" (f32.const -0.0)) (i64.const 0))
(assert_return (invoke "i64.trunc_u_f32" (f32.const 0x1p-149)) (i64.const 0))
(assert_return (invoke "i64.trunc_u_f32" (f32.const -0x1p-149)) (i64.const 0))
(assert_return (invoke "i64.trunc_u_f32" (f32.const 1.0)) (i64.const 1))
(assert_return (invoke "i64.trunc_u_f32" (f32.const 0x1.19999ap+0)) (i64.const 1))
(assert_return (invoke "i64.trunc_u_f32" (f32.const 1.5)) (i64.const 1))
(assert_return (invoke "i64.trunc_u_f32" (f32.const 4294967296)) (i64.const 4294967296))
(assert_return (invoke "i64.trunc_u_f32" (f32.const 18446742974197923840.0)) (i64.const -1099511627776))
(assert_return (invoke "i64.trunc_u_f32" (f32.const -0x1.ccccccp-1)) (i64.const 0))
(assert_return (invoke "i64.trunc_u_f32" (f32.const -0x1.fffffep-1)) (i64.const 0))
(assert_trap (invoke "i64.trunc_u_f32" (f32.const 18446744073709551616.0)) "integer overflow")
(assert_trap (invoke "i64.trunc_u_f32" (f32.const -1.0)) "integer overflow")
(assert_trap (invoke "i64.trunc_u_f32" (f32.const inf)) "integer overflow")
(assert_trap (invoke "i64.trunc_u_f32" (f32.const -inf)) "integer overflow")
(assert_trap (invoke "i64.trunc_u_f32" (f32.const nan)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_u_f32" (f32.const nan:0x200000)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_u_f32" (f32.const -nan)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_u_f32" (f32.const -nan:0x200000)) "invalid conversion to integer")
(assert_return (invoke "i64.trunc_f32_u" (f32.const 0.0)) (i64.const 0))
(assert_return (invoke "i64.trunc_f32_u" (f32.const -0.0)) (i64.const 0))
(assert_return (invoke "i64.trunc_f32_u" (f32.const 0x1p-149)) (i64.const 0))
(assert_return (invoke "i64.trunc_f32_u" (f32.const -0x1p-149)) (i64.const 0))
(assert_return (invoke "i64.trunc_f32_u" (f32.const 1.0)) (i64.const 1))
(assert_return (invoke "i64.trunc_f32_u" (f32.const 0x1.19999ap+0)) (i64.const 1))
(assert_return (invoke "i64.trunc_f32_u" (f32.const 1.5)) (i64.const 1))
(assert_return (invoke "i64.trunc_f32_u" (f32.const 4294967296)) (i64.const 4294967296))
(assert_return (invoke "i64.trunc_f32_u" (f32.const 18446742974197923840.0)) (i64.const -1099511627776))
(assert_return (invoke "i64.trunc_f32_u" (f32.const -0x1.ccccccp-1)) (i64.const 0))
(assert_return (invoke "i64.trunc_f32_u" (f32.const -0x1.fffffep-1)) (i64.const 0))
(assert_trap (invoke "i64.trunc_f32_u" (f32.const 18446744073709551616.0)) "integer overflow")
(assert_trap (invoke "i64.trunc_f32_u" (f32.const -1.0)) "integer overflow")
(assert_trap (invoke "i64.trunc_f32_u" (f32.const inf)) "integer overflow")
(assert_trap (invoke "i64.trunc_f32_u" (f32.const -inf)) "integer overflow")
(assert_trap (invoke "i64.trunc_f32_u" (f32.const nan)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_f32_u" (f32.const nan:0x200000)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_f32_u" (f32.const -nan)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_f32_u" (f32.const -nan:0x200000)) "invalid conversion to integer")
(assert_return (invoke "i64.trunc_s_f64" (f64.const 0.0)) (i64.const 0))
(assert_return (invoke "i64.trunc_s_f64" (f64.const -0.0)) (i64.const 0))
(assert_return (invoke "i64.trunc_s_f64" (f64.const 0x0.0000000000001p-1022)) (i64.const 0))
(assert_return (invoke "i64.trunc_s_f64" (f64.const -0x0.0000000000001p-1022)) (i64.const 0))
(assert_return (invoke "i64.trunc_s_f64" (f64.const 1.0)) (i64.const 1))
(assert_return (invoke "i64.trunc_s_f64" (f64.const 0x1.199999999999ap+0)) (i64.const 1))
(assert_return (invoke "i64.trunc_s_f64" (f64.const 1.5)) (i64.const 1))
(assert_return (invoke "i64.trunc_s_f64" (f64.const -1.0)) (i64.const -1))
(assert_return (invoke "i64.trunc_s_f64" (f64.const -0x1.199999999999ap+0)) (i64.const -1))
(assert_return (invoke "i64.trunc_s_f64" (f64.const -1.5)) (i64.const -1))
(assert_return (invoke "i64.trunc_s_f64" (f64.const -1.9)) (i64.const -1))
(assert_return (invoke "i64.trunc_s_f64" (f64.const -2.0)) (i64.const -2))
(assert_return (invoke "i64.trunc_s_f64" (f64.const 4294967296)) (i64.const 4294967296)) ;; 0x1.00000p+32 -> 1 0000 0000
(assert_return (invoke "i64.trunc_s_f64" (f64.const -4294967296)) (i64.const -4294967296)) ;; -0x1.00000p+32 -> ffff ffff 0000 0000
(assert_return (invoke "i64.trunc_s_f64" (f64.const 9223372036854774784.0)) (i64.const 9223372036854774784))
(assert_return (invoke "i64.trunc_s_f64" (f64.const -9223372036854775808.0)) (i64.const -9223372036854775808))
(assert_trap (invoke "i64.trunc_s_f64" (f64.const 9223372036854775808.0)) "integer overflow")
(assert_trap (invoke "i64.trunc_s_f64" (f64.const -9223372036854777856.0)) "integer overflow")
(assert_trap (invoke "i64.trunc_s_f64" (f64.const inf)) "integer overflow")
(assert_trap (invoke "i64.trunc_s_f64" (f64.const -inf)) "integer overflow")
(assert_trap (invoke "i64.trunc_s_f64" (f64.const nan)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_s_f64" (f64.const nan:0x4000000000000)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_s_f64" (f64.const -nan)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_s_f64" (f64.const -nan:0x4000000000000)) "invalid conversion to integer")
(assert_return (invoke "i64.trunc_f64_s" (f64.const 0.0)) (i64.const 0))
(assert_return (invoke "i64.trunc_f64_s" (f64.const -0.0)) (i64.const 0))
(assert_return (invoke "i64.trunc_f64_s" (f64.const 0x0.0000000000001p-1022)) (i64.const 0))
(assert_return (invoke "i64.trunc_f64_s" (f64.const -0x0.0000000000001p-1022)) (i64.const 0))
(assert_return (invoke "i64.trunc_f64_s" (f64.const 1.0)) (i64.const 1))
(assert_return (invoke "i64.trunc_f64_s" (f64.const 0x1.199999999999ap+0)) (i64.const 1))
(assert_return (invoke "i64.trunc_f64_s" (f64.const 1.5)) (i64.const 1))
(assert_return (invoke "i64.trunc_f64_s" (f64.const -1.0)) (i64.const -1))
(assert_return (invoke "i64.trunc_f64_s" (f64.const -0x1.199999999999ap+0)) (i64.const -1))
(assert_return (invoke "i64.trunc_f64_s" (f64.const -1.5)) (i64.const -1))
(assert_return (invoke "i64.trunc_f64_s" (f64.const -1.9)) (i64.const -1))
(assert_return (invoke "i64.trunc_f64_s" (f64.const -2.0)) (i64.const -2))
(assert_return (invoke "i64.trunc_f64_s" (f64.const 4294967296)) (i64.const 4294967296)) ;; 0x1.00000p+32 -> 1 0000 0000
(assert_return (invoke "i64.trunc_f64_s" (f64.const -4294967296)) (i64.const -4294967296)) ;; -0x1.00000p+32 -> ffff ffff 0000 0000
(assert_return (invoke "i64.trunc_f64_s" (f64.const 9223372036854774784.0)) (i64.const 9223372036854774784))
(assert_return (invoke "i64.trunc_f64_s" (f64.const -9223372036854775808.0)) (i64.const -9223372036854775808))
(assert_trap (invoke "i64.trunc_f64_s" (f64.const 9223372036854775808.0)) "integer overflow")
(assert_trap (invoke "i64.trunc_f64_s" (f64.const -9223372036854777856.0)) "integer overflow")
(assert_trap (invoke "i64.trunc_f64_s" (f64.const inf)) "integer overflow")
(assert_trap (invoke "i64.trunc_f64_s" (f64.const -inf)) "integer overflow")
(assert_trap (invoke "i64.trunc_f64_s" (f64.const nan)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_f64_s" (f64.const nan:0x4000000000000)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_f64_s" (f64.const -nan)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_f64_s" (f64.const -nan:0x4000000000000)) "invalid conversion to integer")
(assert_return (invoke "i64.trunc_u_f64" (f64.const 0.0)) (i64.const 0))
(assert_return (invoke "i64.trunc_u_f64" (f64.const -0.0)) (i64.const 0))
(assert_return (invoke "i64.trunc_u_f64" (f64.const 0x0.0000000000001p-1022)) (i64.const 0))
(assert_return (invoke "i64.trunc_u_f64" (f64.const -0x0.0000000000001p-1022)) (i64.const 0))
(assert_return (invoke "i64.trunc_u_f64" (f64.const 1.0)) (i64.const 1))
(assert_return (invoke "i64.trunc_u_f64" (f64.const 0x1.199999999999ap+0)) (i64.const 1))
(assert_return (invoke "i64.trunc_u_f64" (f64.const 1.5)) (i64.const 1))
(assert_return (invoke "i64.trunc_u_f64" (f64.const 4294967295)) (i64.const 0xffffffff))
(assert_return (invoke "i64.trunc_u_f64" (f64.const 4294967296)) (i64.const 0x100000000))
(assert_return (invoke "i64.trunc_u_f64" (f64.const 18446744073709549568.0)) (i64.const -2048))
(assert_return (invoke "i64.trunc_u_f64" (f64.const -0x1.ccccccccccccdp-1)) (i64.const 0))
(assert_return (invoke "i64.trunc_u_f64" (f64.const -0x1.fffffffffffffp-1)) (i64.const 0))
(assert_return (invoke "i64.trunc_u_f64" (f64.const 1e8)) (i64.const 100000000))
(assert_return (invoke "i64.trunc_u_f64" (f64.const 1e16)) (i64.const 10000000000000000))
(assert_return (invoke "i64.trunc_u_f64" (f64.const 9223372036854775808)) (i64.const -9223372036854775808))
(assert_trap (invoke "i64.trunc_u_f64" (f64.const 18446744073709551616.0)) "integer overflow")
(assert_trap (invoke "i64.trunc_u_f64" (f64.const -1.0)) "integer overflow")
(assert_trap (invoke "i64.trunc_u_f64" (f64.const inf)) "integer overflow")
(assert_trap (invoke "i64.trunc_u_f64" (f64.const -inf)) "integer overflow")
(assert_trap (invoke "i64.trunc_u_f64" (f64.const nan)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_u_f64" (f64.const nan:0x4000000000000)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_u_f64" (f64.const -nan)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_u_f64" (f64.const -nan:0x4000000000000)) "invalid conversion to integer")
(assert_return (invoke "i64.trunc_f64_u" (f64.const 0.0)) (i64.const 0))
(assert_return (invoke "i64.trunc_f64_u" (f64.const -0.0)) (i64.const 0))
(assert_return (invoke "i64.trunc_f64_u" (f64.const 0x0.0000000000001p-1022)) (i64.const 0))
(assert_return (invoke "i64.trunc_f64_u" (f64.const -0x0.0000000000001p-1022)) (i64.const 0))
(assert_return (invoke "i64.trunc_f64_u" (f64.const 1.0)) (i64.const 1))
(assert_return (invoke "i64.trunc_f64_u" (f64.const 0x1.199999999999ap+0)) (i64.const 1))
(assert_return (invoke "i64.trunc_f64_u" (f64.const 1.5)) (i64.const 1))
(assert_return (invoke "i64.trunc_f64_u" (f64.const 4294967295)) (i64.const 0xffffffff))
(assert_return (invoke "i64.trunc_f64_u" (f64.const 4294967296)) (i64.const 0x100000000))
(assert_return (invoke "i64.trunc_f64_u" (f64.const 18446744073709549568.0)) (i64.const -2048))
(assert_return (invoke "i64.trunc_f64_u" (f64.const -0x1.ccccccccccccdp-1)) (i64.const 0))
(assert_return (invoke "i64.trunc_f64_u" (f64.const -0x1.fffffffffffffp-1)) (i64.const 0))
(assert_return (invoke "i64.trunc_f64_u" (f64.const 1e8)) (i64.const 100000000))
(assert_return (invoke "i64.trunc_f64_u" (f64.const 1e16)) (i64.const 10000000000000000))
(assert_return (invoke "i64.trunc_f64_u" (f64.const 9223372036854775808)) (i64.const -9223372036854775808))
(assert_trap (invoke "i64.trunc_f64_u" (f64.const 18446744073709551616.0)) "integer overflow")
(assert_trap (invoke "i64.trunc_f64_u" (f64.const -1.0)) "integer overflow")
(assert_trap (invoke "i64.trunc_f64_u" (f64.const inf)) "integer overflow")
(assert_trap (invoke "i64.trunc_f64_u" (f64.const -inf)) "integer overflow")
(assert_trap (invoke "i64.trunc_f64_u" (f64.const nan)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_f64_u" (f64.const nan:0x4000000000000)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_f64_u" (f64.const -nan)) "invalid conversion to integer")
(assert_trap (invoke "i64.trunc_f64_u" (f64.const -nan:0x4000000000000)) "invalid conversion to integer")
(assert_return (invoke "f32.convert_s_i32" (i32.const 1)) (f32.const 1.0))
(assert_return (invoke "f32.convert_s_i32" (i32.const -1)) (f32.const -1.0))
(assert_return (invoke "f32.convert_s_i32" (i32.const 0)) (f32.const 0.0))
(assert_return (invoke "f32.convert_s_i32" (i32.const 2147483647)) (f32.const 2147483648))
(assert_return (invoke "f32.convert_s_i32" (i32.const -2147483648)) (f32.const -2147483648))
(assert_return (invoke "f32.convert_s_i32" (i32.const 1234567890)) (f32.const 0x1.26580cp+30))
(assert_return (invoke "f32.convert_i32_s" (i32.const 1)) (f32.const 1.0))
(assert_return (invoke "f32.convert_i32_s" (i32.const -1)) (f32.const -1.0))
(assert_return (invoke "f32.convert_i32_s" (i32.const 0)) (f32.const 0.0))
(assert_return (invoke "f32.convert_i32_s" (i32.const 2147483647)) (f32.const 2147483648))
(assert_return (invoke "f32.convert_i32_s" (i32.const -2147483648)) (f32.const -2147483648))
(assert_return (invoke "f32.convert_i32_s" (i32.const 1234567890)) (f32.const 0x1.26580cp+30))
;; Test rounding directions.
(assert_return (invoke "f32.convert_s_i32" (i32.const 16777217)) (f32.const 16777216.0))
(assert_return (invoke "f32.convert_s_i32" (i32.const -16777217)) (f32.const -16777216.0))
(assert_return (invoke "f32.convert_s_i32" (i32.const 16777219)) (f32.const 16777220.0))
(assert_return (invoke "f32.convert_s_i32" (i32.const -16777219)) (f32.const -16777220.0))
(assert_return (invoke "f32.convert_i32_s" (i32.const 16777217)) (f32.const 16777216.0))
(assert_return (invoke "f32.convert_i32_s" (i32.const -16777217)) (f32.const -16777216.0))
(assert_return (invoke "f32.convert_i32_s" (i32.const 16777219)) (f32.const 16777220.0))
(assert_return (invoke "f32.convert_i32_s" (i32.const -16777219)) (f32.const -16777220.0))
(assert_return (invoke "f32.convert_s_i64" (i64.const 1)) (f32.const 1.0))
(assert_return (invoke "f32.convert_s_i64" (i64.const -1)) (f32.const -1.0))
(assert_return (invoke "f32.convert_s_i64" (i64.const 0)) (f32.const 0.0))
(assert_return (invoke "f32.convert_s_i64" (i64.const 9223372036854775807)) (f32.const 9223372036854775807))
(assert_return (invoke "f32.convert_s_i64" (i64.const -9223372036854775808)) (f32.const -9223372036854775808))
(assert_return (invoke "f32.convert_s_i64" (i64.const 314159265358979)) (f32.const 0x1.1db9e8p+48)) ;; PI
(assert_return (invoke "f32.convert_i64_s" (i64.const 1)) (f32.const 1.0))
(assert_return (invoke "f32.convert_i64_s" (i64.const -1)) (f32.const -1.0))
(assert_return (invoke "f32.convert_i64_s" (i64.const 0)) (f32.const 0.0))
(assert_return (invoke "f32.convert_i64_s" (i64.const 9223372036854775807)) (f32.const 9223372036854775807))
(assert_return (invoke "f32.convert_i64_s" (i64.const -9223372036854775808)) (f32.const -9223372036854775808))
(assert_return (invoke "f32.convert_i64_s" (i64.const 314159265358979)) (f32.const 0x1.1db9e8p+48)) ;; PI
;; Test rounding directions.
(assert_return (invoke "f32.convert_s_i64" (i64.const 16777217)) (f32.const 16777216.0))
(assert_return (invoke "f32.convert_s_i64" (i64.const -16777217)) (f32.const -16777216.0))
(assert_return (invoke "f32.convert_s_i64" (i64.const 16777219)) (f32.const 16777220.0))
(assert_return (invoke "f32.convert_s_i64" (i64.const -16777219)) (f32.const -16777220.0))
(assert_return (invoke "f32.convert_i64_s" (i64.const 16777217)) (f32.const 16777216.0))
(assert_return (invoke "f32.convert_i64_s" (i64.const -16777217)) (f32.const -16777216.0))
(assert_return (invoke "f32.convert_i64_s" (i64.const 16777219)) (f32.const 16777220.0))
(assert_return (invoke "f32.convert_i64_s" (i64.const -16777219)) (f32.const -16777220.0))
(assert_return (invoke "f64.convert_s_i32" (i32.const 1)) (f64.const 1.0))
(assert_return (invoke "f64.convert_s_i32" (i32.const -1)) (f64.const -1.0))
(assert_return (invoke "f64.convert_s_i32" (i32.const 0)) (f64.const 0.0))
(assert_return (invoke "f64.convert_s_i32" (i32.const 2147483647)) (f64.const 2147483647))
(assert_return (invoke "f64.convert_s_i32" (i32.const -2147483648)) (f64.const -2147483648))
(assert_return (invoke "f64.convert_s_i32" (i32.const 987654321)) (f64.const 987654321))
(assert_return (invoke "f32.convert_i64_s" (i64.const 0x7fffff4000000001)) (f32.const 0x1.fffffep+62))
(assert_return (invoke "f32.convert_i64_s" (i64.const 0x8000004000000001)) (f32.const -0x1.fffffep+62))
(assert_return (invoke "f32.convert_i64_s" (i64.const 0x0020000020000001)) (f32.const 0x1.000002p+53))
(assert_return (invoke "f32.convert_i64_s" (i64.const 0xffdfffffdfffffff)) (f32.const -0x1.000002p+53))
(assert_return (invoke "f64.convert_s_i64" (i64.const 1)) (f64.const 1.0))
(assert_return (invoke "f64.convert_s_i64" (i64.const -1)) (f64.const -1.0))
(assert_return (invoke "f64.convert_s_i64" (i64.const 0)) (f64.const 0.0))
(assert_return (invoke "f64.convert_s_i64" (i64.const 9223372036854775807)) (f64.const 9223372036854775807))
(assert_return (invoke "f64.convert_s_i64" (i64.const -9223372036854775808)) (f64.const -9223372036854775808))
(assert_return (invoke "f64.convert_s_i64" (i64.const 4669201609102990)) (f64.const 4669201609102990)) ;; Feigenbaum
(assert_return (invoke "f64.convert_i32_s" (i32.const 1)) (f64.const 1.0))
(assert_return (invoke "f64.convert_i32_s" (i32.const -1)) (f64.const -1.0))
(assert_return (invoke "f64.convert_i32_s" (i32.const 0)) (f64.const 0.0))
(assert_return (invoke "f64.convert_i32_s" (i32.const 2147483647)) (f64.const 2147483647))
(assert_return (invoke "f64.convert_i32_s" (i32.const -2147483648)) (f64.const -2147483648))
(assert_return (invoke "f64.convert_i32_s" (i32.const 987654321)) (f64.const 987654321))
(assert_return (invoke "f64.convert_i64_s" (i64.const 1)) (f64.const 1.0))
(assert_return (invoke "f64.convert_i64_s" (i64.const -1)) (f64.const -1.0))
(assert_return (invoke "f64.convert_i64_s" (i64.const 0)) (f64.const 0.0))
(assert_return (invoke "f64.convert_i64_s" (i64.const 9223372036854775807)) (f64.const 9223372036854775807))
(assert_return (invoke "f64.convert_i64_s" (i64.const -9223372036854775808)) (f64.const -9223372036854775808))
(assert_return (invoke "f64.convert_i64_s" (i64.const 4669201609102990)) (f64.const 4669201609102990)) ;; Feigenbaum
;; Test rounding directions.
(assert_return (invoke "f64.convert_s_i64" (i64.const 9007199254740993)) (f64.const 9007199254740992))
(assert_return (invoke "f64.convert_s_i64" (i64.const -9007199254740993)) (f64.const -9007199254740992))
(assert_return (invoke "f64.convert_s_i64" (i64.const 9007199254740995)) (f64.const 9007199254740996))
(assert_return (invoke "f64.convert_s_i64" (i64.const -9007199254740995)) (f64.const -9007199254740996))
(assert_return (invoke "f64.convert_i64_s" (i64.const 9007199254740993)) (f64.const 9007199254740992))
(assert_return (invoke "f64.convert_i64_s" (i64.const -9007199254740993)) (f64.const -9007199254740992))
(assert_return (invoke "f64.convert_i64_s" (i64.const 9007199254740995)) (f64.const 9007199254740996))
(assert_return (invoke "f64.convert_i64_s" (i64.const -9007199254740995)) (f64.const -9007199254740996))
(assert_return (invoke "f32.convert_u_i32" (i32.const 1)) (f32.const 1.0))
(assert_return (invoke "f32.convert_u_i32" (i32.const 0)) (f32.const 0.0))
(assert_return (invoke "f32.convert_u_i32" (i32.const 2147483647)) (f32.const 2147483648))
(assert_return (invoke "f32.convert_u_i32" (i32.const -2147483648)) (f32.const 2147483648))
(assert_return (invoke "f32.convert_u_i32" (i32.const 0x12345678)) (f32.const 0x1.234568p+28))
(assert_return (invoke "f32.convert_u_i32" (i32.const 0xffffffff)) (f32.const 4294967296.0))
(assert_return (invoke "f32.convert_u_i32" (i32.const 0x80000080)) (f32.const 0x1.000000p+31))
(assert_return (invoke "f32.convert_u_i32" (i32.const 0x80000081)) (f32.const 0x1.000002p+31))
(assert_return (invoke "f32.convert_u_i32" (i32.const 0x80000082)) (f32.const 0x1.000002p+31))
(assert_return (invoke "f32.convert_u_i32" (i32.const 0xfffffe80)) (f32.const 0x1.fffffcp+31))
(assert_return (invoke "f32.convert_u_i32" (i32.const 0xfffffe81)) (f32.const 0x1.fffffep+31))
(assert_return (invoke "f32.convert_u_i32" (i32.const 0xfffffe82)) (f32.const 0x1.fffffep+31))
(assert_return (invoke "f32.convert_i32_u" (i32.const 1)) (f32.const 1.0))
(assert_return (invoke "f32.convert_i32_u" (i32.const 0)) (f32.const 0.0))
(assert_return (invoke "f32.convert_i32_u" (i32.const 2147483647)) (f32.const 2147483648))
(assert_return (invoke "f32.convert_i32_u" (i32.const -2147483648)) (f32.const 2147483648))
(assert_return (invoke "f32.convert_i32_u" (i32.const 0x12345678)) (f32.const 0x1.234568p+28))
(assert_return (invoke "f32.convert_i32_u" (i32.const 0xffffffff)) (f32.const 4294967296.0))
(assert_return (invoke "f32.convert_i32_u" (i32.const 0x80000080)) (f32.const 0x1.000000p+31))
(assert_return (invoke "f32.convert_i32_u" (i32.const 0x80000081)) (f32.const 0x1.000002p+31))
(assert_return (invoke "f32.convert_i32_u" (i32.const 0x80000082)) (f32.const 0x1.000002p+31))
(assert_return (invoke "f32.convert_i32_u" (i32.const 0xfffffe80)) (f32.const 0x1.fffffcp+31))
(assert_return (invoke "f32.convert_i32_u" (i32.const 0xfffffe81)) (f32.const 0x1.fffffep+31))
(assert_return (invoke "f32.convert_i32_u" (i32.const 0xfffffe82)) (f32.const 0x1.fffffep+31))
;; Test rounding directions.
(assert_return (invoke "f32.convert_u_i32" (i32.const 16777217)) (f32.const 16777216.0))
(assert_return (invoke "f32.convert_u_i32" (i32.const 16777219)) (f32.const 16777220.0))
(assert_return (invoke "f32.convert_i32_u" (i32.const 16777217)) (f32.const 16777216.0))
(assert_return (invoke "f32.convert_i32_u" (i32.const 16777219)) (f32.const 16777220.0))
(assert_return (invoke "f32.convert_u_i64" (i64.const 1)) (f32.const 1.0))
(assert_return (invoke "f32.convert_u_i64" (i64.const 0)) (f32.const 0.0))
(assert_return (invoke "f32.convert_u_i64" (i64.const 9223372036854775807)) (f32.const 9223372036854775807))
(assert_return (invoke "f32.convert_u_i64" (i64.const -9223372036854775808)) (f32.const 9223372036854775808))
(assert_return (invoke "f32.convert_u_i64" (i64.const 0xffffffffffffffff)) (f32.const 18446744073709551616.0))
(assert_return (invoke "f32.convert_i64_u" (i64.const 1)) (f32.const 1.0))
(assert_return (invoke "f32.convert_i64_u" (i64.const 0)) (f32.const 0.0))
(assert_return (invoke "f32.convert_i64_u" (i64.const 9223372036854775807)) (f32.const 9223372036854775807))
(assert_return (invoke "f32.convert_i64_u" (i64.const -9223372036854775808)) (f32.const 9223372036854775808))
(assert_return (invoke "f32.convert_i64_u" (i64.const 0xffffffffffffffff)) (f32.const 18446744073709551616.0))
;; Test rounding directions.
(assert_return (invoke "f32.convert_u_i64" (i64.const 16777217)) (f32.const 16777216.0))
(assert_return (invoke "f32.convert_u_i64" (i64.const 16777219)) (f32.const 16777220.0))
(assert_return (invoke "f32.convert_i64_u" (i64.const 16777217)) (f32.const 16777216.0))
(assert_return (invoke "f32.convert_i64_u" (i64.const 16777219)) (f32.const 16777220.0))
(assert_return (invoke "f64.convert_u_i32" (i32.const 1)) (f64.const 1.0))
(assert_return (invoke "f64.convert_u_i32" (i32.const 0)) (f64.const 0.0))
(assert_return (invoke "f64.convert_u_i32" (i32.const 2147483647)) (f64.const 2147483647))
(assert_return (invoke "f64.convert_u_i32" (i32.const -2147483648)) (f64.const 2147483648))
(assert_return (invoke "f64.convert_u_i32" (i32.const 0xffffffff)) (f64.const 4294967295.0))
(assert_return (invoke "f32.convert_i64_u" (i64.const 0x0020000020000001)) (f32.const 0x1.000002p+53))
(assert_return (invoke "f32.convert_i64_u" (i64.const 0x7fffffbfffffffff)) (f32.const 0x1.fffffep+62))
(assert_return (invoke "f32.convert_i64_u" (i64.const 0x8000008000000001)) (f32.const 0x1.000002p+63))
(assert_return (invoke "f32.convert_i64_u" (i64.const 0xfffffe8000000001)) (f32.const 0x1.fffffep+63))
(assert_return (invoke "f64.convert_u_i64" (i64.const 1)) (f64.const 1.0))
(assert_return (invoke "f64.convert_u_i64" (i64.const 0)) (f64.const 0.0))
(assert_return (invoke "f64.convert_u_i64" (i64.const 9223372036854775807)) (f64.const 9223372036854775807))
(assert_return (invoke "f64.convert_u_i64" (i64.const -9223372036854775808)) (f64.const 9223372036854775808))
(assert_return (invoke "f64.convert_u_i64" (i64.const 0xffffffffffffffff)) (f64.const 18446744073709551616.0))
(assert_return (invoke "f64.convert_u_i64" (i64.const 0x8000000000000400)) (f64.const 0x1.0000000000000p+63))
(assert_return (invoke "f64.convert_u_i64" (i64.const 0x8000000000000401)) (f64.const 0x1.0000000000001p+63))
(assert_return (invoke "f64.convert_u_i64" (i64.const 0x8000000000000402)) (f64.const 0x1.0000000000001p+63))
(assert_return (invoke "f64.convert_u_i64" (i64.const 0xfffffffffffff400)) (f64.const 0x1.ffffffffffffep+63))
(assert_return (invoke "f64.convert_u_i64" (i64.const 0xfffffffffffff401)) (f64.const 0x1.fffffffffffffp+63))
(assert_return (invoke "f64.convert_u_i64" (i64.const 0xfffffffffffff402)) (f64.const 0x1.fffffffffffffp+63))
(assert_return (invoke "f64.convert_i32_u" (i32.const 1)) (f64.const 1.0))
(assert_return (invoke "f64.convert_i32_u" (i32.const 0)) (f64.const 0.0))
(assert_return (invoke "f64.convert_i32_u" (i32.const 2147483647)) (f64.const 2147483647))
(assert_return (invoke "f64.convert_i32_u" (i32.const -2147483648)) (f64.const 2147483648))
(assert_return (invoke "f64.convert_i32_u" (i32.const 0xffffffff)) (f64.const 4294967295.0))
(assert_return (invoke "f64.convert_i64_u" (i64.const 1)) (f64.const 1.0))
(assert_return (invoke "f64.convert_i64_u" (i64.const 0)) (f64.const 0.0))
(assert_return (invoke "f64.convert_i64_u" (i64.const 9223372036854775807)) (f64.const 9223372036854775807))
(assert_return (invoke "f64.convert_i64_u" (i64.const -9223372036854775808)) (f64.const 9223372036854775808))
(assert_return (invoke "f64.convert_i64_u" (i64.const 0xffffffffffffffff)) (f64.const 18446744073709551616.0))
(assert_return (invoke "f64.convert_i64_u" (i64.const 0x8000000000000400)) (f64.const 0x1.0000000000000p+63))
(assert_return (invoke "f64.convert_i64_u" (i64.const 0x8000000000000401)) (f64.const 0x1.0000000000001p+63))
(assert_return (invoke "f64.convert_i64_u" (i64.const 0x8000000000000402)) (f64.const 0x1.0000000000001p+63))
(assert_return (invoke "f64.convert_i64_u" (i64.const 0xfffffffffffff400)) (f64.const 0x1.ffffffffffffep+63))
(assert_return (invoke "f64.convert_i64_u" (i64.const 0xfffffffffffff401)) (f64.const 0x1.fffffffffffffp+63))
(assert_return (invoke "f64.convert_i64_u" (i64.const 0xfffffffffffff402)) (f64.const 0x1.fffffffffffffp+63))
;; Test rounding directions.
(assert_return (invoke "f64.convert_u_i64" (i64.const 9007199254740993)) (f64.const 9007199254740992))
(assert_return (invoke "f64.convert_u_i64" (i64.const 9007199254740995)) (f64.const 9007199254740996))
(assert_return (invoke "f64.convert_i64_u" (i64.const 9007199254740993)) (f64.const 9007199254740992))
(assert_return (invoke "f64.convert_i64_u" (i64.const 9007199254740995)) (f64.const 9007199254740996))
(assert_return (invoke "f64.promote_f32" (f32.const 0.0)) (f64.const 0.0))
(assert_return (invoke "f64.promote_f32" (f32.const -0.0)) (f64.const -0.0))
@ -459,3 +469,31 @@
(assert_return (invoke "i64.reinterpret_f64" (f64.const -nan)) (i64.const 0xfff8000000000000))
(assert_return (invoke "i64.reinterpret_f64" (f64.const nan:0x4000000000000)) (i64.const 0x7ff4000000000000))
(assert_return (invoke "i64.reinterpret_f64" (f64.const -nan:0x4000000000000)) (i64.const 0xfff4000000000000))
;; Type check
(assert_invalid (module (func (result i32) (i32.wrap_i64 (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.trunc_f32_s (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.trunc_f32_u (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.trunc_f64_s (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.trunc_f64_u (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.reinterpret_f32 (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.extend_i32_s (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.extend_i32_u (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.trunc_f32_s (i32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.trunc_f32_u (i32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.trunc_f64_s (i32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.trunc_f64_u (i32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.reinterpret_f64 (i32.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.convert_i32_s (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.convert_i32_u (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.convert_i64_s (i32.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.convert_i64_u (i32.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.demote_f64 (i32.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.reinterpret_i32 (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.convert_i32_s (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.convert_i32_u (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.convert_i64_s (i32.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.convert_i64_u (i32.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.promote_f32 (i32.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.reinterpret_i64 (i32.const 0)))) "type mismatch")

View File

@ -50,28 +50,28 @@
(module
(global (import "spectest" "global_i32") i32)
(memory 1)
(data (get_global 0) "a")
(data (global.get 0) "a")
)
(module
(global (import "spectest" "global_i32") i32)
(import "spectest" "memory" (memory 1))
(data (get_global 0) "a")
(data (global.get 0) "a")
)
(module
(global $g (import "spectest" "global_i32") i32)
(memory 1)
(data (get_global $g) "a")
(data (global.get $g) "a")
)
(module
(global $g (import "spectest" "global_i32") i32)
(import "spectest" "memory" (memory 1))
(data (get_global $g) "a")
(data (global.get $g) "a")
)
;; Use of internal globals in constant expressions is not allowed in MVP.
;; (module (memory 1) (data (get_global 0) "a") (global i32 (i32.const 0)))
;; (module (memory 1) (data (get_global $g) "a") (global $g i32 (i32.const 0)))
;; (module (memory 1) (data (global.get 0) "a") (global i32 (i32.const 0)))
;; (module (memory 1) (data (global.get $g) "a") (global $g i32 (i32.const 0)))
;; Corner cases
@ -137,13 +137,13 @@
(module
(global (import "spectest" "global_i32") i32)
(import "spectest" "memory" (memory 0))
(data (get_global 0) "a")
(data (global.get 0) "a")
)
(module
(global (import "spectest" "global_i32") i32)
(import "spectest" "memory" (memory 0 3))
(data (get_global 0) "a")
(data (global.get 0) "a")
)
(module
@ -211,7 +211,7 @@
(module
(global (import "spectest" "global_i32") i32)
(memory 0)
(data (get_global 0) "a")
(data (global.get 0) "a")
)
"data segment does not fit"
)
@ -330,6 +330,6 @@
;; Use of internal globals in constant expressions is not allowed in MVP.
;; (assert_invalid
;; (module (memory 1) (data (get_global $g)) (global $g (mut i32) (i32.const 0)))
;; (module (memory 1) (data (global.get $g)) (global $g (mut i32) (i32.const 0)))
;; "constant expression required"
;; )

View File

@ -2,7 +2,7 @@
;; Syntax
(module
(table $t 10 anyfunc)
(table $t 10 funcref)
(func $f)
(elem (i32.const 0))
(elem (i32.const 0) $f $f)
@ -21,18 +21,18 @@
;; Basic use
(module
(table 10 anyfunc)
(table 10 funcref)
(func $f)
(elem (i32.const 0) $f)
)
(module
(import "spectest" "table" (table 10 anyfunc))
(import "spectest" "table" (table 10 funcref))
(func $f)
(elem (i32.const 0) $f)
)
(module
(table 10 anyfunc)
(table 10 funcref)
(func $f)
(elem (i32.const 0) $f)
(elem (i32.const 3) $f)
@ -41,7 +41,7 @@
(elem (i32.const 3) $f)
)
(module
(import "spectest" "table" (table 10 anyfunc))
(import "spectest" "table" (table 10 funcref))
(func $f)
(elem (i32.const 9) $f)
(elem (i32.const 3) $f)
@ -52,21 +52,21 @@
(module
(global (import "spectest" "global_i32") i32)
(table 1000 anyfunc)
(table 1000 funcref)
(func $f)
(elem (i32.const 0) $f)
(elem (global.get 0) $f)
)
(module
(global $g (import "spectest" "global_i32") i32)
(table 1000 anyfunc)
(table 1000 funcref)
(func $f)
(elem (get_global $g) $f)
(elem (global.get $g) $f)
)
(module
(type $out-i32 (func (result i32)))
(table 10 anyfunc)
(table 10 funcref)
(elem (i32.const 7) $const-i32-a)
(elem (i32.const 9) $const-i32-b)
(func $const-i32-a (type $out-i32) (i32.const 65))
@ -84,55 +84,55 @@
;; Corner cases
(module
(table 10 anyfunc)
(table 10 funcref)
(func $f)
(elem (i32.const 9) $f)
)
(module
(import "spectest" "table" (table 10 anyfunc))
(import "spectest" "table" (table 10 funcref))
(func $f)
(elem (i32.const 9) $f)
)
(module
(table 0 anyfunc)
(table 0 funcref)
(elem (i32.const 0))
)
(module
(import "spectest" "table" (table 0 anyfunc))
(import "spectest" "table" (table 0 funcref))
(elem (i32.const 0))
)
(module
(table 0 0 anyfunc)
(table 0 0 funcref)
(elem (i32.const 0))
)
(module
(table 20 anyfunc)
(table 20 funcref)
(elem (i32.const 20))
)
(module
(import "spectest" "table" (table 0 anyfunc))
(import "spectest" "table" (table 0 funcref))
(func $f)
(elem (i32.const 0) $f)
)
(module
(import "spectest" "table" (table 0 100 anyfunc))
(import "spectest" "table" (table 0 100 funcref))
(func $f)
(elem (i32.const 0) $f)
)
(module
(import "spectest" "table" (table 0 anyfunc))
(import "spectest" "table" (table 0 funcref))
(func $f)
(elem (i32.const 1) $f)
)
(module
(import "spectest" "table" (table 0 30 anyfunc))
(import "spectest" "table" (table 0 30 funcref))
(func $f)
(elem (i32.const 1) $f)
)
@ -141,7 +141,7 @@
(assert_unlinkable
(module
(table 0 anyfunc)
(table 0 funcref)
(func $f)
(elem (i32.const 0) $f)
)
@ -150,7 +150,7 @@
(assert_unlinkable
(module
(table 0 0 anyfunc)
(table 0 0 funcref)
(func $f)
(elem (i32.const 0) $f)
)
@ -159,7 +159,7 @@
(assert_unlinkable
(module
(table 0 1 anyfunc)
(table 0 1 funcref)
(func $f)
(elem (i32.const 0) $f)
)
@ -168,7 +168,7 @@
(assert_unlinkable
(module
(table 0 anyfunc)
(table 0 funcref)
(elem (i32.const 1))
)
"elements segment does not fit"
@ -176,7 +176,7 @@
(assert_unlinkable
(module
(table 10 anyfunc)
(table 10 funcref)
(func $f)
(elem (i32.const 10) $f)
)
@ -184,7 +184,7 @@
)
(assert_unlinkable
(module
(import "spectest" "table" (table 10 anyfunc))
(import "spectest" "table" (table 10 funcref))
(func $f)
(elem (i32.const 10) $f)
)
@ -193,7 +193,7 @@
(assert_unlinkable
(module
(table 10 20 anyfunc)
(table 10 20 funcref)
(func $f)
(elem (i32.const 10) $f)
)
@ -201,7 +201,7 @@
)
(assert_unlinkable
(module
(import "spectest" "table" (table 10 anyfunc))
(import "spectest" "table" (table 10 funcref))
(func $f)
(elem (i32.const 10) $f)
)
@ -210,7 +210,7 @@
(assert_unlinkable
(module
(table 10 anyfunc)
(table 10 funcref)
(func $f)
(elem (i32.const -1) $f)
)
@ -218,7 +218,7 @@
)
(assert_unlinkable
(module
(import "spectest" "table" (table 10 anyfunc))
(import "spectest" "table" (table 10 funcref))
(func $f)
(elem (i32.const -1) $f)
)
@ -227,7 +227,7 @@
(assert_unlinkable
(module
(table 10 anyfunc)
(table 10 funcref)
(func $f)
(elem (i32.const -10) $f)
)
@ -235,7 +235,7 @@
)
(assert_unlinkable
(module
(import "spectest" "table" (table 10 anyfunc))
(import "spectest" "table" (table 10 funcref))
(func $f)
(elem (i32.const -10) $f)
)
@ -256,7 +256,7 @@
(assert_invalid
(module
(table 1 anyfunc)
(table 1 funcref)
(elem (i64.const 0))
)
"type mismatch"
@ -264,7 +264,7 @@
(assert_invalid
(module
(table 1 anyfunc)
(table 1 funcref)
(elem (i32.ctz (i32.const 0)))
)
"constant expression required"
@ -272,7 +272,7 @@
(assert_invalid
(module
(table 1 anyfunc)
(table 1 funcref)
(elem (nop))
)
"constant expression required"
@ -280,7 +280,7 @@
(assert_invalid
(module
(table 1 anyfunc)
(table 1 funcref)
(elem (offset (nop) (i32.const 0)))
)
"constant expression required"
@ -288,7 +288,7 @@
(assert_invalid
(module
(table 1 anyfunc)
(table 1 funcref)
(elem (offset (i32.const 0) (nop)))
)
"constant expression required"
@ -296,7 +296,7 @@
;; Use of internal globals in constant expressions is not allowed in MVP.
;; (assert_invalid
;; (module (memory 1) (data (get_global $g)) (global $g (mut i32) (i32.const 0)))
;; (module (memory 1) (data (global.get $g)) (global $g (mut i32) (i32.const 0)))
;; "constant expression required"
;; )
@ -304,7 +304,7 @@
(module
(type $out-i32 (func (result i32)))
(table 10 anyfunc)
(table 10 funcref)
(elem (i32.const 9) $const-i32-a)
(elem (i32.const 9) $const-i32-b)
(func $const-i32-a (type $out-i32) (i32.const 65))
@ -317,7 +317,7 @@
(module
(type $out-i32 (func (result i32)))
(import "spectest" "table" (table 10 anyfunc))
(import "spectest" "table" (table 10 funcref))
(elem (i32.const 9) $const-i32-a)
(elem (i32.const 9) $const-i32-b)
(func $const-i32-a (type $out-i32) (i32.const 65))
@ -332,7 +332,7 @@
(module $module1
(type $out-i32 (func (result i32)))
(table (export "shared-table") 10 anyfunc)
(table (export "shared-table") 10 funcref)
(elem (i32.const 8) $const-i32-a)
(elem (i32.const 9) $const-i32-b)
(func $const-i32-a (type $out-i32) (i32.const 65))
@ -354,32 +354,28 @@
(assert_return (invoke $module1 "call-8") (i32.const 65))
(assert_return (invoke $module1 "call-9") (i32.const 66))
;; SKIP_SHARED_TABLE
;; (module $module2
;; (type $out-i32 (func (result i32)))
;; (import "module1" "shared-table" (table 10 anyfunc))
;; (elem (i32.const 7) $const-i32-c)
;; (elem (i32.const 8) $const-i32-d)
;; (func $const-i32-c (type $out-i32) (i32.const 67))
;; (func $const-i32-d (type $out-i32) (i32.const 68))
;; )
(module $module2
(type $out-i32 (func (result i32)))
(import "module1" "shared-table" (table 10 funcref))
(elem (i32.const 7) $const-i32-c)
(elem (i32.const 8) $const-i32-d)
(func $const-i32-c (type $out-i32) (i32.const 67))
(func $const-i32-d (type $out-i32) (i32.const 68))
)
;; SKIP_SHARED_TABLE
;; (assert_return (invoke $module1 "call-7") (i32.const 67))
;; (assert_return (invoke $module1 "call-8") (i32.const 68))
;; (assert_return (invoke $module1 "call-9") (i32.const 66))
(assert_return (invoke $module1 "call-7") (i32.const 67))
(assert_return (invoke $module1 "call-8") (i32.const 68))
(assert_return (invoke $module1 "call-9") (i32.const 66))
;; SKIP_SHARED_TABLE
;; (module $module3
;; (type $out-i32 (func (result i32)))
;; (import "module1" "shared-table" (table 10 anyfunc))
;; (elem (i32.const 8) $const-i32-e)
;; (elem (i32.const 9) $const-i32-f)
;; (func $const-i32-e (type $out-i32) (i32.const 69))
;; (func $const-i32-f (type $out-i32) (i32.const 70))
;; )
(module $module3
(type $out-i32 (func (result i32)))
(import "module1" "shared-table" (table 10 funcref))
(elem (i32.const 8) $const-i32-e)
(elem (i32.const 9) $const-i32-f)
(func $const-i32-e (type $out-i32) (i32.const 69))
(func $const-i32-f (type $out-i32) (i32.const 70))
)
;; SKIP_SHARED_TABLE
;; (assert_return (invoke $module1 "call-7") (i32.const 67))
;; (assert_return (invoke $module1 "call-8") (i32.const 69))
;; (assert_return (invoke $module1 "call-9") (i32.const 70))
(assert_return (invoke $module1 "call-7") (i32.const 67))
(assert_return (invoke $module1 "call-8") (i32.const 69))
(assert_return (invoke $module1 "call-9") (i32.const 70))

View File

@ -3,130 +3,130 @@
;; Stores an i16 value in little-endian-format
(func $i16_store_little (param $address i32) (param $value i32)
(i32.store8 (get_local $address) (get_local $value))
(i32.store8 (i32.add (get_local $address) (i32.const 1)) (i32.shr_u (get_local $value) (i32.const 8)))
(i32.store8 (local.get $address) (local.get $value))
(i32.store8 (i32.add (local.get $address) (i32.const 1)) (i32.shr_u (local.get $value) (i32.const 8)))
)
;; Stores an i32 value in little-endian format
(func $i32_store_little (param $address i32) (param $value i32)
(call $i16_store_little (get_local $address) (get_local $value))
(call $i16_store_little (i32.add (get_local $address) (i32.const 2)) (i32.shr_u (get_local $value) (i32.const 16)))
(call $i16_store_little (local.get $address) (local.get $value))
(call $i16_store_little (i32.add (local.get $address) (i32.const 2)) (i32.shr_u (local.get $value) (i32.const 16)))
)
;; Stores an i64 value in little-endian format
(func $i64_store_little (param $address i32) (param $value i64)
(call $i32_store_little (get_local $address) (i32.wrap/i64 (get_local $value)))
(call $i32_store_little (i32.add (get_local $address) (i32.const 4)) (i32.wrap/i64 (i64.shr_u (get_local $value) (i64.const 32))))
(call $i32_store_little (local.get $address) (i32.wrap_i64 (local.get $value)))
(call $i32_store_little (i32.add (local.get $address) (i32.const 4)) (i32.wrap_i64 (i64.shr_u (local.get $value) (i64.const 32))))
)
;; Loads an i16 value in little-endian format
(func $i16_load_little (param $address i32) (result i32)
(i32.or
(i32.load8_u (get_local $address))
(i32.shl (i32.load8_u (i32.add (get_local $address) (i32.const 1))) (i32.const 8))
(i32.load8_u (local.get $address))
(i32.shl (i32.load8_u (i32.add (local.get $address) (i32.const 1))) (i32.const 8))
)
)
;; Loads an i32 value in little-endian format
(func $i32_load_little (param $address i32) (result i32)
(i32.or
(call $i16_load_little (get_local $address))
(i32.shl (call $i16_load_little (i32.add (get_local $address) (i32.const 2))) (i32.const 16))
(call $i16_load_little (local.get $address))
(i32.shl (call $i16_load_little (i32.add (local.get $address) (i32.const 2))) (i32.const 16))
)
)
;; Loads an i64 value in little-endian format
(func $i64_load_little (param $address i32) (result i64)
(i64.or
(i64.extend_u/i32 (call $i32_load_little (get_local $address)))
(i64.shl (i64.extend_u/i32 (call $i32_load_little (i32.add (get_local $address) (i32.const 4)))) (i64.const 32))
(i64.extend_i32_u (call $i32_load_little (local.get $address)))
(i64.shl (i64.extend_i32_u (call $i32_load_little (i32.add (local.get $address) (i32.const 4)))) (i64.const 32))
)
)
(func (export "i32_load16_s") (param $value i32) (result i32)
(call $i16_store_little (i32.const 0) (get_local $value))
(call $i16_store_little (i32.const 0) (local.get $value))
(i32.load16_s (i32.const 0))
)
(func (export "i32_load16_u") (param $value i32) (result i32)
(call $i16_store_little (i32.const 0) (get_local $value))
(call $i16_store_little (i32.const 0) (local.get $value))
(i32.load16_u (i32.const 0))
)
(func (export "i32_load") (param $value i32) (result i32)
(call $i32_store_little (i32.const 0) (get_local $value))
(call $i32_store_little (i32.const 0) (local.get $value))
(i32.load (i32.const 0))
)
(func (export "i64_load16_s") (param $value i64) (result i64)
(call $i16_store_little (i32.const 0) (i32.wrap/i64 (get_local $value)))
(call $i16_store_little (i32.const 0) (i32.wrap_i64 (local.get $value)))
(i64.load16_s (i32.const 0))
)
(func (export "i64_load16_u") (param $value i64) (result i64)
(call $i16_store_little (i32.const 0) (i32.wrap/i64 (get_local $value)))
(call $i16_store_little (i32.const 0) (i32.wrap_i64 (local.get $value)))
(i64.load16_u (i32.const 0))
)
(func (export "i64_load32_s") (param $value i64) (result i64)
(call $i32_store_little (i32.const 0) (i32.wrap/i64 (get_local $value)))
(call $i32_store_little (i32.const 0) (i32.wrap_i64 (local.get $value)))
(i64.load32_s (i32.const 0))
)
(func (export "i64_load32_u") (param $value i64) (result i64)
(call $i32_store_little (i32.const 0) (i32.wrap/i64 (get_local $value)))
(call $i32_store_little (i32.const 0) (i32.wrap_i64 (local.get $value)))
(i64.load32_u (i32.const 0))
)
(func (export "i64_load") (param $value i64) (result i64)
(call $i64_store_little (i32.const 0) (get_local $value))
(call $i64_store_little (i32.const 0) (local.get $value))
(i64.load (i32.const 0))
)
(func (export "f32_load") (param $value f32) (result f32)
(call $i32_store_little (i32.const 0) (i32.reinterpret/f32 (get_local $value)))
(call $i32_store_little (i32.const 0) (i32.reinterpret_f32 (local.get $value)))
(f32.load (i32.const 0))
)
(func (export "f64_load") (param $value f64) (result f64)
(call $i64_store_little (i32.const 0) (i64.reinterpret/f64 (get_local $value)))
(call $i64_store_little (i32.const 0) (i64.reinterpret_f64 (local.get $value)))
(f64.load (i32.const 0))
)
(func (export "i32_store16") (param $value i32) (result i32)
(i32.store16 (i32.const 0) (get_local $value))
(i32.store16 (i32.const 0) (local.get $value))
(call $i16_load_little (i32.const 0))
)
(func (export "i32_store") (param $value i32) (result i32)
(i32.store (i32.const 0) (get_local $value))
(i32.store (i32.const 0) (local.get $value))
(call $i32_load_little (i32.const 0))
)
(func (export "i64_store16") (param $value i64) (result i64)
(i64.store16 (i32.const 0) (get_local $value))
(i64.extend_u/i32 (call $i16_load_little (i32.const 0)))
(i64.store16 (i32.const 0) (local.get $value))
(i64.extend_i32_u (call $i16_load_little (i32.const 0)))
)
(func (export "i64_store32") (param $value i64) (result i64)
(i64.store32 (i32.const 0) (get_local $value))
(i64.extend_u/i32 (call $i32_load_little (i32.const 0)))
(i64.store32 (i32.const 0) (local.get $value))
(i64.extend_i32_u (call $i32_load_little (i32.const 0)))
)
(func (export "i64_store") (param $value i64) (result i64)
(i64.store (i32.const 0) (get_local $value))
(i64.store (i32.const 0) (local.get $value))
(call $i64_load_little (i32.const 0))
)
(func (export "f32_store") (param $value f32) (result f32)
(f32.store (i32.const 0) (get_local $value))
(f32.reinterpret/i32 (call $i32_load_little (i32.const 0)))
(f32.store (i32.const 0) (local.get $value))
(f32.reinterpret_i32 (call $i32_load_little (i32.const 0)))
)
(func (export "f64_store") (param $value f64) (result f64)
(f64.store (i32.const 0) (get_local $value))
(f64.reinterpret/i64 (call $i64_load_little (i32.const 0)))
(f64.store (i32.const 0) (local.get $value))
(f64.reinterpret_i64 (call $i64_load_little (i32.const 0)))
)
)

View File

@ -16,14 +16,14 @@
(module $Func
(export "e" (func $f))
(func $f (param $n i32) (result i32)
(return (i32.add (get_local $n) (i32.const 1)))
(return (i32.add (local.get $n) (i32.const 1)))
)
)
(assert_return (invoke "e" (i32.const 42)) (i32.const 43))
(assert_return (invoke $Func "e" (i32.const 42)) (i32.const 43))
;; (module)
;; (module $Other1)
;; (assert_return (invoke $Func "e" (i32.const 42)) (i32.const 43))
(module)
(module $Other1)
(assert_return (invoke $Func "e" (i32.const 42)) (i32.const 43))
(assert_invalid
(module (func) (export "a" (func 1)))
@ -42,7 +42,7 @@
"duplicate export name"
)
(assert_invalid
(module (func) (table 0 anyfunc) (export "a" (func 0)) (export "a" (table 0)))
(module (func) (table 0 funcref) (export "a" (func 0)) (export "a" (table 0)))
"duplicate export name"
)
(assert_invalid
@ -70,9 +70,9 @@
)
(assert_return (get "e") (i32.const 42))
(assert_return (get $Global "e") (i32.const 42))
;; (module)
;; (module $Other2)
;; (assert_return (get $Global "e") (i32.const 42))
(module)
(module $Other2)
(assert_return (get $Global "e") (i32.const 42))
(assert_invalid
(module (global i32 (i32.const 0)) (export "a" (global 1)))
@ -91,7 +91,7 @@
"duplicate export name"
)
(assert_invalid
(module (global i32 (i32.const 0)) (table 0 anyfunc) (export "a" (global 0)) (export "a" (table 0)))
(module (global i32 (i32.const 0)) (table 0 funcref) (export "a" (global 0)) (export "a" (table 0)))
"duplicate export name"
)
(assert_invalid
@ -102,49 +102,49 @@
;; Tables
(module (table 0 anyfunc) (export "a" (table 0)))
(module (table 0 anyfunc) (export "a" (table 0)) (export "b" (table 0)))
(module (table 0 funcref) (export "a" (table 0)))
(module (table 0 funcref) (export "a" (table 0)) (export "b" (table 0)))
;; No multiple tables yet.
;; (module (table 0 anyfunc) (table 0 anyfunc) (export "a" (table 0)) (export "b" (table 1)))
;; (module (table 0 funcref) (table 0 funcref) (export "a" (table 0)) (export "b" (table 1)))
(module (table (export "a") 0 anyfunc))
(module (table (export "a") 0 1 anyfunc))
(module (table 0 anyfunc) (export "a" (table 0)))
(module (table 0 1 anyfunc) (export "a" (table 0)))
(module (table $a (export "a") 0 anyfunc))
(module (table $a (export "a") 0 1 anyfunc))
(module (table $a 0 anyfunc) (export "a" (table $a)))
(module (table $a 0 1 anyfunc) (export "a" (table $a)))
(module (export "a" (table 0)) (table 0 anyfunc))
(module (export "a" (table 0)) (table 0 1 anyfunc))
(module (export "a" (table $a)) (table $a 0 anyfunc))
(module (export "a" (table $a)) (table $a 0 1 anyfunc))
(module (table (export "a") 0 funcref))
(module (table (export "a") 0 1 funcref))
(module (table 0 funcref) (export "a" (table 0)))
(module (table 0 1 funcref) (export "a" (table 0)))
(module (table $a (export "a") 0 funcref))
(module (table $a (export "a") 0 1 funcref))
(module (table $a 0 funcref) (export "a" (table $a)))
(module (table $a 0 1 funcref) (export "a" (table $a)))
(module (export "a" (table 0)) (table 0 funcref))
(module (export "a" (table 0)) (table 0 1 funcref))
(module (export "a" (table $a)) (table $a 0 funcref))
(module (export "a" (table $a)) (table $a 0 1 funcref))
(; TODO: access table ;)
(assert_invalid
(module (table 0 anyfunc) (export "a" (table 1)))
(module (table 0 funcref) (export "a" (table 1)))
"unknown table"
)
(assert_invalid
(module (table 0 anyfunc) (export "a" (table 0)) (export "a" (table 0)))
(module (table 0 funcref) (export "a" (table 0)) (export "a" (table 0)))
"duplicate export name"
)
;; No multiple tables yet.
;; (assert_invalid
;; (module (table 0 anyfunc) (table 0 anyfunc) (export "a" (table 0)) (export "a" (table 1)))
;; (module (table 0 funcref) (table 0 funcref) (export "a" (table 0)) (export "a" (table 1)))
;; "duplicate export name"
;; )
(assert_invalid
(module (table 0 anyfunc) (func) (export "a" (table 0)) (export "a" (func 0)))
(module (table 0 funcref) (func) (export "a" (table 0)) (export "a" (func 0)))
"duplicate export name"
)
(assert_invalid
(module (table 0 anyfunc) (global i32 (i32.const 0)) (export "a" (table 0)) (export "a" (global 0)))
(module (table 0 funcref) (global i32 (i32.const 0)) (export "a" (table 0)) (export "a" (global 0)))
"duplicate export name"
)
(assert_invalid
(module (table 0 anyfunc) (memory 0) (export "a" (table 0)) (export "a" (memory 0)))
(module (table 0 funcref) (memory 0) (export "a" (table 0)) (export "a" (memory 0)))
"duplicate export name"
)
@ -193,6 +193,6 @@
"duplicate export name"
)
(assert_invalid
(module (memory 0) (table 0 anyfunc) (export "a" (memory 0)) (export "a" (table 0)))
(module (memory 0) (table 0 funcref) (export "a" (memory 0)) (export "a" (table 0)))
"duplicate export name"
)

View File

@ -3,17 +3,17 @@
;; f32_bitwise.wast and f32_cmp.wast).
(module
(func (export "add") (param $x f32) (param $y f32) (result f32) (f32.add (get_local $x) (get_local $y)))
(func (export "sub") (param $x f32) (param $y f32) (result f32) (f32.sub (get_local $x) (get_local $y)))
(func (export "mul") (param $x f32) (param $y f32) (result f32) (f32.mul (get_local $x) (get_local $y)))
(func (export "div") (param $x f32) (param $y f32) (result f32) (f32.div (get_local $x) (get_local $y)))
(func (export "sqrt") (param $x f32) (result f32) (f32.sqrt (get_local $x)))
(func (export "min") (param $x f32) (param $y f32) (result f32) (f32.min (get_local $x) (get_local $y)))
(func (export "max") (param $x f32) (param $y f32) (result f32) (f32.max (get_local $x) (get_local $y)))
(func (export "ceil") (param $x f32) (result f32) (f32.ceil (get_local $x)))
(func (export "floor") (param $x f32) (result f32) (f32.floor (get_local $x)))
(func (export "trunc") (param $x f32) (result f32) (f32.trunc (get_local $x)))
(func (export "nearest") (param $x f32) (result f32) (f32.nearest (get_local $x)))
(func (export "add") (param $x f32) (param $y f32) (result f32) (f32.add (local.get $x) (local.get $y)))
(func (export "sub") (param $x f32) (param $y f32) (result f32) (f32.sub (local.get $x) (local.get $y)))
(func (export "mul") (param $x f32) (param $y f32) (result f32) (f32.mul (local.get $x) (local.get $y)))
(func (export "div") (param $x f32) (param $y f32) (result f32) (f32.div (local.get $x) (local.get $y)))
(func (export "sqrt") (param $x f32) (result f32) (f32.sqrt (local.get $x)))
(func (export "min") (param $x f32) (param $y f32) (result f32) (f32.min (local.get $x) (local.get $y)))
(func (export "max") (param $x f32) (param $y f32) (result f32) (f32.max (local.get $x) (local.get $y)))
(func (export "ceil") (param $x f32) (result f32) (f32.ceil (local.get $x)))
(func (export "floor") (param $x f32) (result f32) (f32.floor (local.get $x)))
(func (export "trunc") (param $x f32) (result f32) (f32.trunc (local.get $x)))
(func (export "nearest") (param $x f32) (result f32) (f32.nearest (local.get $x)))
)
(assert_return (invoke "add" (f32.const -0x0p+0) (f32.const -0x0p+0)) (f32.const -0x0p+0))
@ -2516,3 +2516,18 @@
(assert_return_arithmetic_nan (invoke "nearest" (f32.const -nan:0x200000)))
(assert_return_canonical_nan (invoke "nearest" (f32.const nan)))
(assert_return_arithmetic_nan (invoke "nearest" (f32.const nan:0x200000)))
;; Type check
(assert_invalid (module (func (result f32) (f32.add (i64.const 0) (f64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.div (i64.const 0) (f64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.max (i64.const 0) (f64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.min (i64.const 0) (f64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.mul (i64.const 0) (f64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.sub (i64.const 0) (f64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.ceil (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.floor (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.nearest (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.sqrt (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.trunc (i64.const 0)))) "type mismatch")

View File

@ -2,9 +2,9 @@
;; values.
(module
(func (export "abs") (param $x f32) (result f32) (f32.abs (get_local $x)))
(func (export "neg") (param $x f32) (result f32) (f32.neg (get_local $x)))
(func (export "copysign") (param $x f32) (param $y f32) (result f32) (f32.copysign (get_local $x) (get_local $y)))
(func (export "abs") (param $x f32) (result f32) (f32.abs (local.get $x)))
(func (export "neg") (param $x f32) (result f32) (f32.neg (local.get $x)))
(func (export "copysign") (param $x f32) (param $y f32) (result f32) (f32.copysign (local.get $x) (local.get $y)))
)
(assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const -0x0p+0)) (f32.const -0x0p+0))
@ -367,3 +367,10 @@
(assert_return (invoke "neg" (f32.const inf)) (f32.const -inf))
(assert_return (invoke "neg" (f32.const -nan)) (f32.const nan))
(assert_return (invoke "neg" (f32.const nan)) (f32.const -nan))
;; Type check
(assert_invalid (module (func (result f32) (f32.copysign (i64.const 0) (f64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.abs (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.neg (i64.const 0)))) "type mismatch")

View File

@ -2,12 +2,12 @@
;; special values.
(module
(func (export "eq") (param $x f32) (param $y f32) (result i32) (f32.eq (get_local $x) (get_local $y)))
(func (export "ne") (param $x f32) (param $y f32) (result i32) (f32.ne (get_local $x) (get_local $y)))
(func (export "lt") (param $x f32) (param $y f32) (result i32) (f32.lt (get_local $x) (get_local $y)))
(func (export "le") (param $x f32) (param $y f32) (result i32) (f32.le (get_local $x) (get_local $y)))
(func (export "gt") (param $x f32) (param $y f32) (result i32) (f32.gt (get_local $x) (get_local $y)))
(func (export "ge") (param $x f32) (param $y f32) (result i32) (f32.ge (get_local $x) (get_local $y)))
(func (export "eq") (param $x f32) (param $y f32) (result i32) (f32.eq (local.get $x) (local.get $y)))
(func (export "ne") (param $x f32) (param $y f32) (result i32) (f32.ne (local.get $x) (local.get $y)))
(func (export "lt") (param $x f32) (param $y f32) (result i32) (f32.lt (local.get $x) (local.get $y)))
(func (export "le") (param $x f32) (param $y f32) (result i32) (f32.le (local.get $x) (local.get $y)))
(func (export "gt") (param $x f32) (param $y f32) (result i32) (f32.gt (local.get $x) (local.get $y)))
(func (export "ge") (param $x f32) (param $y f32) (result i32) (f32.ge (local.get $x) (local.get $y)))
)
(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const -0x0p+0)) (i32.const 1))
@ -2410,3 +2410,13 @@
(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const nan)) (i32.const 0))
(assert_return (invoke "ge" (f32.const nan) (f32.const nan:0x200000)) (i32.const 0))
(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const nan:0x200000)) (i32.const 0))
;; Type check
(assert_invalid (module (func (result f32) (f32.eq (i64.const 0) (f64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.ge (i64.const 0) (f64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.gt (i64.const 0) (f64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.le (i64.const 0) (f64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.lt (i64.const 0) (f64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f32) (f32.ne (i64.const 0) (f64.const 0)))) "type mismatch")

View File

@ -3,17 +3,17 @@
;; f64_bitwise.wast and f64_cmp.wast).
(module
(func (export "add") (param $x f64) (param $y f64) (result f64) (f64.add (get_local $x) (get_local $y)))
(func (export "sub") (param $x f64) (param $y f64) (result f64) (f64.sub (get_local $x) (get_local $y)))
(func (export "mul") (param $x f64) (param $y f64) (result f64) (f64.mul (get_local $x) (get_local $y)))
(func (export "div") (param $x f64) (param $y f64) (result f64) (f64.div (get_local $x) (get_local $y)))
(func (export "sqrt") (param $x f64) (result f64) (f64.sqrt (get_local $x)))
(func (export "min") (param $x f64) (param $y f64) (result f64) (f64.min (get_local $x) (get_local $y)))
(func (export "max") (param $x f64) (param $y f64) (result f64) (f64.max (get_local $x) (get_local $y)))
(func (export "ceil") (param $x f64) (result f64) (f64.ceil (get_local $x)))
(func (export "floor") (param $x f64) (result f64) (f64.floor (get_local $x)))
(func (export "trunc") (param $x f64) (result f64) (f64.trunc (get_local $x)))
(func (export "nearest") (param $x f64) (result f64) (f64.nearest (get_local $x)))
(func (export "add") (param $x f64) (param $y f64) (result f64) (f64.add (local.get $x) (local.get $y)))
(func (export "sub") (param $x f64) (param $y f64) (result f64) (f64.sub (local.get $x) (local.get $y)))
(func (export "mul") (param $x f64) (param $y f64) (result f64) (f64.mul (local.get $x) (local.get $y)))
(func (export "div") (param $x f64) (param $y f64) (result f64) (f64.div (local.get $x) (local.get $y)))
(func (export "sqrt") (param $x f64) (result f64) (f64.sqrt (local.get $x)))
(func (export "min") (param $x f64) (param $y f64) (result f64) (f64.min (local.get $x) (local.get $y)))
(func (export "max") (param $x f64) (param $y f64) (result f64) (f64.max (local.get $x) (local.get $y)))
(func (export "ceil") (param $x f64) (result f64) (f64.ceil (local.get $x)))
(func (export "floor") (param $x f64) (result f64) (f64.floor (local.get $x)))
(func (export "trunc") (param $x f64) (result f64) (f64.trunc (local.get $x)))
(func (export "nearest") (param $x f64) (result f64) (f64.nearest (local.get $x)))
)
(assert_return (invoke "add" (f64.const -0x0p+0) (f64.const -0x0p+0)) (f64.const -0x0p+0))
@ -2516,3 +2516,18 @@
(assert_return_arithmetic_nan (invoke "nearest" (f64.const -nan:0x4000000000000)))
(assert_return_canonical_nan (invoke "nearest" (f64.const nan)))
(assert_return_arithmetic_nan (invoke "nearest" (f64.const nan:0x4000000000000)))
;; Type check
(assert_invalid (module (func (result f64) (f64.add (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.div (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.max (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.min (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.mul (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.sub (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.ceil (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.floor (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.nearest (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.sqrt (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.trunc (i64.const 0)))) "type mismatch")

View File

@ -2,9 +2,9 @@
;; values.
(module
(func (export "abs") (param $x f64) (result f64) (f64.abs (get_local $x)))
(func (export "neg") (param $x f64) (result f64) (f64.neg (get_local $x)))
(func (export "copysign") (param $x f64) (param $y f64) (result f64) (f64.copysign (get_local $x) (get_local $y)))
(func (export "abs") (param $x f64) (result f64) (f64.abs (local.get $x)))
(func (export "neg") (param $x f64) (result f64) (f64.neg (local.get $x)))
(func (export "copysign") (param $x f64) (param $y f64) (result f64) (f64.copysign (local.get $x) (local.get $y)))
)
(assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const -0x0p+0)) (f64.const -0x0p+0))
@ -367,3 +367,10 @@
(assert_return (invoke "neg" (f64.const inf)) (f64.const -inf))
(assert_return (invoke "neg" (f64.const -nan)) (f64.const nan))
(assert_return (invoke "neg" (f64.const nan)) (f64.const -nan))
;; Type check
(assert_invalid (module (func (result f64) (f64.copysign (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.abs (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.neg (i64.const 0)))) "type mismatch")

View File

@ -2,12 +2,12 @@
;; special values.
(module
(func (export "eq") (param $x f64) (param $y f64) (result i32) (f64.eq (get_local $x) (get_local $y)))
(func (export "ne") (param $x f64) (param $y f64) (result i32) (f64.ne (get_local $x) (get_local $y)))
(func (export "lt") (param $x f64) (param $y f64) (result i32) (f64.lt (get_local $x) (get_local $y)))
(func (export "le") (param $x f64) (param $y f64) (result i32) (f64.le (get_local $x) (get_local $y)))
(func (export "gt") (param $x f64) (param $y f64) (result i32) (f64.gt (get_local $x) (get_local $y)))
(func (export "ge") (param $x f64) (param $y f64) (result i32) (f64.ge (get_local $x) (get_local $y)))
(func (export "eq") (param $x f64) (param $y f64) (result i32) (f64.eq (local.get $x) (local.get $y)))
(func (export "ne") (param $x f64) (param $y f64) (result i32) (f64.ne (local.get $x) (local.get $y)))
(func (export "lt") (param $x f64) (param $y f64) (result i32) (f64.lt (local.get $x) (local.get $y)))
(func (export "le") (param $x f64) (param $y f64) (result i32) (f64.le (local.get $x) (local.get $y)))
(func (export "gt") (param $x f64) (param $y f64) (result i32) (f64.gt (local.get $x) (local.get $y)))
(func (export "ge") (param $x f64) (param $y f64) (result i32) (f64.ge (local.get $x) (local.get $y)))
)
(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const -0x0p+0)) (i32.const 1))
@ -2410,3 +2410,13 @@
(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const nan)) (i32.const 0))
(assert_return (invoke "ge" (f64.const nan) (f64.const nan:0x4000000000000)) (i32.const 0))
(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const nan:0x4000000000000)) (i32.const 0))
;; Type check
(assert_invalid (module (func (result f64) (f64.eq (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.ge (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.gt (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.le (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.lt (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result f64) (f64.ne (i64.const 0) (f32.const 0)))) "type mismatch")

View File

@ -1,22 +1,22 @@
(module
;; Recursive factorial
(func (export "fac-rec") (param i64) (result i64)
(if (result i64) (i64.eq (get_local 0) (i64.const 0))
(if (result i64) (i64.eq (local.get 0) (i64.const 0))
(then (i64.const 1))
(else
(i64.mul (get_local 0) (call 0 (i64.sub (get_local 0) (i64.const 1))))
(i64.mul (local.get 0) (call 0 (i64.sub (local.get 0) (i64.const 1))))
)
)
)
;; Recursive factorial named
(func $fac-rec-named (export "fac-rec-named") (param $n i64) (result i64)
(if (result i64) (i64.eq (get_local $n) (i64.const 0))
(if (result i64) (i64.eq (local.get $n) (i64.const 0))
(then (i64.const 1))
(else
(i64.mul
(get_local $n)
(call $fac-rec-named (i64.sub (get_local $n) (i64.const 1)))
(local.get $n)
(call $fac-rec-named (i64.sub (local.get $n) (i64.const 1)))
)
)
)
@ -25,59 +25,59 @@
;; Iterative factorial
(func (export "fac-iter") (param i64) (result i64)
(local i64 i64)
(set_local 1 (get_local 0))
(set_local 2 (i64.const 1))
(local.set 1 (local.get 0))
(local.set 2 (i64.const 1))
(block
(loop
(if
(i64.eq (get_local 1) (i64.const 0))
(i64.eq (local.get 1) (i64.const 0))
(then (br 2))
(else
(set_local 2 (i64.mul (get_local 1) (get_local 2)))
(set_local 1 (i64.sub (get_local 1) (i64.const 1)))
(local.set 2 (i64.mul (local.get 1) (local.get 2)))
(local.set 1 (i64.sub (local.get 1) (i64.const 1)))
)
)
(br 0)
)
)
(get_local 2)
(local.get 2)
)
;; Iterative factorial named
(func (export "fac-iter-named") (param $n i64) (result i64)
(local $i i64)
(local $res i64)
(set_local $i (get_local $n))
(set_local $res (i64.const 1))
(local.set $i (local.get $n))
(local.set $res (i64.const 1))
(block $done
(loop $loop
(if
(i64.eq (get_local $i) (i64.const 0))
(i64.eq (local.get $i) (i64.const 0))
(then (br $done))
(else
(set_local $res (i64.mul (get_local $i) (get_local $res)))
(set_local $i (i64.sub (get_local $i) (i64.const 1)))
(local.set $res (i64.mul (local.get $i) (local.get $res)))
(local.set $i (i64.sub (local.get $i) (i64.const 1)))
)
)
(br $loop)
)
)
(get_local $res)
(local.get $res)
)
;; Optimized factorial.
(func (export "fac-opt") (param i64) (result i64)
(local i64)
(set_local 1 (i64.const 1))
(local.set 1 (i64.const 1))
(block
(br_if 0 (i64.lt_s (get_local 0) (i64.const 2)))
(br_if 0 (i64.lt_s (local.get 0) (i64.const 2)))
(loop
(set_local 1 (i64.mul (get_local 1) (get_local 0)))
(set_local 0 (i64.add (get_local 0) (i64.const -1)))
(br_if 0 (i64.gt_s (get_local 0) (i64.const 1)))
(local.set 1 (i64.mul (local.get 1) (local.get 0)))
(local.set 0 (i64.add (local.get 0) (i64.const -1)))
(br_if 0 (i64.gt_s (local.get 0) (i64.const 1)))
)
)
(get_local 1)
(local.get 1)
)
)

File diff suppressed because it is too large Load Diff

View File

@ -2,82 +2,82 @@
(module
;; f32 special values
(func (export "f32.nan") (result i32) (i32.reinterpret/f32 (f32.const nan)))
(func (export "f32.positive_nan") (result i32) (i32.reinterpret/f32 (f32.const +nan)))
(func (export "f32.negative_nan") (result i32) (i32.reinterpret/f32 (f32.const -nan)))
(func (export "f32.plain_nan") (result i32) (i32.reinterpret/f32 (f32.const nan:0x400000)))
(func (export "f32.informally_known_as_plain_snan") (result i32) (i32.reinterpret/f32 (f32.const nan:0x200000)))
(func (export "f32.all_ones_nan") (result i32) (i32.reinterpret/f32 (f32.const -nan:0x7fffff)))
(func (export "f32.misc_nan") (result i32) (i32.reinterpret/f32 (f32.const nan:0x012345)))
(func (export "f32.misc_positive_nan") (result i32) (i32.reinterpret/f32 (f32.const +nan:0x304050)))
(func (export "f32.misc_negative_nan") (result i32) (i32.reinterpret/f32 (f32.const -nan:0x2abcde)))
(func (export "f32.infinity") (result i32) (i32.reinterpret/f32 (f32.const inf)))
(func (export "f32.positive_infinity") (result i32) (i32.reinterpret/f32 (f32.const +inf)))
(func (export "f32.negative_infinity") (result i32) (i32.reinterpret/f32 (f32.const -inf)))
(func (export "f32.nan") (result i32) (i32.reinterpret_f32 (f32.const nan)))
(func (export "f32.positive_nan") (result i32) (i32.reinterpret_f32 (f32.const +nan)))
(func (export "f32.negative_nan") (result i32) (i32.reinterpret_f32 (f32.const -nan)))
(func (export "f32.plain_nan") (result i32) (i32.reinterpret_f32 (f32.const nan:0x400000)))
(func (export "f32.informally_known_as_plain_snan") (result i32) (i32.reinterpret_f32 (f32.const nan:0x200000)))
(func (export "f32.all_ones_nan") (result i32) (i32.reinterpret_f32 (f32.const -nan:0x7fffff)))
(func (export "f32.misc_nan") (result i32) (i32.reinterpret_f32 (f32.const nan:0x012345)))
(func (export "f32.misc_positive_nan") (result i32) (i32.reinterpret_f32 (f32.const +nan:0x304050)))
(func (export "f32.misc_negative_nan") (result i32) (i32.reinterpret_f32 (f32.const -nan:0x2abcde)))
(func (export "f32.infinity") (result i32) (i32.reinterpret_f32 (f32.const inf)))
(func (export "f32.positive_infinity") (result i32) (i32.reinterpret_f32 (f32.const +inf)))
(func (export "f32.negative_infinity") (result i32) (i32.reinterpret_f32 (f32.const -inf)))
;; f32 numbers
(func (export "f32.zero") (result i32) (i32.reinterpret/f32 (f32.const 0x0.0p0)))
(func (export "f32.positive_zero") (result i32) (i32.reinterpret/f32 (f32.const +0x0.0p0)))
(func (export "f32.negative_zero") (result i32) (i32.reinterpret/f32 (f32.const -0x0.0p0)))
(func (export "f32.misc") (result i32) (i32.reinterpret/f32 (f32.const 0x1.921fb6p+2)))
(func (export "f32.min_positive") (result i32) (i32.reinterpret/f32 (f32.const 0x1p-149)))
(func (export "f32.min_normal") (result i32) (i32.reinterpret/f32 (f32.const 0x1p-126)))
(func (export "f32.max_finite") (result i32) (i32.reinterpret/f32 (f32.const 0x1.fffffep+127)))
(func (export "f32.max_subnormal") (result i32) (i32.reinterpret/f32 (f32.const 0x1.fffffcp-127)))
(func (export "f32.trailing_dot") (result i32) (i32.reinterpret/f32 (f32.const 0x1.p10)))
(func (export "f32.zero") (result i32) (i32.reinterpret_f32 (f32.const 0x0.0p0)))
(func (export "f32.positive_zero") (result i32) (i32.reinterpret_f32 (f32.const +0x0.0p0)))
(func (export "f32.negative_zero") (result i32) (i32.reinterpret_f32 (f32.const -0x0.0p0)))
(func (export "f32.misc") (result i32) (i32.reinterpret_f32 (f32.const 0x1.921fb6p+2)))
(func (export "f32.min_positive") (result i32) (i32.reinterpret_f32 (f32.const 0x1p-149)))
(func (export "f32.min_normal") (result i32) (i32.reinterpret_f32 (f32.const 0x1p-126)))
(func (export "f32.max_finite") (result i32) (i32.reinterpret_f32 (f32.const 0x1.fffffep+127)))
(func (export "f32.max_subnormal") (result i32) (i32.reinterpret_f32 (f32.const 0x1.fffffcp-127)))
(func (export "f32.trailing_dot") (result i32) (i32.reinterpret_f32 (f32.const 0x1.p10)))
;; f32 in decimal format
(func (export "f32_dec.zero") (result i32) (i32.reinterpret/f32 (f32.const 0.0e0)))
(func (export "f32_dec.positive_zero") (result i32) (i32.reinterpret/f32 (f32.const +0.0e0)))
(func (export "f32_dec.negative_zero") (result i32) (i32.reinterpret/f32 (f32.const -0.0e0)))
(func (export "f32_dec.misc") (result i32) (i32.reinterpret/f32 (f32.const 6.28318548202514648)))
(func (export "f32_dec.min_positive") (result i32) (i32.reinterpret/f32 (f32.const 1.4013e-45)))
(func (export "f32_dec.min_normal") (result i32) (i32.reinterpret/f32 (f32.const 1.1754944e-38)))
(func (export "f32_dec.max_subnormal") (result i32) (i32.reinterpret/f32 (f32.const 1.1754942e-38)))
(func (export "f32_dec.max_finite") (result i32) (i32.reinterpret/f32 (f32.const 3.4028234e+38)))
(func (export "f32_dec.trailing_dot") (result i32) (i32.reinterpret/f32 (f32.const 1.e10)))
(func (export "f32_dec.zero") (result i32) (i32.reinterpret_f32 (f32.const 0.0e0)))
(func (export "f32_dec.positive_zero") (result i32) (i32.reinterpret_f32 (f32.const +0.0e0)))
(func (export "f32_dec.negative_zero") (result i32) (i32.reinterpret_f32 (f32.const -0.0e0)))
(func (export "f32_dec.misc") (result i32) (i32.reinterpret_f32 (f32.const 6.28318548202514648)))
(func (export "f32_dec.min_positive") (result i32) (i32.reinterpret_f32 (f32.const 1.4013e-45)))
(func (export "f32_dec.min_normal") (result i32) (i32.reinterpret_f32 (f32.const 1.1754944e-38)))
(func (export "f32_dec.max_subnormal") (result i32) (i32.reinterpret_f32 (f32.const 1.1754942e-38)))
(func (export "f32_dec.max_finite") (result i32) (i32.reinterpret_f32 (f32.const 3.4028234e+38)))
(func (export "f32_dec.trailing_dot") (result i32) (i32.reinterpret_f32 (f32.const 1.e10)))
;; https://twitter.com/Archivd/status/994637336506912768
(func (export "f32_dec.root_beer_float") (result i32) (i32.reinterpret/f32 (f32.const 1.000000119)))
(func (export "f32_dec.root_beer_float") (result i32) (i32.reinterpret_f32 (f32.const 1.000000119)))
;; f64 special values
(func (export "f64.nan") (result i64) (i64.reinterpret/f64 (f64.const nan)))
(func (export "f64.positive_nan") (result i64) (i64.reinterpret/f64 (f64.const +nan)))
(func (export "f64.negative_nan") (result i64) (i64.reinterpret/f64 (f64.const -nan)))
(func (export "f64.plain_nan") (result i64) (i64.reinterpret/f64 (f64.const nan:0x8000000000000)))
(func (export "f64.informally_known_as_plain_snan") (result i64) (i64.reinterpret/f64 (f64.const nan:0x4000000000000)))
(func (export "f64.all_ones_nan") (result i64) (i64.reinterpret/f64 (f64.const -nan:0xfffffffffffff)))
(func (export "f64.misc_nan") (result i64) (i64.reinterpret/f64 (f64.const nan:0x0123456789abc)))
(func (export "f64.misc_positive_nan") (result i64) (i64.reinterpret/f64 (f64.const +nan:0x3040506070809)))
(func (export "f64.misc_negative_nan") (result i64) (i64.reinterpret/f64 (f64.const -nan:0x2abcdef012345)))
(func (export "f64.infinity") (result i64) (i64.reinterpret/f64 (f64.const inf)))
(func (export "f64.positive_infinity") (result i64) (i64.reinterpret/f64 (f64.const +inf)))
(func (export "f64.negative_infinity") (result i64) (i64.reinterpret/f64 (f64.const -inf)))
(func (export "f64.nan") (result i64) (i64.reinterpret_f64 (f64.const nan)))
(func (export "f64.positive_nan") (result i64) (i64.reinterpret_f64 (f64.const +nan)))
(func (export "f64.negative_nan") (result i64) (i64.reinterpret_f64 (f64.const -nan)))
(func (export "f64.plain_nan") (result i64) (i64.reinterpret_f64 (f64.const nan:0x8000000000000)))
(func (export "f64.informally_known_as_plain_snan") (result i64) (i64.reinterpret_f64 (f64.const nan:0x4000000000000)))
(func (export "f64.all_ones_nan") (result i64) (i64.reinterpret_f64 (f64.const -nan:0xfffffffffffff)))
(func (export "f64.misc_nan") (result i64) (i64.reinterpret_f64 (f64.const nan:0x0123456789abc)))
(func (export "f64.misc_positive_nan") (result i64) (i64.reinterpret_f64 (f64.const +nan:0x3040506070809)))
(func (export "f64.misc_negative_nan") (result i64) (i64.reinterpret_f64 (f64.const -nan:0x2abcdef012345)))
(func (export "f64.infinity") (result i64) (i64.reinterpret_f64 (f64.const inf)))
(func (export "f64.positive_infinity") (result i64) (i64.reinterpret_f64 (f64.const +inf)))
(func (export "f64.negative_infinity") (result i64) (i64.reinterpret_f64 (f64.const -inf)))
;; f64 numbers
(func (export "f64.zero") (result i64) (i64.reinterpret/f64 (f64.const 0x0.0p0)))
(func (export "f64.positive_zero") (result i64) (i64.reinterpret/f64 (f64.const +0x0.0p0)))
(func (export "f64.negative_zero") (result i64) (i64.reinterpret/f64 (f64.const -0x0.0p0)))
(func (export "f64.misc") (result i64) (i64.reinterpret/f64 (f64.const 0x1.921fb54442d18p+2)))
(func (export "f64.min_positive") (result i64) (i64.reinterpret/f64 (f64.const 0x0.0000000000001p-1022)))
(func (export "f64.min_normal") (result i64) (i64.reinterpret/f64 (f64.const 0x1p-1022)))
(func (export "f64.max_subnormal") (result i64) (i64.reinterpret/f64 (f64.const 0x0.fffffffffffffp-1022)))
(func (export "f64.max_finite") (result i64) (i64.reinterpret/f64 (f64.const 0x1.fffffffffffffp+1023)))
(func (export "f64.trailing_dot") (result i64) (i64.reinterpret/f64 (f64.const 0x1.p100)))
(func (export "f64.zero") (result i64) (i64.reinterpret_f64 (f64.const 0x0.0p0)))
(func (export "f64.positive_zero") (result i64) (i64.reinterpret_f64 (f64.const +0x0.0p0)))
(func (export "f64.negative_zero") (result i64) (i64.reinterpret_f64 (f64.const -0x0.0p0)))
(func (export "f64.misc") (result i64) (i64.reinterpret_f64 (f64.const 0x1.921fb54442d18p+2)))
(func (export "f64.min_positive") (result i64) (i64.reinterpret_f64 (f64.const 0x0.0000000000001p-1022)))
(func (export "f64.min_normal") (result i64) (i64.reinterpret_f64 (f64.const 0x1p-1022)))
(func (export "f64.max_subnormal") (result i64) (i64.reinterpret_f64 (f64.const 0x0.fffffffffffffp-1022)))
(func (export "f64.max_finite") (result i64) (i64.reinterpret_f64 (f64.const 0x1.fffffffffffffp+1023)))
(func (export "f64.trailing_dot") (result i64) (i64.reinterpret_f64 (f64.const 0x1.p100)))
;; f64 numbers in decimal format
(func (export "f64_dec.zero") (result i64) (i64.reinterpret/f64 (f64.const 0.0e0)))
(func (export "f64_dec.positive_zero") (result i64) (i64.reinterpret/f64 (f64.const +0.0e0)))
(func (export "f64_dec.negative_zero") (result i64) (i64.reinterpret/f64 (f64.const -0.0e0)))
(func (export "f64_dec.misc") (result i64) (i64.reinterpret/f64 (f64.const 6.28318530717958623)))
(func (export "f64_dec.min_positive") (result i64) (i64.reinterpret/f64 (f64.const 4.94066e-324)))
(func (export "f64_dec.min_normal") (result i64) (i64.reinterpret/f64 (f64.const 2.2250738585072012e-308)))
(func (export "f64_dec.max_subnormal") (result i64) (i64.reinterpret/f64 (f64.const 2.2250738585072011e-308)))
(func (export "f64_dec.max_finite") (result i64) (i64.reinterpret/f64 (f64.const 1.7976931348623157e+308)))
(func (export "f64_dec.trailing_dot") (result i64) (i64.reinterpret/f64 (f64.const 1.e100)))
(func (export "f64_dec.zero") (result i64) (i64.reinterpret_f64 (f64.const 0.0e0)))
(func (export "f64_dec.positive_zero") (result i64) (i64.reinterpret_f64 (f64.const +0.0e0)))
(func (export "f64_dec.negative_zero") (result i64) (i64.reinterpret_f64 (f64.const -0.0e0)))
(func (export "f64_dec.misc") (result i64) (i64.reinterpret_f64 (f64.const 6.28318530717958623)))
(func (export "f64_dec.min_positive") (result i64) (i64.reinterpret_f64 (f64.const 4.94066e-324)))
(func (export "f64_dec.min_normal") (result i64) (i64.reinterpret_f64 (f64.const 2.2250738585072012e-308)))
(func (export "f64_dec.max_subnormal") (result i64) (i64.reinterpret_f64 (f64.const 2.2250738585072011e-308)))
(func (export "f64_dec.max_finite") (result i64) (i64.reinterpret_f64 (f64.const 1.7976931348623157e+308)))
(func (export "f64_dec.trailing_dot") (result i64) (i64.reinterpret_f64 (f64.const 1.e100)))
;; https://twitter.com/Archivd/status/994637336506912768
(func (export "f64_dec.root_beer_float") (result i64) (i64.reinterpret/f64 (f64.const 1.000000119)))
(func (export "f64_dec.root_beer_float") (result i64) (i64.reinterpret_f64 (f64.const 1.000000119)))
(func (export "f32-dec-sep1") (result f32) (f32.const 1_000_000))
(func (export "f32-dec-sep2") (result f32) (f32.const 1_0_0_0))

View File

@ -15,35 +15,35 @@
;; covering additional miscellaneous interesting cases.
(module
(func (export "f32.add") (param $x f32) (param $y f32) (result f32) (f32.add (get_local $x) (get_local $y)))
(func (export "f32.sub") (param $x f32) (param $y f32) (result f32) (f32.sub (get_local $x) (get_local $y)))
(func (export "f32.mul") (param $x f32) (param $y f32) (result f32) (f32.mul (get_local $x) (get_local $y)))
(func (export "f32.div") (param $x f32) (param $y f32) (result f32) (f32.div (get_local $x) (get_local $y)))
(func (export "f32.sqrt") (param $x f32) (result f32) (f32.sqrt (get_local $x)))
(func (export "f32.abs") (param $x f32) (result f32) (f32.abs (get_local $x)))
(func (export "f32.neg") (param $x f32) (result f32) (f32.neg (get_local $x)))
(func (export "f32.copysign") (param $x f32) (param $y f32) (result f32) (f32.copysign (get_local $x) (get_local $y)))
(func (export "f32.ceil") (param $x f32) (result f32) (f32.ceil (get_local $x)))
(func (export "f32.floor") (param $x f32) (result f32) (f32.floor (get_local $x)))
(func (export "f32.trunc") (param $x f32) (result f32) (f32.trunc (get_local $x)))
(func (export "f32.nearest") (param $x f32) (result f32) (f32.nearest (get_local $x)))
(func (export "f32.min") (param $x f32) (param $y f32) (result f32) (f32.min (get_local $x) (get_local $y)))
(func (export "f32.max") (param $x f32) (param $y f32) (result f32) (f32.max (get_local $x) (get_local $y)))
(func (export "f32.add") (param $x f32) (param $y f32) (result f32) (f32.add (local.get $x) (local.get $y)))
(func (export "f32.sub") (param $x f32) (param $y f32) (result f32) (f32.sub (local.get $x) (local.get $y)))
(func (export "f32.mul") (param $x f32) (param $y f32) (result f32) (f32.mul (local.get $x) (local.get $y)))
(func (export "f32.div") (param $x f32) (param $y f32) (result f32) (f32.div (local.get $x) (local.get $y)))
(func (export "f32.sqrt") (param $x f32) (result f32) (f32.sqrt (local.get $x)))
(func (export "f32.abs") (param $x f32) (result f32) (f32.abs (local.get $x)))
(func (export "f32.neg") (param $x f32) (result f32) (f32.neg (local.get $x)))
(func (export "f32.copysign") (param $x f32) (param $y f32) (result f32) (f32.copysign (local.get $x) (local.get $y)))
(func (export "f32.ceil") (param $x f32) (result f32) (f32.ceil (local.get $x)))
(func (export "f32.floor") (param $x f32) (result f32) (f32.floor (local.get $x)))
(func (export "f32.trunc") (param $x f32) (result f32) (f32.trunc (local.get $x)))
(func (export "f32.nearest") (param $x f32) (result f32) (f32.nearest (local.get $x)))
(func (export "f32.min") (param $x f32) (param $y f32) (result f32) (f32.min (local.get $x) (local.get $y)))
(func (export "f32.max") (param $x f32) (param $y f32) (result f32) (f32.max (local.get $x) (local.get $y)))
(func (export "f64.add") (param $x f64) (param $y f64) (result f64) (f64.add (get_local $x) (get_local $y)))
(func (export "f64.sub") (param $x f64) (param $y f64) (result f64) (f64.sub (get_local $x) (get_local $y)))
(func (export "f64.mul") (param $x f64) (param $y f64) (result f64) (f64.mul (get_local $x) (get_local $y)))
(func (export "f64.div") (param $x f64) (param $y f64) (result f64) (f64.div (get_local $x) (get_local $y)))
(func (export "f64.sqrt") (param $x f64) (result f64) (f64.sqrt (get_local $x)))
(func (export "f64.abs") (param $x f64) (result f64) (f64.abs (get_local $x)))
(func (export "f64.neg") (param $x f64) (result f64) (f64.neg (get_local $x)))
(func (export "f64.copysign") (param $x f64) (param $y f64) (result f64) (f64.copysign (get_local $x) (get_local $y)))
(func (export "f64.ceil") (param $x f64) (result f64) (f64.ceil (get_local $x)))
(func (export "f64.floor") (param $x f64) (result f64) (f64.floor (get_local $x)))
(func (export "f64.trunc") (param $x f64) (result f64) (f64.trunc (get_local $x)))
(func (export "f64.nearest") (param $x f64) (result f64) (f64.nearest (get_local $x)))
(func (export "f64.min") (param $x f64) (param $y f64) (result f64) (f64.min (get_local $x) (get_local $y)))
(func (export "f64.max") (param $x f64) (param $y f64) (result f64) (f64.max (get_local $x) (get_local $y)))
(func (export "f64.add") (param $x f64) (param $y f64) (result f64) (f64.add (local.get $x) (local.get $y)))
(func (export "f64.sub") (param $x f64) (param $y f64) (result f64) (f64.sub (local.get $x) (local.get $y)))
(func (export "f64.mul") (param $x f64) (param $y f64) (result f64) (f64.mul (local.get $x) (local.get $y)))
(func (export "f64.div") (param $x f64) (param $y f64) (result f64) (f64.div (local.get $x) (local.get $y)))
(func (export "f64.sqrt") (param $x f64) (result f64) (f64.sqrt (local.get $x)))
(func (export "f64.abs") (param $x f64) (result f64) (f64.abs (local.get $x)))
(func (export "f64.neg") (param $x f64) (result f64) (f64.neg (local.get $x)))
(func (export "f64.copysign") (param $x f64) (param $y f64) (result f64) (f64.copysign (local.get $x) (local.get $y)))
(func (export "f64.ceil") (param $x f64) (result f64) (f64.ceil (local.get $x)))
(func (export "f64.floor") (param $x f64) (result f64) (f64.floor (local.get $x)))
(func (export "f64.trunc") (param $x f64) (result f64) (f64.trunc (local.get $x)))
(func (export "f64.nearest") (param $x f64) (result f64) (f64.nearest (local.get $x)))
(func (export "f64.min") (param $x f64) (param $y f64) (result f64) (f64.min (local.get $x) (local.get $y)))
(func (export "f64.max") (param $x f64) (param $y f64) (result f64) (f64.max (local.get $x) (local.get $y)))
)
;; Miscellaneous values.

View File

@ -1,15 +1,15 @@
(module
(func $even (export "even") (param $n i32) (result i32)
(if (result i32) (i32.eq (get_local $n) (i32.const 0))
(if (result i32) (i32.eq (local.get $n) (i32.const 0))
(then (i32.const 1))
(else (call $odd (i32.sub (get_local $n) (i32.const 1))))
(else (call $odd (i32.sub (local.get $n) (i32.const 1))))
)
)
(func $odd (export "odd") (param $n i32) (result i32)
(if (result i32) (i32.eq (get_local $n) (i32.const 0))
(if (result i32) (i32.eq (local.get $n) (i32.const 0))
(then (i32.const 0))
(else (call $even (i32.sub (get_local $n) (i32.const 1))))
(else (call $even (i32.sub (local.get $n) (i32.const 1))))
)
)
)

View File

@ -64,44 +64,44 @@
;; Typing of locals
(func (export "local-first-i32") (result i32) (local i32 i32) (get_local 0))
(func (export "local-first-i64") (result i64) (local i64 i64) (get_local 0))
(func (export "local-first-f32") (result f32) (local f32 f32) (get_local 0))
(func (export "local-first-f64") (result f64) (local f64 f64) (get_local 0))
(func (export "local-second-i32") (result i32) (local i32 i32) (get_local 1))
(func (export "local-second-i64") (result i64) (local i64 i64) (get_local 1))
(func (export "local-second-f32") (result f32) (local f32 f32) (get_local 1))
(func (export "local-second-f64") (result f64) (local f64 f64) (get_local 1))
(func (export "local-first-i32") (result i32) (local i32 i32) (local.get 0))
(func (export "local-first-i64") (result i64) (local i64 i64) (local.get 0))
(func (export "local-first-f32") (result f32) (local f32 f32) (local.get 0))
(func (export "local-first-f64") (result f64) (local f64 f64) (local.get 0))
(func (export "local-second-i32") (result i32) (local i32 i32) (local.get 1))
(func (export "local-second-i64") (result i64) (local i64 i64) (local.get 1))
(func (export "local-second-f32") (result f32) (local f32 f32) (local.get 1))
(func (export "local-second-f64") (result f64) (local f64 f64) (local.get 1))
(func (export "local-mixed") (result f64)
(local f32) (local $x i32) (local i64 i32) (local) (local f64 i32)
(drop (f32.neg (get_local 0)))
(drop (i32.eqz (get_local 1)))
(drop (i64.eqz (get_local 2)))
(drop (i32.eqz (get_local 3)))
(drop (f64.neg (get_local 4)))
(drop (i32.eqz (get_local 5)))
(get_local 4)
(drop (f32.neg (local.get 0)))
(drop (i32.eqz (local.get 1)))
(drop (i64.eqz (local.get 2)))
(drop (i32.eqz (local.get 3)))
(drop (f64.neg (local.get 4)))
(drop (i32.eqz (local.get 5)))
(local.get 4)
)
;; Typing of parameters
(func (export "param-first-i32") (param i32 i32) (result i32) (get_local 0))
(func (export "param-first-i64") (param i64 i64) (result i64) (get_local 0))
(func (export "param-first-f32") (param f32 f32) (result f32) (get_local 0))
(func (export "param-first-f64") (param f64 f64) (result f64) (get_local 0))
(func (export "param-second-i32") (param i32 i32) (result i32) (get_local 1))
(func (export "param-second-i64") (param i64 i64) (result i64) (get_local 1))
(func (export "param-second-f32") (param f32 f32) (result f32) (get_local 1))
(func (export "param-second-f64") (param f64 f64) (result f64) (get_local 1))
(func (export "param-first-i32") (param i32 i32) (result i32) (local.get 0))
(func (export "param-first-i64") (param i64 i64) (result i64) (local.get 0))
(func (export "param-first-f32") (param f32 f32) (result f32) (local.get 0))
(func (export "param-first-f64") (param f64 f64) (result f64) (local.get 0))
(func (export "param-second-i32") (param i32 i32) (result i32) (local.get 1))
(func (export "param-second-i64") (param i64 i64) (result i64) (local.get 1))
(func (export "param-second-f32") (param f32 f32) (result f32) (local.get 1))
(func (export "param-second-f64") (param f64 f64) (result f64) (local.get 1))
(func (export "param-mixed") (param f32 i32) (param) (param $x i64) (param i32 f64 i32)
(result f64)
(drop (f32.neg (get_local 0)))
(drop (i32.eqz (get_local 1)))
(drop (i64.eqz (get_local 2)))
(drop (i32.eqz (get_local 3)))
(drop (f64.neg (get_local 4)))
(drop (i32.eqz (get_local 5)))
(get_local 4)
(drop (f32.neg (local.get 0)))
(drop (i32.eqz (local.get 1)))
(drop (i64.eqz (local.get 2)))
(drop (i32.eqz (local.get 3)))
(drop (f64.neg (local.get 4)))
(drop (i32.eqz (local.get 5)))
(local.get 4)
)
;; Typing of result
@ -136,25 +136,25 @@
)
(func (export "break-br_if-empty") (param i32)
(br_if 0 (get_local 0))
(br_if 0 (local.get 0))
)
(func (export "break-br_if-num") (param i32) (result i32)
(drop (br_if 0 (i32.const 50) (get_local 0))) (i32.const 51)
(drop (br_if 0 (i32.const 50) (local.get 0))) (i32.const 51)
)
(func (export "break-br_table-empty") (param i32)
(br_table 0 0 0 (get_local 0))
(br_table 0 0 0 (local.get 0))
)
(func (export "break-br_table-num") (param i32) (result i32)
(br_table 0 0 (i32.const 50) (get_local 0)) (i32.const 51)
(br_table 0 0 (i32.const 50) (local.get 0)) (i32.const 51)
)
(func (export "break-br_table-nested-empty") (param i32)
(block (br_table 0 1 0 (get_local 0)))
(block (br_table 0 1 0 (local.get 0)))
)
(func (export "break-br_table-nested-num") (param i32) (result i32)
(i32.add
(block (result i32)
(br_table 0 1 0 (i32.const 50) (get_local 0)) (i32.const 51)
(br_table 0 1 0 (i32.const 50) (local.get 0)) (i32.const 51)
)
(i32.const 2)
)
@ -162,10 +162,10 @@
;; Default initialization of locals
(func (export "init-local-i32") (result i32) (local i32) (get_local 0))
(func (export "init-local-i64") (result i64) (local i64) (get_local 0))
(func (export "init-local-f32") (result f32) (local f32) (get_local 0))
(func (export "init-local-f64") (result f64) (local f64) (get_local 0))
(func (export "init-local-i32") (result i32) (local i32) (local.get 0))
(func (export "init-local-i64") (result i64) (local i64) (local.get 0))
(func (export "init-local-f32") (result f32) (local f32) (local.get 0))
(func (export "init-local-f64") (result f64) (local f64) (local.get 0))
)
(assert_return (invoke "type-use-1"))
@ -325,7 +325,7 @@
(type $empty-sig-duplicate (func))
(type $complex-sig-duplicate (func (param i64 i64 f64 i64 f64 i64 f32 i32)))
(table anyfunc
(table funcref
(elem
$complex-sig-3 $empty-sig-2 $complex-sig-1 $complex-sig-3 $empty-sig-1
$complex-sig-4 $complex-sig-5
@ -458,15 +458,15 @@
;; Invalid typing of locals
(assert_invalid
(module (func $type-local-num-vs-num (result i64) (local i32) (get_local 0)))
(module (func $type-local-num-vs-num (result i64) (local i32) (local.get 0)))
"type mismatch"
)
(assert_invalid
(module (func $type-local-num-vs-num (local f32) (i32.eqz (get_local 0))))
(module (func $type-local-num-vs-num (local f32) (i32.eqz (local.get 0))))
"type mismatch"
)
(assert_invalid
(module (func $type-local-num-vs-num (local f64 i64) (f64.neg (get_local 1))))
(module (func $type-local-num-vs-num (local f64 i64) (f64.neg (local.get 1))))
"type mismatch"
)
@ -474,15 +474,15 @@
;; Invalid typing of parameters
(assert_invalid
(module (func $type-param-num-vs-num (param i32) (result i64) (get_local 0)))
(module (func $type-param-num-vs-num (param i32) (result i64) (local.get 0)))
"type mismatch"
)
(assert_invalid
(module (func $type-param-num-vs-num (param f32) (i32.eqz (get_local 0))))
(module (func $type-param-num-vs-num (param f32) (i32.eqz (local.get 0))))
"type mismatch"
)
(assert_invalid
(module (func $type-param-num-vs-num (param f64 i64) (f64.neg (get_local 1))))
(module (func $type-param-num-vs-num (param f64 i64) (f64.neg (local.get 1))))
"type mismatch"
)
@ -652,10 +652,10 @@
"unexpected token"
)
(assert_malformed
(module quote "(func (local i32) (result i32) (get_local 0))")
(module quote "(func (local i32) (result i32) (local.get 0))")
"unexpected token"
)
(assert_malformed
(module quote "(func (result i32) (param i32) (get_local 0))")
(module quote "(func (result i32) (param i32) (local.get 0))")
"unexpected token"
)

View File

@ -13,15 +13,15 @@
(func (type $S))
(func (export "one") (type 4) (i32.const 13))
(func (export "two") (type $T) (i32.add (get_local 0) (i32.const 1)))
(func (export "two") (type $T) (i32.add (local.get 0) (i32.const 1)))
;; Both signature and parameters are allowed (and required to match)
;; since this allows the naming of parameters.
(func (export "three") (type $T) (param $a i32) (result i32)
(i32.sub (get_local 0) (i32.const 2))
(i32.sub (local.get 0) (i32.const 2))
)
(func (export "four") (type $U) (call $print (get_local 0)))
(func (export "four") (type $U) (call $print (local.get 0)))
)
(assert_return (invoke "one") (i32.const 13))
@ -33,15 +33,15 @@
(assert_invalid (module (elem (i32.const 0) 0) (func)) "unknown table")
(assert_invalid
(module (table 1 anyfunc) (elem (i64.const 0)))
(module (table 1 funcref) (elem (i64.const 0)))
"type mismatch"
)
(assert_invalid
(module (table 1 anyfunc) (elem (i32.ctz (i32.const 0))))
(module (table 1 funcref) (elem (i32.ctz (i32.const 0))))
"constant expression required"
)
(assert_invalid
(module (table 1 anyfunc) (elem (nop)))
(module (table 1 funcref) (elem (nop)))
"constant expression required"
)
@ -51,7 +51,7 @@
(module
(type $T (func (param) (result i32)))
(type $U (func (param) (result i32)))
(table anyfunc (elem $t1 $t2 $t3 $u1 $u2 $t1 $t3))
(table funcref (elem $t1 $t2 $t3 $u1 $u2 $t1 $t3))
(func $t1 (type $T) (i32.const 1))
(func $t2 (type $T) (i32.const 2))
@ -60,11 +60,11 @@
(func $u2 (type $U) (i32.const 5))
(func (export "callt") (param $i i32) (result i32)
(call_indirect (type $T) (get_local $i))
(call_indirect (type $T) (local.get $i))
)
(func (export "callu") (param $i i32) (result i32)
(call_indirect (type $U) (get_local $i))
(call_indirect (type $U) (local.get $i))
)
)
@ -92,13 +92,13 @@
(module
(type $T (func (result i32)))
(table anyfunc (elem 0 1))
(table funcref (elem 0 1))
(func $t1 (type $T) (i32.const 1))
(func $t2 (type $T) (i32.const 2))
(func (export "callt") (param $i i32) (result i32)
(call_indirect (type $T) (get_local $i))
(call_indirect (type $T) (local.get $i))
)
)

View File

@ -1,148 +0,0 @@
;; Test `get_local` operator
(module
;; Typing
(func (export "type-local-i32") (result i32) (local i32) (get_local 0))
(func (export "type-local-i64") (result i64) (local i64) (get_local 0))
(func (export "type-local-f32") (result f32) (local f32) (get_local 0))
(func (export "type-local-f64") (result f64) (local f64) (get_local 0))
(func (export "type-param-i32") (param i32) (result i32) (get_local 0))
(func (export "type-param-i64") (param i64) (result i64) (get_local 0))
(func (export "type-param-f32") (param f32) (result f32) (get_local 0))
(func (export "type-param-f64") (param f64) (result f64) (get_local 0))
(func (export "type-mixed") (param i64 f32 f64 i32 i32)
(local f32 i64 i64 f64)
(drop (i64.eqz (get_local 0)))
(drop (f32.neg (get_local 1)))
(drop (f64.neg (get_local 2)))
(drop (i32.eqz (get_local 3)))
(drop (i32.eqz (get_local 4)))
(drop (f32.neg (get_local 5)))
(drop (i64.eqz (get_local 6)))
(drop (i64.eqz (get_local 7)))
(drop (f64.neg (get_local 8)))
)
;; Reading
(func (export "read") (param i64 f32 f64 i32 i32) (result f64)
(local f32 i64 i64 f64)
(set_local 5 (f32.const 5.5))
(set_local 6 (i64.const 6))
(set_local 8 (f64.const 8))
(f64.add
(f64.convert_u/i64 (get_local 0))
(f64.add
(f64.promote/f32 (get_local 1))
(f64.add
(get_local 2)
(f64.add
(f64.convert_u/i32 (get_local 3))
(f64.add
(f64.convert_s/i32 (get_local 4))
(f64.add
(f64.promote/f32 (get_local 5))
(f64.add
(f64.convert_u/i64 (get_local 6))
(f64.add
(f64.convert_u/i64 (get_local 7))
(get_local 8)
)
)
)
)
)
)
)
)
)
)
(assert_return (invoke "type-local-i32") (i32.const 0))
(assert_return (invoke "type-local-i64") (i64.const 0))
(assert_return (invoke "type-local-f32") (f32.const 0))
(assert_return (invoke "type-local-f64") (f64.const 0))
(assert_return (invoke "type-param-i32" (i32.const 2)) (i32.const 2))
(assert_return (invoke "type-param-i64" (i64.const 3)) (i64.const 3))
(assert_return (invoke "type-param-f32" (f32.const 4.4)) (f32.const 4.4))
(assert_return (invoke "type-param-f64" (f64.const 5.5)) (f64.const 5.5))
(assert_return
(invoke "type-mixed"
(i64.const 1) (f32.const 2.2) (f64.const 3.3) (i32.const 4) (i32.const 5)
)
)
(assert_return
(invoke "read"
(i64.const 1) (f32.const 2) (f64.const 3.3) (i32.const 4) (i32.const 5)
)
(f64.const 34.8)
)
;; Invalid typing of access to locals
(assert_invalid
(module (func $type-local-num-vs-num (result i64) (local i32) (get_local 0)))
"type mismatch"
)
(assert_invalid
(module (func $type-local-num-vs-num (local f32) (i32.eqz (get_local 0))))
"type mismatch"
)
(assert_invalid
(module (func $type-local-num-vs-num (local f64 i64) (f64.neg (get_local 1))))
"type mismatch"
)
;; Invalid typing of access to parameters
(assert_invalid
(module (func $type-param-num-vs-num (param i32) (result i64) (get_local 0)))
"type mismatch"
)
(assert_invalid
(module (func $type-param-num-vs-num (param f32) (i32.eqz (get_local 0))))
"type mismatch"
)
(assert_invalid
(module (func $type-param-num-vs-num (param f64 i64) (f64.neg (get_local 1))))
"type mismatch"
)
;; Invalid local index
(assert_invalid
(module (func $unbound-local (local i32 i64) (get_local 3)))
"unknown local"
)
(assert_invalid
(module (func $large-local (local i32 i64) (get_local 14324343)))
"unknown local"
)
(assert_invalid
(module (func $unbound-param (param i32 i64) (get_local 2)))
"unknown local"
)
(assert_invalid
(module (func $large-param (local i32 i64) (get_local 714324343)))
"unknown local"
)
(assert_invalid
(module (func $unbound-mixed (param i32) (local i32 i64) (get_local 3)))
"unknown local"
)
(assert_invalid
(module (func $large-mixed (param i64) (local i32 i64) (get_local 214324343)))
"unknown local"
)

View File

@ -1,4 +1,3 @@
;; Test globals
(module
@ -12,19 +11,19 @@
(global (;6;) (mut f64) (f64.const -14))
(global $y (mut i64) (i64.const -15))
(func (export "get-a") (result i32) (get_global $a))
(func (export "get-b") (result i64) (get_global $b))
(func (export "get-x") (result i32) (get_global $x))
(func (export "get-y") (result i64) (get_global $y))
(func (export "set-x") (param i32) (set_global $x (get_local 0)))
(func (export "set-y") (param i64) (set_global $y (get_local 0)))
(func (export "get-a") (result i32) (global.get $a))
(func (export "get-b") (result i64) (global.get $b))
(func (export "get-x") (result i32) (global.get $x))
(func (export "get-y") (result i64) (global.get $y))
(func (export "set-x") (param i32) (global.set $x (local.get 0)))
(func (export "set-y") (param i64) (global.set $y (local.get 0)))
(func (export "get-1") (result f32) (get_global 1))
(func (export "get-2") (result f64) (get_global 2))
(func (export "get-5") (result f32) (get_global 5))
(func (export "get-6") (result f64) (get_global 6))
(func (export "set-5") (param f32) (set_global 5 (get_local 0)))
(func (export "set-6") (param f64) (set_global 6 (get_local 0)))
(func (export "get-1") (result f32) (global.get 1))
(func (export "get-2") (result f64) (global.get 2))
(func (export "get-5") (result f32) (global.get 5))
(func (export "get-6") (result f64) (global.get 6))
(func (export "set-5") (param f32) (global.set 5 (local.get 0)))
(func (export "set-6") (param f64) (global.set 6 (local.get 0)))
;; As the argument of control constructs and instructions
@ -33,148 +32,148 @@
(func $dummy)
(func (export "as-select-first") (result i32)
(select (get_global $x) (i32.const 2) (i32.const 3))
(select (global.get $x) (i32.const 2) (i32.const 3))
)
(func (export "as-select-mid") (result i32)
(select (i32.const 2) (get_global $x) (i32.const 3))
(select (i32.const 2) (global.get $x) (i32.const 3))
)
(func (export "as-select-last") (result i32)
(select (i32.const 2) (i32.const 3) (get_global $x))
(select (i32.const 2) (i32.const 3) (global.get $x))
)
(func (export "as-loop-first") (result i32)
(loop (result i32)
(get_global $x) (call $dummy) (call $dummy)
(global.get $x) (call $dummy) (call $dummy)
)
)
(func (export "as-loop-mid") (result i32)
(loop (result i32)
(call $dummy) (get_global $x) (call $dummy)
(call $dummy) (global.get $x) (call $dummy)
)
)
(func (export "as-loop-last") (result i32)
(loop (result i32)
(call $dummy) (call $dummy) (get_global $x)
(call $dummy) (call $dummy) (global.get $x)
)
)
(func (export "as-if-condition") (result i32)
(if (result i32) (get_global $x)
(if (result i32) (global.get $x)
(then (call $dummy) (i32.const 2))
(else (call $dummy) (i32.const 3))
)
)
(func (export "as-if-then") (result i32)
(if (result i32) (i32.const 1)
(then (get_global $x)) (else (i32.const 2))
(then (global.get $x)) (else (i32.const 2))
)
)
(func (export "as-if-else") (result i32)
(if (result i32) (i32.const 0)
(then (i32.const 2)) (else (get_global $x))
(then (i32.const 2)) (else (global.get $x))
)
)
(func (export "as-br_if-first") (result i32)
(block (result i32)
(br_if 0 (get_global $x) (i32.const 2))
(br_if 0 (global.get $x) (i32.const 2))
(return (i32.const 3))
)
)
(func (export "as-br_if-last") (result i32)
(block (result i32)
(br_if 0 (i32.const 2) (get_global $x))
(br_if 0 (i32.const 2) (global.get $x))
(return (i32.const 3))
)
)
(func (export "as-br_table-first") (result i32)
(block (result i32)
(get_global $x) (i32.const 2) (br_table 0 0)
(global.get $x) (i32.const 2) (br_table 0 0)
)
)
(func (export "as-br_table-last") (result i32)
(block (result i32)
(i32.const 2) (get_global $x) (br_table 0 0)
(i32.const 2) (global.get $x) (br_table 0 0)
)
)
(func $func (param i32 i32) (result i32) (get_local 0))
(func $func (param i32 i32) (result i32) (local.get 0))
(type $check (func (param i32 i32) (result i32)))
(table anyfunc (elem $func))
(table funcref (elem $func))
(func (export "as-call_indirect-first") (result i32)
(block (result i32)
(call_indirect (type $check)
(get_global $x) (i32.const 2) (i32.const 0)
(global.get $x) (i32.const 2) (i32.const 0)
)
)
)
(func (export "as-call_indirect-mid") (result i32)
(block (result i32)
(call_indirect (type $check)
(i32.const 2) (get_global $x) (i32.const 0)
(i32.const 2) (global.get $x) (i32.const 0)
)
)
)
(func (export "as-call_indirect-last") (result i32)
(block (result i32)
(call_indirect (type $check)
(i32.const 2) (i32.const 0) (get_global $x)
(i32.const 2) (i32.const 0) (global.get $x)
)
)
)
(func (export "as-store-first")
(get_global $x) (i32.const 1) (i32.store)
(global.get $x) (i32.const 1) (i32.store)
)
(func (export "as-store-last")
(i32.const 0) (get_global $x) (i32.store)
(i32.const 0) (global.get $x) (i32.store)
)
(func (export "as-load-operand") (result i32)
(i32.load (get_global $x))
(i32.load (global.get $x))
)
(func (export "as-memory.grow-value") (result i32)
(memory.grow (get_global $x))
(memory.grow (global.get $x))
)
(func $f (param i32) (result i32) (get_local 0))
(func $f (param i32) (result i32) (local.get 0))
(func (export "as-call-value") (result i32)
(call $f (get_global $x))
(call $f (global.get $x))
)
(func (export "as-return-value") (result i32)
(get_global $x) (return)
(global.get $x) (return)
)
(func (export "as-drop-operand")
(drop (get_global $x))
(drop (global.get $x))
)
(func (export "as-br-value") (result i32)
(block (result i32) (br 0 (get_global $x)))
(block (result i32) (br 0 (global.get $x)))
)
(func (export "as-set_local-value") (param i32) (result i32)
(set_local 0 (get_global $x))
(get_local 0)
(func (export "as-local.set-value") (param i32) (result i32)
(local.set 0 (global.get $x))
(local.get 0)
)
(func (export "as-tee_local-value") (param i32) (result i32)
(tee_local 0 (get_global $x))
(func (export "as-local.tee-value") (param i32) (result i32)
(local.tee 0 (global.get $x))
)
(func (export "as-set_global-value") (result i32)
(set_global $x (get_global $x))
(get_global $x)
(func (export "as-global.set-value") (result i32)
(global.set $x (global.get $x))
(global.get $x)
)
(func (export "as-unary-operand") (result i32)
(i32.eqz (get_global $x))
(i32.eqz (global.get $x))
)
(func (export "as-binary-operand") (result i32)
(i32.mul
(get_global $x) (get_global $x)
(global.get $x) (global.get $x)
)
)
(func (export "as-compare-operand") (result i32)
(i32.gt_u
(get_global 0) (i32.const 1)
(global.get 0) (i32.const 1)
)
)
)
@ -232,22 +231,21 @@
(assert_return (invoke "as-drop-operand"))
(assert_return (invoke "as-br-value") (i32.const 6))
(assert_return (invoke "as-set_local-value" (i32.const 1)) (i32.const 6))
(assert_return (invoke "as-tee_local-value" (i32.const 1)) (i32.const 6))
(assert_return (invoke "as-set_global-value") (i32.const 6))
(assert_return (invoke "as-local.set-value" (i32.const 1)) (i32.const 6))
(assert_return (invoke "as-local.tee-value" (i32.const 1)) (i32.const 6))
(assert_return (invoke "as-global.set-value") (i32.const 6))
(assert_return (invoke "as-unary-operand") (i32.const 0))
(assert_return (invoke "as-binary-operand") (i32.const 36))
(assert_return (invoke "as-compare-operand") (i32.const 1))
(assert_invalid
(module (global f32 (f32.const 0)) (func (set_global 0 (i32.const 1))))
(module (global f32 (f32.const 0)) (func (global.set 0 (f32.const 1))))
"global is immutable"
)
;; mutable globals can be exported
(module (global (mut f32) (f32.const 0)) (export "a" (global 0)))
(module (global (export "a") (mut f32) (f32.const 0)))
(assert_invalid
@ -256,7 +254,7 @@
)
(assert_invalid
(module (global f32 (get_local 0)))
(module (global f32 (local.get 0)))
"constant expression required"
)
@ -285,41 +283,28 @@
"type mismatch"
)
(assert_invalid
(module (global i32 (i32.const 0)) (global i64 (get_global 1)))
"unknown global"
)
(assert_invalid
(module (global i32 (;empty instruction sequence;)))
"type mismatch"
)
(assert_invalid
(module (global i32 (get_global 0)))
(module (global i32 (global.get 0)))
"unknown global"
)
(assert_invalid
(module (global i32 (get_global 1)) (global i32 (i32.const 0)))
(module (global i32 (global.get 1)) (global i32 (i32.const 0)))
"unknown global"
)
(module
(import "spectest" "global_i32" (global i32))
(global i32 (get_global 0))
(func (export "get-0") (result i32) (get_global 0))
(func (export "get-0-ref") (result i32) (get_global 1))
)
(assert_return (invoke "get-0") (i32.const 666))
(assert_return (invoke "get-0-ref") (i32.const 666))
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\02\94\80\80\80\00" ;; import section
"\02\98\80\80\80\00" ;; import section
"\01" ;; length 1
"\08\73\70\65\63\74\65\73\74" ;; "spectest"
"\0a\67\6c\6f\62\61\6c\5f\69\33\32" ;; "global_i32"
@ -332,7 +317,7 @@
(assert_malformed
(module binary
"\00asm" "\01\00\00\00"
"\02\94\80\80\80\00" ;; import section
"\02\98\80\80\80\00" ;; import section
"\01" ;; length 1
"\08\73\70\65\63\74\65\73\74" ;; "spectest"
"\0a\67\6c\6f\62\61\6c\5f\69\33\32" ;; "global_i32"
@ -370,3 +355,128 @@
)
"invalid mutability"
)
(assert_invalid
(module
(global $x (mut i32) (i32.const 0))
(func $type-global.set-value-empty
(global.set $x)
)
)
"type mismatch"
)
(assert_invalid
(module
(global $x (mut i32) (i32.const 0))
(func $type-global.set-value-empty-in-block
(i32.const 0)
(block (global.set $x))
)
)
"type mismatch"
)
(assert_invalid
(module
(global $x (mut i32) (i32.const 0))
(func $type-global.set-value-empty-in-loop
(i32.const 0)
(loop (global.set $x))
)
)
"type mismatch"
)
(assert_invalid
(module
(global $x (mut i32) (i32.const 0))
(func $type-global.set-value-empty-in-then
(i32.const 0) (i32.const 0)
(if (then (global.set $x)))
)
)
"type mismatch"
)
(assert_invalid
(module
(global $x (mut i32) (i32.const 0))
(func $type-global.set-value-empty-in-else
(i32.const 0) (i32.const 0)
(if (result i32) (then (i32.const 0)) (else (global.set $x)))
)
)
"type mismatch"
)
(assert_invalid
(module
(global $x (mut i32) (i32.const 0))
(func $type-global.set-value-empty-in-br
(i32.const 0)
(block (br 0 (global.set $x)))
)
)
"type mismatch"
)
(assert_invalid
(module
(global $x (mut i32) (i32.const 0))
(func $type-global.set-value-empty-in-br_if
(i32.const 0)
(block (br_if 0 (global.set $x)))
)
)
"type mismatch"
)
(assert_invalid
(module
(global $x (mut i32) (i32.const 0))
(func $type-global.set-value-empty-in-br_table
(i32.const 0)
(block (br_table 0 (global.set $x)))
)
)
"type mismatch"
)
(assert_invalid
(module
(global $x (mut i32) (i32.const 0))
(func $type-global.set-value-empty-in-return
(return (global.set $x))
)
)
"type mismatch"
)
(assert_invalid
(module
(global $x (mut i32) (i32.const 0))
(func $type-global.set-value-empty-in-select
(select (global.set $x) (i32.const 1) (i32.const 2))
)
)
"type mismatch"
)
(assert_invalid
(module
(global $x (mut i32) (i32.const 0))
(func $type-global.set-value-empty-in-call
(call 1 (global.set $x))
)
(func (param i32) (result i32) (local.get 0))
)
"type mismatch"
)
(assert_invalid
(module
(global $x (mut i32) (i32.const 0))
(func $f (param i32) (result i32) (local.get 0))
(type $sig (func (param i32) (result i32)))
(table funcref (elem $f))
(func $type-global.set-value-empty-in-call_indirect
(block (result i32)
(call_indirect (type $sig)
(global.set $x) (i32.const 0)
)
)
)
)
"type mismatch"
)

View File

@ -1,35 +1,35 @@
;; i32 operations
(module
(func (export "add") (param $x i32) (param $y i32) (result i32) (i32.add (get_local $x) (get_local $y)))
(func (export "sub") (param $x i32) (param $y i32) (result i32) (i32.sub (get_local $x) (get_local $y)))
(func (export "mul") (param $x i32) (param $y i32) (result i32) (i32.mul (get_local $x) (get_local $y)))
(func (export "div_s") (param $x i32) (param $y i32) (result i32) (i32.div_s (get_local $x) (get_local $y)))
(func (export "div_u") (param $x i32) (param $y i32) (result i32) (i32.div_u (get_local $x) (get_local $y)))
(func (export "rem_s") (param $x i32) (param $y i32) (result i32) (i32.rem_s (get_local $x) (get_local $y)))
(func (export "rem_u") (param $x i32) (param $y i32) (result i32) (i32.rem_u (get_local $x) (get_local $y)))
(func (export "and") (param $x i32) (param $y i32) (result i32) (i32.and (get_local $x) (get_local $y)))
(func (export "or") (param $x i32) (param $y i32) (result i32) (i32.or (get_local $x) (get_local $y)))
(func (export "xor") (param $x i32) (param $y i32) (result i32) (i32.xor (get_local $x) (get_local $y)))
(func (export "shl") (param $x i32) (param $y i32) (result i32) (i32.shl (get_local $x) (get_local $y)))
(func (export "shr_s") (param $x i32) (param $y i32) (result i32) (i32.shr_s (get_local $x) (get_local $y)))
(func (export "shr_u") (param $x i32) (param $y i32) (result i32) (i32.shr_u (get_local $x) (get_local $y)))
(func (export "rotl") (param $x i32) (param $y i32) (result i32) (i32.rotl (get_local $x) (get_local $y)))
(func (export "rotr") (param $x i32) (param $y i32) (result i32) (i32.rotr (get_local $x) (get_local $y)))
(func (export "clz") (param $x i32) (result i32) (i32.clz (get_local $x)))
(func (export "ctz") (param $x i32) (result i32) (i32.ctz (get_local $x)))
(func (export "popcnt") (param $x i32) (result i32) (i32.popcnt (get_local $x)))
(func (export "eqz") (param $x i32) (result i32) (i32.eqz (get_local $x)))
(func (export "eq") (param $x i32) (param $y i32) (result i32) (i32.eq (get_local $x) (get_local $y)))
(func (export "ne") (param $x i32) (param $y i32) (result i32) (i32.ne (get_local $x) (get_local $y)))
(func (export "lt_s") (param $x i32) (param $y i32) (result i32) (i32.lt_s (get_local $x) (get_local $y)))
(func (export "lt_u") (param $x i32) (param $y i32) (result i32) (i32.lt_u (get_local $x) (get_local $y)))
(func (export "le_s") (param $x i32) (param $y i32) (result i32) (i32.le_s (get_local $x) (get_local $y)))
(func (export "le_u") (param $x i32) (param $y i32) (result i32) (i32.le_u (get_local $x) (get_local $y)))
(func (export "gt_s") (param $x i32) (param $y i32) (result i32) (i32.gt_s (get_local $x) (get_local $y)))
(func (export "gt_u") (param $x i32) (param $y i32) (result i32) (i32.gt_u (get_local $x) (get_local $y)))
(func (export "ge_s") (param $x i32) (param $y i32) (result i32) (i32.ge_s (get_local $x) (get_local $y)))
(func (export "ge_u") (param $x i32) (param $y i32) (result i32) (i32.ge_u (get_local $x) (get_local $y)))
(func (export "add") (param $x i32) (param $y i32) (result i32) (i32.add (local.get $x) (local.get $y)))
(func (export "sub") (param $x i32) (param $y i32) (result i32) (i32.sub (local.get $x) (local.get $y)))
(func (export "mul") (param $x i32) (param $y i32) (result i32) (i32.mul (local.get $x) (local.get $y)))
(func (export "div_s") (param $x i32) (param $y i32) (result i32) (i32.div_s (local.get $x) (local.get $y)))
(func (export "div_u") (param $x i32) (param $y i32) (result i32) (i32.div_u (local.get $x) (local.get $y)))
(func (export "rem_s") (param $x i32) (param $y i32) (result i32) (i32.rem_s (local.get $x) (local.get $y)))
(func (export "rem_u") (param $x i32) (param $y i32) (result i32) (i32.rem_u (local.get $x) (local.get $y)))
(func (export "and") (param $x i32) (param $y i32) (result i32) (i32.and (local.get $x) (local.get $y)))
(func (export "or") (param $x i32) (param $y i32) (result i32) (i32.or (local.get $x) (local.get $y)))
(func (export "xor") (param $x i32) (param $y i32) (result i32) (i32.xor (local.get $x) (local.get $y)))
(func (export "shl") (param $x i32) (param $y i32) (result i32) (i32.shl (local.get $x) (local.get $y)))
(func (export "shr_s") (param $x i32) (param $y i32) (result i32) (i32.shr_s (local.get $x) (local.get $y)))
(func (export "shr_u") (param $x i32) (param $y i32) (result i32) (i32.shr_u (local.get $x) (local.get $y)))
(func (export "rotl") (param $x i32) (param $y i32) (result i32) (i32.rotl (local.get $x) (local.get $y)))
(func (export "rotr") (param $x i32) (param $y i32) (result i32) (i32.rotr (local.get $x) (local.get $y)))
(func (export "clz") (param $x i32) (result i32) (i32.clz (local.get $x)))
(func (export "ctz") (param $x i32) (result i32) (i32.ctz (local.get $x)))
(func (export "popcnt") (param $x i32) (result i32) (i32.popcnt (local.get $x)))
(func (export "eqz") (param $x i32) (result i32) (i32.eqz (local.get $x)))
(func (export "eq") (param $x i32) (param $y i32) (result i32) (i32.eq (local.get $x) (local.get $y)))
(func (export "ne") (param $x i32) (param $y i32) (result i32) (i32.ne (local.get $x) (local.get $y)))
(func (export "lt_s") (param $x i32) (param $y i32) (result i32) (i32.lt_s (local.get $x) (local.get $y)))
(func (export "lt_u") (param $x i32) (param $y i32) (result i32) (i32.lt_u (local.get $x) (local.get $y)))
(func (export "le_s") (param $x i32) (param $y i32) (result i32) (i32.le_s (local.get $x) (local.get $y)))
(func (export "le_u") (param $x i32) (param $y i32) (result i32) (i32.le_u (local.get $x) (local.get $y)))
(func (export "gt_s") (param $x i32) (param $y i32) (result i32) (i32.gt_s (local.get $x) (local.get $y)))
(func (export "gt_u") (param $x i32) (param $y i32) (result i32) (i32.gt_u (local.get $x) (local.get $y)))
(func (export "ge_s") (param $x i32) (param $y i32) (result i32) (i32.ge_s (local.get $x) (local.get $y)))
(func (export "ge_u") (param $x i32) (param $y i32) (result i32) (i32.ge_u (local.get $x) (local.get $y)))
)
(assert_return (invoke "add" (i32.const 1) (i32.const 1)) (i32.const 2))
@ -419,3 +419,539 @@
(assert_return (invoke "ge_u" (i32.const -1) (i32.const 0x80000000)) (i32.const 1))
(assert_return (invoke "ge_u" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 1))
(assert_return (invoke "ge_u" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 0))
(assert_invalid
(module
(func $type-unary-operand-empty
(i32.eqz) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-unary-operand-empty-in-block
(i32.const 0)
(block (i32.eqz) (drop))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-unary-operand-empty-in-loop
(i32.const 0)
(loop (i32.eqz) (drop))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-unary-operand-empty-in-if
(i32.const 0) (i32.const 0)
(if (then (i32.eqz) (drop)))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-unary-operand-empty-in-else
(i32.const 0) (i32.const 0)
(if (result i32) (then (i32.const 0)) (else (i32.eqz))) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-unary-operand-empty-in-br
(i32.const 0)
(block (br 0 (i32.eqz)) (drop))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-unary-operand-empty-in-br_if
(i32.const 0)
(block (br_if 0 (i32.eqz) (i32.const 1)) (drop))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-unary-operand-empty-in-br_table
(i32.const 0)
(block (br_table 0 (i32.eqz)) (drop))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-unary-operand-empty-in-return
(return (i32.eqz)) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-unary-operand-empty-in-select
(select (i32.eqz) (i32.const 1) (i32.const 2)) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-unary-operand-empty-in-call
(call 1 (i32.eqz)) (drop)
)
(func (param i32) (result i32) (local.get 0))
)
"type mismatch"
)
(assert_invalid
(module
(func $f (param i32) (result i32) (local.get 0))
(type $sig (func (param i32) (result i32)))
(table funcref (elem $f))
(func $type-unary-operand-empty-in-call_indirect
(block (result i32)
(call_indirect (type $sig)
(i32.eqz) (i32.const 0)
)
(drop)
)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-unary-operand-empty-in-local.set
(local i32)
(local.set 0 (i32.eqz)) (local.get 0) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-unary-operand-empty-in-local.tee
(local i32)
(local.tee 0 (i32.eqz)) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(global $x (mut i32) (i32.const 0))
(func $type-unary-operand-empty-in-global.set
(global.set $x (i32.eqz)) (global.get $x) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(memory 0)
(func $type-unary-operand-empty-in-memory.grow
(memory.grow (i32.eqz)) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(memory 0)
(func $type-unary-operand-empty-in-load
(i32.load (i32.eqz)) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(memory 1)
(func $type-unary-operand-empty-in-store
(i32.store (i32.eqz) (i32.const 1))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-1st-operand-empty
(i32.add) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-2nd-operand-empty
(i32.const 0) (i32.add) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-1st-operand-empty-in-block
(i32.const 0) (i32.const 0)
(block (i32.add) (drop))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-2nd-operand-empty-in-block
(i32.const 0)
(block (i32.const 0) (i32.add) (drop))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-1st-operand-empty-in-loop
(i32.const 0) (i32.const 0)
(loop (i32.add) (drop))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-2nd-operand-empty-in-loop
(i32.const 0)
(loop (i32.const 0) (i32.add) (drop))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-1st-operand-empty-in-if
(i32.const 0) (i32.const 0) (i32.const 0)
(if (i32.add) (then (drop)))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-2nd-operand-empty-in-if
(i32.const 0) (i32.const 0)
(if (i32.const 0) (then (i32.add)) (else (drop)))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-1st-operand-empty-in-else
(i32.const 0) (i32.const 0) (i32.const 0)
(if (result i32) (then (i32.const 0)) (else (i32.add) (i32.const 0)))
(drop) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-2nd-operand-empty-in-else
(i32.const 0) (i32.const 0)
(if (result i32) (then (i32.const 0)) (else (i32.add)))
(drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-1st-operand-empty-in-br
(i32.const 0) (i32.const 0)
(block (br 0 (i32.add)) (drop))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-2nd-operand-empty-in-br
(i32.const 0)
(block (br 0 (i32.const 0) (i32.add)) (drop))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-1st-operand-empty-in-br_if
(i32.const 0) (i32.const 0)
(block (br_if 0 (i32.add) (i32.const 1)) (drop))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-2nd-operand-empty-in-br_if
(i32.const 0)
(block (br_if 0 (i32.const 0) (i32.add) (i32.const 1)) (drop))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-1st-operand-empty-in-br_table
(i32.const 0) (i32.const 0)
(block (br_table 0 (i32.add)) (drop))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-2nd-operand-empty-in-br_table
(i32.const 0)
(block (br_table 0 (i32.const 0) (i32.add)) (drop))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-1st-operand-empty-in-return
(return (i32.add)) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-2nd-operand-empty-in-return
(return (i32.const 0) (i32.add)) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-1st-operand-empty-in-select
(select (i32.add) (i32.const 1) (i32.const 2)) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-2nd-operand-empty-in-select
(select (i32.const 0) (i32.add) (i32.const 1) (i32.const 2)) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-1st-operand-empty-in-call
(call 1 (i32.add)) (drop)
)
(func (param i32 i32) (result i32) (local.get 0))
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-2nd-operand-empty-in-call
(call 1 (i32.const 0) (i32.add)) (drop)
)
(func (param i32 i32) (result i32) (local.get 0))
)
"type mismatch"
)
(assert_invalid
(module
(func $f (param i32) (result i32) (local.get 0))
(type $sig (func (param i32) (result i32)))
(table funcref (elem $f))
(func $type-binary-1st-operand-empty-in-call_indirect
(block (result i32)
(call_indirect (type $sig)
(i32.add) (i32.const 0)
)
(drop)
)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $f (param i32) (result i32) (local.get 0))
(type $sig (func (param i32) (result i32)))
(table funcref (elem $f))
(func $type-binary-2nd-operand-empty-in-call_indirect
(block (result i32)
(call_indirect (type $sig)
(i32.const 0) (i32.add) (i32.const 0)
)
(drop)
)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-1st-operand-empty-in-local.set
(local i32)
(local.set 0 (i32.add)) (local.get 0) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-2nd-operand-empty-in-local.set
(local i32)
(local.set 0 (i32.const 0) (i32.add)) (local.get 0) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-1st-operand-empty-in-local.tee
(local i32)
(local.tee 0 (i32.add)) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-binary-2nd-operand-empty-in-local.tee
(local i32)
(local.tee 0 (i32.const 0) (i32.add)) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(global $x (mut i32) (i32.const 0))
(func $type-binary-1st-operand-empty-in-global.set
(global.set $x (i32.add)) (global.get $x) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(global $x (mut i32) (i32.const 0))
(func $type-binary-2nd-operand-empty-in-global.set
(global.set $x (i32.const 0) (i32.add)) (global.get $x) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(memory 0)
(func $type-binary-1st-operand-empty-in-memory.grow
(memory.grow (i32.add)) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(memory 0)
(func $type-binary-2nd-operand-empty-in-memory.grow
(memory.grow (i32.const 0) (i32.add)) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(memory 0)
(func $type-binary-1st-operand-empty-in-load
(i32.load (i32.add)) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(memory 0)
(func $type-binary-2nd-operand-empty-in-load
(i32.load (i32.const 0) (i32.add)) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(memory 1)
(func $type-binary-1st-operand-empty-in-store
(i32.store (i32.add) (i32.const 1))
)
)
"type mismatch"
)
(assert_invalid
(module
(memory 1)
(func $type-binary-2nd-operand-empty-in-store
(i32.store (i32.const 1) (i32.add) (i32.const 0))
)
)
"type mismatch"
)
;; Type check
(assert_invalid (module (func (result i32) (i32.add (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.and (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.div_s (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.div_u (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.mul (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.or (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.rem_s (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.rem_u (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.rotl (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.rotr (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.shl (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.shr_s (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.shr_u (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.sub (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.xor (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.eqz (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.clz (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.ctz (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.popcnt (i64.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.eq (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.ge_s (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.ge_u (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.gt_s (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.gt_u (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.le_s (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.le_u (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.lt_s (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.lt_u (i64.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i32) (i32.ne (i64.const 0) (f32.const 0)))) "type mismatch")

View File

@ -1,35 +1,35 @@
;; i64 operations
(module
(func (export "add") (param $x i64) (param $y i64) (result i64) (i64.add (get_local $x) (get_local $y)))
(func (export "sub") (param $x i64) (param $y i64) (result i64) (i64.sub (get_local $x) (get_local $y)))
(func (export "mul") (param $x i64) (param $y i64) (result i64) (i64.mul (get_local $x) (get_local $y)))
(func (export "div_s") (param $x i64) (param $y i64) (result i64) (i64.div_s (get_local $x) (get_local $y)))
(func (export "div_u") (param $x i64) (param $y i64) (result i64) (i64.div_u (get_local $x) (get_local $y)))
(func (export "rem_s") (param $x i64) (param $y i64) (result i64) (i64.rem_s (get_local $x) (get_local $y)))
(func (export "rem_u") (param $x i64) (param $y i64) (result i64) (i64.rem_u (get_local $x) (get_local $y)))
(func (export "and") (param $x i64) (param $y i64) (result i64) (i64.and (get_local $x) (get_local $y)))
(func (export "or") (param $x i64) (param $y i64) (result i64) (i64.or (get_local $x) (get_local $y)))
(func (export "xor") (param $x i64) (param $y i64) (result i64) (i64.xor (get_local $x) (get_local $y)))
(func (export "shl") (param $x i64) (param $y i64) (result i64) (i64.shl (get_local $x) (get_local $y)))
(func (export "shr_s") (param $x i64) (param $y i64) (result i64) (i64.shr_s (get_local $x) (get_local $y)))
(func (export "shr_u") (param $x i64) (param $y i64) (result i64) (i64.shr_u (get_local $x) (get_local $y)))
(func (export "rotl") (param $x i64) (param $y i64) (result i64) (i64.rotl (get_local $x) (get_local $y)))
(func (export "rotr") (param $x i64) (param $y i64) (result i64) (i64.rotr (get_local $x) (get_local $y)))
(func (export "clz") (param $x i64) (result i64) (i64.clz (get_local $x)))
(func (export "ctz") (param $x i64) (result i64) (i64.ctz (get_local $x)))
(func (export "popcnt") (param $x i64) (result i64) (i64.popcnt (get_local $x)))
(func (export "eqz") (param $x i64) (result i32) (i64.eqz (get_local $x)))
(func (export "eq") (param $x i64) (param $y i64) (result i32) (i64.eq (get_local $x) (get_local $y)))
(func (export "ne") (param $x i64) (param $y i64) (result i32) (i64.ne (get_local $x) (get_local $y)))
(func (export "lt_s") (param $x i64) (param $y i64) (result i32) (i64.lt_s (get_local $x) (get_local $y)))
(func (export "lt_u") (param $x i64) (param $y i64) (result i32) (i64.lt_u (get_local $x) (get_local $y)))
(func (export "le_s") (param $x i64) (param $y i64) (result i32) (i64.le_s (get_local $x) (get_local $y)))
(func (export "le_u") (param $x i64) (param $y i64) (result i32) (i64.le_u (get_local $x) (get_local $y)))
(func (export "gt_s") (param $x i64) (param $y i64) (result i32) (i64.gt_s (get_local $x) (get_local $y)))
(func (export "gt_u") (param $x i64) (param $y i64) (result i32) (i64.gt_u (get_local $x) (get_local $y)))
(func (export "ge_s") (param $x i64) (param $y i64) (result i32) (i64.ge_s (get_local $x) (get_local $y)))
(func (export "ge_u") (param $x i64) (param $y i64) (result i32) (i64.ge_u (get_local $x) (get_local $y)))
(func (export "add") (param $x i64) (param $y i64) (result i64) (i64.add (local.get $x) (local.get $y)))
(func (export "sub") (param $x i64) (param $y i64) (result i64) (i64.sub (local.get $x) (local.get $y)))
(func (export "mul") (param $x i64) (param $y i64) (result i64) (i64.mul (local.get $x) (local.get $y)))
(func (export "div_s") (param $x i64) (param $y i64) (result i64) (i64.div_s (local.get $x) (local.get $y)))
(func (export "div_u") (param $x i64) (param $y i64) (result i64) (i64.div_u (local.get $x) (local.get $y)))
(func (export "rem_s") (param $x i64) (param $y i64) (result i64) (i64.rem_s (local.get $x) (local.get $y)))
(func (export "rem_u") (param $x i64) (param $y i64) (result i64) (i64.rem_u (local.get $x) (local.get $y)))
(func (export "and") (param $x i64) (param $y i64) (result i64) (i64.and (local.get $x) (local.get $y)))
(func (export "or") (param $x i64) (param $y i64) (result i64) (i64.or (local.get $x) (local.get $y)))
(func (export "xor") (param $x i64) (param $y i64) (result i64) (i64.xor (local.get $x) (local.get $y)))
(func (export "shl") (param $x i64) (param $y i64) (result i64) (i64.shl (local.get $x) (local.get $y)))
(func (export "shr_s") (param $x i64) (param $y i64) (result i64) (i64.shr_s (local.get $x) (local.get $y)))
(func (export "shr_u") (param $x i64) (param $y i64) (result i64) (i64.shr_u (local.get $x) (local.get $y)))
(func (export "rotl") (param $x i64) (param $y i64) (result i64) (i64.rotl (local.get $x) (local.get $y)))
(func (export "rotr") (param $x i64) (param $y i64) (result i64) (i64.rotr (local.get $x) (local.get $y)))
(func (export "clz") (param $x i64) (result i64) (i64.clz (local.get $x)))
(func (export "ctz") (param $x i64) (result i64) (i64.ctz (local.get $x)))
(func (export "popcnt") (param $x i64) (result i64) (i64.popcnt (local.get $x)))
(func (export "eqz") (param $x i64) (result i32) (i64.eqz (local.get $x)))
(func (export "eq") (param $x i64) (param $y i64) (result i32) (i64.eq (local.get $x) (local.get $y)))
(func (export "ne") (param $x i64) (param $y i64) (result i32) (i64.ne (local.get $x) (local.get $y)))
(func (export "lt_s") (param $x i64) (param $y i64) (result i32) (i64.lt_s (local.get $x) (local.get $y)))
(func (export "lt_u") (param $x i64) (param $y i64) (result i32) (i64.lt_u (local.get $x) (local.get $y)))
(func (export "le_s") (param $x i64) (param $y i64) (result i32) (i64.le_s (local.get $x) (local.get $y)))
(func (export "le_u") (param $x i64) (param $y i64) (result i32) (i64.le_u (local.get $x) (local.get $y)))
(func (export "gt_s") (param $x i64) (param $y i64) (result i32) (i64.gt_s (local.get $x) (local.get $y)))
(func (export "gt_u") (param $x i64) (param $y i64) (result i32) (i64.gt_u (local.get $x) (local.get $y)))
(func (export "ge_s") (param $x i64) (param $y i64) (result i32) (i64.ge_s (local.get $x) (local.get $y)))
(func (export "ge_u") (param $x i64) (param $y i64) (result i32) (i64.ge_u (local.get $x) (local.get $y)))
)
(assert_return (invoke "add" (i64.const 1) (i64.const 1)) (i64.const 2))
@ -419,3 +419,36 @@
(assert_return (invoke "ge_u" (i64.const -1) (i64.const 0x8000000000000000)) (i32.const 1))
(assert_return (invoke "ge_u" (i64.const 0x8000000000000000) (i64.const 0x7fffffffffffffff)) (i32.const 1))
(assert_return (invoke "ge_u" (i64.const 0x7fffffffffffffff) (i64.const 0x8000000000000000)) (i32.const 0))
;; Type check
(assert_invalid (module (func (result i64) (i64.add (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.and (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.div_s (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.div_u (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.mul (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.or (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.rem_s (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.rem_u (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.rotl (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.rotr (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.shl (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.shr_s (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.shr_u (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.sub (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.xor (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.eqz (i32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.clz (i32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.ctz (i32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.popcnt (i32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.eq (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.ge_s (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.ge_u (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.gt_s (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.gt_u (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.le_s (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.le_u (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.lt_s (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.lt_u (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result i64) (i64.ne (i32.const 0) (f32.const 0)))) "type mismatch")

View File

@ -7,41 +7,41 @@
(func $dummy)
(func (export "empty") (param i32)
(if (get_local 0) (then))
(if (get_local 0) (then) (else))
(if $l (get_local 0) (then))
(if $l (get_local 0) (then) (else))
(if (local.get 0) (then))
(if (local.get 0) (then) (else))
(if $l (local.get 0) (then))
(if $l (local.get 0) (then) (else))
)
(func (export "singular") (param i32) (result i32)
(if (get_local 0) (then (nop)))
(if (get_local 0) (then (nop)) (else (nop)))
(if (result i32) (get_local 0) (then (i32.const 7)) (else (i32.const 8)))
(if (local.get 0) (then (nop)))
(if (local.get 0) (then (nop)) (else (nop)))
(if (result i32) (local.get 0) (then (i32.const 7)) (else (i32.const 8)))
)
(func (export "multi") (param i32) (result i32)
(if (get_local 0) (then (call $dummy) (call $dummy) (call $dummy)))
(if (get_local 0) (then) (else (call $dummy) (call $dummy) (call $dummy)))
(if (result i32) (get_local 0)
(if (local.get 0) (then (call $dummy) (call $dummy) (call $dummy)))
(if (local.get 0) (then) (else (call $dummy) (call $dummy) (call $dummy)))
(if (result i32) (local.get 0)
(then (call $dummy) (call $dummy) (i32.const 8))
(else (call $dummy) (call $dummy) (i32.const 9))
)
)
(func (export "nested") (param i32 i32) (result i32)
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then
(if (get_local 1) (then (call $dummy) (block) (nop)))
(if (get_local 1) (then) (else (call $dummy) (block) (nop)))
(if (result i32) (get_local 1)
(if (local.get 1) (then (call $dummy) (block) (nop)))
(if (local.get 1) (then) (else (call $dummy) (block) (nop)))
(if (result i32) (local.get 1)
(then (call $dummy) (i32.const 9))
(else (call $dummy) (i32.const 10))
)
)
(else
(if (get_local 1) (then (call $dummy) (block) (nop)))
(if (get_local 1) (then) (else (call $dummy) (block) (nop)))
(if (result i32) (get_local 1)
(if (local.get 1) (then (call $dummy) (block) (nop)))
(if (local.get 1) (then) (else (call $dummy) (block) (nop)))
(if (result i32) (local.get 1)
(then (call $dummy) (i32.const 10))
(else (call $dummy) (i32.const 11))
)
@ -51,7 +51,7 @@
(func (export "as-select-first") (param i32) (result i32)
(select
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (call $dummy) (i32.const 1))
(else (call $dummy) (i32.const 0))
)
@ -61,7 +61,7 @@
(func (export "as-select-mid") (param i32) (result i32)
(select
(i32.const 2)
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (call $dummy) (i32.const 1))
(else (call $dummy) (i32.const 0))
)
@ -71,7 +71,7 @@
(func (export "as-select-last") (param i32) (result i32)
(select
(i32.const 2) (i32.const 3)
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (call $dummy) (i32.const 1))
(else (call $dummy) (i32.const 0))
)
@ -80,7 +80,7 @@
(func (export "as-loop-first") (param i32) (result i32)
(loop (result i32)
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (call $dummy) (i32.const 1))
(else (call $dummy) (i32.const 0))
)
@ -90,7 +90,7 @@
(func (export "as-loop-mid") (param i32) (result i32)
(loop (result i32)
(call $dummy)
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (call $dummy) (i32.const 1))
(else (call $dummy) (i32.const 0))
)
@ -100,7 +100,7 @@
(func (export "as-loop-last") (param i32) (result i32)
(loop (result i32)
(call $dummy) (call $dummy)
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (call $dummy) (i32.const 1))
(else (call $dummy) (i32.const 0))
)
@ -109,7 +109,7 @@
(func (export "as-if-condition") (param i32) (result i32)
(if (result i32)
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (i32.const 1)) (else (i32.const 0))
)
(then (call $dummy) (i32.const 2))
@ -120,7 +120,7 @@
(func (export "as-br_if-first") (param i32) (result i32)
(block (result i32)
(br_if 0
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (call $dummy) (i32.const 1))
(else (call $dummy) (i32.const 0))
)
@ -133,7 +133,7 @@
(block (result i32)
(br_if 0
(i32.const 2)
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (call $dummy) (i32.const 1))
(else (call $dummy) (i32.const 0))
)
@ -144,7 +144,7 @@
(func (export "as-br_table-first") (param i32) (result i32)
(block (result i32)
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (call $dummy) (i32.const 1))
(else (call $dummy) (i32.const 0))
)
@ -155,7 +155,7 @@
(func (export "as-br_table-last") (param i32) (result i32)
(block (result i32)
(i32.const 2)
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (call $dummy) (i32.const 1))
(else (call $dummy) (i32.const 0))
)
@ -163,13 +163,13 @@
)
)
(func $func (param i32 i32) (result i32) (get_local 0))
(func $func (param i32 i32) (result i32) (local.get 0))
(type $check (func (param i32 i32) (result i32)))
(table anyfunc (elem $func))
(table funcref (elem $func))
(func (export "as-call_indirect-first") (param i32) (result i32)
(block (result i32)
(call_indirect (type $check)
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (call $dummy) (i32.const 1))
(else (call $dummy) (i32.const 0))
)
@ -181,7 +181,7 @@
(block (result i32)
(call_indirect (type $check)
(i32.const 2)
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (call $dummy) (i32.const 1))
(else (call $dummy) (i32.const 0))
)
@ -193,7 +193,7 @@
(block (result i32)
(call_indirect (type $check)
(i32.const 2) (i32.const 0)
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (call $dummy) (i32.const 1))
(else (call $dummy) (i32.const 0))
)
@ -202,7 +202,7 @@
)
(func (export "as-store-first") (param i32)
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (call $dummy) (i32.const 1))
(else (call $dummy) (i32.const 0))
)
@ -211,7 +211,7 @@
)
(func (export "as-store-last") (param i32)
(i32.const 2)
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (call $dummy) (i32.const 1))
(else (call $dummy) (i32.const 0))
)
@ -220,32 +220,32 @@
(func (export "as-memory.grow-value") (param i32) (result i32)
(memory.grow
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (i32.const 1))
(else (i32.const 0))
)
)
)
(func $f (param i32) (result i32) (get_local 0))
(func $f (param i32) (result i32) (local.get 0))
(func (export "as-call-value") (param i32) (result i32)
(call $f
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (i32.const 1))
(else (i32.const 0))
)
)
)
(func (export "as-return-value") (param i32) (result i32)
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (i32.const 1))
(else (i32.const 0)))
(return)
)
(func (export "as-drop-operand") (param i32)
(drop
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (i32.const 1))
(else (i32.const 0))
)
@ -254,43 +254,43 @@
(func (export "as-br-value") (param i32) (result i32)
(block (result i32)
(br 0
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (i32.const 1))
(else (i32.const 0))
)
)
)
)
(func (export "as-set_local-value") (param i32) (result i32)
(func (export "as-local.set-value") (param i32) (result i32)
(local i32)
(set_local 0
(if (result i32) (get_local 0)
(local.set 0
(if (result i32) (local.get 0)
(then (i32.const 1))
(else (i32.const 0))
)
)
(get_local 0)
(local.get 0)
)
(func (export "as-tee_local-value") (param i32) (result i32)
(tee_local 0
(if (result i32) (get_local 0)
(func (export "as-local.tee-value") (param i32) (result i32)
(local.tee 0
(if (result i32) (local.get 0)
(then (i32.const 1))
(else (i32.const 0))
)
)
)
(global $a (mut i32) (i32.const 10))
(func (export "as-set_global-value") (param i32) (result i32)
(set_global $a
(if (result i32) (get_local 0)
(func (export "as-global.set-value") (param i32) (result i32)
(global.set $a
(if (result i32) (local.get 0)
(then (i32.const 1))
(else (i32.const 0))
)
) (get_global $a)
) (global.get $a)
)
(func (export "as-load-operand") (param i32) (result i32)
(i32.load
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (i32.const 11))
(else (i32.const 10))
)
@ -299,7 +299,7 @@
(func (export "as-unary-operand") (param i32) (result i32)
(i32.ctz
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (call $dummy) (i32.const 13))
(else (call $dummy) (i32.const -13))
)
@ -307,11 +307,11 @@
)
(func (export "as-binary-operand") (param i32 i32) (result i32)
(i32.mul
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (call $dummy) (i32.const 3))
(else (call $dummy) (i32.const -3))
)
(if (result i32) (get_local 1)
(if (result i32) (local.get 1)
(then (call $dummy) (i32.const 4))
(else (call $dummy) (i32.const -5))
)
@ -319,7 +319,7 @@
)
(func (export "as-test-operand") (param i32) (result i32)
(i32.eqz
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (call $dummy) (i32.const 13))
(else (call $dummy) (i32.const 0))
)
@ -327,11 +327,11 @@
)
(func (export "as-compare-operand") (param i32 i32) (result i32)
(f32.gt
(if (result f32) (get_local 0)
(if (result f32) (local.get 0)
(then (call $dummy) (f32.const 3))
(else (call $dummy) (f32.const -3))
)
(if (result f32) (get_local 1)
(if (result f32) (local.get 1)
(then (call $dummy) (f32.const 4))
(else (call $dummy) (f32.const -4))
)
@ -352,7 +352,7 @@
)
(func (export "break-value") (param i32) (result i32)
(if (result i32) (get_local 0)
(if (result i32) (local.get 0)
(then (br 0 (i32.const 18)) (i32.const 19))
(else (br 0 (i32.const 21)) (i32.const 20))
)
@ -361,23 +361,23 @@
(func (export "effects") (param i32) (result i32)
(local i32)
(if
(block (result i32) (set_local 1 (i32.const 1)) (get_local 0))
(block (result i32) (local.set 1 (i32.const 1)) (local.get 0))
(then
(set_local 1 (i32.mul (get_local 1) (i32.const 3)))
(set_local 1 (i32.sub (get_local 1) (i32.const 5)))
(set_local 1 (i32.mul (get_local 1) (i32.const 7)))
(local.set 1 (i32.mul (local.get 1) (i32.const 3)))
(local.set 1 (i32.sub (local.get 1) (i32.const 5)))
(local.set 1 (i32.mul (local.get 1) (i32.const 7)))
(br 0)
(set_local 1 (i32.mul (get_local 1) (i32.const 100)))
(local.set 1 (i32.mul (local.get 1) (i32.const 100)))
)
(else
(set_local 1 (i32.mul (get_local 1) (i32.const 5)))
(set_local 1 (i32.sub (get_local 1) (i32.const 7)))
(set_local 1 (i32.mul (get_local 1) (i32.const 3)))
(local.set 1 (i32.mul (local.get 1) (i32.const 5)))
(local.set 1 (i32.sub (local.get 1) (i32.const 7)))
(local.set 1 (i32.mul (local.get 1) (i32.const 3)))
(br 0)
(set_local 1 (i32.mul (get_local 1) (i32.const 1000)))
(local.set 1 (i32.mul (local.get 1) (i32.const 1000)))
)
)
(get_local 1)
(local.get 1)
)
)
@ -459,14 +459,14 @@
(assert_return (invoke "as-br-value" (i32.const 0)) (i32.const 0))
(assert_return (invoke "as-br-value" (i32.const 1)) (i32.const 1))
(assert_return (invoke "as-set_local-value" (i32.const 0)) (i32.const 0))
(assert_return (invoke "as-set_local-value" (i32.const 1)) (i32.const 1))
(assert_return (invoke "as-local.set-value" (i32.const 0)) (i32.const 0))
(assert_return (invoke "as-local.set-value" (i32.const 1)) (i32.const 1))
(assert_return (invoke "as-tee_local-value" (i32.const 0)) (i32.const 0))
(assert_return (invoke "as-tee_local-value" (i32.const 1)) (i32.const 1))
(assert_return (invoke "as-local.tee-value" (i32.const 0)) (i32.const 0))
(assert_return (invoke "as-local.tee-value" (i32.const 1)) (i32.const 1))
(assert_return (invoke "as-set_global-value" (i32.const 0)) (i32.const 0))
(assert_return (invoke "as-set_global-value" (i32.const 1)) (i32.const 1))
(assert_return (invoke "as-global.set-value" (i32.const 0)) (i32.const 0))
(assert_return (invoke "as-global.set-value" (i32.const 1)) (i32.const 1))
(assert_return (invoke "as-load-operand" (i32.const 0)) (i32.const 0))
(assert_return (invoke "as-load-operand" (i32.const 1)) (i32.const 0))
@ -722,6 +722,174 @@
"type mismatch"
)
(assert_invalid
(module
(func $type-condition-empty
(if (then))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-condition-empty-in-block
(i32.const 0)
(block (if (then)))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-condition-empty-in-loop
(i32.const 0)
(loop (if (then)))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-condition-empty-in-then
(i32.const 0) (i32.const 0)
(if (then (if (then))))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-condition-empty-in-else
(i32.const 0) (i32.const 0)
(if (result i32) (then (i32.const 0)) (else (if (then)) (i32.const 0)))
(drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-condition-empty-in-br
(i32.const 0)
(block (br 0 (if(then))) (drop))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-condition-empty-in-br_if
(i32.const 0)
(block (br_if 0 (if(then)) (i32.const 1)) (drop))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-condition-empty-in-br_table
(i32.const 0)
(block (br_table 0 (if(then))) (drop))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-condition-empty-in-return
(return (if(then))) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-condition-empty-in-select
(select (if(then)) (i32.const 1) (i32.const 2)) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-condition-empty-in-call
(call 1 (if(then))) (drop)
)
(func (param i32) (result i32) (local.get 0))
)
"type mismatch"
)
(assert_invalid
(module
(func $f (param i32) (result i32) (local.get 0))
(type $sig (func (param i32) (result i32)))
(table funcref (elem $f))
(func $type-condition-empty-in-call_indirect
(block (result i32)
(call_indirect (type $sig)
(if(then)) (i32.const 0)
)
(drop)
)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-condition-empty-in-local.set
(local i32)
(local.set 0 (if(then))) (local.get 0) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-condition-empty-in-local.tee
(local i32)
(local.tee 0 (if(then))) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(global $x (mut i32) (i32.const 0))
(func $type-condition-empty-in-global.set
(global.set $x (if(then))) (global.get $x) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(memory 0)
(func $type-condition-empty-in-memory.grow
(memory.grow (if(then))) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(memory 0)
(func $type-condition-empty-in-load
(i32.load (if(then))) (drop)
)
)
"type mismatch"
)
(assert_invalid
(module
(memory 1)
(func $type-condition-empty-in-store
(i32.store (if(then)) (i32.const 1))
)
)
"type mismatch"
)
(assert_malformed
(module quote "(func if end $l)")

Some files were not shown because too many files have changed in this diff Show More