Merge branch 'master' into feature/merge-cranelift-0-43-1

This commit is contained in:
Syrus Akbary 2019-09-24 11:41:14 -07:00 committed by GitHub
commit 588a77d2af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 486 additions and 342 deletions

View File

@ -7,6 +7,10 @@ Blocks of changes will separated by version increments.
## **[Unreleased]** ## **[Unreleased]**
- [#822](https://github.com/wasmerio/wasmer/pull/822) Update Cranelift fork version to `0.43.1` - [#822](https://github.com/wasmerio/wasmer/pull/822) Update Cranelift fork version to `0.43.1`
- [#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. - [#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 - [#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` - [#803](https://github.com/wasmerio/wasmer/issues/803) Add method to `Ctx` to invoke functions by their `TableIndex`

74
Cargo.lock generated
View File

@ -70,7 +70,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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]] [[package]]
@ -118,7 +118,7 @@ dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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]] [[package]]
@ -156,8 +156,8 @@ name = "cargo_toml"
version = "0.6.4" version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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_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)",
"toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -175,7 +175,7 @@ dependencies = [
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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)", "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)", "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)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -310,8 +310,8 @@ dependencies = [
"rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "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 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)", "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 1.0.101 (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)",
"serde_json 1.0.40 (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)", "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)", "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -375,7 +375,7 @@ dependencies = [
"csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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]] [[package]]
@ -458,7 +458,7 @@ name = "erased-serde"
version = "0.3.9" version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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]] [[package]]
@ -529,7 +529,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
@ -606,7 +606,7 @@ name = "indexmap"
version = "1.2.0" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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]] [[package]]
@ -1130,10 +1130,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.100" version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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]] [[package]]
@ -1142,7 +1142,7 @@ version = "0.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"byteorder 1.3.2 (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]] [[package]]
@ -1150,12 +1150,12 @@ name = "serde_bytes"
version = "0.11.2" version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.100" version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1170,7 +1170,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"itoa 0.4.4 (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)", "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]] [[package]]
@ -1195,16 +1195,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "structopt" name = "structopt"
version = "0.3.1" version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
name = "structopt-derive" name = "structopt-derive"
version = "0.3.1" version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1330,7 +1330,7 @@ name = "tinytemplate"
version = "1.0.2" version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -1339,7 +1339,7 @@ name = "toml"
version = "0.4.10" version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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]] [[package]]
@ -1347,7 +1347,7 @@ name = "toml"
version = "0.5.3" version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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]] [[package]]
@ -1363,7 +1363,7 @@ dependencies = [
"erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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)", "typetag-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -1422,8 +1422,8 @@ name = "wabt"
version = "0.9.2" version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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_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)",
"serde_json 1.0.40 (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)", "wabt-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -1461,8 +1461,8 @@ dependencies = [
"errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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)",
"structopt 0.3.1 (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)", "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)", "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-clif-backend 0.7.0", "wasmer-clif-backend 0.7.0",
@ -1491,10 +1491,10 @@ dependencies = [
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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-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_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.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-clif-fork-frontend 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-clif-fork-frontend 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-clif-fork-wasm 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-clif-fork-wasm 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1655,10 +1655,10 @@ dependencies = [
"page_size 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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-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_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)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmparser 0.37.2 (registry+https://github.com/rust-lang/crates.io-index)", "wasmparser 0.37.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1701,7 +1701,7 @@ dependencies = [
"libc 0.2.62 (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)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.2 (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.100 (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)", "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)", "typetag 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-runtime-core 0.7.0", "wasmer-runtime-core 0.7.0",
@ -1925,17 +1925,17 @@ dependencies = [
"checksum scroll_derive 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1aa96c45e7f5a91cb7fabe7b279f02fea7126239fc40b732316e8b6a2d0fcb" "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 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 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-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_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 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 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 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 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 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 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe8d3289b63ef2f196d89e7701f986583c0895e764b78f052a55b9b5d34d84a"
"checksum structopt-derive 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ae9e5165d463a0dea76967d021f8d0f9316057bf5163aa2a4843790e842ff37" "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.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 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" "checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"

View File

@ -2,10 +2,14 @@
# Generate files # Generate files
generate-spectests: 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: 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 generate-wasitests: wasitests-setup
WASM_WASI_GENERATE_WASITESTS=1 cargo build -p wasmer-wasi-tests --release -vv \ WASM_WASI_GENERATE_WASITESTS=1 cargo build -p wasmer-wasi-tests --release -vv \
@ -136,11 +140,15 @@ install:
# Checks # Checks
check-bench-singlepass: 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: 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: 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 check-bench: check-bench-singlepass check-bench-llvm
@ -164,11 +172,15 @@ release-llvm:
cargo build --release --features backend-llvm cargo build --release --features backend-llvm
bench-singlepass: 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: 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: 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 utils
build-install: build-install:

26
docs/feature_matrix.md Normal file
View 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

View File

@ -474,11 +474,7 @@ impl EmscriptenGlobals {
let (memory_min, memory_max, shared) = get_emscripten_memory_size(&module)?; let (memory_min, memory_max, shared) = get_emscripten_memory_size(&module)?;
// Memory initialization // Memory initialization
let memory_type = MemoryDescriptor { let memory_type = MemoryDescriptor::new(memory_min, memory_max, shared)?;
minimum: memory_min,
maximum: memory_max,
shared: shared,
};
let memory = Memory::new(memory_type).unwrap(); let memory = Memory::new(memory_type).unwrap();
let table_type = TableDescriptor { let table_type = TableDescriptor {
@ -735,8 +731,9 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
"___syscall345" => func!(crate::syscalls::___syscall345), "___syscall345" => func!(crate::syscalls::___syscall345),
// Process // Process
"abort" => func!(crate::process::em_abort), "abort" => func!(crate::process::_abort),
"_abort" => func!(crate::process::_abort), "_abort" => func!(crate::process::_abort),
"_prctl" => func!(crate::process::_prctl),
"abortStackOverflow" => func!(crate::process::abort_stack_overflow), "abortStackOverflow" => func!(crate::process::abort_stack_overflow),
"_llvm_trap" => func!(crate::process::_llvm_trap), "_llvm_trap" => func!(crate::process::_llvm_trap),
"_fork" => func!(crate::process::_fork), "_fork" => func!(crate::process::_fork),
@ -829,6 +826,9 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
"_gmtime" => func!(crate::time::_gmtime), "_gmtime" => func!(crate::time::_gmtime),
// Math // Math
"sqrt" => func!(crate::math::sqrt),
"floor" => func!(crate::math::floor),
"fabs" => func!(crate::math::fabs),
"f64-rem" => func!(crate::math::f64_rem), "f64-rem" => func!(crate::math::f64_rem),
"_llvm_copysign_f32" => func!(crate::math::_llvm_copysign_f32), "_llvm_copysign_f32" => func!(crate::math::_llvm_copysign_f32),
"_llvm_copysign_f64" => func!(crate::math::_llvm_copysign_f64), "_llvm_copysign_f64" => func!(crate::math::_llvm_copysign_f64),

View File

@ -88,6 +88,21 @@ pub fn log(_ctx: &mut Ctx, value: f64) -> f64 {
value.ln() 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 // emscripten: asm2wasm.f64-to-int
pub fn f64_to_int(_ctx: &mut Ctx, value: f64) -> i32 { pub fn f64_to_int(_ctx: &mut Ctx, value: f64) -> i32 {
debug!("emscripten::f64_to_int {}", value); debug!("emscripten::f64_to_int {}", value);

View File

@ -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"))] #[cfg(not(target_os = "windows"))]
type PidT = libc::pid_t; type PidT = libc::pid_t;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
type PidT = c_int; type PidT = c_int;
use std::ffi::CStr;
use wasmer_runtime_core::vm::Ctx; use wasmer_runtime_core::vm::Ctx;
pub fn abort_with_message(ctx: &mut Ctx, message: &str) { 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 { pub fn _fork(_ctx: &mut Ctx) -> PidT {
debug!("emscripten::_fork"); debug!("emscripten::_fork");
// unsafe { // unsafe {
@ -45,18 +50,6 @@ pub fn _exit(_ctx: &mut Ctx, status: c_int) {
unsafe { exit(status) } 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 { pub fn _kill(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
debug!("emscripten::_kill"); debug!("emscripten::_kill");
-1 -1

View File

@ -24,7 +24,9 @@ pub fn is_emscripten_module(module: &Module) -> bool {
.namespace_table .namespace_table
.get(import_name.namespace_index); .get(import_name.namespace_index);
let field = module.info().name_table.get(import_name.name_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" && namespace == "env"
{ {
return true; return true;

View File

@ -1,6 +1,6 @@
//! Create, read, write, grow, destroy memory of an instance. //! Create, read, write, grow, destroy memory of an instance.
use crate::{error::update_last_error, wasmer_limits_t, wasmer_result_t}; use crate::{error::update_last_error, error::CApiError, wasmer_limits_t, wasmer_result_t};
use std::cell::Cell; use std::cell::Cell;
use wasmer_runtime::Memory; use wasmer_runtime::Memory;
use wasmer_runtime_core::{ use wasmer_runtime_core::{
@ -31,12 +31,17 @@ pub unsafe extern "C" fn wasmer_memory_new(
} else { } else {
None None
}; };
let desc = MemoryDescriptor { let desc = MemoryDescriptor::new(Pages(limits.min), max, false);
minimum: Pages(limits.min), let new_desc = match desc {
maximum: max, Ok(desc) => desc,
shared: false, Err(error) => {
update_last_error(CApiError {
msg: error.to_string(),
});
return wasmer_result_t::WASMER_ERROR;
}
}; };
let result = Memory::new(desc); let result = Memory::new(new_desc);
let new_memory = match result { let new_memory = match result {
Ok(memory) => memory, Ok(memory) => memory,
Err(error) => { Err(error) => {

View File

@ -54,6 +54,9 @@ pub struct LocalBacking {
pub(crate) internals: Internals, pub(crate) internals: Internals,
} }
// Manually implemented because LocalBacking contains raw pointers directly
unsafe impl Send for LocalBacking {}
impl LocalBacking { impl LocalBacking {
pub(crate) fn new( pub(crate) fn new(
module: &ModuleInner, module: &ModuleInner,
@ -461,6 +464,9 @@ pub struct ImportBacking {
pub(crate) vm_globals: BoxedMap<ImportedGlobalIndex, *mut vm::LocalGlobal>, pub(crate) vm_globals: BoxedMap<ImportedGlobalIndex, *mut vm::LocalGlobal>,
} }
// manually implemented because ImportBacking contains raw pointers directly
unsafe impl Send for ImportBacking {}
impl ImportBacking { impl ImportBacking {
pub fn new( pub fn new(
module: &ModuleInner, module: &ModuleInner,
@ -536,9 +542,8 @@ fn import_functions(
let namespace = module.info.namespace_table.get(*namespace_index); let namespace = module.info.namespace_table.get(*namespace_index);
let name = module.info.name_table.get(*name_index); let name = module.info.name_table.get(*name_index);
let import = imports let import =
.get_namespace(namespace) imports.maybe_with_namespace(namespace, |namespace| namespace.get_export(name));
.and_then(|namespace| namespace.get_export(name));
match import { match import {
Some(Export::Function { Some(Export::Function {
func, func,
@ -624,9 +629,8 @@ fn import_memories(
let namespace = module.info.namespace_table.get(*namespace_index); let namespace = module.info.namespace_table.get(*namespace_index);
let name = module.info.name_table.get(*name_index); let name = module.info.name_table.get(*name_index);
let memory_import = imports let memory_import =
.get_namespace(&namespace) imports.maybe_with_namespace(namespace, |namespace| namespace.get_export(name));
.and_then(|namespace| namespace.get_export(&name));
match memory_import { match memory_import {
Some(Export::Memory(memory)) => { Some(Export::Memory(memory)) => {
if expected_memory_desc.fits_in_imported(memory.descriptor()) { 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 namespace = module.info.namespace_table.get(*namespace_index);
let name = module.info.name_table.get(*name_index); let name = module.info.name_table.get(*name_index);
let table_import = imports let table_import =
.get_namespace(&namespace) imports.maybe_with_namespace(namespace, |namespace| namespace.get_export(name));
.and_then(|namespace| namespace.get_export(&name));
match table_import { match table_import {
Some(Export::Table(mut table)) => { Some(Export::Table(mut table)) => {
if expected_table_desc.fits_in_imported(table.descriptor()) { 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 namespace = module.info.namespace_table.get(*namespace_index);
let name = module.info.name_table.get(*name_index); let name = module.info.name_table.get(*name_index);
let import = imports let import =
.get_namespace(namespace) imports.maybe_with_namespace(namespace, |namespace| namespace.get_export(name));
.and_then(|namespace| namespace.get_export(name));
match import { match import {
Some(Export::Global(mut global)) => { Some(Export::Global(mut global)) => {
if global.descriptor() == *imported_global_desc { if global.descriptor() == *imported_global_desc {

View File

@ -11,6 +11,9 @@ pub enum Context {
Internal, Internal,
} }
// Manually implemented because context contains a raw pointer to Ctx
unsafe impl Send for Context {}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Export { pub enum Export {
Function { Function {
@ -26,6 +29,9 @@ pub enum Export {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct FuncPointer(*const vm::Func); pub struct FuncPointer(*const vm::Func);
// Manually implemented because FuncPointer contains a raw pointer to Ctx
unsafe impl Send for FuncPointer {}
impl FuncPointer { impl FuncPointer {
/// This needs to be unsafe because there is /// This needs to be unsafe because there is
/// no way to check whether the passed function /// no way to check whether the passed function

View File

@ -4,11 +4,14 @@ use crate::{
types::{GlobalDescriptor, Type, Value}, types::{GlobalDescriptor, Type, Value},
vm, vm,
}; };
use std::{cell::RefCell, fmt, rc::Rc}; use std::{
fmt,
sync::{Arc, Mutex},
};
pub struct Global { pub struct Global {
desc: GlobalDescriptor, desc: GlobalDescriptor,
storage: Rc<RefCell<vm::LocalGlobal>>, storage: Arc<Mutex<vm::LocalGlobal>>,
} }
impl Global { impl Global {
@ -56,7 +59,7 @@ impl Global {
Self { Self {
desc, 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, Value::V128(x) => x,
}, },
}; };
*self.storage.borrow_mut() = local_global; let mut storage = self.storage.lock().unwrap();
*storage = local_global;
} else { } else {
panic!("Wrong type for setting this global") panic!("Wrong type for setting this global")
} }
@ -94,7 +98,8 @@ impl Global {
/// Get the value held by this global. /// Get the value held by this global.
pub fn get(&self) -> Value { 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 { match self.desc.ty {
Type::I32 => Value::I32(data as i32), 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 { 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 { fn clone(&self) -> Self {
Self { Self {
desc: self.desc, desc: self.desc,
storage: Rc::clone(&self.storage), storage: Arc::clone(&self.storage),
} }
} }
} }

View File

@ -2,9 +2,9 @@ use crate::export::Export;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::collections::{hash_map::Entry, HashMap}; use std::collections::{hash_map::Entry, HashMap};
use std::{ use std::{
cell::{Ref, RefCell}, borrow::{Borrow, BorrowMut},
ffi::c_void, ffi::c_void,
rc::Rc, sync::{Arc, Mutex},
}; };
pub trait LikeNamespace { pub trait LikeNamespace {
@ -45,8 +45,9 @@ impl IsExport for Export {
/// } /// }
/// ``` /// ```
pub struct ImportObject { pub struct ImportObject {
map: Rc<RefCell<HashMap<String, Box<dyn LikeNamespace>>>>, map: Arc<Mutex<HashMap<String, Box<dyn LikeNamespace + Send>>>>,
pub(crate) state_creator: Option<Rc<dyn Fn() -> (*mut c_void, fn(*mut c_void))>>, pub(crate) state_creator:
Option<Arc<dyn Fn() -> (*mut c_void, fn(*mut c_void)) + Send + Sync + 'static>>,
pub allow_missing_functions: bool, pub allow_missing_functions: bool,
} }
@ -54,7 +55,7 @@ impl ImportObject {
/// Create a new `ImportObject`. /// Create a new `ImportObject`.
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
map: Rc::new(RefCell::new(HashMap::new())), map: Arc::new(Mutex::new(HashMap::new())),
state_creator: None, state_creator: None,
allow_missing_functions: false, allow_missing_functions: false,
} }
@ -62,11 +63,11 @@ impl ImportObject {
pub fn new_with_data<F>(state_creator: F) -> Self pub fn new_with_data<F>(state_creator: F) -> Self
where where
F: Fn() -> (*mut c_void, fn(*mut c_void)) + 'static, F: Fn() -> (*mut c_void, fn(*mut c_void)) + 'static + Send + Sync,
{ {
Self { Self {
map: Rc::new(RefCell::new(HashMap::new())), map: Arc::new(Mutex::new(HashMap::new())),
state_creator: Some(Rc::new(state_creator)), state_creator: Some(Arc::new(state_creator)),
allow_missing_functions: false, 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>> pub fn register<S, N>(&mut self, name: S, namespace: N) -> Option<Box<dyn LikeNamespace>>
where where
S: Into<String>, 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()) { match map.entry(name.into()) {
Entry::Vacant(empty) => { Entry::Vacant(empty) => {
@ -105,19 +107,39 @@ impl ImportObject {
} }
} }
pub fn get_namespace(&self, namespace: &str) -> Option<Ref<dyn LikeNamespace + 'static>> { /// Apply a function on the namespace if it exists
let map_ref = self.map.borrow(); /// 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) { if map_ref.contains_key(namespace) {
Some(Ref::map(map_ref, |map| &*map[namespace])) Some(f(map_ref[namespace].as_ref()))
} else { } else {
None 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 { pub fn clone_ref(&self) -> Self {
Self { Self {
map: Rc::clone(&self.map), map: Arc::clone(&self.map),
state_creator: self.state_creator.clone(), state_creator: self.state_creator.clone(),
allow_missing_functions: false, allow_missing_functions: false,
} }
@ -125,7 +147,9 @@ impl ImportObject {
fn get_objects(&self) -> VecDeque<(String, String, Export)> { fn get_objects(&self) -> VecDeque<(String, String, Export)> {
let mut out = VecDeque::new(); 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() { for (id, exp) in ns.get_exports() {
out.push_back((name.clone(), id, exp)); out.push_back((name.clone(), id, exp));
} }
@ -158,7 +182,8 @@ impl IntoIterator for ImportObject {
impl Extend<(String, String, Export)> for ImportObject { impl Extend<(String, String, Export)> for ImportObject {
fn extend<T: IntoIterator<Item = (String, String, Export)>>(&mut self, iter: T) { 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() { for (ns, id, exp) in iter.into_iter() {
if let Some(like_ns) = map.get_mut(&ns) { if let Some(like_ns) = map.get_mut(&ns) {
like_ns.maybe_insert(&id, exp); like_ns.maybe_insert(&id, exp);
@ -172,7 +197,7 @@ impl Extend<(String, String, Export)> for ImportObject {
} }
pub struct Namespace { pub struct Namespace {
map: HashMap<String, Box<dyn IsExport>>, map: HashMap<String, Box<dyn IsExport + Send>>,
} }
impl Namespace { 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 where
S: Into<String>, S: Into<String>,
E: IsExport + 'static, E: IsExport + Send + 'static,
{ {
self.map.insert(name.into(), Box::new(export)) self.map.insert(name.into(), Box::new(export))
} }
@ -241,12 +266,14 @@ mod test {
imports1.extend(imports2); imports1.extend(imports2);
let cat_ns = imports1.get_namespace("cat").unwrap(); let small_cat_export =
assert!(cat_ns.get_export("small").is_some()); 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(); let entries = imports1.maybe_with_namespace("dog", |dog_ns| {
assert!(dog_ns.get_export("happy").is_some()); Some((dog_ns.get_export("happy")?, dog_ns.get_export("small")?))
assert!(dog_ns.get_export("small").is_some()); });
assert!(entries.is_some());
} }
#[test] #[test]
@ -264,14 +291,14 @@ mod test {
}; };
imports1.extend(imports2); 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!( assert!(if let Export::Global(happy_dog_global) = happy_dog_entry {
if let Export::Global(happy_dog_global) = dog_ns.get_export("happy").unwrap() { happy_dog_global.get() == Value::I32(4)
happy_dog_global.get() == Value::I32(4) } else {
} else { false
false });
}
);
} }
} }

View File

@ -16,7 +16,12 @@ use crate::{
vm::{self, InternalField}, vm::{self, InternalField},
}; };
use smallvec::{smallvec, SmallVec}; 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 { pub(crate) struct InstanceInner {
#[allow(dead_code)] #[allow(dead_code)]
@ -25,6 +30,9 @@ pub(crate) struct InstanceInner {
pub(crate) vmctx: *mut vm::Ctx, 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 { impl Drop for InstanceInner {
fn drop(&mut self) { fn drop(&mut self) {
// Drop the vmctx. // 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] #[must_use]
fn call_func_with_index( fn call_func_with_index(
info: &ModuleInfo, info: &ModuleInfo,
@ -763,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>();
}
}

View File

@ -8,12 +8,9 @@ use crate::{
units::Pages, units::Pages,
vm, vm,
}; };
use std::{ use std::{cell::Cell, fmt, mem, sync::Arc};
cell::{Cell, RefCell},
fmt, mem, use std::sync::Mutex as StdMutex;
rc::Rc,
sync::Arc,
};
pub use self::dynamic::DynamicMemory; pub use self::dynamic::DynamicMemory;
pub use self::static_::StaticMemory; pub use self::static_::StaticMemory;
@ -53,16 +50,12 @@ impl Memory {
/// # use wasmer_runtime_core::memory::Memory; /// # use wasmer_runtime_core::memory::Memory;
/// # use wasmer_runtime_core::error::Result; /// # use wasmer_runtime_core::error::Result;
/// # use wasmer_runtime_core::units::Pages; /// # use wasmer_runtime_core::units::Pages;
/// # fn create_memory() -> Result<()> { /// fn create_memory() -> Result<()> {
/// let descriptor = MemoryDescriptor { /// let descriptor = MemoryDescriptor::new(Pages(10), None, false).unwrap();
/// minimum: Pages(10),
/// maximum: None,
/// shared: false,
/// };
/// ///
/// let memory = Memory::new(descriptor)?; /// let memory = Memory::new(descriptor)?;
/// # Ok(()) /// Ok(())
/// # } /// }
/// ``` /// ```
pub fn new(desc: MemoryDescriptor) -> Result<Self, CreationError> { pub fn new(desc: MemoryDescriptor) -> Result<Self, CreationError> {
if let Some(max) = desc.maximum { if let Some(max) = desc.maximum {
@ -131,11 +124,11 @@ impl Memory {
/// ///
/// ``` /// ```
/// # use wasmer_runtime_core::memory::{Memory, MemoryView}; /// # use wasmer_runtime_core::memory::{Memory, MemoryView};
/// # use std::sync::atomic::Ordering; /// # use std::{cell::Cell, sync::atomic::Ordering};
/// # fn view_memory(memory: Memory) { /// # fn view_memory(memory: Memory) {
/// // Without synchronization. /// // Without synchronization.
/// let view: MemoryView<u8> = memory.view(); /// 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); /// println!("byte: {}", byte);
/// } /// }
/// ///
@ -177,7 +170,7 @@ impl fmt::Debug for Memory {
} }
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum MemoryType { pub enum MemoryType {
Dynamic, Dynamic,
Static, Static,
@ -208,14 +201,18 @@ enum UnsharedMemoryStorage {
} }
pub struct UnsharedMemory { pub struct UnsharedMemory {
internal: Rc<UnsharedMemoryInternal>, internal: Arc<UnsharedMemoryInternal>,
} }
struct UnsharedMemoryInternal { struct UnsharedMemoryInternal {
storage: RefCell<UnsharedMemoryStorage>, storage: StdMutex<UnsharedMemoryStorage>,
local: Cell<vm::LocalMemory>, 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 { impl UnsharedMemory {
pub fn new(desc: MemoryDescriptor) -> Result<Self, CreationError> { pub fn new(desc: MemoryDescriptor) -> Result<Self, CreationError> {
let mut local = vm::LocalMemory { let mut local = vm::LocalMemory {
@ -231,19 +228,23 @@ impl UnsharedMemory {
MemoryType::Static => { MemoryType::Static => {
UnsharedMemoryStorage::Static(StaticMemory::new(desc, &mut local)?) UnsharedMemoryStorage::Static(StaticMemory::new(desc, &mut local)?)
} }
MemoryType::SharedStatic => panic!("attempting to create shared unshared memory"), MemoryType::SharedStatic => {
return Err(CreationError::InvalidDescriptor(
"attempting to create shared unshared memory".to_string(),
));
}
}; };
Ok(Self { Ok(Self {
internal: Rc::new(UnsharedMemoryInternal { internal: Arc::new(UnsharedMemoryInternal {
storage: RefCell::new(storage), storage: StdMutex::new(storage),
local: Cell::new(local), local: Cell::new(local),
}), }),
}) })
} }
pub fn grow(&self, delta: Pages) -> Result<Pages, GrowError> { 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(); let mut local = self.internal.local.get();
@ -260,7 +261,7 @@ impl UnsharedMemory {
} }
pub fn size(&self) -> Pages { pub fn size(&self) -> Pages {
let storage = self.internal.storage.borrow(); let storage = self.internal.storage.lock().unwrap();
match &*storage { match &*storage {
UnsharedMemoryStorage::Dynamic(ref dynamic_memory) => dynamic_memory.size(), UnsharedMemoryStorage::Dynamic(ref dynamic_memory) => dynamic_memory.size(),
@ -276,7 +277,7 @@ impl UnsharedMemory {
impl Clone for UnsharedMemory { impl Clone for UnsharedMemory {
fn clone(&self) -> Self { fn clone(&self) -> Self {
UnsharedMemory { UnsharedMemory {
internal: Rc::clone(&self.internal), internal: Arc::clone(&self.internal),
} }
} }
} }
@ -286,11 +287,15 @@ pub struct SharedMemory {
} }
pub struct SharedMemoryInternal { pub struct SharedMemoryInternal {
memory: RefCell<Box<StaticMemory>>, memory: StdMutex<Box<StaticMemory>>,
local: Cell<vm::LocalMemory>, local: Cell<vm::LocalMemory>,
lock: Mutex<()>, 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 { impl SharedMemory {
fn new(desc: MemoryDescriptor) -> Result<Self, CreationError> { fn new(desc: MemoryDescriptor) -> Result<Self, CreationError> {
let mut local = vm::LocalMemory { let mut local = vm::LocalMemory {
@ -303,7 +308,7 @@ impl SharedMemory {
Ok(Self { Ok(Self {
internal: Arc::new(SharedMemoryInternal { internal: Arc::new(SharedMemoryInternal {
memory: RefCell::new(memory), memory: StdMutex::new(memory),
local: Cell::new(local), local: Cell::new(local),
lock: Mutex::new(()), lock: Mutex::new(()),
}), }),
@ -313,15 +318,18 @@ impl SharedMemory {
pub fn grow(&self, delta: Pages) -> Result<Pages, GrowError> { pub fn grow(&self, delta: Pages) -> Result<Pages, GrowError> {
let _guard = self.internal.lock.lock(); let _guard = self.internal.lock.lock();
let mut local = self.internal.local.get(); 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 pages
} }
pub fn size(&self) -> Pages { pub fn size(&self) -> Pages {
let _guard = self.internal.lock.lock(); 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 { pub(crate) fn vm_local_memory(&self) -> *mut vm::LocalMemory {
self.internal.local.as_ptr() self.internal.local.as_ptr()
} }
@ -342,24 +350,16 @@ mod memory_tests {
#[test] #[test]
fn test_initial_memory_size() { fn test_initial_memory_size() {
let unshared_memory = Memory::new(MemoryDescriptor { let memory_desc = MemoryDescriptor::new(Pages(10), Some(Pages(20)), false).unwrap();
minimum: Pages(10), let unshared_memory = Memory::new(memory_desc).unwrap();
maximum: Some(Pages(20)),
shared: false,
})
.unwrap();
assert_eq!(unshared_memory.size(), Pages(10)); assert_eq!(unshared_memory.size(), Pages(10));
} }
#[test] #[test]
fn test_invalid_descriptor_returns_error() { fn test_invalid_descriptor_returns_error() {
let result = Memory::new(MemoryDescriptor { let memory_desc = MemoryDescriptor::new(Pages(10), None, true);
minimum: Pages(10),
maximum: None,
shared: true,
});
assert!( assert!(
result.is_err(), memory_desc.is_err(),
"Max number of pages is required for shared memory" "Max number of pages is required for shared memory"
) )
} }

View File

@ -136,11 +136,13 @@ pub fn read_module<
.push((import_name, table_desc)); .push((import_name, table_desc));
} }
ImportSectionEntryType::Memory(memory_ty) => { ImportSectionEntryType::Memory(memory_ty) => {
let mem_desc = MemoryDescriptor { let mem_desc = MemoryDescriptor::new(
minimum: Pages(memory_ty.limits.initial), Pages(memory_ty.limits.initial),
maximum: memory_ty.limits.maximum.map(|max| Pages(max)), memory_ty.limits.maximum.map(|max| Pages(max)),
shared: memory_ty.shared, memory_ty.shared,
}; )
.map_err(|x| LoadError::Codegen(format!("{:?}", x)))?;
info.write() info.write()
.unwrap() .unwrap()
.imported_memories .imported_memories
@ -172,11 +174,12 @@ pub fn read_module<
info.write().unwrap().tables.push(table_desc); info.write().unwrap().tables.push(table_desc);
} }
ParserState::MemorySectionEntry(memory_ty) => { ParserState::MemorySectionEntry(memory_ty) => {
let mem_desc = MemoryDescriptor { let mem_desc = MemoryDescriptor::new(
minimum: Pages(memory_ty.limits.initial), Pages(memory_ty.limits.initial),
maximum: memory_ty.limits.maximum.map(|max| Pages(max)), memory_ty.limits.maximum.map(|max| Pages(max)),
shared: memory_ty.shared, memory_ty.shared,
}; )
.map_err(|x| LoadError::Codegen(format!("{:?}", x)))?;
info.write().unwrap().memories.push(mem_desc); info.write().unwrap().memories.push(mem_desc);
} }

View File

@ -39,6 +39,10 @@ where
self.elems.len() self.elems.len()
} }
pub fn is_empty(&self) -> bool {
self.elems.is_empty()
}
pub fn push(&mut self, value: V) -> K { pub fn push(&mut self, value: V) -> K {
let len = self.len(); let len = self.len();
self.elems.push(value); self.elems.push(value);

View File

@ -4,7 +4,7 @@ use errno;
use nix::libc; use nix::libc;
use page_size; use page_size;
use std::ops::{Bound, RangeBounds}; 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 Send for Memory {}
unsafe impl Sync for Memory {} unsafe impl Sync for Memory {}
@ -14,7 +14,7 @@ pub struct Memory {
ptr: *mut u8, ptr: *mut u8,
size: usize, size: usize,
protection: Protect, protection: Protect,
fd: Option<Rc<RawFd>>, fd: Option<Arc<RawFd>>,
} }
impl Memory { impl Memory {
@ -49,7 +49,7 @@ impl Memory {
ptr: ptr as *mut u8, ptr: ptr as *mut u8,
size: file_len as usize, size: file_len as usize,
protection, protection,
fd: Some(Rc::new(raw_fd)), fd: Some(Arc::new(raw_fd)),
}) })
} }
} }

View File

@ -5,7 +5,10 @@ use crate::{
types::{ElementType, TableDescriptor}, types::{ElementType, TableDescriptor},
vm, vm,
}; };
use std::{cell::RefCell, fmt, ptr, rc::Rc}; use std::{
fmt, ptr,
sync::{Arc, Mutex},
};
mod anyfunc; mod anyfunc;
@ -25,7 +28,7 @@ pub enum TableStorage {
pub struct Table { pub struct Table {
desc: TableDescriptor, desc: TableDescriptor,
storage: Rc<RefCell<(TableStorage, vm::LocalTable)>>, storage: Arc<Mutex<(TableStorage, vm::LocalTable)>>,
} }
impl Table { impl Table {
@ -71,7 +74,7 @@ impl Table {
Ok(Self { Ok(Self {
desc, 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. /// Set the element at index.
pub fn set(&self, index: u32, element: Element) -> Result<(), ()> { 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), _) => { (TableStorage::Anyfunc(ref mut anyfunc_table), _) => {
match element { match element {
Element::Anyfunc(anyfunc) => anyfunc_table.set(index, anyfunc), Element::Anyfunc(anyfunc) => anyfunc_table.set(index, anyfunc),
@ -96,14 +100,16 @@ impl Table {
where where
F: FnOnce(&mut [vm::Anyfunc]) -> R, 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()), (TableStorage::Anyfunc(ref mut anyfunc_table), _) => f(anyfunc_table.internal_buffer()),
} }
} }
/// The current size of this table. /// The current size of this table.
pub fn size(&self) -> u32 { 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(), (TableStorage::Anyfunc(ref anyfunc_table), _) => anyfunc_table.current_size(),
} }
} }
@ -114,7 +120,8 @@ impl Table {
return Ok(self.size()); 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 (TableStorage::Anyfunc(ref mut anyfunc_table), ref mut local) => anyfunc_table
.grow(delta, local) .grow(delta, local)
.ok_or(GrowError::TableGrowError), .ok_or(GrowError::TableGrowError),
@ -122,7 +129,8 @@ impl Table {
} }
pub fn vm_local_table(&mut self) -> *mut vm::LocalTable { 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 { fn clone(&self) -> Self {
Self { Self {
desc: self.desc, desc: self.desc,
storage: Rc::clone(&self.storage), storage: Arc::clone(&self.storage),
} }
} }
} }

View File

@ -165,6 +165,9 @@ pub struct Func<'a, Args = (), Rets = (), Inner: Kind = Wasm> {
_phantom: PhantomData<(&'a (), Args, Rets)>, _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> impl<'a, Args, Rets> Func<'a, Args, Rets, Wasm>
where where
Args: WasmTypeList, Args: WasmTypeList,

View File

@ -326,7 +326,7 @@ pub struct GlobalInit {
pub init: Initializer, pub init: Initializer,
} }
/// A wasm memory. /// A wasm memory descriptor.
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)] #[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct MemoryDescriptor { pub struct MemoryDescriptor {
/// The minimum number of allowed pages. /// The minimum number of allowed pages.
@ -335,16 +335,30 @@ pub struct MemoryDescriptor {
pub maximum: Option<Pages>, pub maximum: Option<Pages>,
/// This memory can be shared between wasm threads. /// This memory can be shared between wasm threads.
pub shared: bool, pub shared: bool,
/// The type of the memory
pub memory_type: MemoryType,
} }
impl MemoryDescriptor { impl MemoryDescriptor {
pub fn memory_type(self) -> MemoryType { pub fn new(minimum: Pages, maximum: Option<Pages>, shared: bool) -> Result<Self, String> {
match (self.maximum.is_some(), self.shared) { let memory_type = match (maximum.is_some(), shared) {
(true, true) => MemoryType::SharedStatic, (true, true) => MemoryType::SharedStatic,
(true, false) => MemoryType::Static, (true, false) => MemoryType::Static,
(false, false) => MemoryType::Dynamic, (false, false) => MemoryType::Dynamic,
(false, true) => panic!("shared memory without a max is not allowed"), (false, true) => {
} return Err("Max number of pages is required for shared memory".to_string());
}
};
Ok(MemoryDescriptor {
minimum,
maximum,
shared,
memory_type,
})
}
pub fn memory_type(&self) -> MemoryType {
self.memory_type
} }
pub(crate) fn fits_in_imported(&self, imported: MemoryDescriptor) -> bool { pub(crate) fn fits_in_imported(&self, imported: MemoryDescriptor) -> bool {

View File

@ -513,6 +513,9 @@ pub struct ImportedFunc {
pub vmctx: *mut Ctx, 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 { impl ImportedFunc {
#[allow(clippy::erasing_op)] // TODO #[allow(clippy::erasing_op)] // TODO
pub fn offset_func() -> u8 { pub fn offset_func() -> u8 {
@ -540,6 +543,9 @@ pub struct LocalTable {
pub table: *mut (), pub table: *mut (),
} }
// manually implemented because LocalTable contains raw pointers directly
unsafe impl Send for LocalTable {}
impl LocalTable { impl LocalTable {
#[allow(clippy::erasing_op)] // TODO #[allow(clippy::erasing_op)] // TODO
pub fn offset_base() -> u8 { pub fn offset_base() -> u8 {
@ -569,6 +575,9 @@ pub struct LocalMemory {
pub memory: *mut (), pub memory: *mut (),
} }
// manually implemented because LocalMemory contains raw pointers
unsafe impl Send for LocalMemory {}
impl LocalMemory { impl LocalMemory {
#[allow(clippy::erasing_op)] // TODO #[allow(clippy::erasing_op)] // TODO
pub fn offset_base() -> u8 { pub fn offset_base() -> u8 {
@ -619,6 +628,9 @@ pub struct Anyfunc {
pub sig_id: SigId, pub sig_id: SigId,
} }
// manually implemented because Anyfunc contains raw pointers directly
unsafe impl Send for Anyfunc {}
impl Anyfunc { impl Anyfunc {
pub fn null() -> Self { pub fn null() -> Self {
Self { Self {

View File

@ -42,12 +42,8 @@ fn main() -> error::Result<()> {
let inner_module = wasmer_runtime_core::compile_with(&wasm_binary, &get_compiler())?; let inner_module = wasmer_runtime_core::compile_with(&wasm_binary, &get_compiler())?;
let memory = Memory::new(MemoryDescriptor { let memory_desc = MemoryDescriptor::new(Pages(1), Some(Pages(1)), false).unwrap();
minimum: Pages(1), let memory = Memory::new(memory_desc).unwrap();
maximum: Some(Pages(1)),
shared: false,
})
.unwrap();
let global = Global::new(Value::I32(42)); let global = Global::new(Value::I32(42));

View File

@ -18,7 +18,7 @@ mod tests {
// TODO Files could be run with multiple threads // TODO Files could be run with multiple threads
// TODO Allow running WAST &str directly (E.g. for use outside of spectests) // TODO Allow running WAST &str directly (E.g. for use outside of spectests)
use std::rc::Rc; use std::sync::{Arc, Mutex};
struct SpecFailure { struct SpecFailure {
file: String, file: String,
@ -119,6 +119,24 @@ mod tests {
"unknown" "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 glob::glob;
use std::collections::HashMap; use std::collections::HashMap;
use std::fs; use std::fs;
@ -173,11 +191,11 @@ mod tests {
.expect(&format!("Failed to parse script {}", &filename)); .expect(&format!("Failed to parse script {}", &filename));
use std::panic; 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 }) = while let Some(Command { kind, line }) =
@ -236,9 +254,9 @@ mod tests {
instance = None; instance = None;
} }
Ok(i) => { Ok(i) => {
let i = Rc::new(i); let i = Arc::new(Mutex::new(i));
if name.is_some() { if name.is_some() {
named_modules.insert(name.unwrap(), Rc::clone(&i)); named_modules.insert(name.unwrap(), Arc::clone(&i));
} }
instance = Some(i); instance = Some(i);
} }
@ -251,20 +269,17 @@ mod tests {
field, field,
args, args,
} => { } => {
let instance: Option<&Instance> = match module { let maybe_call_result = with_instance(
Some(ref name) => { instance.clone(),
let i = named_modules.get(name); &named_modules,
match i { &module,
Some(ins) => Some(ins.borrow()), |instance| {
None => None, let params: Vec<wasmer_runtime_core::types::Value> =
} args.iter().cloned().map(convert_value).collect();
} instance.call(&field, &params[..])
None => match instance {
Some(ref i) => Some(i.borrow()),
None => None,
}, },
}; );
if instance.is_none() { if maybe_call_result.is_none() {
test_report.add_failure( test_report.add_failure(
SpecFailure { SpecFailure {
file: filename.to_string(), file: filename.to_string(),
@ -276,9 +291,7 @@ mod tests {
excludes, excludes,
); );
} else { } else {
let params: Vec<wasmer_runtime_core::types::Value> = let call_result = maybe_call_result.unwrap();
args.iter().cloned().map(|x| convert_value(x)).collect();
let call_result = instance.unwrap().call(&field, &params[..]);
match call_result { match call_result {
Err(e) => { Err(e) => {
test_report.add_failure( test_report.add_failure(
@ -316,20 +329,17 @@ mod tests {
} }
} }
Action::Get { module, field } => { Action::Get { module, field } => {
let instance: Option<&Instance> = match module { let maybe_call_result = with_instance(
Some(ref name) => { instance.clone(),
let i = named_modules.get(name); &named_modules,
match i { &module,
Some(ins) => Some(ins.borrow()), |instance| {
None => None, instance
} .get_export(&field)
} .expect(&format!("missing global {:?}", &field))
None => match instance {
Some(ref i) => Some(i.borrow()),
None => None,
}, },
}; );
if instance.is_none() { if maybe_call_result.is_none() {
test_report.add_failure( test_report.add_failure(
SpecFailure { SpecFailure {
file: filename.to_string(), file: filename.to_string(),
@ -341,10 +351,7 @@ mod tests {
excludes, excludes,
); );
} else { } else {
let export: Export = instance let export: Export = maybe_call_result.unwrap();
.unwrap()
.get_export(&field)
.expect(&format!("missing global {:?}", &field));
match export { match export {
Export::Global(g) => { Export::Global(g) => {
let value = g.get(); let value = g.get();
@ -392,20 +399,13 @@ mod tests {
field, field,
args, args,
} => { } => {
let instance: Option<&Instance> = match module { let maybe_call_result =
Some(ref name) => { with_instance(instance.clone(), &named_modules, &module, |instance| {
let i = named_modules.get(name); let params: Vec<wasmer_runtime_core::types::Value> =
match i { args.iter().cloned().map(convert_value).collect();
Some(ins) => Some(ins.borrow()), instance.call(&field, &params[..])
None => None, });
} if maybe_call_result.is_none() {
}
None => match instance {
Some(ref i) => Some(i.borrow()),
None => None,
},
};
if instance.is_none() {
test_report.add_failure( test_report.add_failure(
SpecFailure { SpecFailure {
file: filename.to_string(), file: filename.to_string(),
@ -417,9 +417,7 @@ mod tests {
excludes, excludes,
); );
} else { } else {
let params: Vec<wasmer_runtime_core::types::Value> = let call_result = maybe_call_result.unwrap();
args.iter().cloned().map(|x| convert_value(x)).collect();
let call_result = instance.unwrap().call(&field, &params[..]);
match call_result { match call_result {
Err(e) => { Err(e) => {
test_report.add_failure( test_report.add_failure(
@ -468,20 +466,13 @@ mod tests {
field, field,
args, args,
} => { } => {
let instance: Option<&Instance> = match module { let maybe_call_result =
Some(ref name) => { with_instance(instance.clone(), &named_modules, &module, |instance| {
let i = named_modules.get(name); let params: Vec<wasmer_runtime_core::types::Value> =
match i { args.iter().cloned().map(convert_value).collect();
Some(ins) => Some(ins.borrow()), instance.call(&field, &params[..])
None => None, });
} if maybe_call_result.is_none() {
}
None => match instance {
Some(ref i) => Some(i.borrow()),
None => None,
},
};
if instance.is_none() {
test_report.add_failure( test_report.add_failure(
SpecFailure { SpecFailure {
file: filename.to_string(), file: filename.to_string(),
@ -493,9 +484,7 @@ mod tests {
excludes, excludes,
); );
} else { } else {
let params: Vec<wasmer_runtime_core::types::Value> = let call_result = maybe_call_result.unwrap();
args.iter().cloned().map(|x| convert_value(x)).collect();
let call_result = instance.unwrap().call(&field, &params[..]);
match call_result { match call_result {
Err(e) => { Err(e) => {
test_report.add_failure( test_report.add_failure(
@ -544,20 +533,13 @@ mod tests {
field, field,
args, args,
} => { } => {
let instance: Option<&Instance> = match module { let maybe_call_result =
Some(ref name) => { with_instance(instance.clone(), &named_modules, &module, |instance| {
let i = named_modules.get(name); let params: Vec<wasmer_runtime_core::types::Value> =
match i { args.iter().cloned().map(convert_value).collect();
Some(ins) => Some(ins.borrow()), instance.call(&field, &params[..])
None => None, });
} if maybe_call_result.is_none() {
}
None => match instance {
Some(ref i) => Some(i.borrow()),
None => None,
},
};
if instance.is_none() {
test_report.add_failure( test_report.add_failure(
SpecFailure { SpecFailure {
file: filename.to_string(), file: filename.to_string(),
@ -569,9 +551,7 @@ mod tests {
excludes, excludes,
); );
} else { } else {
let params: Vec<wasmer_runtime_core::types::Value> = let call_result = maybe_call_result.unwrap();
args.iter().cloned().map(|x| convert_value(x)).collect();
let call_result = instance.unwrap().call(&field, &params[..]);
use wasmer_runtime_core::error::{CallError, RuntimeError}; use wasmer_runtime_core::error::{CallError, RuntimeError};
match call_result { match call_result {
Err(e) => { Err(e) => {
@ -749,20 +729,17 @@ mod tests {
field, field,
args, args,
} => { } => {
let instance: Option<&Instance> = match module { let maybe_call_result = with_instance(
Some(ref name) => { instance.clone(),
let i = named_modules.get(name); &named_modules,
match i { &module,
Some(ins) => Some(ins.borrow()), |instance| {
None => None, let params: Vec<wasmer_runtime_core::types::Value> =
} args.iter().cloned().map(convert_value).collect();
} instance.call(&field, &params[..])
None => match instance {
Some(ref i) => Some(i.borrow()),
None => None,
}, },
}; );
if instance.is_none() { if maybe_call_result.is_none() {
test_report.add_failure( test_report.add_failure(
SpecFailure { SpecFailure {
file: filename.to_string(), file: filename.to_string(),
@ -774,9 +751,7 @@ mod tests {
excludes, excludes,
); );
} else { } else {
let params: Vec<wasmer_runtime_core::types::Value> = let call_result = maybe_call_result.unwrap();
args.iter().cloned().map(|x| convert_value(x)).collect();
let call_result = instance.unwrap().call(&field, &params[..]);
match call_result { match call_result {
Err(_e) => { Err(_e) => {
// TODO is specific error required? // TODO is specific error required?
@ -871,16 +846,16 @@ mod tests {
} }
} }
CommandKind::Register { name, as_name } => { CommandKind::Register { name, as_name } => {
let instance: Option<Rc<Instance>> = match name { let instance: Option<Arc<Mutex<Instance>>> = match name {
Some(ref name) => { Some(ref name) => {
let i = named_modules.get(name); let i = named_modules.get(name);
match i { match i {
Some(ins) => Some(Rc::clone(ins)), Some(ins) => Some(Arc::clone(ins)),
None => None, None => None,
} }
} }
None => match instance { None => match instance {
Some(ref i) => Some(Rc::clone(i)), Some(ref i) => Some(Arc::clone(i)),
None => None, None => None,
}, },
}; };
@ -906,21 +881,13 @@ mod tests {
field, field,
args, args,
} => { } => {
let instance: Option<&Instance> = match module { let maybe_call_result =
Some(ref name) => { with_instance(instance.clone(), &named_modules, &module, |instance| {
let i = named_modules.get(name); let params: Vec<wasmer_runtime_core::types::Value> =
match i { args.iter().cloned().map(convert_value).collect();
Some(ins) => Some(ins.borrow()), instance.call(&field, &params[..])
None => None, });
} if maybe_call_result.is_none() {
}
None => match instance {
Some(ref i) => Some(i.borrow()),
None => None,
},
};
if instance.is_none() {
test_report.add_failure( test_report.add_failure(
SpecFailure { SpecFailure {
file: filename.to_string(), file: filename.to_string(),
@ -932,9 +899,7 @@ mod tests {
excludes, excludes,
); );
} else { } else {
let params: Vec<wasmer_runtime_core::types::Value> = let call_result = maybe_call_result.unwrap();
args.iter().cloned().map(|x| convert_value(x)).collect();
let call_result = instance.unwrap().call(&field, &params[..]);
match call_result { match call_result {
Err(e) => { Err(e) => {
test_report.add_failure( test_report.add_failure(
@ -1054,14 +1019,10 @@ mod tests {
} }
fn get_spectest_import_object( fn get_spectest_import_object(
registered_modules: &HashMap<String, Rc<Instance>>, registered_modules: &HashMap<String, Arc<Mutex<Instance>>>,
) -> ImportObject { ) -> ImportObject {
let memory = Memory::new(MemoryDescriptor { let memory_desc = MemoryDescriptor::new(Pages(1), Some(Pages(2)), false).unwrap();
minimum: Pages(1), let memory = Memory::new(memory_desc).unwrap();
maximum: Some(Pages(2)),
shared: false,
})
.unwrap();
let global_i32 = Global::new(wasmer_runtime_core::types::Value::I32(666)); let global_i32 = Global::new(wasmer_runtime_core::types::Value::I32(666));
let global_f32 = Global::new(wasmer_runtime_core::types::Value::F32(666.0)); let global_f32 = Global::new(wasmer_runtime_core::types::Value::F32(666.0));
@ -1091,7 +1052,7 @@ mod tests {
}; };
for (name, instance) in registered_modules.iter() { 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 import_object
} }

View File

@ -2,14 +2,17 @@ use wasmer_runtime_core::module::Module;
/// Check if a provided module is compiled with WASI support /// Check if a provided module is compiled with WASI support
pub fn is_wasi_module(module: &Module) -> bool { 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 { for (_, import_name) in &module.info().imported_functions {
let namespace = module let namespace = module
.info() .info()
.namespace_table .namespace_table
.get(import_name.namespace_index); .get(import_name.namespace_index);
if namespace == "wasi_unstable" { if namespace != "wasi_unstable" {
return true; return false;
} }
} }
false true
} }

View File

@ -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. import_object.allow_missing_functions = true; // Import initialization might be left to the loader.
let instance = module let instance = module
.instantiate(&import_object) .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 let args: Vec<Value> = options
.args .args
@ -551,7 +551,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
let import_object = wasmer_emscripten::generate_emscripten_env(&mut emscripten_globals); let import_object = wasmer_emscripten::generate_emscripten_env(&mut emscripten_globals);
let mut instance = module let mut instance = module
.instantiate(&import_object) .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( wasmer_emscripten::run_emscripten_instance(
&module, &module,
@ -591,7 +591,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
#[allow(unused_mut)] // mut used in feature #[allow(unused_mut)] // mut used in feature
let mut instance = module let mut instance = module
.instantiate(&import_object) .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))?; let start: Func<(), ()> = instance.func("_start").map_err(|e| format!("{:?}", e))?;
@ -752,7 +752,7 @@ fn run(options: Run) {
match execute_wasm(&options) { match execute_wasm(&options) {
Ok(()) => {} Ok(()) => {}
Err(message) => { Err(message) => {
eprintln!("execute_wasm: {:?}", message); eprintln!("Error: {}", message);
exit(1); exit(1);
} }
} }