mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-24 06:01:33 +00:00
Merge branch 'master' into ventuzelo/fix-653-panic-memorydescriptor
This commit is contained in:
2
.github/pull_request_template.md
vendored
2
.github/pull_request_template.md
vendored
@ -12,4 +12,4 @@ links to related issues, and the context of the PR.
|
||||
|
||||
# Review
|
||||
|
||||
- [ ] Create a short description of the the change in the CHANGELOG.md file
|
||||
- [ ] Add a short description of the the change to the CHANGELOG.md file
|
||||
|
@ -6,6 +6,13 @@ Blocks of changes will separated by version increments.
|
||||
|
||||
## **[Unreleased]**
|
||||
|
||||
- [#829](https://github.com/wasmerio/wasmer/pull/829) Fix deps on `make bench-*` commands; benchmarks don't compile other backends now
|
||||
- [#807](https://github.com/wasmerio/wasmer/pull/807) Implement Send for `Instance`, breaking change on `ImportObject`, remove method `get_namespace` replaced with `with_namespace` and `maybe_with_namespace`
|
||||
- [#817](https://github.com/wasmerio/wasmer/pull/817) Add document for tracking features across backends and language integrations, [docs/feature_matrix.md]
|
||||
- [#823](https://github.com/wasmerio/wasmer/issues/823) Improved Emscripten / WASI integration
|
||||
- [#821](https://github.com/wasmerio/wasmer/issues/821) Remove patch version on most deps Cargo manifests. This gives Wasmer library users more control over which versions of the deps they use.
|
||||
- [#820](https://github.com/wasmerio/wasmer/issues/820) Remove null-pointer checks in `WasmPtr` from runtime-core, re-add them in Emscripten
|
||||
- [#803](https://github.com/wasmerio/wasmer/issues/803) Add method to `Ctx` to invoke functions by their `TableIndex`
|
||||
- [#790](https://github.com/wasmerio/wasmer/pull/790) Fix flaky test failure with LLVM, switch to large code model.
|
||||
- [#788](https://github.com/wasmerio/wasmer/pull/788) Use union merge on the changelog file.
|
||||
- [#785](https://github.com/wasmerio/wasmer/pull/785) Include Apache license file for spectests.
|
||||
|
153
Cargo.lock
generated
153
Cargo.lock
generated
@ -16,11 +16,6 @@ dependencies = [
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "approx"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.5"
|
||||
@ -75,7 +70,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.6 (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.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -123,7 +118,7 @@ dependencies = [
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -161,8 +156,8 @@ name = "cargo_toml"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -180,7 +175,7 @@ dependencies = [
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -205,16 +200,6 @@ name = "cfg-if"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cgmath"
|
||||
version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "0.28.1"
|
||||
@ -255,15 +240,6 @@ dependencies = [
|
||||
"cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winconsole 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.1.4"
|
||||
@ -333,8 +309,8 @@ dependencies = [
|
||||
"rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -398,7 +374,7 @@ dependencies = [
|
||||
"csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -481,7 +457,7 @@ name = "erased-serde"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -552,7 +528,7 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -629,7 +605,7 @@ name = "indexmap"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -810,14 +786,6 @@ dependencies = [
|
||||
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.8"
|
||||
@ -949,19 +917,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.0"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1108,11 +1064,6 @@ dependencies = [
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rgb"
|
||||
version = "0.8.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.16"
|
||||
@ -1178,10 +1129,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.100"
|
||||
version = "1.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1190,7 +1141,7 @@ 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.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1198,12 +1149,12 @@ name = "serde_bytes"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.100"
|
||||
version = "1.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1218,7 +1169,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 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1243,16 +1194,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "structopt"
|
||||
version = "0.3.1"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"structopt-derive 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"structopt-derive 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "structopt-derive"
|
||||
version = "0.3.1"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1333,7 +1284,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1378,7 +1329,7 @@ name = "tinytemplate"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -1387,7 +1338,7 @@ name = "toml"
|
||||
version = "0.4.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1395,7 +1346,7 @@ name = "toml"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1411,7 +1362,7 @@ dependencies = [
|
||||
"erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"inventory 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"typetag-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -1470,8 +1421,8 @@ name = "wabt"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wabt-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -1509,8 +1460,8 @@ dependencies = [
|
||||
"errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"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)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"structopt 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"structopt 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"typetag 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmer-clif-backend 0.7.0",
|
||||
@ -1539,10 +1490,10 @@ dependencies = [
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (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.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.101 (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)",
|
||||
"wasmer-clif-fork-wasm 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1590,7 +1541,7 @@ dependencies = [
|
||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.7.2 (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.7.0",
|
||||
]
|
||||
@ -1691,7 +1642,6 @@ dependencies = [
|
||||
"bincode 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"blake2b_simd 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.45 (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)",
|
||||
"field-offset 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1703,10 +1653,10 @@ 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.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (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.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.101 (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.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1717,7 +1667,6 @@ name = "wasmer-singlepass-backend"
|
||||
version = "0.7.0"
|
||||
dependencies = [
|
||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"colored 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dynasm 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dynasmrt 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1749,8 +1698,8 @@ dependencies = [
|
||||
"generational-arena 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (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)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"typetag 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmer-runtime-core 0.7.0",
|
||||
@ -1843,21 +1792,9 @@ dependencies = [
|
||||
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winconsole"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cgmath 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rgb 0.8.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[metadata]
|
||||
"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"
|
||||
"checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba"
|
||||
"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90"
|
||||
@ -1879,12 +1816,10 @@ dependencies = [
|
||||
"checksum cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc9a35e1f4290eb9e5fc54ba6cf40671ed2a2514c3eeb2b2a908dda2ea5a1be"
|
||||
"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"
|
||||
"checksum clang-sys 0.28.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81de550971c976f176130da4b2978d3b524eaa0fd9ac31f3ceb5ae1231fb4853"
|
||||
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
|
||||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
"checksum cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62"
|
||||
"checksum colored 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6cdb90b60f2927f8d76139c72dbde7e10c3a2bc47c8594c9c7a66529f2687c03"
|
||||
"checksum constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120"
|
||||
"checksum cranelift-bforest 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)" = "409f92af3dd276e112b72873a3ef02613e3c5f55b81d5d5d04f3157d4f8b8c54"
|
||||
"checksum cranelift-codegen 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b303542a56fba4cbaeea099fb30ed078b50de0e765fd69f7f5f410adbe31d95b"
|
||||
@ -1946,7 +1881,6 @@ dependencies = [
|
||||
"checksum nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b2e0b4f3320ed72aaedb9a5ac838690a8047c7b275da22711fddff4f8a14229"
|
||||
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
|
||||
"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
|
||||
"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
|
||||
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
|
||||
"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273"
|
||||
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
|
||||
@ -1963,8 +1897,7 @@ dependencies = [
|
||||
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
||||
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
|
||||
"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
|
||||
"checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c"
|
||||
"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412"
|
||||
"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
|
||||
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||
@ -1981,7 +1914,6 @@ dependencies = [
|
||||
"checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9"
|
||||
"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
|
||||
"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
|
||||
"checksum rgb 0.8.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2089e4031214d129e201f8c3c8c2fe97cd7322478a0d1cdf78e7029b0042efdb"
|
||||
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
|
||||
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997"
|
||||
@ -1991,17 +1923,17 @@ 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.100 (registry+https://github.com/rust-lang/crates.io-index)" = "f4473e8506b213730ff2061073b48fa51dcc66349219e2e7c5608f0296a1d95a"
|
||||
"checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd"
|
||||
"checksum serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d733da87e79faaac25616e33d26299a41143fd4cd42746cbb0e91d8feea243fd"
|
||||
"checksum serde_bytes 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "45af0182ff64abaeea290235eb67da3825a576c5d53e642c4d5b652e12e6effc"
|
||||
"checksum serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)" = "11e410fde43e157d789fc290d26bc940778ad0fdd47836426fbac36573710dbb"
|
||||
"checksum serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e"
|
||||
"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704"
|
||||
"checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
|
||||
"checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7"
|
||||
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
|
||||
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
"checksum structopt 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ac9d6e93dd792b217bf89cda5c14566e3043960c6f9da890c2ba5d09d07804c"
|
||||
"checksum structopt-derive 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ae9e5165d463a0dea76967d021f8d0f9316057bf5163aa2a4843790e842ff37"
|
||||
"checksum structopt 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe8d3289b63ef2f196d89e7701f986583c0895e764b78f052a55b9b5d34d84a"
|
||||
"checksum structopt-derive 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f3add731f5b4fb85931d362a3c92deb1ad7113649a8d51701fb257673705f122"
|
||||
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
|
||||
"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
|
||||
"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
|
||||
@ -2043,4 +1975,3 @@ dependencies = [
|
||||
"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
"checksum wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96f5016b18804d24db43cebf3c77269e7569b8954a8464501c216cc5e070eaa9"
|
||||
"checksum winconsole 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ef84b96d10db72dd980056666d7f1e7663ce93d82fa33b63e71c966f4cf5032"
|
||||
|
16
Cargo.toml
16
Cargo.toml
@ -19,9 +19,9 @@ include = [
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
byteorder = "1.3.2"
|
||||
errno = "0.2.4"
|
||||
structopt = "0.3.0"
|
||||
byteorder = "1.3"
|
||||
errno = "0.2"
|
||||
structopt = "0.3"
|
||||
wabt = "0.9.1"
|
||||
wasmer-clif-backend = { path = "lib/clif-backend" }
|
||||
wasmer-singlepass-backend = { path = "lib/singlepass-backend", optional = true }
|
||||
@ -58,13 +58,13 @@ members = [
|
||||
"lib/wasi-tests",
|
||||
"lib/emscripten-tests",
|
||||
"lib/middleware-common-tests",
|
||||
"examples/plugin-for-example"
|
||||
"examples/plugin-for-example",
|
||||
]
|
||||
|
||||
[build-dependencies]
|
||||
wabt = "0.9.1"
|
||||
glob = "0.3.0"
|
||||
rustc_version = "0.2.3"
|
||||
glob = "0.3"
|
||||
rustc_version = "0.2"
|
||||
|
||||
[dev-dependencies]
|
||||
serde = { version = "1", features = ["derive"] } # used by the plugin example
|
||||
@ -105,3 +105,7 @@ managed = ["backend-singlepass", "wasmer-runtime-core/managed"]
|
||||
[[example]]
|
||||
name = "plugin"
|
||||
crate-type = ["bin"]
|
||||
|
||||
[[example]]
|
||||
name = "callback"
|
||||
crate-type = ["bin"]
|
||||
|
36
Makefile
36
Makefile
@ -1,11 +1,15 @@
|
||||
.PHONY: spectests emtests clean build install lint precommit docs
|
||||
.PHONY: spectests emtests clean build install lint precommit docs examples
|
||||
|
||||
# Generate files
|
||||
generate-spectests:
|
||||
WASMER_RUNTIME_GENERATE_SPECTESTS=1 cargo build -p wasmer-runtime-core --release
|
||||
WASMER_RUNTIME_GENERATE_SPECTESTS=1 cargo build -p wasmer-runtime-core --release \
|
||||
&& echo "formatting" \
|
||||
&& cargo fmt
|
||||
|
||||
generate-emtests:
|
||||
WASM_EMSCRIPTEN_GENERATE_EMTESTS=1 cargo build -p wasmer-emscripten-tests --release
|
||||
WASM_EMSCRIPTEN_GENERATE_EMTESTS=1 cargo build -p wasmer-emscripten-tests --release \
|
||||
&& echo "formatting" \
|
||||
&& cargo fmt
|
||||
|
||||
generate-wasitests: wasitests-setup
|
||||
WASM_WASI_GENERATE_WASITESTS=1 cargo build -p wasmer-wasi-tests --release -vv \
|
||||
@ -111,12 +115,16 @@ test: spectests emtests middleware wasitests circleci-clean test-rest
|
||||
|
||||
|
||||
# Integration tests
|
||||
integration-tests: release-clif
|
||||
integration-tests: release-clif examples
|
||||
echo "Running Integration Tests"
|
||||
./integration_tests/lua/test.sh
|
||||
./integration_tests/nginx/test.sh
|
||||
./integration_tests/cowsay/test.sh
|
||||
|
||||
examples:
|
||||
cargo run --example plugin
|
||||
cargo run --example callback
|
||||
|
||||
|
||||
# Utils
|
||||
lint:
|
||||
@ -132,11 +140,15 @@ install:
|
||||
|
||||
# Checks
|
||||
check-bench-singlepass:
|
||||
cargo bench --all --no-run --no-default-features --features "backend-singlepass"
|
||||
cargo bench --all --no-run --no-default-features --features "backend-singlepass" \
|
||||
--exclude wasmer-clif-backend --exclude wasmer-llvm-backend --exclude wasmer-kernel-loader
|
||||
check-bench-clif:
|
||||
cargo bench --all --no-run --no-default-features --features "backend-cranelift"
|
||||
cargo bench --all --no-run --no-default-features --features "backend-cranelift" \
|
||||
--exclude wasmer-singlepass-backend --exclude wasmer-llvm-backend --exclude wasmer-kernel-loader \
|
||||
--exclude wasmer-middleware-common-tests
|
||||
check-bench-llvm:
|
||||
cargo bench --all --no-run --no-default-features --features "backend-llvm"
|
||||
cargo bench --all --no-run --no-default-features --features "backend-llvm" \
|
||||
--exclude wasmer-singlepass-backend --exclude wasmer-clif-backend --exclude wasmer-kernel-loader
|
||||
|
||||
check-bench: check-bench-singlepass check-bench-llvm
|
||||
|
||||
@ -160,11 +172,15 @@ release-llvm:
|
||||
cargo build --release --features backend-llvm
|
||||
|
||||
bench-singlepass:
|
||||
cargo bench --all --no-default-features --features "backend-singlepass"
|
||||
cargo bench --all --no-default-features --features "backend-singlepass" \
|
||||
--exclude wasmer-clif-backend --exclude wasmer-llvm-backend --exclude wasmer-kernel-loader
|
||||
bench-clif:
|
||||
cargo bench --all --no-default-features --features "backend-cranelift"
|
||||
cargo bench --all --no-default-features --features "backend-cranelift" \
|
||||
--exclude wasmer-singlepass-backend --exclude wasmer-llvm-backend --exclude wasmer-kernel-loader \
|
||||
--exclude wasmer-middleware-common-tests
|
||||
bench-llvm:
|
||||
cargo bench --all --no-default-features --features "backend-llvm"
|
||||
cargo bench --all --no-default-features --features "backend-llvm" \
|
||||
--exclude wasmer-singlepass-backend --exclude wasmer-clif-backend --exclude wasmer-kernel-loader
|
||||
|
||||
# Build utils
|
||||
build-install:
|
||||
|
26
docs/feature_matrix.md
Normal file
26
docs/feature_matrix.md
Normal file
@ -0,0 +1,26 @@
|
||||
# Feature Table
|
||||
|
||||
## Compiler Backend
|
||||
|
||||
| | Singlepass | Cranelift | LLVM |
|
||||
| - | - | - | - |
|
||||
| Caching | ❌ | ✅ | ✅ |
|
||||
| Emscripten | ✅ | ✅ | ✅ |
|
||||
| Metering | ✅ | ❌ | ✅ |
|
||||
| Multi-value return | ❌ | ❌ | ❌ |
|
||||
| OSR | 🚧 | ❓ | ❓ |
|
||||
| SIMD | ❌ | ❌ | ✅ |
|
||||
| WASI | ✅ | ✅ | ✅ |
|
||||
|
||||
|
||||
## Language integration
|
||||
|
||||
TODO: define a set of features that are relevant and mark them here
|
||||
|
||||
Current ideas:
|
||||
|
||||
- WASI FS API
|
||||
- Callbacks
|
||||
- Exiting early in hostcall
|
||||
- Metering
|
||||
- Caching
|
5
examples/callback-guest/README.md
Normal file
5
examples/callback-guest/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# Call back guest
|
||||
|
||||
This is part of the `callback` example. This Wasm module passes host imports and its own functions to the Wasm host to execute.
|
||||
|
||||
See `examples/callback.rs` for the host
|
24
examples/callback-guest/callback-guest.rs
Normal file
24
examples/callback-guest/callback-guest.rs
Normal file
@ -0,0 +1,24 @@
|
||||
extern "C" {
|
||||
fn call_guest_fn(f: u32) -> u32;
|
||||
fn call_guest_fn2(f: u32) -> u32;
|
||||
fn host_callback() -> u32;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
fn test_callback() -> u32 {
|
||||
42
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
fn test_callback2() -> u32 {
|
||||
45
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe { call_guest_fn(test_callback as usize as u32) };
|
||||
unsafe { call_guest_fn(host_callback as usize as u32) };
|
||||
unsafe { call_guest_fn(test_callback2 as usize as u32) };
|
||||
unsafe { call_guest_fn2(test_callback2 as usize as u32) };
|
||||
unsafe { call_guest_fn2(test_callback as usize as u32) };
|
||||
unsafe { call_guest_fn2(host_callback as usize as u32) };
|
||||
}
|
BIN
examples/callback-guest/callback-guest.wasm
Executable file
BIN
examples/callback-guest/callback-guest.wasm
Executable file
Binary file not shown.
46
examples/callback.rs
Normal file
46
examples/callback.rs
Normal file
@ -0,0 +1,46 @@
|
||||
/// This example demonstrates the use of callbacks: calling functions (Host and Wasm)
|
||||
/// passed to us from the Wasm via hostcall
|
||||
use wasmer_runtime::{compile_with, compiler_for_backend, func, imports, Backend, Ctx};
|
||||
use wasmer_runtime_core::{structures::TypedIndex, types::TableIndex};
|
||||
|
||||
static WASM: &'static str = "examples/callback-guest/callback-guest.wasm";
|
||||
|
||||
/// This function matches our arbitrarily decided callback signature
|
||||
/// in this example we'll only call functions that take no arguments and return one value
|
||||
fn host_callback(_ctx: &mut Ctx) -> u32 {
|
||||
55
|
||||
}
|
||||
|
||||
fn call_guest_fn(ctx: &mut Ctx, guest_fn: u32) -> u32 {
|
||||
// We get a TableIndex from our raw value passed in
|
||||
let guest_fn_typed = TableIndex::new(guest_fn as usize);
|
||||
// and use it to call the corresponding function
|
||||
let result = ctx.call_with_table_index(guest_fn_typed, &[]).unwrap();
|
||||
|
||||
println!("Guest fn {} returned {:?}", guest_fn, result);
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let wasm_bytes =
|
||||
std::fs::read(WASM).expect(&format!("Could not read in WASM plugin at {}", WASM));
|
||||
|
||||
let imports = imports! {
|
||||
"env" => {
|
||||
"call_guest_fn" => func!(call_guest_fn),
|
||||
"call_guest_fn2" => func!(call_guest_fn),
|
||||
"host_callback" => func!(host_callback),
|
||||
},
|
||||
};
|
||||
|
||||
let compiler = compiler_for_backend(Backend::default()).unwrap();
|
||||
let module = compile_with(&wasm_bytes[..], compiler.as_ref()).unwrap();
|
||||
let instance = module
|
||||
.instantiate(&imports)
|
||||
.expect("failed to instantiate wasm module");
|
||||
|
||||
let entry_point = instance.func::<(u32, u32), u32>("main").unwrap();
|
||||
|
||||
entry_point.call(0, 0).expect("START");
|
||||
}
|
@ -15,26 +15,26 @@ cranelift-codegen = { version = "0.31" }
|
||||
cranelift-entity = { version = "0.31" }
|
||||
cranelift-frontend = { package = "wasmer-clif-fork-frontend", version = "0.33" }
|
||||
cranelift-wasm = { package = "wasmer-clif-fork-wasm", version = "0.33" }
|
||||
target-lexicon = "0.4.0"
|
||||
target-lexicon = "0.4"
|
||||
wasmparser = "0.35.1"
|
||||
byteorder = "1.3.2"
|
||||
nix = "0.15.0"
|
||||
byteorder = "1.3"
|
||||
nix = "0.15"
|
||||
libc = "0.2.60"
|
||||
rayon = "1.1.0"
|
||||
rayon = "1.1"
|
||||
|
||||
# Dependencies for caching.
|
||||
[dependencies.serde]
|
||||
version = "1.0.99"
|
||||
version = "1.0"
|
||||
features = ["rc"]
|
||||
[dependencies.serde_derive]
|
||||
version = "1.0.98"
|
||||
version = "1.0"
|
||||
[dependencies.serde_bytes]
|
||||
version = "0.11.2"
|
||||
version = "0.11"
|
||||
[dependencies.serde-bench]
|
||||
version = "0.0.7"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winapi = { version = "0.3.8", features = ["errhandlingapi", "minwindef", "minwinbase", "winnt"] }
|
||||
winapi = { version = "0.3", features = ["errhandlingapi", "minwindef", "minwinbase", "winnt"] }
|
||||
wasmer-win-exception-handler = { path = "../win-exception-handler", version = "0.7.0" }
|
||||
|
||||
[features]
|
||||
|
@ -20,7 +20,7 @@ wabt = "0.9.1"
|
||||
wasmer-dev-utils = { path = "../dev-utils", version = "0.7.0"}
|
||||
|
||||
[build-dependencies]
|
||||
glob = "0.3.0"
|
||||
glob = "0.3"
|
||||
|
||||
[features]
|
||||
clif = []
|
||||
|
@ -8,14 +8,14 @@ repository = "https://github.com/wasmerio/wasmer"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
byteorder = "1.3.2"
|
||||
lazy_static = "1.4.0"
|
||||
byteorder = "1.3"
|
||||
lazy_static = "1.4"
|
||||
libc = "0.2.60"
|
||||
time = "0.1.42"
|
||||
time = "0.1"
|
||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.7.0" }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
rand = "0.7.0"
|
||||
rand = "0.7"
|
||||
|
||||
[features]
|
||||
debug = ["wasmer-runtime-core/debug"]
|
||||
|
12
lib/emscripten/src/env/mod.rs
vendored
12
lib/emscripten/src/env/mod.rs
vendored
@ -12,14 +12,14 @@ pub use self::windows::*;
|
||||
|
||||
use libc::c_char;
|
||||
|
||||
use crate::{allocate_on_stack, EmscriptenData};
|
||||
use crate::{
|
||||
allocate_on_stack,
|
||||
ptr::{Array, WasmPtr},
|
||||
EmscriptenData,
|
||||
};
|
||||
|
||||
use std::os::raw::c_int;
|
||||
use wasmer_runtime_core::{
|
||||
memory::ptr::{Array, WasmPtr},
|
||||
types::ValueType,
|
||||
vm::Ctx,
|
||||
};
|
||||
use wasmer_runtime_core::{types::ValueType, vm::Ctx};
|
||||
|
||||
pub fn call_malloc(ctx: &mut Ctx, size: u32) -> u32 {
|
||||
get_emscripten_data(ctx)
|
||||
|
6
lib/emscripten/src/env/unix/mod.rs
vendored
6
lib/emscripten/src/env/unix/mod.rs
vendored
@ -9,11 +9,9 @@ use std::mem;
|
||||
use std::os::raw::c_char;
|
||||
|
||||
use crate::env::{call_malloc, call_malloc_with_cast, EmAddrInfo, EmSockAddr};
|
||||
use crate::ptr::{Array, WasmPtr};
|
||||
use crate::utils::{copy_cstr_into_wasm, copy_terminated_array_of_cstrs};
|
||||
use wasmer_runtime_core::{
|
||||
memory::ptr::{Array, WasmPtr},
|
||||
vm::Ctx,
|
||||
};
|
||||
use wasmer_runtime_core::vm::Ctx;
|
||||
|
||||
// #[no_mangle]
|
||||
/// emscripten: _getenv // (name: *const char) -> *const c_char;
|
||||
|
3
lib/emscripten/src/env/windows/mod.rs
vendored
3
lib/emscripten/src/env/windows/mod.rs
vendored
@ -6,8 +6,9 @@ use std::mem;
|
||||
use std::os::raw::c_char;
|
||||
|
||||
use crate::env::{call_malloc, EmAddrInfo};
|
||||
use crate::ptr::WasmPtr;
|
||||
use crate::utils::{copy_cstr_into_wasm, read_string_from_wasm};
|
||||
use wasmer_runtime_core::{memory::ptr::WasmPtr, vm::Ctx};
|
||||
use wasmer_runtime_core::vm::Ctx;
|
||||
|
||||
extern "C" {
|
||||
#[link_name = "_putenv"]
|
||||
|
@ -62,6 +62,7 @@ mod math;
|
||||
mod memory;
|
||||
mod process;
|
||||
mod pthread;
|
||||
mod ptr;
|
||||
mod signal;
|
||||
mod storage;
|
||||
mod syscalls;
|
||||
@ -730,8 +731,9 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
||||
"___syscall345" => func!(crate::syscalls::___syscall345),
|
||||
|
||||
// Process
|
||||
"abort" => func!(crate::process::em_abort),
|
||||
"abort" => func!(crate::process::_abort),
|
||||
"_abort" => func!(crate::process::_abort),
|
||||
"_prctl" => func!(crate::process::_prctl),
|
||||
"abortStackOverflow" => func!(crate::process::abort_stack_overflow),
|
||||
"_llvm_trap" => func!(crate::process::_llvm_trap),
|
||||
"_fork" => func!(crate::process::_fork),
|
||||
@ -824,6 +826,9 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
||||
"_gmtime" => func!(crate::time::_gmtime),
|
||||
|
||||
// Math
|
||||
"sqrt" => func!(crate::math::sqrt),
|
||||
"floor" => func!(crate::math::floor),
|
||||
"fabs" => func!(crate::math::fabs),
|
||||
"f64-rem" => func!(crate::math::f64_rem),
|
||||
"_llvm_copysign_f32" => func!(crate::math::_llvm_copysign_f32),
|
||||
"_llvm_copysign_f64" => func!(crate::math::_llvm_copysign_f64),
|
||||
|
@ -88,6 +88,21 @@ pub fn log(_ctx: &mut Ctx, value: f64) -> f64 {
|
||||
value.ln()
|
||||
}
|
||||
|
||||
// emscripten: global.Math sqrt
|
||||
pub fn sqrt(_ctx: &mut Ctx, value: f64) -> f64 {
|
||||
value.sqrt()
|
||||
}
|
||||
|
||||
// emscripten: global.Math floor
|
||||
pub fn floor(_ctx: &mut Ctx, value: f64) -> f64 {
|
||||
value.floor()
|
||||
}
|
||||
|
||||
// emscripten: global.Math fabs
|
||||
pub fn fabs(_ctx: &mut Ctx, value: f64) -> f64 {
|
||||
value.abs()
|
||||
}
|
||||
|
||||
// emscripten: asm2wasm.f64-to-int
|
||||
pub fn f64_to_int(_ctx: &mut Ctx, value: f64) -> i32 {
|
||||
debug!("emscripten::f64_to_int {}", value);
|
||||
|
@ -1,11 +1,10 @@
|
||||
use libc::{abort, c_char, c_int, exit, EAGAIN};
|
||||
use libc::{abort, c_int, exit, EAGAIN};
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
type PidT = libc::pid_t;
|
||||
#[cfg(target_os = "windows")]
|
||||
type PidT = c_int;
|
||||
|
||||
use std::ffi::CStr;
|
||||
use wasmer_runtime_core::vm::Ctx;
|
||||
|
||||
pub fn abort_with_message(ctx: &mut Ctx, message: &str) {
|
||||
@ -21,6 +20,12 @@ pub fn _abort(_ctx: &mut Ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn _prctl(ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
debug!("emscripten::_prctl");
|
||||
abort_with_message(ctx, "missing function: prctl");
|
||||
-1
|
||||
}
|
||||
|
||||
pub fn _fork(_ctx: &mut Ctx) -> PidT {
|
||||
debug!("emscripten::_fork");
|
||||
// unsafe {
|
||||
@ -45,18 +50,6 @@ pub fn _exit(_ctx: &mut Ctx, status: c_int) {
|
||||
unsafe { exit(status) }
|
||||
}
|
||||
|
||||
pub fn em_abort(ctx: &mut Ctx, message: u32) {
|
||||
debug!("emscripten::em_abort {}", message);
|
||||
let message_addr = emscripten_memory_pointer!(ctx.memory(0), message) as *mut c_char;
|
||||
unsafe {
|
||||
let message = CStr::from_ptr(message_addr)
|
||||
.to_str()
|
||||
.unwrap_or("Unexpected abort");
|
||||
|
||||
abort_with_message(ctx, message);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn _kill(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
|
||||
debug!("emscripten::_kill");
|
||||
-1
|
||||
|
116
lib/emscripten/src/ptr.rs
Normal file
116
lib/emscripten/src/ptr.rs
Normal file
@ -0,0 +1,116 @@
|
||||
//! This is a wrapper around the `WasmPtr` abstraction that does not allow deref of address 0
|
||||
//! This is a common assumption in Emscripten code
|
||||
|
||||
// this is a wrapper with extra logic around the runtime-core `WasmPtr`, so we
|
||||
// don't want to warn about unusued code here
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::{cell::Cell, fmt};
|
||||
pub use wasmer_runtime_core::memory::ptr::Array;
|
||||
use wasmer_runtime_core::{
|
||||
memory::{ptr, Memory},
|
||||
types::{ValueType, WasmExternType},
|
||||
};
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct WasmPtr<T: Copy, Ty = ptr::Item>(ptr::WasmPtr<T, Ty>);
|
||||
|
||||
unsafe impl<T: Copy, Ty> ValueType for WasmPtr<T, Ty> {}
|
||||
impl<T: Copy, Ty> Copy for WasmPtr<T, Ty> {}
|
||||
|
||||
impl<T: Copy, Ty> Clone for WasmPtr<T, Ty> {
|
||||
fn clone(&self) -> Self {
|
||||
Self(self.0.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy, Ty> fmt::Debug for WasmPtr<T, Ty> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{:?}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: Copy, Ty> WasmExternType for WasmPtr<T, Ty> {
|
||||
type Native = <ptr::WasmPtr<T, Ty> as WasmExternType>::Native;
|
||||
|
||||
fn to_native(self) -> Self::Native {
|
||||
self.0.to_native()
|
||||
}
|
||||
fn from_native(n: Self::Native) -> Self {
|
||||
Self(ptr::WasmPtr::from_native(n))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy, Ty> PartialEq for WasmPtr<T, Ty> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.0 == other.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy, Ty> Eq for WasmPtr<T, Ty> {}
|
||||
|
||||
impl<T: Copy, Ty> WasmPtr<T, Ty> {
|
||||
#[inline(always)]
|
||||
pub fn new(offset: u32) -> Self {
|
||||
Self(ptr::WasmPtr::new(offset))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn offset(self) -> u32 {
|
||||
self.0.offset()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + ValueType> WasmPtr<T, ptr::Item> {
|
||||
#[inline(always)]
|
||||
pub fn deref<'a>(self, memory: &'a Memory) -> Option<&'a Cell<T>> {
|
||||
if self.0.offset() == 0 {
|
||||
None
|
||||
} else {
|
||||
self.0.deref(memory)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn deref_mut<'a>(self, memory: &'a Memory) -> Option<&'a mut Cell<T>> {
|
||||
if self.0.offset() == 0 {
|
||||
None
|
||||
} else {
|
||||
self.0.deref_mut(memory)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + ValueType> WasmPtr<T, ptr::Array> {
|
||||
#[inline(always)]
|
||||
pub fn deref<'a>(self, memory: &'a Memory, index: u32, length: u32) -> Option<&'a [Cell<T>]> {
|
||||
if self.0.offset() == 0 {
|
||||
None
|
||||
} else {
|
||||
self.0.deref(memory, index, length)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn deref_mut<'a>(
|
||||
self,
|
||||
memory: &'a Memory,
|
||||
index: u32,
|
||||
length: u32,
|
||||
) -> Option<&'a mut [Cell<T>]> {
|
||||
if self.0.offset() == 0 {
|
||||
None
|
||||
} else {
|
||||
self.0.deref_mut(memory, index, length)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn get_utf8_string<'a>(self, memory: &'a Memory, str_len: u32) -> Option<&'a str> {
|
||||
if self.0.offset() == 0 {
|
||||
None
|
||||
} else {
|
||||
self.0.get_utf8_string(memory, str_len)
|
||||
}
|
||||
}
|
||||
}
|
@ -10,7 +10,10 @@ pub use self::unix::*;
|
||||
#[cfg(windows)]
|
||||
pub use self::windows::*;
|
||||
|
||||
use crate::utils::{copy_stat_into_wasm, get_cstr_path, get_current_directory};
|
||||
use crate::{
|
||||
ptr::{Array, WasmPtr},
|
||||
utils::{copy_stat_into_wasm, get_cstr_path, get_current_directory},
|
||||
};
|
||||
|
||||
use super::varargs::VarArgs;
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
@ -40,10 +43,7 @@ use libc::{
|
||||
write,
|
||||
// ENOTTY,
|
||||
};
|
||||
use wasmer_runtime_core::{
|
||||
memory::ptr::{Array, WasmPtr},
|
||||
vm::Ctx,
|
||||
};
|
||||
use wasmer_runtime_core::vm::Ctx;
|
||||
|
||||
use super::env;
|
||||
use std::cell::Cell;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::varargs::VarArgs;
|
||||
use crate::{ptr::WasmPtr, varargs::VarArgs};
|
||||
#[cfg(target_os = "macos")]
|
||||
use libc::size_t;
|
||||
/// NOTE: TODO: These syscalls only support wasm_32 for now because they assume offsets are u32
|
||||
@ -111,7 +111,7 @@ fn translate_ioctl(wasm_ioctl: u32) -> c_ulong {
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use std::ffi::CStr;
|
||||
use wasmer_runtime_core::{memory::ptr::WasmPtr, vm::Ctx};
|
||||
use wasmer_runtime_core::vm::Ctx;
|
||||
|
||||
use crate::env::EmSockAddr;
|
||||
use crate::utils::{self, get_cstr_path};
|
||||
|
@ -24,7 +24,9 @@ pub fn is_emscripten_module(module: &Module) -> bool {
|
||||
.namespace_table
|
||||
.get(import_name.namespace_index);
|
||||
let field = module.info().name_table.get(import_name.name_index);
|
||||
if (field == "_emscripten_memcpy_big" || field == "emscripten_memcpy_big")
|
||||
if (field == "_emscripten_memcpy_big"
|
||||
|| field == "emscripten_memcpy_big"
|
||||
|| field == "__map_file")
|
||||
&& namespace == "env"
|
||||
{
|
||||
return true;
|
||||
|
@ -8,10 +8,10 @@ readme = "README.md"
|
||||
[dependencies]
|
||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.7.0" }
|
||||
wasmparser = "0.35.1"
|
||||
smallvec = "0.6.10"
|
||||
smallvec = "0.6"
|
||||
goblin = "0.0.24"
|
||||
libc = "0.2.60"
|
||||
capstone = { version = "0.6.0", optional = true }
|
||||
capstone = { version = "0.6", optional = true }
|
||||
byteorder = "1"
|
||||
|
||||
[dependencies.inkwell]
|
||||
@ -21,17 +21,17 @@ default-features = false
|
||||
features = ["llvm8-0", "target-x86"]
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
nix = "0.15.0"
|
||||
nix = "0.15"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winapi = { version = "0.3.8", features = ["memoryapi"] }
|
||||
winapi = { version = "0.3", features = ["memoryapi"] }
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0"
|
||||
lazy_static = "1.4.0"
|
||||
regex = "1.2.1"
|
||||
lazy_static = "1.4"
|
||||
regex = "1.2"
|
||||
semver = "0.9"
|
||||
rustc_version = "0.2.3"
|
||||
rustc_version = "0.2"
|
||||
|
||||
[dev-dependencies]
|
||||
wabt = "0.9.1"
|
||||
|
@ -1176,7 +1176,11 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
|
||||
BasicTypeEnum::FloatType(float_ty) => {
|
||||
float_ty.const_float(0.0).as_basic_value_enum()
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
_ => {
|
||||
return Err(CodegenError {
|
||||
message: "Operator::End phi type unimplemented".to_string(),
|
||||
});
|
||||
}
|
||||
};
|
||||
state.push1(placeholder_value);
|
||||
phi.as_instruction().erase_from_basic_block();
|
||||
@ -1741,7 +1745,12 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
|
||||
_ => value,
|
||||
});
|
||||
}
|
||||
_ => unimplemented!("multi-value returns"),
|
||||
_ => {
|
||||
return Err(CodegenError {
|
||||
message: "Operator::CallIndirect multi-value returns unimplemented"
|
||||
.to_string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6853,7 +6862,9 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
|
||||
state.push1(result.try_as_basic_value().left().unwrap());
|
||||
}
|
||||
_ => {
|
||||
unimplemented!("{:?}", op);
|
||||
return Err(CodegenError {
|
||||
message: format!("Operator {:?} unimplemented", op),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -6876,7 +6887,11 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
|
||||
"return",
|
||||
)));
|
||||
}
|
||||
_ => unimplemented!("multi-value returns not yet implemented"),
|
||||
_ => {
|
||||
return Err(CodegenError {
|
||||
message: "multi-value returns not yet implemented".to_string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -7051,7 +7066,10 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
|
||||
self.context.as_ref().unwrap(),
|
||||
self.builder.as_ref().unwrap(),
|
||||
self.intrinsics.as_ref().unwrap(),
|
||||
);
|
||||
)
|
||||
.map_err(|e| CodegenError {
|
||||
message: format!("trampolines generation error: {:?}", e),
|
||||
})?;
|
||||
|
||||
if let Some(path) = unsafe { &crate::GLOBAL_OPTIONS.pre_opt_ir } {
|
||||
self.module.print_to_file(path).unwrap();
|
||||
|
@ -20,7 +20,7 @@ pub fn generate_trampolines(
|
||||
context: &Context,
|
||||
builder: &Builder,
|
||||
intrinsics: &Intrinsics,
|
||||
) {
|
||||
) -> Result<(), String> {
|
||||
for (sig_index, sig) in info.signatures.iter() {
|
||||
let func_type = signatures[sig_index];
|
||||
|
||||
@ -42,8 +42,9 @@ pub fn generate_trampolines(
|
||||
Some(Linkage::External),
|
||||
);
|
||||
|
||||
generate_trampoline(trampoline_func, sig, context, builder, intrinsics);
|
||||
generate_trampoline(trampoline_func, sig, context, builder, intrinsics)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn generate_trampoline(
|
||||
@ -52,7 +53,7 @@ fn generate_trampoline(
|
||||
context: &Context,
|
||||
builder: &Builder,
|
||||
intrinsics: &Intrinsics,
|
||||
) {
|
||||
) -> Result<(), String> {
|
||||
let entry_block = context.append_basic_block(&trampoline_func, "entry");
|
||||
builder.position_at_end(&entry_block);
|
||||
|
||||
@ -64,7 +65,7 @@ fn generate_trampoline(
|
||||
args_ptr.into_pointer_value(),
|
||||
returns_ptr.into_pointer_value(),
|
||||
),
|
||||
_ => unimplemented!(),
|
||||
_ => return Err("trampoline function unimplemented".to_string()),
|
||||
};
|
||||
|
||||
let cast_ptr_ty = |wasmer_ty| match wasmer_ty {
|
||||
@ -108,8 +109,11 @@ fn generate_trampoline(
|
||||
call_site.try_as_basic_value().left().unwrap(),
|
||||
);
|
||||
}
|
||||
_ => unimplemented!("multi-value returns"),
|
||||
_ => {
|
||||
return Err("trampoline function multi-value returns unimplemented".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
builder.build_return(None);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -32,4 +32,4 @@ llvm-backend = ["wasmer-runtime/llvm", "wasmer-runtime/default-backend-llvm"]
|
||||
singlepass-backend = ["wasmer-runtime/singlepass", "wasmer-runtime/default-backend-singlepass"]
|
||||
|
||||
[build-dependencies]
|
||||
cbindgen = "0.9.1"
|
||||
cbindgen = "0.9"
|
||||
|
@ -242,7 +242,7 @@ int main()
|
||||
|
||||
wasmer_result_t call_result = wasmer_export_func_call(exported_function, inputs, inputs_arity, outputs, outputs_arity);
|
||||
|
||||
printf("Result: %lld\n", outputs[0].value.I64);
|
||||
printf("Result: %ld\n", outputs[0].value.I64);
|
||||
|
||||
assert(outputs[0].value.I64 == 7);
|
||||
assert(call_result == WASMER_OK);
|
||||
|
@ -8,47 +8,46 @@ repository = "https://github.com/wasmerio/wasmer"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
nix = "0.15.0"
|
||||
page_size = "0.4.1"
|
||||
nix = "0.15"
|
||||
page_size = "0.4"
|
||||
wasmparser = "0.35.1"
|
||||
parking_lot = "0.9.0"
|
||||
lazy_static = "1.4.0"
|
||||
errno = "0.2.4"
|
||||
parking_lot = "0.9"
|
||||
lazy_static = "1.4"
|
||||
errno = "0.2"
|
||||
libc = "0.2.60"
|
||||
hex = "0.3.2"
|
||||
smallvec = "0.6.10"
|
||||
hex = "0.3"
|
||||
smallvec = "0.6"
|
||||
bincode = "1.1"
|
||||
colored = "1.8"
|
||||
|
||||
[dependencies.indexmap]
|
||||
version = "1.2.0"
|
||||
version = "1.2"
|
||||
features = ["serde-1"]
|
||||
|
||||
# Dependencies for caching.
|
||||
[dependencies.serde]
|
||||
version = "1.0.99"
|
||||
version = "1.0"
|
||||
# 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"
|
||||
version = "1.0"
|
||||
[dependencies.serde_bytes]
|
||||
version = "0.11.2"
|
||||
version = "0.11"
|
||||
[dependencies.serde-bench]
|
||||
version = "0.0.7"
|
||||
[dependencies.blake2b_simd]
|
||||
version = "0.5.8"
|
||||
version = "0.5"
|
||||
[dependencies.digest]
|
||||
version = "0.8.1"
|
||||
version = "0.8"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winapi = { version = "0.3.8", features = ["memoryapi"] }
|
||||
winapi = { version = "0.3", features = ["memoryapi"] }
|
||||
|
||||
[dev-dependencies]
|
||||
field-offset = "0.1.1"
|
||||
field-offset = "0.1"
|
||||
|
||||
[build-dependencies]
|
||||
blake2b_simd = "0.5.8"
|
||||
rustc_version = "0.2.3"
|
||||
blake2b_simd = "0.5"
|
||||
rustc_version = "0.2"
|
||||
cc = "1.0"
|
||||
|
||||
[features]
|
||||
|
@ -81,7 +81,7 @@ pushq %r8
|
||||
pushq %r9
|
||||
pushq %r10
|
||||
|
||||
callq get_boundary_register_preservation
|
||||
callq get_boundary_register_preservation@PLT
|
||||
|
||||
# Keep this consistent with BoundaryRegisterPreservation
|
||||
movq %r15, 0(%rax)
|
||||
|
@ -54,6 +54,9 @@ pub struct LocalBacking {
|
||||
pub(crate) internals: Internals,
|
||||
}
|
||||
|
||||
// Manually implemented because LocalBacking contains raw pointers directly
|
||||
unsafe impl Send for LocalBacking {}
|
||||
|
||||
impl LocalBacking {
|
||||
pub(crate) fn new(
|
||||
module: &ModuleInner,
|
||||
@ -461,6 +464,9 @@ pub struct ImportBacking {
|
||||
pub(crate) vm_globals: BoxedMap<ImportedGlobalIndex, *mut vm::LocalGlobal>,
|
||||
}
|
||||
|
||||
// manually implemented because ImportBacking contains raw pointers directly
|
||||
unsafe impl Send for ImportBacking {}
|
||||
|
||||
impl ImportBacking {
|
||||
pub fn new(
|
||||
module: &ModuleInner,
|
||||
@ -536,9 +542,8 @@ fn import_functions(
|
||||
let namespace = module.info.namespace_table.get(*namespace_index);
|
||||
let name = module.info.name_table.get(*name_index);
|
||||
|
||||
let import = imports
|
||||
.get_namespace(namespace)
|
||||
.and_then(|namespace| namespace.get_export(name));
|
||||
let import =
|
||||
imports.maybe_with_namespace(namespace, |namespace| namespace.get_export(name));
|
||||
match import {
|
||||
Some(Export::Function {
|
||||
func,
|
||||
@ -624,9 +629,8 @@ fn import_memories(
|
||||
let namespace = module.info.namespace_table.get(*namespace_index);
|
||||
let name = module.info.name_table.get(*name_index);
|
||||
|
||||
let memory_import = imports
|
||||
.get_namespace(&namespace)
|
||||
.and_then(|namespace| namespace.get_export(&name));
|
||||
let memory_import =
|
||||
imports.maybe_with_namespace(namespace, |namespace| namespace.get_export(name));
|
||||
match memory_import {
|
||||
Some(Export::Memory(memory)) => {
|
||||
if expected_memory_desc.fits_in_imported(memory.descriptor()) {
|
||||
@ -696,9 +700,8 @@ fn import_tables(
|
||||
let namespace = module.info.namespace_table.get(*namespace_index);
|
||||
let name = module.info.name_table.get(*name_index);
|
||||
|
||||
let table_import = imports
|
||||
.get_namespace(&namespace)
|
||||
.and_then(|namespace| namespace.get_export(&name));
|
||||
let table_import =
|
||||
imports.maybe_with_namespace(namespace, |namespace| namespace.get_export(name));
|
||||
match table_import {
|
||||
Some(Export::Table(mut table)) => {
|
||||
if expected_table_desc.fits_in_imported(table.descriptor()) {
|
||||
@ -767,9 +770,8 @@ fn import_globals(
|
||||
{
|
||||
let namespace = module.info.namespace_table.get(*namespace_index);
|
||||
let name = module.info.name_table.get(*name_index);
|
||||
let import = imports
|
||||
.get_namespace(namespace)
|
||||
.and_then(|namespace| namespace.get_export(name));
|
||||
let import =
|
||||
imports.maybe_with_namespace(namespace, |namespace| namespace.get_export(name));
|
||||
match import {
|
||||
Some(Export::Global(mut global)) => {
|
||||
if global.descriptor() == *imported_global_desc {
|
||||
|
@ -11,6 +11,9 @@ pub enum Context {
|
||||
Internal,
|
||||
}
|
||||
|
||||
// Manually implemented because context contains a raw pointer to Ctx
|
||||
unsafe impl Send for Context {}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Export {
|
||||
Function {
|
||||
@ -26,6 +29,9 @@ pub enum Export {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FuncPointer(*const vm::Func);
|
||||
|
||||
// Manually implemented because FuncPointer contains a raw pointer to Ctx
|
||||
unsafe impl Send for FuncPointer {}
|
||||
|
||||
impl FuncPointer {
|
||||
/// This needs to be unsafe because there is
|
||||
/// no way to check whether the passed function
|
||||
|
@ -283,13 +283,10 @@ extern "C" fn signal_trap_handler(
|
||||
let image = build_instance_image(ctx, es_image);
|
||||
unwind_result = Box::new(image);
|
||||
} else {
|
||||
use colored::*;
|
||||
if es_image.frames.len() > 0 {
|
||||
eprintln!(
|
||||
"\n{}",
|
||||
"Wasmer encountered an error while running your WebAssembly program."
|
||||
.bold()
|
||||
.red()
|
||||
);
|
||||
es_image.print_backtrace_if_needed();
|
||||
}
|
||||
|
@ -4,11 +4,14 @@ use crate::{
|
||||
types::{GlobalDescriptor, Type, Value},
|
||||
vm,
|
||||
};
|
||||
use std::{cell::RefCell, fmt, rc::Rc};
|
||||
use std::{
|
||||
fmt,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
pub struct Global {
|
||||
desc: GlobalDescriptor,
|
||||
storage: Rc<RefCell<vm::LocalGlobal>>,
|
||||
storage: Arc<Mutex<vm::LocalGlobal>>,
|
||||
}
|
||||
|
||||
impl Global {
|
||||
@ -56,7 +59,7 @@ impl Global {
|
||||
|
||||
Self {
|
||||
desc,
|
||||
storage: Rc::new(RefCell::new(local_global)),
|
||||
storage: Arc::new(Mutex::new(local_global)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,7 +86,8 @@ impl Global {
|
||||
Value::V128(x) => x,
|
||||
},
|
||||
};
|
||||
*self.storage.borrow_mut() = local_global;
|
||||
let mut storage = self.storage.lock().unwrap();
|
||||
*storage = local_global;
|
||||
} else {
|
||||
panic!("Wrong type for setting this global")
|
||||
}
|
||||
@ -94,7 +98,8 @@ impl Global {
|
||||
|
||||
/// Get the value held by this global.
|
||||
pub fn get(&self) -> Value {
|
||||
let data = self.storage.borrow().data;
|
||||
let storage = self.storage.lock().unwrap();
|
||||
let data = storage.data;
|
||||
|
||||
match self.desc.ty {
|
||||
Type::I32 => Value::I32(data as i32),
|
||||
@ -105,8 +110,10 @@ impl Global {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: think about this and if this should now be unsafe
|
||||
pub(crate) fn vm_local_global(&mut self) -> *mut vm::LocalGlobal {
|
||||
&mut *self.storage.borrow_mut()
|
||||
let mut storage = self.storage.lock().unwrap();
|
||||
&mut *storage
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,7 +127,7 @@ impl Clone for Global {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
desc: self.desc,
|
||||
storage: Rc::clone(&self.storage),
|
||||
storage: Arc::clone(&self.storage),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,9 @@ use crate::export::Export;
|
||||
use std::collections::VecDeque;
|
||||
use std::collections::{hash_map::Entry, HashMap};
|
||||
use std::{
|
||||
cell::{Ref, RefCell},
|
||||
borrow::{Borrow, BorrowMut},
|
||||
ffi::c_void,
|
||||
rc::Rc,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
pub trait LikeNamespace {
|
||||
@ -45,8 +45,9 @@ impl IsExport for Export {
|
||||
/// }
|
||||
/// ```
|
||||
pub struct ImportObject {
|
||||
map: Rc<RefCell<HashMap<String, Box<dyn LikeNamespace>>>>,
|
||||
pub(crate) state_creator: Option<Rc<dyn Fn() -> (*mut c_void, fn(*mut c_void))>>,
|
||||
map: Arc<Mutex<HashMap<String, Box<dyn LikeNamespace + Send>>>>,
|
||||
pub(crate) state_creator:
|
||||
Option<Arc<dyn Fn() -> (*mut c_void, fn(*mut c_void)) + Send + Sync + 'static>>,
|
||||
pub allow_missing_functions: bool,
|
||||
}
|
||||
|
||||
@ -54,7 +55,7 @@ impl ImportObject {
|
||||
/// Create a new `ImportObject`.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
map: Rc::new(RefCell::new(HashMap::new())),
|
||||
map: Arc::new(Mutex::new(HashMap::new())),
|
||||
state_creator: None,
|
||||
allow_missing_functions: false,
|
||||
}
|
||||
@ -62,11 +63,11 @@ impl ImportObject {
|
||||
|
||||
pub fn new_with_data<F>(state_creator: F) -> Self
|
||||
where
|
||||
F: Fn() -> (*mut c_void, fn(*mut c_void)) + 'static,
|
||||
F: Fn() -> (*mut c_void, fn(*mut c_void)) + 'static + Send + Sync,
|
||||
{
|
||||
Self {
|
||||
map: Rc::new(RefCell::new(HashMap::new())),
|
||||
state_creator: Some(Rc::new(state_creator)),
|
||||
map: Arc::new(Mutex::new(HashMap::new())),
|
||||
state_creator: Some(Arc::new(state_creator)),
|
||||
allow_missing_functions: false,
|
||||
}
|
||||
}
|
||||
@ -92,9 +93,10 @@ impl ImportObject {
|
||||
pub fn register<S, N>(&mut self, name: S, namespace: N) -> Option<Box<dyn LikeNamespace>>
|
||||
where
|
||||
S: Into<String>,
|
||||
N: LikeNamespace + 'static,
|
||||
N: LikeNamespace + Send + 'static,
|
||||
{
|
||||
let mut map = self.map.borrow_mut();
|
||||
let mut guard = self.map.lock().unwrap();
|
||||
let map = guard.borrow_mut();
|
||||
|
||||
match map.entry(name.into()) {
|
||||
Entry::Vacant(empty) => {
|
||||
@ -105,19 +107,39 @@ impl ImportObject {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_namespace(&self, namespace: &str) -> Option<Ref<dyn LikeNamespace + 'static>> {
|
||||
let map_ref = self.map.borrow();
|
||||
|
||||
/// Apply a function on the namespace if it exists
|
||||
/// If your function can fail, consider using `maybe_with_namespace`
|
||||
pub fn with_namespace<Func, InnerRet>(&self, namespace: &str, f: Func) -> Option<InnerRet>
|
||||
where
|
||||
Func: FnOnce(&(dyn LikeNamespace + Send)) -> InnerRet,
|
||||
InnerRet: Sized,
|
||||
{
|
||||
let guard = self.map.lock().unwrap();
|
||||
let map_ref = guard.borrow();
|
||||
if map_ref.contains_key(namespace) {
|
||||
Some(Ref::map(map_ref, |map| &*map[namespace]))
|
||||
Some(f(map_ref[namespace].as_ref()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// The same as `with_namespace` but takes a function that may fail
|
||||
pub fn maybe_with_namespace<Func, InnerRet>(&self, namespace: &str, f: Func) -> Option<InnerRet>
|
||||
where
|
||||
Func: FnOnce(&(dyn LikeNamespace + Send)) -> Option<InnerRet>,
|
||||
InnerRet: Sized,
|
||||
{
|
||||
let guard = self.map.lock().unwrap();
|
||||
let map_ref = guard.borrow();
|
||||
map_ref
|
||||
.get(namespace)
|
||||
.map(|ns| ns.as_ref())
|
||||
.and_then(|ns| f(ns))
|
||||
}
|
||||
|
||||
pub fn clone_ref(&self) -> Self {
|
||||
Self {
|
||||
map: Rc::clone(&self.map),
|
||||
map: Arc::clone(&self.map),
|
||||
state_creator: self.state_creator.clone(),
|
||||
allow_missing_functions: false,
|
||||
}
|
||||
@ -125,7 +147,9 @@ impl ImportObject {
|
||||
|
||||
fn get_objects(&self) -> VecDeque<(String, String, Export)> {
|
||||
let mut out = VecDeque::new();
|
||||
for (name, ns) in self.map.borrow().iter() {
|
||||
let guard = self.map.lock().unwrap();
|
||||
let map = guard.borrow();
|
||||
for (name, ns) in map.iter() {
|
||||
for (id, exp) in ns.get_exports() {
|
||||
out.push_back((name.clone(), id, exp));
|
||||
}
|
||||
@ -158,7 +182,8 @@ impl IntoIterator for ImportObject {
|
||||
|
||||
impl Extend<(String, String, Export)> for ImportObject {
|
||||
fn extend<T: IntoIterator<Item = (String, String, Export)>>(&mut self, iter: T) {
|
||||
let mut map = self.map.borrow_mut();
|
||||
let mut guard = self.map.lock().unwrap();
|
||||
let map = guard.borrow_mut();
|
||||
for (ns, id, exp) in iter.into_iter() {
|
||||
if let Some(like_ns) = map.get_mut(&ns) {
|
||||
like_ns.maybe_insert(&id, exp);
|
||||
@ -172,7 +197,7 @@ impl Extend<(String, String, Export)> for ImportObject {
|
||||
}
|
||||
|
||||
pub struct Namespace {
|
||||
map: HashMap<String, Box<dyn IsExport>>,
|
||||
map: HashMap<String, Box<dyn IsExport + Send>>,
|
||||
}
|
||||
|
||||
impl Namespace {
|
||||
@ -182,10 +207,10 @@ impl Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert<S, E>(&mut self, name: S, export: E) -> Option<Box<dyn IsExport>>
|
||||
pub fn insert<S, E>(&mut self, name: S, export: E) -> Option<Box<dyn IsExport + Send>>
|
||||
where
|
||||
S: Into<String>,
|
||||
E: IsExport + 'static,
|
||||
E: IsExport + Send + 'static,
|
||||
{
|
||||
self.map.insert(name.into(), Box::new(export))
|
||||
}
|
||||
@ -241,12 +266,14 @@ mod test {
|
||||
|
||||
imports1.extend(imports2);
|
||||
|
||||
let cat_ns = imports1.get_namespace("cat").unwrap();
|
||||
assert!(cat_ns.get_export("small").is_some());
|
||||
let small_cat_export =
|
||||
imports1.maybe_with_namespace("cat", |cat_ns| cat_ns.get_export("small"));
|
||||
assert!(small_cat_export.is_some());
|
||||
|
||||
let dog_ns = imports1.get_namespace("dog").unwrap();
|
||||
assert!(dog_ns.get_export("happy").is_some());
|
||||
assert!(dog_ns.get_export("small").is_some());
|
||||
let entries = imports1.maybe_with_namespace("dog", |dog_ns| {
|
||||
Some((dog_ns.get_export("happy")?, dog_ns.get_export("small")?))
|
||||
});
|
||||
assert!(entries.is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -264,14 +291,14 @@ mod test {
|
||||
};
|
||||
|
||||
imports1.extend(imports2);
|
||||
let dog_ns = imports1.get_namespace("dog").unwrap();
|
||||
let happy_dog_entry = imports1
|
||||
.maybe_with_namespace("dog", |dog_ns| dog_ns.get_export("happy"))
|
||||
.unwrap();
|
||||
|
||||
assert!(
|
||||
if let Export::Global(happy_dog_global) = dog_ns.get_export("happy").unwrap() {
|
||||
happy_dog_global.get() == Value::I32(4)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
);
|
||||
assert!(if let Export::Global(happy_dog_global) = happy_dog_entry {
|
||||
happy_dog_global.get() == Value::I32(4)
|
||||
} else {
|
||||
false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,12 @@ use crate::{
|
||||
vm::{self, InternalField},
|
||||
};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use std::{mem, pin::Pin, ptr::NonNull, sync::Arc};
|
||||
use std::{
|
||||
mem,
|
||||
pin::Pin,
|
||||
ptr::NonNull,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
pub(crate) struct InstanceInner {
|
||||
#[allow(dead_code)]
|
||||
@ -25,6 +30,9 @@ pub(crate) struct InstanceInner {
|
||||
pub(crate) vmctx: *mut vm::Ctx,
|
||||
}
|
||||
|
||||
// manually implemented because InstanceInner contains a raw pointer to Ctx
|
||||
unsafe impl Send for InstanceInner {}
|
||||
|
||||
impl Drop for InstanceInner {
|
||||
fn drop(&mut self) {
|
||||
// Drop the vmctx.
|
||||
@ -517,6 +525,27 @@ impl LikeNamespace for Rc<Instance> {
|
||||
}
|
||||
}
|
||||
|
||||
impl LikeNamespace for Arc<Mutex<Instance>> {
|
||||
fn get_export(&self, name: &str) -> Option<Export> {
|
||||
let instance = self.lock().unwrap();
|
||||
let export_index = instance.module.info.exports.get(name)?;
|
||||
|
||||
Some(
|
||||
instance
|
||||
.inner
|
||||
.get_export_from_index(&instance.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,
|
||||
@ -527,29 +556,12 @@ fn call_func_with_index(
|
||||
args: &[Value],
|
||||
rets: &mut Vec<Value>,
|
||||
) -> CallResult<()> {
|
||||
rets.clear();
|
||||
|
||||
let sig_index = *info
|
||||
.func_assoc
|
||||
.get(func_index)
|
||||
.expect("broken invariant, incorrect func index");
|
||||
|
||||
let signature = &info.signatures[sig_index];
|
||||
let num_results = signature.returns().len();
|
||||
let num_results = num_results
|
||||
+ signature
|
||||
.returns()
|
||||
.iter()
|
||||
.filter(|&&ty| ty == Type::V128)
|
||||
.count();
|
||||
rets.reserve(num_results);
|
||||
|
||||
if !signature.check_param_value_types(args) {
|
||||
Err(ResolveError::Signature {
|
||||
expected: signature.clone(),
|
||||
found: args.iter().map(|val| val.ty()).collect(),
|
||||
})?
|
||||
}
|
||||
|
||||
let func_ptr = match func_index.local_or_import(info) {
|
||||
LocalOrImport::Local(local_func_index) => {
|
||||
@ -567,6 +579,39 @@ fn call_func_with_index(
|
||||
}
|
||||
};
|
||||
|
||||
let wasm = runnable
|
||||
.get_trampoline(info, sig_index)
|
||||
.expect("wasm trampoline");
|
||||
|
||||
call_func_with_index_inner(ctx_ptr, func_ptr, signature, wasm, args, rets)
|
||||
}
|
||||
|
||||
pub(crate) fn call_func_with_index_inner(
|
||||
ctx_ptr: *mut vm::Ctx,
|
||||
func_ptr: NonNull<vm::Func>,
|
||||
signature: &FuncSig,
|
||||
wasm: Wasm,
|
||||
args: &[Value],
|
||||
rets: &mut Vec<Value>,
|
||||
) -> CallResult<()> {
|
||||
rets.clear();
|
||||
|
||||
let num_results = signature.returns().len();
|
||||
let num_results = num_results
|
||||
+ signature
|
||||
.returns()
|
||||
.iter()
|
||||
.filter(|&&ty| ty == Type::V128)
|
||||
.count();
|
||||
rets.reserve(num_results);
|
||||
|
||||
if !signature.check_param_value_types(args) {
|
||||
Err(ResolveError::Signature {
|
||||
expected: signature.clone(),
|
||||
found: args.iter().map(|val| val.ty()).collect(),
|
||||
})?
|
||||
}
|
||||
|
||||
let mut raw_args: SmallVec<[u64; 8]> = SmallVec::new();
|
||||
for v in args {
|
||||
match v {
|
||||
@ -598,9 +643,7 @@ fn call_func_with_index(
|
||||
trampoline,
|
||||
invoke,
|
||||
invoke_env,
|
||||
} = runnable
|
||||
.get_trampoline(info, sig_index)
|
||||
.expect("wasm trampoline");
|
||||
} = wasm;
|
||||
|
||||
let run_wasm = |result_space: *mut u64| unsafe {
|
||||
let mut trap_info = WasmTrapInfo::Unknown;
|
||||
@ -749,3 +792,15 @@ impl<'a> DynFunc<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
fn is_send<T: Send>() {}
|
||||
|
||||
#[test]
|
||||
fn test_instance_is_send() {
|
||||
is_send::<Instance>();
|
||||
}
|
||||
}
|
||||
|
@ -8,12 +8,9 @@ use crate::{
|
||||
units::Pages,
|
||||
vm,
|
||||
};
|
||||
use std::{
|
||||
cell::{Cell, RefCell},
|
||||
fmt, mem,
|
||||
rc::Rc,
|
||||
sync::Arc,
|
||||
};
|
||||
use std::{cell::Cell, fmt, mem, sync::Arc};
|
||||
|
||||
use std::sync::Mutex as StdMutex;
|
||||
|
||||
pub use self::dynamic::DynamicMemory;
|
||||
pub use self::static_::StaticMemory;
|
||||
@ -127,11 +124,11 @@ impl Memory {
|
||||
///
|
||||
/// ```
|
||||
/// # use wasmer_runtime_core::memory::{Memory, MemoryView};
|
||||
/// # use std::sync::atomic::Ordering;
|
||||
/// # use std::{cell::Cell, sync::atomic::Ordering};
|
||||
/// # fn view_memory(memory: Memory) {
|
||||
/// // Without synchronization.
|
||||
/// let view: MemoryView<u8> = memory.view();
|
||||
/// for byte in view[0x1000 .. 0x1010].iter().map(|cell| cell.get()) {
|
||||
/// for byte in view[0x1000 .. 0x1010].iter().map(Cell::get) {
|
||||
/// println!("byte: {}", byte);
|
||||
/// }
|
||||
///
|
||||
@ -204,14 +201,18 @@ enum UnsharedMemoryStorage {
|
||||
}
|
||||
|
||||
pub struct UnsharedMemory {
|
||||
internal: Rc<UnsharedMemoryInternal>,
|
||||
internal: Arc<UnsharedMemoryInternal>,
|
||||
}
|
||||
|
||||
struct UnsharedMemoryInternal {
|
||||
storage: RefCell<UnsharedMemoryStorage>,
|
||||
storage: StdMutex<UnsharedMemoryStorage>,
|
||||
local: Cell<vm::LocalMemory>,
|
||||
}
|
||||
|
||||
// Manually implemented because UnsharedMemoryInternal uses `Cell` and is used in an Arc;
|
||||
// this is safe because the lock for storage can be used to protect (seems like a weak reason: PLEASE REVIEW!)
|
||||
unsafe impl Sync for UnsharedMemoryInternal {}
|
||||
|
||||
impl UnsharedMemory {
|
||||
pub fn new(desc: MemoryDescriptor) -> Result<Self, CreationError> {
|
||||
let mut local = vm::LocalMemory {
|
||||
@ -235,15 +236,15 @@ impl UnsharedMemory {
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
internal: Rc::new(UnsharedMemoryInternal {
|
||||
storage: RefCell::new(storage),
|
||||
internal: Arc::new(UnsharedMemoryInternal {
|
||||
storage: StdMutex::new(storage),
|
||||
local: Cell::new(local),
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn grow(&self, delta: Pages) -> Result<Pages, GrowError> {
|
||||
let mut storage = self.internal.storage.borrow_mut();
|
||||
let mut storage = self.internal.storage.lock().unwrap();
|
||||
|
||||
let mut local = self.internal.local.get();
|
||||
|
||||
@ -260,7 +261,7 @@ impl UnsharedMemory {
|
||||
}
|
||||
|
||||
pub fn size(&self) -> Pages {
|
||||
let storage = self.internal.storage.borrow();
|
||||
let storage = self.internal.storage.lock().unwrap();
|
||||
|
||||
match &*storage {
|
||||
UnsharedMemoryStorage::Dynamic(ref dynamic_memory) => dynamic_memory.size(),
|
||||
@ -276,7 +277,7 @@ impl UnsharedMemory {
|
||||
impl Clone for UnsharedMemory {
|
||||
fn clone(&self) -> Self {
|
||||
UnsharedMemory {
|
||||
internal: Rc::clone(&self.internal),
|
||||
internal: Arc::clone(&self.internal),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -286,11 +287,15 @@ pub struct SharedMemory {
|
||||
}
|
||||
|
||||
pub struct SharedMemoryInternal {
|
||||
memory: RefCell<Box<StaticMemory>>,
|
||||
memory: StdMutex<Box<StaticMemory>>,
|
||||
local: Cell<vm::LocalMemory>,
|
||||
lock: Mutex<()>,
|
||||
}
|
||||
|
||||
// Manually implemented because SharedMemoryInternal uses `Cell` and is used in Arc;
|
||||
// this is safe because of `lock`; accesing `local` without locking `lock` is not safe (Maybe we could put the lock on Local then?)
|
||||
unsafe impl Sync for SharedMemoryInternal {}
|
||||
|
||||
impl SharedMemory {
|
||||
fn new(desc: MemoryDescriptor) -> Result<Self, CreationError> {
|
||||
let mut local = vm::LocalMemory {
|
||||
@ -303,7 +308,7 @@ impl SharedMemory {
|
||||
|
||||
Ok(Self {
|
||||
internal: Arc::new(SharedMemoryInternal {
|
||||
memory: RefCell::new(memory),
|
||||
memory: StdMutex::new(memory),
|
||||
local: Cell::new(local),
|
||||
lock: Mutex::new(()),
|
||||
}),
|
||||
@ -313,15 +318,18 @@ impl SharedMemory {
|
||||
pub fn grow(&self, delta: Pages) -> Result<Pages, GrowError> {
|
||||
let _guard = self.internal.lock.lock();
|
||||
let mut local = self.internal.local.get();
|
||||
let pages = self.internal.memory.borrow_mut().grow(delta, &mut local);
|
||||
let mut memory = self.internal.memory.lock().unwrap();
|
||||
let pages = memory.grow(delta, &mut local);
|
||||
pages
|
||||
}
|
||||
|
||||
pub fn size(&self) -> Pages {
|
||||
let _guard = self.internal.lock.lock();
|
||||
self.internal.memory.borrow_mut().size()
|
||||
let memory = self.internal.memory.lock().unwrap();
|
||||
memory.size()
|
||||
}
|
||||
|
||||
// This function is scary, because the mutex is not locked here
|
||||
pub(crate) fn vm_local_memory(&self) -> *mut vm::LocalMemory {
|
||||
self.internal.local.as_ptr()
|
||||
}
|
||||
|
@ -46,9 +46,7 @@ fn align_pointer(ptr: usize, align: usize) -> usize {
|
||||
impl<T: Copy + ValueType> WasmPtr<T, Item> {
|
||||
#[inline]
|
||||
pub fn deref<'a>(self, memory: &'a Memory) -> Option<&'a Cell<T>> {
|
||||
if self.offset == 0
|
||||
|| (self.offset as usize) + mem::size_of::<T>() >= memory.size().bytes().0
|
||||
{
|
||||
if (self.offset as usize) + mem::size_of::<T>() >= memory.size().bytes().0 {
|
||||
return None;
|
||||
}
|
||||
unsafe {
|
||||
@ -62,9 +60,7 @@ impl<T: Copy + ValueType> WasmPtr<T, Item> {
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn deref_mut<'a>(self, memory: &'a Memory) -> Option<&'a mut Cell<T>> {
|
||||
if self.offset == 0
|
||||
|| (self.offset as usize) + mem::size_of::<T>() >= memory.size().bytes().0
|
||||
{
|
||||
if (self.offset as usize) + mem::size_of::<T>() >= memory.size().bytes().0 {
|
||||
return None;
|
||||
}
|
||||
let cell_ptr = align_pointer(
|
||||
@ -83,9 +79,7 @@ impl<T: Copy + ValueType> WasmPtr<T, Array> {
|
||||
let item_size = mem::size_of::<T>() + (mem::size_of::<T>() % mem::align_of::<T>());
|
||||
let slice_full_len = index as usize + length as usize;
|
||||
|
||||
if self.offset == 0
|
||||
|| (self.offset as usize) + (item_size * slice_full_len) >= memory.size().bytes().0
|
||||
{
|
||||
if (self.offset as usize) + (item_size * slice_full_len) >= memory.size().bytes().0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
@ -112,9 +106,7 @@ impl<T: Copy + ValueType> WasmPtr<T, Array> {
|
||||
let item_size = mem::size_of::<T>() + (mem::size_of::<T>() % mem::align_of::<T>());
|
||||
let slice_full_len = index as usize + length as usize;
|
||||
|
||||
if self.offset == 0
|
||||
|| (self.offset as usize) + (item_size * slice_full_len) >= memory.size().bytes().0
|
||||
{
|
||||
if (self.offset as usize) + (item_size * slice_full_len) >= memory.size().bytes().0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -395,14 +395,19 @@ pub fn read_module<
|
||||
}
|
||||
|
||||
pub fn wp_type_to_type(ty: WpType) -> Result<Type, BinaryReaderError> {
|
||||
Ok(match ty {
|
||||
WpType::I32 => Type::I32,
|
||||
WpType::I64 => Type::I64,
|
||||
WpType::F32 => Type::F32,
|
||||
WpType::F64 => Type::F64,
|
||||
WpType::V128 => Type::V128,
|
||||
_ => panic!("broken invariant, invalid type"),
|
||||
})
|
||||
match ty {
|
||||
WpType::I32 => Ok(Type::I32),
|
||||
WpType::I64 => Ok(Type::I64),
|
||||
WpType::F32 => Ok(Type::F32),
|
||||
WpType::F64 => Ok(Type::F64),
|
||||
WpType::V128 => Ok(Type::V128),
|
||||
_ => {
|
||||
return Err(BinaryReaderError {
|
||||
message: "broken invariant, invalid type",
|
||||
offset: -1isize as usize,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_to_wp_type(ty: Type) -> WpType {
|
||||
|
@ -303,7 +303,7 @@ impl ExecutionStateImage {
|
||||
|
||||
if let Ok(x) = env::var("WASMER_BACKTRACE") {
|
||||
if x == "1" {
|
||||
eprintln!("{}", self.colored_output());
|
||||
eprintln!("{}", self.output());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -311,9 +311,7 @@ impl ExecutionStateImage {
|
||||
eprintln!("Run with `WASMER_BACKTRACE=1` environment variable to display a backtrace.");
|
||||
}
|
||||
|
||||
pub fn colored_output(&self) -> String {
|
||||
use colored::*;
|
||||
|
||||
pub fn output(&self) -> String {
|
||||
fn join_strings(x: impl Iterator<Item = String>, sep: &str) -> String {
|
||||
let mut ret = String::new();
|
||||
let mut first = true;
|
||||
@ -341,8 +339,6 @@ impl ExecutionStateImage {
|
||||
i,
|
||||
x.map(|x| format!("{}", x))
|
||||
.unwrap_or_else(|| "?".to_string())
|
||||
.bold()
|
||||
.cyan()
|
||||
)
|
||||
}),
|
||||
", ",
|
||||
@ -353,27 +349,23 @@ impl ExecutionStateImage {
|
||||
let mut ret = String::new();
|
||||
|
||||
if self.frames.len() == 0 {
|
||||
ret += &"Unknown fault address, cannot read stack.".yellow();
|
||||
ret += &"Unknown fault address, cannot read stack.";
|
||||
ret += "\n";
|
||||
} else {
|
||||
ret += &"Backtrace:".bold();
|
||||
ret += &"Backtrace:";
|
||||
ret += "\n";
|
||||
for (i, f) in self.frames.iter().enumerate() {
|
||||
ret += &format!("* Frame {} @ Local function {}", i, f.local_function_id).bold();
|
||||
ret += &format!("* Frame {} @ Local function {}", i, f.local_function_id);
|
||||
ret += "\n";
|
||||
ret += &format!(" {} {}\n", "Offset:", format!("{}", f.wasm_inst_offset),);
|
||||
ret += &format!(
|
||||
" {} {}\n",
|
||||
"Offset:".bold().yellow(),
|
||||
format!("{}", f.wasm_inst_offset).bold().cyan(),
|
||||
);
|
||||
ret += &format!(
|
||||
" {} {}\n",
|
||||
"Locals:".bold().yellow(),
|
||||
"Locals:",
|
||||
format_optional_u64_sequence(&f.locals)
|
||||
);
|
||||
ret += &format!(
|
||||
" {} {}\n\n",
|
||||
"Stack:".bold().yellow(),
|
||||
"Stack:",
|
||||
format_optional_u64_sequence(&f.stack)
|
||||
);
|
||||
}
|
||||
|
@ -39,6 +39,10 @@ where
|
||||
self.elems.len()
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.elems.is_empty()
|
||||
}
|
||||
|
||||
pub fn push(&mut self, value: V) -> K {
|
||||
let len = self.len();
|
||||
self.elems.push(value);
|
||||
|
@ -4,7 +4,7 @@ use errno;
|
||||
use nix::libc;
|
||||
use page_size;
|
||||
use std::ops::{Bound, RangeBounds};
|
||||
use std::{fs::File, os::unix::io::IntoRawFd, path::Path, ptr, rc::Rc, slice};
|
||||
use std::{fs::File, os::unix::io::IntoRawFd, path::Path, ptr, slice, sync::Arc};
|
||||
|
||||
unsafe impl Send for Memory {}
|
||||
unsafe impl Sync for Memory {}
|
||||
@ -14,7 +14,7 @@ pub struct Memory {
|
||||
ptr: *mut u8,
|
||||
size: usize,
|
||||
protection: Protect,
|
||||
fd: Option<Rc<RawFd>>,
|
||||
fd: Option<Arc<RawFd>>,
|
||||
}
|
||||
|
||||
impl Memory {
|
||||
@ -49,7 +49,7 @@ impl Memory {
|
||||
ptr: ptr as *mut u8,
|
||||
size: file_len as usize,
|
||||
protection,
|
||||
fd: Some(Rc::new(raw_fd)),
|
||||
fd: Some(Arc::new(raw_fd)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ impl<'a> From<DynFunc<'a>> for Anyfunc<'a> {
|
||||
}
|
||||
|
||||
pub struct AnyfuncTable {
|
||||
backing: Vec<vm::Anyfunc>,
|
||||
pub(crate) backing: Vec<vm::Anyfunc>,
|
||||
max: Option<u32>,
|
||||
}
|
||||
|
||||
|
@ -5,12 +5,15 @@ use crate::{
|
||||
types::{ElementType, TableDescriptor},
|
||||
vm,
|
||||
};
|
||||
use std::{cell::RefCell, fmt, ptr, rc::Rc};
|
||||
use std::{
|
||||
fmt, ptr,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
mod anyfunc;
|
||||
|
||||
pub use self::anyfunc::Anyfunc;
|
||||
use self::anyfunc::AnyfuncTable;
|
||||
pub(crate) use self::anyfunc::AnyfuncTable;
|
||||
use crate::error::GrowError;
|
||||
|
||||
pub enum Element<'a> {
|
||||
@ -25,7 +28,7 @@ pub enum TableStorage {
|
||||
|
||||
pub struct Table {
|
||||
desc: TableDescriptor,
|
||||
storage: Rc<RefCell<(TableStorage, vm::LocalTable)>>,
|
||||
storage: Arc<Mutex<(TableStorage, vm::LocalTable)>>,
|
||||
}
|
||||
|
||||
impl Table {
|
||||
@ -71,7 +74,7 @@ impl Table {
|
||||
|
||||
Ok(Self {
|
||||
desc,
|
||||
storage: Rc::new(RefCell::new((storage, local))),
|
||||
storage: Arc::new(Mutex::new((storage, local))),
|
||||
})
|
||||
}
|
||||
|
||||
@ -82,7 +85,8 @@ impl Table {
|
||||
|
||||
/// Set the element at index.
|
||||
pub fn set(&self, index: u32, element: Element) -> Result<(), ()> {
|
||||
match &mut *self.storage.borrow_mut() {
|
||||
let mut storage = self.storage.lock().unwrap();
|
||||
match &mut *storage {
|
||||
(TableStorage::Anyfunc(ref mut anyfunc_table), _) => {
|
||||
match element {
|
||||
Element::Anyfunc(anyfunc) => anyfunc_table.set(index, anyfunc),
|
||||
@ -96,14 +100,16 @@ impl Table {
|
||||
where
|
||||
F: FnOnce(&mut [vm::Anyfunc]) -> R,
|
||||
{
|
||||
match &mut *self.storage.borrow_mut() {
|
||||
let mut storage = self.storage.lock().unwrap();
|
||||
match &mut *storage {
|
||||
(TableStorage::Anyfunc(ref mut anyfunc_table), _) => f(anyfunc_table.internal_buffer()),
|
||||
}
|
||||
}
|
||||
|
||||
/// The current size of this table.
|
||||
pub fn size(&self) -> u32 {
|
||||
match &*self.storage.borrow() {
|
||||
let storage = self.storage.lock().unwrap();
|
||||
match &*storage {
|
||||
(TableStorage::Anyfunc(ref anyfunc_table), _) => anyfunc_table.current_size(),
|
||||
}
|
||||
}
|
||||
@ -114,7 +120,8 @@ impl Table {
|
||||
return Ok(self.size());
|
||||
}
|
||||
|
||||
match &mut *self.storage.borrow_mut() {
|
||||
let mut storage = self.storage.lock().unwrap();
|
||||
match &mut *storage {
|
||||
(TableStorage::Anyfunc(ref mut anyfunc_table), ref mut local) => anyfunc_table
|
||||
.grow(delta, local)
|
||||
.ok_or(GrowError::TableGrowError),
|
||||
@ -122,7 +129,8 @@ impl Table {
|
||||
}
|
||||
|
||||
pub fn vm_local_table(&mut self) -> *mut vm::LocalTable {
|
||||
&mut self.storage.borrow_mut().1
|
||||
let mut storage = self.storage.lock().unwrap();
|
||||
&mut storage.1
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,7 +144,7 @@ impl Clone for Table {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
desc: self.desc,
|
||||
storage: Rc::clone(&self.storage),
|
||||
storage: Arc::clone(&self.storage),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -165,6 +165,9 @@ pub struct Func<'a, Args = (), Rets = (), Inner: Kind = Wasm> {
|
||||
_phantom: PhantomData<(&'a (), Args, Rets)>,
|
||||
}
|
||||
|
||||
unsafe impl<'a, Args, Rets> Send for Func<'a, Args, Rets, Wasm> {}
|
||||
unsafe impl<'a, Args, Rets> Send for Func<'a, Args, Rets, Host> {}
|
||||
|
||||
impl<'a, Args, Rets> Func<'a, Args, Rets, Wasm>
|
||||
where
|
||||
Args: WasmTypeList,
|
||||
|
@ -1,15 +1,19 @@
|
||||
pub use crate::backing::{ImportBacking, LocalBacking, INTERNALS_SIZE};
|
||||
use crate::{
|
||||
error::CallResult,
|
||||
instance::call_func_with_index_inner,
|
||||
memory::{Memory, MemoryType},
|
||||
module::{ModuleInfo, ModuleInner},
|
||||
sig_registry::SigRegistry,
|
||||
structures::TypedIndex,
|
||||
types::{LocalOrImport, MemoryIndex},
|
||||
types::{LocalOrImport, MemoryIndex, TableIndex, Value},
|
||||
vmcalls,
|
||||
};
|
||||
use std::{
|
||||
cell::UnsafeCell,
|
||||
ffi::c_void,
|
||||
mem, ptr,
|
||||
mem,
|
||||
ptr::{self, NonNull},
|
||||
sync::atomic::{AtomicUsize, Ordering},
|
||||
sync::Once,
|
||||
};
|
||||
@ -393,6 +397,41 @@ impl Ctx {
|
||||
(*self.internal.internals)[field.index()] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// Calls a host or Wasm function at the given table index
|
||||
pub fn call_with_table_index(
|
||||
&mut self,
|
||||
index: TableIndex,
|
||||
args: &[Value],
|
||||
) -> CallResult<Vec<Value>> {
|
||||
let anyfunc_table =
|
||||
unsafe { &*((**self.internal.tables).table as *mut crate::table::AnyfuncTable) };
|
||||
let Anyfunc { func, ctx, sig_id } = anyfunc_table.backing[index.index()];
|
||||
|
||||
let signature = SigRegistry.lookup_signature(unsafe { std::mem::transmute(sig_id.0) });
|
||||
let mut rets = vec![];
|
||||
|
||||
let wasm = {
|
||||
let module = unsafe { &*self.module };
|
||||
let runnable = &module.runnable_module;
|
||||
|
||||
let sig_index = SigRegistry.lookup_sig_index(signature.clone());
|
||||
runnable
|
||||
.get_trampoline(&module.info, sig_index)
|
||||
.expect("wasm trampoline")
|
||||
};
|
||||
|
||||
call_func_with_index_inner(
|
||||
ctx,
|
||||
NonNull::new(func as *mut _).unwrap(),
|
||||
&signature,
|
||||
wasm,
|
||||
args,
|
||||
&mut rets,
|
||||
)?;
|
||||
|
||||
Ok(rets)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
@ -474,6 +513,9 @@ pub struct ImportedFunc {
|
||||
pub vmctx: *mut Ctx,
|
||||
}
|
||||
|
||||
// manually implemented because ImportedFunc contains raw pointers directly; `Func` is marked Send (But `Ctx` actually isn't! (TODO: review this, shouldn't `Ctx` be Send?))
|
||||
unsafe impl Send for ImportedFunc {}
|
||||
|
||||
impl ImportedFunc {
|
||||
#[allow(clippy::erasing_op)] // TODO
|
||||
pub fn offset_func() -> u8 {
|
||||
@ -501,6 +543,9 @@ pub struct LocalTable {
|
||||
pub table: *mut (),
|
||||
}
|
||||
|
||||
// manually implemented because LocalTable contains raw pointers directly
|
||||
unsafe impl Send for LocalTable {}
|
||||
|
||||
impl LocalTable {
|
||||
#[allow(clippy::erasing_op)] // TODO
|
||||
pub fn offset_base() -> u8 {
|
||||
@ -530,6 +575,9 @@ pub struct LocalMemory {
|
||||
pub memory: *mut (),
|
||||
}
|
||||
|
||||
// manually implemented because LocalMemory contains raw pointers
|
||||
unsafe impl Send for LocalMemory {}
|
||||
|
||||
impl LocalMemory {
|
||||
#[allow(clippy::erasing_op)] // TODO
|
||||
pub fn offset_base() -> u8 {
|
||||
@ -580,6 +628,9 @@ pub struct Anyfunc {
|
||||
pub sig_id: SigId,
|
||||
}
|
||||
|
||||
// manually implemented because Anyfunc contains raw pointers directly
|
||||
unsafe impl Send for Anyfunc {}
|
||||
|
||||
impl Anyfunc {
|
||||
pub fn null() -> Self {
|
||||
Self {
|
||||
|
@ -10,8 +10,8 @@ readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.7.0", optional = true }
|
||||
lazy_static = "1.4.0"
|
||||
memmap = "0.7.0"
|
||||
lazy_static = "1.4"
|
||||
memmap = "0.7"
|
||||
|
||||
[dependencies.wasmer-runtime-core]
|
||||
path = "../runtime-core"
|
||||
@ -23,7 +23,7 @@ version = "0.7.0"
|
||||
optional = true
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3.1.0"
|
||||
tempfile = "3.1"
|
||||
criterion = "0.2"
|
||||
wabt = "0.9.1"
|
||||
|
||||
|
@ -13,9 +13,8 @@ wasmer-runtime-core = { path = "../runtime-core", version = "0.7.0" }
|
||||
wasmparser = "0.35.1"
|
||||
dynasm = "0.3.2"
|
||||
dynasmrt = "0.3.1"
|
||||
lazy_static = "1.4.0"
|
||||
byteorder = "1.3.2"
|
||||
nix = "0.15.0"
|
||||
lazy_static = "1.4"
|
||||
byteorder = "1.3"
|
||||
nix = "0.15"
|
||||
libc = "0.2.60"
|
||||
smallvec = "0.6.10"
|
||||
colored = "1.8"
|
||||
smallvec = "0.6"
|
||||
|
@ -8,7 +8,7 @@ repository = "https://github.com/wasmerio/wasmer"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
glob = "0.3.0"
|
||||
glob = "0.3"
|
||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.7.0" }
|
||||
wasmer-clif-backend = { path = "../clif-backend", version = "0.7.0" }
|
||||
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.7.0", optional = true }
|
||||
|
@ -863,7 +863,6 @@ llvm:skip:unwind.wast:*:windows
|
||||
|
||||
# LLVM Linux after OSR - https://github.com/wasmerio/wasmer/pull/567
|
||||
llvm:skip:simd.wast:352:unix # Module - caught panic Any
|
||||
llvm:skip:simd.wast:355:unix # Module - caught panic Any
|
||||
llvm:skip:simd_binaryen.wast:*:unix # Module - caught panic Any
|
||||
|
||||
|
||||
|
@ -18,7 +18,7 @@ mod tests {
|
||||
// TODO Files could be run with multiple threads
|
||||
// TODO Allow running WAST &str directly (E.g. for use outside of spectests)
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
struct SpecFailure {
|
||||
file: String,
|
||||
@ -119,6 +119,24 @@ mod tests {
|
||||
"unknown"
|
||||
}
|
||||
|
||||
fn with_instance<F, R>(
|
||||
maybe_instance: Option<Arc<Mutex<Instance>>>,
|
||||
named_modules: &HashMap<String, Arc<Mutex<Instance>>>,
|
||||
module: &Option<String>,
|
||||
f: F,
|
||||
) -> Option<R>
|
||||
where
|
||||
R: Sized,
|
||||
F: FnOnce(&Instance) -> R,
|
||||
{
|
||||
let ref ins = module
|
||||
.as_ref()
|
||||
.and_then(|name| named_modules.get(name).cloned())
|
||||
.or(maybe_instance)?;
|
||||
let guard = ins.lock().unwrap();
|
||||
Some(f(guard.borrow()))
|
||||
}
|
||||
|
||||
use glob::glob;
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
@ -173,11 +191,11 @@ mod tests {
|
||||
.expect(&format!("Failed to parse script {}", &filename));
|
||||
|
||||
use std::panic;
|
||||
let mut instance: Option<Rc<Instance>> = None;
|
||||
let mut instance: Option<Arc<Mutex<Instance>>> = None;
|
||||
|
||||
let mut named_modules: HashMap<String, Rc<Instance>> = HashMap::new();
|
||||
let mut named_modules: HashMap<String, Arc<Mutex<Instance>>> = HashMap::new();
|
||||
|
||||
let mut registered_modules: HashMap<String, Rc<Instance>> = HashMap::new();
|
||||
let mut registered_modules: HashMap<String, Arc<Mutex<Instance>>> = HashMap::new();
|
||||
//
|
||||
|
||||
while let Some(Command { kind, line }) =
|
||||
@ -236,9 +254,9 @@ mod tests {
|
||||
instance = None;
|
||||
}
|
||||
Ok(i) => {
|
||||
let i = Rc::new(i);
|
||||
let i = Arc::new(Mutex::new(i));
|
||||
if name.is_some() {
|
||||
named_modules.insert(name.unwrap(), Rc::clone(&i));
|
||||
named_modules.insert(name.unwrap(), Arc::clone(&i));
|
||||
}
|
||||
instance = Some(i);
|
||||
}
|
||||
@ -251,20 +269,17 @@ mod tests {
|
||||
field,
|
||||
args,
|
||||
} => {
|
||||
let instance: Option<&Instance> = match module {
|
||||
Some(ref name) => {
|
||||
let i = named_modules.get(name);
|
||||
match i {
|
||||
Some(ins) => Some(ins.borrow()),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
None => match instance {
|
||||
Some(ref i) => Some(i.borrow()),
|
||||
None => None,
|
||||
let maybe_call_result = with_instance(
|
||||
instance.clone(),
|
||||
&named_modules,
|
||||
&module,
|
||||
|instance| {
|
||||
let params: Vec<wasmer_runtime_core::types::Value> =
|
||||
args.iter().cloned().map(convert_value).collect();
|
||||
instance.call(&field, ¶ms[..])
|
||||
},
|
||||
};
|
||||
if instance.is_none() {
|
||||
);
|
||||
if maybe_call_result.is_none() {
|
||||
test_report.add_failure(
|
||||
SpecFailure {
|
||||
file: filename.to_string(),
|
||||
@ -276,9 +291,7 @@ mod tests {
|
||||
excludes,
|
||||
);
|
||||
} else {
|
||||
let params: Vec<wasmer_runtime_core::types::Value> =
|
||||
args.iter().cloned().map(|x| convert_value(x)).collect();
|
||||
let call_result = instance.unwrap().call(&field, ¶ms[..]);
|
||||
let call_result = maybe_call_result.unwrap();
|
||||
match call_result {
|
||||
Err(e) => {
|
||||
test_report.add_failure(
|
||||
@ -316,20 +329,17 @@ mod tests {
|
||||
}
|
||||
}
|
||||
Action::Get { module, field } => {
|
||||
let instance: Option<&Instance> = match module {
|
||||
Some(ref name) => {
|
||||
let i = named_modules.get(name);
|
||||
match i {
|
||||
Some(ins) => Some(ins.borrow()),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
None => match instance {
|
||||
Some(ref i) => Some(i.borrow()),
|
||||
None => None,
|
||||
let maybe_call_result = with_instance(
|
||||
instance.clone(),
|
||||
&named_modules,
|
||||
&module,
|
||||
|instance| {
|
||||
instance
|
||||
.get_export(&field)
|
||||
.expect(&format!("missing global {:?}", &field))
|
||||
},
|
||||
};
|
||||
if instance.is_none() {
|
||||
);
|
||||
if maybe_call_result.is_none() {
|
||||
test_report.add_failure(
|
||||
SpecFailure {
|
||||
file: filename.to_string(),
|
||||
@ -341,10 +351,7 @@ mod tests {
|
||||
excludes,
|
||||
);
|
||||
} else {
|
||||
let export: Export = instance
|
||||
.unwrap()
|
||||
.get_export(&field)
|
||||
.expect(&format!("missing global {:?}", &field));
|
||||
let export: Export = maybe_call_result.unwrap();
|
||||
match export {
|
||||
Export::Global(g) => {
|
||||
let value = g.get();
|
||||
@ -392,20 +399,13 @@ mod tests {
|
||||
field,
|
||||
args,
|
||||
} => {
|
||||
let instance: Option<&Instance> = match module {
|
||||
Some(ref name) => {
|
||||
let i = named_modules.get(name);
|
||||
match i {
|
||||
Some(ins) => Some(ins.borrow()),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
None => match instance {
|
||||
Some(ref i) => Some(i.borrow()),
|
||||
None => None,
|
||||
},
|
||||
};
|
||||
if instance.is_none() {
|
||||
let maybe_call_result =
|
||||
with_instance(instance.clone(), &named_modules, &module, |instance| {
|
||||
let params: Vec<wasmer_runtime_core::types::Value> =
|
||||
args.iter().cloned().map(convert_value).collect();
|
||||
instance.call(&field, ¶ms[..])
|
||||
});
|
||||
if maybe_call_result.is_none() {
|
||||
test_report.add_failure(
|
||||
SpecFailure {
|
||||
file: filename.to_string(),
|
||||
@ -417,9 +417,7 @@ mod tests {
|
||||
excludes,
|
||||
);
|
||||
} else {
|
||||
let params: Vec<wasmer_runtime_core::types::Value> =
|
||||
args.iter().cloned().map(|x| convert_value(x)).collect();
|
||||
let call_result = instance.unwrap().call(&field, ¶ms[..]);
|
||||
let call_result = maybe_call_result.unwrap();
|
||||
match call_result {
|
||||
Err(e) => {
|
||||
test_report.add_failure(
|
||||
@ -468,20 +466,13 @@ mod tests {
|
||||
field,
|
||||
args,
|
||||
} => {
|
||||
let instance: Option<&Instance> = match module {
|
||||
Some(ref name) => {
|
||||
let i = named_modules.get(name);
|
||||
match i {
|
||||
Some(ins) => Some(ins.borrow()),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
None => match instance {
|
||||
Some(ref i) => Some(i.borrow()),
|
||||
None => None,
|
||||
},
|
||||
};
|
||||
if instance.is_none() {
|
||||
let maybe_call_result =
|
||||
with_instance(instance.clone(), &named_modules, &module, |instance| {
|
||||
let params: Vec<wasmer_runtime_core::types::Value> =
|
||||
args.iter().cloned().map(convert_value).collect();
|
||||
instance.call(&field, ¶ms[..])
|
||||
});
|
||||
if maybe_call_result.is_none() {
|
||||
test_report.add_failure(
|
||||
SpecFailure {
|
||||
file: filename.to_string(),
|
||||
@ -493,9 +484,7 @@ mod tests {
|
||||
excludes,
|
||||
);
|
||||
} else {
|
||||
let params: Vec<wasmer_runtime_core::types::Value> =
|
||||
args.iter().cloned().map(|x| convert_value(x)).collect();
|
||||
let call_result = instance.unwrap().call(&field, ¶ms[..]);
|
||||
let call_result = maybe_call_result.unwrap();
|
||||
match call_result {
|
||||
Err(e) => {
|
||||
test_report.add_failure(
|
||||
@ -544,20 +533,13 @@ mod tests {
|
||||
field,
|
||||
args,
|
||||
} => {
|
||||
let instance: Option<&Instance> = match module {
|
||||
Some(ref name) => {
|
||||
let i = named_modules.get(name);
|
||||
match i {
|
||||
Some(ins) => Some(ins.borrow()),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
None => match instance {
|
||||
Some(ref i) => Some(i.borrow()),
|
||||
None => None,
|
||||
},
|
||||
};
|
||||
if instance.is_none() {
|
||||
let maybe_call_result =
|
||||
with_instance(instance.clone(), &named_modules, &module, |instance| {
|
||||
let params: Vec<wasmer_runtime_core::types::Value> =
|
||||
args.iter().cloned().map(convert_value).collect();
|
||||
instance.call(&field, ¶ms[..])
|
||||
});
|
||||
if maybe_call_result.is_none() {
|
||||
test_report.add_failure(
|
||||
SpecFailure {
|
||||
file: filename.to_string(),
|
||||
@ -569,9 +551,7 @@ mod tests {
|
||||
excludes,
|
||||
);
|
||||
} else {
|
||||
let params: Vec<wasmer_runtime_core::types::Value> =
|
||||
args.iter().cloned().map(|x| convert_value(x)).collect();
|
||||
let call_result = instance.unwrap().call(&field, ¶ms[..]);
|
||||
let call_result = maybe_call_result.unwrap();
|
||||
use wasmer_runtime_core::error::{CallError, RuntimeError};
|
||||
match call_result {
|
||||
Err(e) => {
|
||||
@ -749,20 +729,17 @@ mod tests {
|
||||
field,
|
||||
args,
|
||||
} => {
|
||||
let instance: Option<&Instance> = match module {
|
||||
Some(ref name) => {
|
||||
let i = named_modules.get(name);
|
||||
match i {
|
||||
Some(ins) => Some(ins.borrow()),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
None => match instance {
|
||||
Some(ref i) => Some(i.borrow()),
|
||||
None => None,
|
||||
let maybe_call_result = with_instance(
|
||||
instance.clone(),
|
||||
&named_modules,
|
||||
&module,
|
||||
|instance| {
|
||||
let params: Vec<wasmer_runtime_core::types::Value> =
|
||||
args.iter().cloned().map(convert_value).collect();
|
||||
instance.call(&field, ¶ms[..])
|
||||
},
|
||||
};
|
||||
if instance.is_none() {
|
||||
);
|
||||
if maybe_call_result.is_none() {
|
||||
test_report.add_failure(
|
||||
SpecFailure {
|
||||
file: filename.to_string(),
|
||||
@ -774,9 +751,7 @@ mod tests {
|
||||
excludes,
|
||||
);
|
||||
} else {
|
||||
let params: Vec<wasmer_runtime_core::types::Value> =
|
||||
args.iter().cloned().map(|x| convert_value(x)).collect();
|
||||
let call_result = instance.unwrap().call(&field, ¶ms[..]);
|
||||
let call_result = maybe_call_result.unwrap();
|
||||
match call_result {
|
||||
Err(_e) => {
|
||||
// TODO is specific error required?
|
||||
@ -871,16 +846,16 @@ mod tests {
|
||||
}
|
||||
}
|
||||
CommandKind::Register { name, as_name } => {
|
||||
let instance: Option<Rc<Instance>> = match name {
|
||||
let instance: Option<Arc<Mutex<Instance>>> = match name {
|
||||
Some(ref name) => {
|
||||
let i = named_modules.get(name);
|
||||
match i {
|
||||
Some(ins) => Some(Rc::clone(ins)),
|
||||
Some(ins) => Some(Arc::clone(ins)),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
None => match instance {
|
||||
Some(ref i) => Some(Rc::clone(i)),
|
||||
Some(ref i) => Some(Arc::clone(i)),
|
||||
None => None,
|
||||
},
|
||||
};
|
||||
@ -906,21 +881,13 @@ mod tests {
|
||||
field,
|
||||
args,
|
||||
} => {
|
||||
let instance: Option<&Instance> = match module {
|
||||
Some(ref name) => {
|
||||
let i = named_modules.get(name);
|
||||
match i {
|
||||
Some(ins) => Some(ins.borrow()),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
None => match instance {
|
||||
Some(ref i) => Some(i.borrow()),
|
||||
None => None,
|
||||
},
|
||||
};
|
||||
|
||||
if instance.is_none() {
|
||||
let maybe_call_result =
|
||||
with_instance(instance.clone(), &named_modules, &module, |instance| {
|
||||
let params: Vec<wasmer_runtime_core::types::Value> =
|
||||
args.iter().cloned().map(convert_value).collect();
|
||||
instance.call(&field, ¶ms[..])
|
||||
});
|
||||
if maybe_call_result.is_none() {
|
||||
test_report.add_failure(
|
||||
SpecFailure {
|
||||
file: filename.to_string(),
|
||||
@ -932,9 +899,7 @@ mod tests {
|
||||
excludes,
|
||||
);
|
||||
} else {
|
||||
let params: Vec<wasmer_runtime_core::types::Value> =
|
||||
args.iter().cloned().map(|x| convert_value(x)).collect();
|
||||
let call_result = instance.unwrap().call(&field, ¶ms[..]);
|
||||
let call_result = maybe_call_result.unwrap();
|
||||
match call_result {
|
||||
Err(e) => {
|
||||
test_report.add_failure(
|
||||
@ -1054,7 +1019,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn get_spectest_import_object(
|
||||
registered_modules: &HashMap<String, Rc<Instance>>,
|
||||
registered_modules: &HashMap<String, Arc<Mutex<Instance>>>,
|
||||
) -> ImportObject {
|
||||
let memory_desc = MemoryDescriptor::new(Pages(1), Some(Pages(2)), false).unwrap();
|
||||
let memory = Memory::new(memory_desc).unwrap();
|
||||
@ -1087,7 +1052,7 @@ mod tests {
|
||||
};
|
||||
|
||||
for (name, instance) in registered_modules.iter() {
|
||||
import_object.register(name.clone(), Rc::clone(instance));
|
||||
import_object.register(name.clone(), Arc::clone(instance));
|
||||
}
|
||||
import_object
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ wasmer-llvm-backend = { path = "../llvm-backend", version = "0.7.0", optional =
|
||||
|
||||
|
||||
[build-dependencies]
|
||||
glob = "0.3.0"
|
||||
glob = "0.3"
|
||||
|
||||
[dev-dependencies]
|
||||
wasmer-clif-backend = { path = "../clif-backend", version = "0.7.0" }
|
||||
|
@ -9,16 +9,16 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
bincode = "1"
|
||||
byteorder = "1.3.2"
|
||||
generational-arena = { version = "0.2.2", features = ["serde"] }
|
||||
byteorder = "1.3"
|
||||
generational-arena = { version = "0.2", features = ["serde"] }
|
||||
libc = "0.2.60"
|
||||
log = "0.4.8"
|
||||
rand = "0.7.0"
|
||||
time = "0.1.42"
|
||||
log = "0.4"
|
||||
rand = "0.7"
|
||||
time = "0.1"
|
||||
typetag = "0.1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
# wasmer-runtime-abi = { path = "../runtime-abi" }
|
||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.7.0" }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winapi = "0.3.8"
|
||||
winapi = "0.3"
|
||||
|
@ -2,14 +2,17 @@ use wasmer_runtime_core::module::Module;
|
||||
|
||||
/// Check if a provided module is compiled with WASI support
|
||||
pub fn is_wasi_module(module: &Module) -> bool {
|
||||
if module.info().imported_functions.is_empty() {
|
||||
return false;
|
||||
}
|
||||
for (_, import_name) in &module.info().imported_functions {
|
||||
let namespace = module
|
||||
.info()
|
||||
.namespace_table
|
||||
.get(import_name.namespace_index);
|
||||
if namespace == "wasi_unstable" {
|
||||
return true;
|
||||
if namespace != "wasi_unstable" {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
false
|
||||
true
|
||||
}
|
||||
|
@ -13,6 +13,6 @@ winapi = { version = "0.3.8", features = ["winbase", "errhandlingapi", "minwinde
|
||||
libc = "0.2.60"
|
||||
|
||||
[build-dependencies]
|
||||
cmake = "0.1.40"
|
||||
bindgen = "0.51.0"
|
||||
regex = "1.2.1"
|
||||
cmake = "0.1"
|
||||
bindgen = "0.51"
|
||||
regex = "1.2"
|
||||
|
@ -512,7 +512,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
||||
import_object.allow_missing_functions = true; // Import initialization might be left to the loader.
|
||||
let instance = module
|
||||
.instantiate(&import_object)
|
||||
.map_err(|e| format!("Can't instantiate module: {:?}", e))?;
|
||||
.map_err(|e| format!("Can't instantiate loader module: {:?}", e))?;
|
||||
|
||||
let args: Vec<Value> = options
|
||||
.args
|
||||
@ -551,7 +551,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
||||
let import_object = wasmer_emscripten::generate_emscripten_env(&mut emscripten_globals);
|
||||
let mut instance = module
|
||||
.instantiate(&import_object)
|
||||
.map_err(|e| format!("Can't instantiate module: {:?}", e))?;
|
||||
.map_err(|e| format!("Can't instantiate emscripten module: {:?}", e))?;
|
||||
|
||||
wasmer_emscripten::run_emscripten_instance(
|
||||
&module,
|
||||
@ -591,7 +591,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
||||
#[allow(unused_mut)] // mut used in feature
|
||||
let mut instance = module
|
||||
.instantiate(&import_object)
|
||||
.map_err(|e| format!("Can't instantiate module: {:?}", e))?;
|
||||
.map_err(|e| format!("Can't instantiate WASI module: {:?}", e))?;
|
||||
|
||||
let start: Func<(), ()> = instance.func("_start").map_err(|e| format!("{:?}", e))?;
|
||||
|
||||
@ -732,7 +732,7 @@ fn interactive_shell(mut ctx: InteractiveShellContext) -> ShellExitOperation {
|
||||
}
|
||||
"backtrace" | "bt" => {
|
||||
if let Some(ref image) = ctx.image {
|
||||
println!("{}", image.execution_state.colored_output());
|
||||
println!("{}", image.execution_state.output());
|
||||
} else {
|
||||
println!("State not available");
|
||||
}
|
||||
@ -752,7 +752,7 @@ fn run(options: Run) {
|
||||
match execute_wasm(&options) {
|
||||
Ok(()) => {}
|
||||
Err(message) => {
|
||||
eprintln!("execute_wasm: {:?}", message);
|
||||
eprintln!("Error: {}", message);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user