Merge upstream/master into feature/llvm-feature

This commit is contained in:
Lachlan Sneff
2019-02-22 14:14:18 -08:00
273 changed files with 4556 additions and 834 deletions

View File

@ -12,6 +12,9 @@ environment:
ABI: msvc ABI: msvc
TARGET: x86_64-pc-windows-msvc TARGET: x86_64-pc-windows-msvc
cache:
- 'C:\Users\appveyor\.cargo'
install: install:
- appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe - appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
- rustup-init.exe -yv --default-host %target% - rustup-init.exe -yv --default-host %target%
@ -27,9 +30,9 @@ test_script:
- cd ./lib/spectests && cargo test -- --test-threads 1 && cd ../.. - cd ./lib/spectests && cargo test -- --test-threads 1 && cd ../..
before_deploy: before_deploy:
- cd installer - cd ./src/installer
- iscc wasmer.iss - iscc wasmer.iss
- copy /y .\WasmerInstaller.exe ..\WasmerInstaller-%APPVEYOR_REPO_TAG_NAME%.exe - copy /y .\WasmerInstaller.exe ..\..\WasmerInstaller-%APPVEYOR_REPO_TAG_NAME%.exe
- appveyor PushArtifact WasmerInstaller-%APPVEYOR_REPO_TAG_NAME%.exe - appveyor PushArtifact WasmerInstaller-%APPVEYOR_REPO_TAG_NAME%.exe
artifacts: artifacts:

View File

@ -2,19 +2,19 @@
Wasmer uses the following components: Wasmer uses the following components:
- [Cranelift](https://github.com/cranestation/cranelift): for compiling WASM function binaries into Machine IR - [Cranelift](https://github.com/cranestation/cranelift): for compiling Wasm binaries to machine code
- [wabt](https://github.com/pepyakin/wabt-rs): for transforming `.wast` files to `.wasm` and also to run WebAssembly spectests - [wabt](https://github.com/pepyakin/wabt-rs): for transforming `.wast` files to `.wasm` and running WebAssembly spec tests
- [wasmparser](https://github.com/yurydelendik/wasmparser.rs): for parsing the `.wasm` files and translating them into WebAssembly Modules - [wasmparser](https://github.com/yurydelendik/wasmparser.rs): for parsing the `.wasm` files and translating them into WebAssembly modules
## How Wasmer works? ## How Wasmer works
The first time you run `wasmer run myfile.wasm`, wasmer will: The first time you run `wasmer run myfile.wasm`, Wasmer will:
- Check if is a `.wast` file. If so, transform it to `.wasm` - Check if is a `.wast` file, and if so, transform it to `.wasm`
- Check that the provided binary is a valid WebAssembly one. That means, that its binary format starts with `\0asm`. - Check that the provided binary is a valid WebAssembly one, i.e. its binary format starts with `\0asm`.
- If it looks like a WebAssembly file, try to parse it with `wasmparser` and generate a `Module` from it - Parse it with `wasmparser` and generate a `Module` from it
- Once a `Module` is generated, an `Instance` is created with the proper `import_object` (that means, if is detected as an emscripten file, it will add the emscripten expected imports) - Generate an `Instance` with the proper `import_object` (that means, if is detected to be an Emscripten file, it will add the Emscripten expected imports)
- Try to call the WebAssembly start function, or if unexistent try to search for the one that is exported as `main`. - Try to call the WebAssembly `start` function, or if it does not exist, try to search for the function that is exported as `main`
Find a more detailed explanation of the process below: Find a more detailed explanation of the process below:
@ -22,7 +22,7 @@ Find a more detailed explanation of the process below:
As the WebAssembly file is being parsed, it will read the sections in the WebAssembly file (memory, table, function, global and element definitions) using the `Module` (or `ModuleEnvironment`) as the structure to hold this information. As the WebAssembly file is being parsed, it will read the sections in the WebAssembly file (memory, table, function, global and element definitions) using the `Module` (or `ModuleEnvironment`) as the structure to hold this information.
However, the real IR initialization happens while a function body is being parsed/created. That means, when the parser reads the section `(func ...)`. However, the real IR initialization happens while a function body is being parsed/created, i.e. when the parser reads the section `(func ...)`.
While the function body is being parsed the corresponding `FuncEnvironment` methods will be called. While the function body is being parsed the corresponding `FuncEnvironment` methods will be called.
So for example, if the function is using a table, the `make_table` method within that `FuncEnvironment` will be called. So for example, if the function is using a table, the `make_table` method within that `FuncEnvironment` will be called.
@ -41,15 +41,14 @@ Once we have the compiled values, we will push them to memory and mark them as e
#### Relocations #### Relocations
Sometimes the functions that we generated will need to call other functions. Sometimes the functions that we generate will need to call other functions, but the generated code has no idea how to link these functions together.
However the generated code have no idea how to link this functions together.
For example, if a function `A` is calling function `B` (that means is having a `(call b)` on it's body) while compiling `A` we will have no idea where the function `B` lives on memory (as `B` is not yet compiled nor pushed into memory). For example, if a function `A` is calling function `B` (that means is having a `(call b)` on its body) while compiling `A` we will have no idea where the function `B` lives on memory (as `B` is not yet compiled nor pushed into memory).
For that reason, we will start collecting all the calls that function `A` will need to do under the hood, and save it's offsets. For that reason, we will start collecting all the calls that function `A` will need to do under the hood, and save it's offsets.
We do that, so we can patch the function calls after compilation, to point to the correct memory address. We do that, so we can patch the function calls after compilation, to point to the correct memory address.
Note: Sometimes this functions rather than living in the same WebAssembly module, they will be provided as import values. Note: sometimes this functions rather than living in the same WebAssembly module, they will be provided as import values.
#### Traps #### Traps
@ -66,5 +65,5 @@ Once that's finished, we will have a `Instance` function that will be ready to e
## Emscripten ## Emscripten
The Wasmer Emscripten integration tries to wrap (and emulate) all the different syscalls that Emscripten needs. Wasmer's Emscripten integration tries to wrap (and emulate) all the different syscalls that Emscripten needs.
We provide this integration by filling the `import_object` with the emscripten functions, while instantiating the WebAssembly Instance. We provide this integration by filling the `import_object` with the Emscripten functions, while instantiating the WebAssembly Instance.

View File

@ -2,7 +2,7 @@
Wasmer is a community effort. Wasmer is a community effort.
In order to build the best WebAssembly runtime it's our duty to see how other runtimes are approaching the same space In order to build the best WebAssembly runtime it's our duty to see how other runtimes are approaching the same space
and get inspired from them on the things that they got right, so wasmer and its community can benefit from a solid and get inspired from them on the things that they got right, so Wasmer and its community can benefit from a solid
foundation. foundation.
These are the different project that we used as inspiration: These are the different project that we used as inspiration:
@ -10,9 +10,9 @@ These are the different project that we used as inspiration:
- [Nebulet](https://github.com/nebulet/nebulet): as the base for creating a great Rust WebAssembly runtime - [Nebulet](https://github.com/nebulet/nebulet): as the base for creating a great Rust WebAssembly runtime
- [WAVM](https://github.com/wavm/wavm): for their great integration and testing framework - [WAVM](https://github.com/wavm/wavm): for their great integration and testing framework
- [greenwasm](https://github.com/Kimundi/greenwasm): for their [spectests framework](https://github.com/Kimundi/greenwasm/tree/master/greenwasm-spectest) - [greenwasm](https://github.com/Kimundi/greenwasm): for their [spectests framework](https://github.com/Kimundi/greenwasm/tree/master/greenwasm-spectest)
- [wasmtime](/wasmtime): on their [mmap implementation](https://github.com/CraneStation/wasmtime/blob/3f24098edc81cd9bf0f877fb7fba018cad0f039e/lib/runtime/src/mmap.rs). - [wasmtime](https://github.com/CraneStation/wasmtime): for their [mmap implementation](https://github.com/CraneStation/wasmtime/blob/3f24098edc81cd9bf0f877fb7fba018cad0f039e/lib/runtime/src/mmap.rs)
- [stackoverflow](https://stackoverflow.com/a/45795699/1072990): to create an efficient HashMap with pair keys. - [stackoverflow](https://stackoverflow.com/a/45795699/1072990): to create an efficient HashMap with pair keys
- [Emscripten](https://github.com/kripken/emscripten): for emtests test sources to ensure compatibility. - [Emscripten](https://github.com/kripken/emscripten): for emtests test sources to ensure compatibility
We would love to hear from you if you think we can take inspiration from other projects that we haven't covered here. We would love to hear from you if you think we can take inspiration from other projects that we haven't covered here.
😊 😊
@ -21,7 +21,7 @@ We would love to hear from you if you think we can take inspiration from other p
### Nebulet ### Nebulet
``` ```text
MIT License MIT License
Copyright (c) 2018 Copyright (c) 2018
@ -47,7 +47,7 @@ SOFTWARE.
### WAVM ### WAVM
``` ```text
Copyright (c) 2018, Andrew Scheidecker Copyright (c) 2018, Andrew Scheidecker
All rights reserved. All rights reserved.
@ -69,7 +69,7 @@ The contents of [Test/spec](Test/spec) is covered by the license in [Test/spec/L
### Greenwasm ### Greenwasm
``` ```text
Apache License Apache License
Version 2.0, January 2004 Version 2.0, January 2004
http://www.apache.org/licenses/ http://www.apache.org/licenses/
@ -275,7 +275,7 @@ limitations under the License.
### Wasmtime ### Wasmtime
``` ```text
Apache License Apache License
Version 2.0, January 2004 Version 2.0, January 2004
http://www.apache.org/licenses/ http://www.apache.org/licenses/
@ -497,7 +497,7 @@ Software.
``` ```
### Emscripten ### Emscripten
``` ```text
Emscripten is available under 2 licenses, the MIT license and the Emscripten is available under 2 licenses, the MIT license and the
University of Illinois/NCSA Open Source License. University of Illinois/NCSA Open Source License.

72
Cargo.lock generated
View File

@ -111,6 +111,21 @@ name = "cast"
version = "0.2.2" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cbindgen"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.29" version = "1.0.29"
@ -373,6 +388,11 @@ dependencies = [
"unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "hex"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "humantime" name = "humantime"
version = "1.2.0" version = "1.2.0"
@ -761,6 +781,14 @@ dependencies = [
"ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "remove_dir_all"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.13" version = "0.1.13"
@ -820,6 +848,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "serde" name = "serde"
version = "1.0.87" version = "1.0.87"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde_derive 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "serde-bench" name = "serde-bench"
@ -956,6 +987,19 @@ dependencies = [
"serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "tempfile"
version = "3.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
"remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "termcolor" name = "termcolor"
version = "1.0.4" version = "1.0.4"
@ -1000,6 +1044,14 @@ dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "toml"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "typenum" name = "typenum"
version = "1.10.0" version = "1.10.0"
@ -1122,6 +1174,8 @@ dependencies = [
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.49 (git+https://github.com/rust-lang/libc)", "libc 0.2.49 (git+https://github.com/rust-lang/libc)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.5 (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)",
"wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-clif-backend 0.1.2", "wasmer-clif-backend 0.1.2",
@ -1133,10 +1187,21 @@ name = "wasmer-runtime"
version = "0.1.4" version = "0.1.4"
dependencies = [ dependencies = [
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-clif-backend 0.1.2", "wasmer-clif-backend 0.1.2",
"wasmer-runtime-core 0.1.2", "wasmer-runtime-core 0.1.2",
] ]
[[package]]
name = "wasmer-runtime-c-api"
version = "0.1.4"
dependencies = [
"cbindgen 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-runtime 0.1.4",
"wasmer-runtime-core 0.1.2",
]
[[package]] [[package]]
name = "wasmer-runtime-core" name = "wasmer-runtime-core"
version = "0.1.2" version = "0.1.2"
@ -1144,10 +1209,10 @@ 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)",
"field-offset 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "field-offset 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"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.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1267,6 +1332,7 @@ dependencies = [
"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
"checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427" "checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427"
"checksum cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4390a3b5f4f6bce9c1d0c00128379df433e53777fdd30e92f16a529332baec4e" "checksum cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4390a3b5f4f6bce9c1d0c00128379df433e53777fdd30e92f16a529332baec4e"
"checksum cbindgen 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "32e01024aaf5390d6a8145047371a4f5b0063a14c1e411bc731353bd2278ca44"
"checksum cexpr 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "644d693ecfa91955ed32dcc7eda4914e1be97a641fb6f0645a37348e20b230da" "checksum cexpr 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "644d693ecfa91955ed32dcc7eda4914e1be97a641fb6f0645a37348e20b230da"
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" "checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
"checksum clang-sys 0.26.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ef0c1bcf2e99c649104bd7a7012d8f8802684400e03db0ec0af48583c6fa0e4" "checksum clang-sys 0.26.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ef0c1bcf2e99c649104bd7a7012d8f8802684400e03db0ec0af48583c6fa0e4"
@ -1297,6 +1363,7 @@ dependencies = [
"checksum goblin 0.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "84473a5302fa5094d3d9911c2f312f522f9a37462a777f195f63fae1bf7faf4d" "checksum goblin 0.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "84473a5302fa5094d3d9911c2f312f522f9a37462a777f195f63fae1bf7faf4d"
"checksum hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da" "checksum hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da"
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" "checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114"
"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
"checksum inkwell 0.1.0 (git+https://github.com/TheDan64/inkwell?branch=llvm7-0)" = "<none>" "checksum inkwell 0.1.0 (git+https://github.com/TheDan64/inkwell?branch=llvm7-0)" = "<none>"
@ -1342,6 +1409,7 @@ dependencies = [
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f" "checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f"
"checksum regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8c2f35eedad5295fdf00a63d7d4b238135723f92b434ec06774dad15c7ab0861" "checksum regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8c2f35eedad5295fdf00a63d7d4b238135723f92b434ec06774dad15c7ab0861"
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
"checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619" "checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" "checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7"
@ -1366,11 +1434,13 @@ dependencies = [
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
"checksum target-lexicon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4af5e2227f0b887d591d3724b796a96eff04226104d872f5b3883fcd427d64b9" "checksum target-lexicon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4af5e2227f0b887d591d3724b796a96eff04226104d872f5b3883fcd427d64b9"
"checksum tempfile 3.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "37daa55a7240c4931c84559f03b3cad7d19535840d1c4a0cc4e9b2fb0dcf70ff"
"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" "checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
"checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" "checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" "checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"

View File

@ -27,7 +27,7 @@ wasmer-runtime-core = { path = "lib/runtime-core" }
wasmer-emscripten = { path = "lib/emscripten" } wasmer-emscripten = { path = "lib/emscripten" }
[workspace] [workspace]
members = ["lib/clif-backend", "lib/runtime", "lib/runtime-core", "lib/emscripten", "lib/spectests", "lib/win-exception-handler", "lib/llvm-backend"] members = ["lib/clif-backend", "lib/runtime", "lib/runtime-core", "lib/emscripten", "lib/spectests", "lib/win-exception-handler", "lib/runtime-c-api", "lib/llvm-backend"]
[build-dependencies] [build-dependencies]
wabt = "0.7.2" wabt = "0.7.2"

View File

@ -1,6 +1,4 @@
The MIT License (MIT) Copyright (c) 2019 Syrus Akbary
Copyright (c) 2018-Present Syrus Akbary
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -12,6 +12,9 @@ spectests:
emtests: emtests:
WASM_EMSCRIPTEN_GENERATE_EMTESTS=1 cargo build -p wasmer-emscripten WASM_EMSCRIPTEN_GENERATE_EMTESTS=1 cargo build -p wasmer-emscripten
capi:
WASM_EMSCRIPTEN_GENERATE_C_API_HEADERS=1 cargo build --manifest-path lib/runtime-c-api/Cargo.toml --features generate-c-api-headers
# clean: # clean:
# rm -rf artifacts # rm -rf artifacts
@ -34,9 +37,10 @@ precommit: lint test
test: test:
# We use one thread so the emscripten stdouts doesn't collide # We use one thread so the emscripten stdouts doesn't collide
cargo test --all -- --test-threads=1 $(runargs) cargo test --all --exclude wasmer-runtime-c-api -- --test-threads=1 $(runargs)
# cargo test --all --exclude wasmer-emscripten -- --test-threads=1 $(runargs) # cargo test --all --exclude wasmer-emscripten -- --test-threads=1 $(runargs)
# cargo test -p wasmer-spectests -- --test-threads=1 $(runargs) cargo build -p wasmer-runtime-c-api
cargo test -p wasmer-runtime-c-api -- --nocapture
release: release:
# If you are in OS-X, you will need mingw-w64 for cross compiling to windows # If you are in OS-X, you will need mingw-w64 for cross compiling to windows

View File

@ -1,16 +1,24 @@
<p align="center"><a href="https://wasmer.io" target="_blank" rel="noopener noreferrer"><img width="400" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/logo.png" alt="Wasmer logo"></a></p> <p align="center">
<a href="https://wasmer.io" target="_blank" rel="noopener noreferrer">
<img width="400" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/logo.png" alt="Wasmer logo">
</a>
</p>
<p align="center"> <p align="center">
<a href="https://circleci.com/gh/wasmerio/wasmer/"><img src="https://img.shields.io/circleci/project/github/wasmerio/wasmer/master.svg" alt="Build Status"></a> <a href="https://circleci.com/gh/wasmerio/wasmer/">
<a href="https://github.com/wasmerio/wasmer/blob/master/LICENSE"><img src="https://img.shields.io/github/license/wasmerio/wasmer.svg" alt="License"></a> <img src="https://img.shields.io/circleci/project/github/wasmerio/wasmer/master.svg" alt="Build Status">
</a>
<a href="https://github.com/wasmerio/wasmer/blob/master/LICENSE">
<img src="https://img.shields.io/github/license/wasmerio/wasmer.svg" alt="License">
</a>
<a href="https://spectrum.chat/wasmer"> <a href="https://spectrum.chat/wasmer">
<img alt="Join the Wasmer Community" src="https://withspectrum.github.io/badge/badge.svg" /> <img src="https://withspectrum.github.io/badge/badge.svg" alt="Join the Wasmer Community">
</a> </a>
</p> </p>
## Introduction ## Introduction
[Wasmer](https://wasmer.io/) is a Standalone JIT WebAssembly runtime, aiming to be fully compatible with Emscripten, Rust and Go. [Wasmer](https://wasmer.io/) is a standalone JIT WebAssembly runtime, aiming to be fully compatible with Emscripten, Rust and Go.
Install Wasmer with: Install Wasmer with:
@ -18,20 +26,20 @@ Install Wasmer with:
curl https://get.wasmer.io -sSfL | sh curl https://get.wasmer.io -sSfL | sh
``` ```
_**NEW ✨**: Now you can also embed Wasmer in your Rust application, check our [example repo](https://github.com/wasmerio/wasmer-rust-example) to see how to do it!_ _**NEW ✨**: You can now embed Wasmer in your Rust application, check our [example repo](https://github.com/wasmerio/wasmer-rust-example) to see how!_
### Usage ### Usage
`wasmer` can execute both the standard binary format (`.wasm`) and the text Wasmer can execute both the standard binary format (`.wasm`) and the text
format defined by the WebAssembly reference interpreter (`.wat`). format defined by the WebAssembly reference interpreter (`.wat`).
Once installed, you will be able to run any WebAssembly files (_including Nginx, and Lua!_): Once installed, you will be able to run any WebAssembly files (_including nginx and Lua!_):
```sh ```sh
# Run Lua # Run Lua
wasmer run examples/lua.wasm wasmer run examples/lua.wasm
# Run Nginx # Run nginx
wasmer run examples/nginx/nginx.wasm -- -p examples/nginx -c nginx.conf wasmer run examples/nginx/nginx.wasm -- -p examples/nginx -c nginx.conf
``` ```
@ -39,13 +47,13 @@ wasmer run examples/nginx/nginx.wasm -- -p examples/nginx -c nginx.conf
Wasmer is structured into different directories: Wasmer is structured into different directories:
- [`src`](./src): code related to the wasmer excutable binary itself - [`src`](./src): code related to the Wasmer executable itself
- [`lib`](./lib): modularized libraries that Wasmer uses under the hood - [`lib`](./lib): modularized libraries that Wasmer uses under the hood
- [`examples`](./examples): some useful examples to getting started with wasmer - [`examples`](./examples): some useful examples to getting started with Wasmer
## Dependencies ## Dependencies
Building wasmer requires [rustup](https://rustup.rs/). Building Wasmer requires [rustup](https://rustup.rs/).
To build on Windows, download and run [`rustup-init.exe`](https://win.rustup.rs/) To build on Windows, download and run [`rustup-init.exe`](https://win.rustup.rs/)
then follow the onscreen instructions. then follow the onscreen instructions.
@ -66,13 +74,13 @@ Please select your operating system:
#### macOS #### macOS
If you have [homebrew](https://brew.sh/) installed: If you have [Homebrew](https://brew.sh/) installed:
```sh ```sh
brew install cmake brew install cmake
``` ```
Or, in case you have [ports](https://www.macports.org/install.php): Or, in case you have [MacPorts](https://www.macports.org/install.php):
```sh ```sh
sudo port install cmake sudo port install cmake
@ -86,16 +94,16 @@ sudo apt install cmake
#### Windows (MSVC) #### Windows (MSVC)
Windows support is _highly experimental_. Only simple wasm programs may be run, and no syscalls are allowed. This means Windows support is _highly experimental_. Only simple Wasm programs may be run, and no syscalls are allowed. This means
nginx and lua do not work on Windows. See [this issue for ongoing Emscripten syscall polyfills for Windows](https://github.com/wasmerio/wasmer/pull/176). nginx and Lua do not work on Windows. See [this issue](https://github.com/wasmerio/wasmer/issues/176) regarding Emscripten syscall polyfills for Windows.
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). The Windows x86-64 MSI installer is fine. 1. Install [Python for Windows](https://www.python.org/downloads/release/python-2714/). The Windows x86-64 MSI installer is fine.
You should change the installation to install the "Add python.exe to Path" feature. Make sure to enable "Add python.exe to Path" during installation.
2. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default 2. Install [Git for Windows](https://git-scm.com/download/win). Allow it to add `git.exe` to your PATH (default
settings for the installer are fine). settings for the installer are fine).
3. Install CMake (https://cmake.org/download/). Ensure CMake is in the PATH. 3. Install [CMake](https://cmake.org/download/). Ensure CMake is in your PATH.
## Building ## Building
@ -113,7 +121,7 @@ cargo install --path .
## Testing ## Testing
Thanks to [spectests](https://github.com/wasmerio/wasmer/tree/master/lib/runtime-core/spectests) we can assure 100% compatibility with the WebAssembly spec test suite. Thanks to [spec tests](https://github.com/wasmerio/wasmer/tree/master/lib/spectests/spectests) we can ensure 100% compatibility with the WebAssembly spec test suite.
Tests can be run with: Tests can be run with:
@ -121,7 +129,7 @@ Tests can be run with:
make test make test
``` ```
If you need to re-generate the Rust tests from the spectests If you need to regenerate the Rust tests from the spec tests
you can run: you can run:
```sh ```sh
@ -138,20 +146,20 @@ make integration-tests
Wasmer is an open project guided by strong principles, aiming to be modular, flexible and fast. It is open to the community to help set its direction. Wasmer is an open project guided by strong principles, aiming to be modular, flexible and fast. It is open to the community to help set its direction.
Below are some of the goals (written with order) of this project: Below are some of the goals of this project (in order of priority):
- [x] It should be 100% compatible with the [WebAssembly Spectest](https://github.com/wasmerio/wasmer/tree/master/spectests) - [x] It should be 100% compatible with the [WebAssembly spec tests](https://github.com/wasmerio/wasmer/tree/master/lib/spectests/spectests)
- [x] It should be fast _(partially achieved)_ - [x] It should be fast _(partially achieved)_
- [ ] Support Emscripten calls _(in the works)_ - [ ] Support Emscripten calls _(in the works)_
- [ ] Support Rust ABI calls - [ ] Support Rust ABI calls
- [ ] Support GO ABI calls - [ ] Support Go ABI calls
## Architecture ## Architecture
If you would like to know how Wasmer works under the hood, please visit our [ARCHITECTURE](https://github.com/wasmerio/wasmer/blob/master/ARCHITECTURE.md) document. If you would like to know how Wasmer works under the hood, please see [ARCHITECTURE.md](./ARCHITECTURE.md).
## License ## License
MIT/Apache-2.0 Wasmer is primarily distributed under the terms of the [MIT license](http://opensource.org/licenses/MIT) ([LICENSE](./LICENSE)).
<small>[Attributions](./ATTRIBUTIONS.md)</small>. [ATTRIBUTIONS](./ATTRIBUTIONS.md)

View File

@ -130,7 +130,7 @@ wasmer_link() {
printf "$cyan> Adding to bash profile...$reset\n" printf "$cyan> Adding to bash profile...$reset\n"
WASMER_PROFILE="$(wasmer_detect_profile)" WASMER_PROFILE="$(wasmer_detect_profile)"
LOAD_STR="\n# Wasmer\nexport WASMER_DIR=\"\$HOME/.wasmer\"\n[ -s \"\$WASMER_DIR/wasmer.sh\" ] && source \"\$WASMER_DIR/wasmer.sh\" # This loads wasmer\n" LOAD_STR="\n# Wasmer\nexport WASMER_DIR=\"\$HOME/.wasmer\"\n[ -s \"\$WASMER_DIR/wasmer.sh\" ] && source \"\$WASMER_DIR/wasmer.sh\" # This loads wasmer\n"
SOURCE_STR="# Wasmer config\nexport WASMER_DIR=\"\$HOME/.wasmer\"\nexport PATH=\"\$HOME/.wasmer/bin:\$PATH\"\n" SOURCE_STR="# Wasmer config\nexport WASMER_DIR=\"\$HOME/.wasmer\"\nexport WASMER_CACHE_DIR=\"\$WASMER_DIR/cache\"\nexport PATH=\"\$HOME/.wasmer/bin:\$PATH\"\n"
# We create the wasmer.sh file # We create the wasmer.sh file
echo "$SOURCE_STR" > "$HOME/.wasmer/wasmer.sh" echo "$SOURCE_STR" > "$HOME/.wasmer/wasmer.sh"

View File

@ -1,8 +1,8 @@
# `lua` integration test # `lua` integration test
This starts wasmer with the lua wasm file. The test asserts on This starts Wasmer with the Lua Wasm file. The test makes assertions on
the output of wasmer. Run test with: the output of Wasmer. Run test with:
``` ```
> ./integration_tests/lua/test.sh > ./integration_tests/lua/test.sh

View File

@ -1,7 +1,7 @@
# `nginx` integration test # `nginx` integration test
This starts wasmer with the nginx wasm file and serves an html This starts Wasmer with the nginx Wasm file and serves an HTML
file with some simple text to assert on. The test script does file with some simple text to assert on. The test script does
the assertion. the assertion.

View File

@ -2,34 +2,34 @@
Wasmer is modularized into different libraries, separated into three main sections: Wasmer is modularized into different libraries, separated into three main sections:
- [Runtime](#Runtime) - [Runtime](#runtime)
- [Integrations](#Integrations) - [Integrations](#integrations)
- [Backends](#Backends) - [Backends](#backends)
## Runtime ## Runtime
The core of Wasmer is the runtime, which provides the necessary The core of Wasmer is the runtime, which provides the necessary
abstractions to create a good user-experience when embedding. abstractions to create a good user experience when embedding.
The runtime is divided into two main libraries: The runtime is divided into two main libraries:
- [runtime-core](./runtime-core/): The main implementation of the runtime. - [runtime-core](./runtime-core/): The main implementation of the runtime.
- [runtime](./runtime/): Easy-to-use api on top of runtime-core. - [runtime](./runtime/): Easy-to-use API on top of `runtime-core`.
## Integrations ## Integrations
The intergration run on-top of the Wasmer runtime and allow us to run WebAssembly files compiled for different environments. The integration builds on the Wasmer runtime and allow us to run WebAssembly files compiled for different environments.
Wasmer intends to support different integrations: Wasmer intends to support different integrations:
- [emscripten](./emscripten): run emscripten-generated WebAssembly files, such as [Lua](../examples/lua.wasm) or [Nginx](../examples/nginx/nginx.wasm). - [emscripten](./emscripten): run Emscripten-generated WebAssembly files, such as [Lua](../examples/lua.wasm) or [nginx](../examples/nginx/nginx.wasm).
- Go ABI: _we will work on this soon! Want to give us a hand? ✋_ - Go ABI: _we will work on this soon! Want to give us a hand? ✋_
- Blazor: _researching period, see [tracking issue](https://github.com/wasmerio/wasmer/issues/97)_ - Blazor: _research period, see [tracking issue](https://github.com/wasmerio/wasmer/issues/97)_
## Backends ## Backends
The Wasmer [runtime](./runtime) is designed to support multiple compiler backends, allowing the user The Wasmer [runtime](./runtime) is designed to support multiple compiler backends, allowing the user
to tune the codegen properties (compile speed, performance, etc) to fit your usecase best. to tune the codegen properties (compile speed, performance, etc) to best fit their use case.
Currently, we support a Cranelift compiler backend: Currently, we support a Cranelift compiler backend:

View File

@ -23,24 +23,16 @@ libc = "0.2.48"
# Dependencies for caching. # Dependencies for caching.
[dependencies.serde] [dependencies.serde]
version = "1.0" version = "1.0"
optional = true
[dependencies.serde_derive] [dependencies.serde_derive]
version = "1.0" version = "1.0"
optional = true
[dependencies.serde_bytes] [dependencies.serde_bytes]
version = "0.10" version = "0.10"
optional = true
# [dependencies.bincode]
# version = "1.0.1"
# optional = true
[dependencies.serde-bench] [dependencies.serde-bench]
version = "0.0.7" version = "0.0.7"
optional = true
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["errhandlingapi", "minwindef", "minwinbase", "winnt"] } winapi = { version = "0.3", features = ["errhandlingapi", "minwindef", "minwinbase", "winnt"] }
wasmer-win-exception-handler = { path = "../win-exception-handler", version = "0.0.1" } wasmer-win-exception-handler = { path = "../win-exception-handler", version = "0.0.1" }
[features] [features]
cache = ["serde", "serde_derive", "serde_bytes", "serde-bench", "wasmer-runtime-core/cache"]
debug = ["wasmer-runtime-core/debug"] debug = ["wasmer-runtime-core/debug"]

View File

@ -1,16 +1,50 @@
use crate::relocation::{ExternalRelocation, TrapSink}; use crate::relocation::{ExternalRelocation, TrapSink};
use hashbrown::HashMap; use hashbrown::HashMap;
use std::sync::Arc;
use wasmer_runtime_core::{ use wasmer_runtime_core::{
backend::sys::Memory, backend::{sys::Memory, CacheGen},
cache::{Cache, Error}, cache::{Artifact, Error},
module::ModuleInfo, module::{ModuleInfo, ModuleInner},
structures::Map, structures::Map,
types::{LocalFuncIndex, SigIndex}, types::{LocalFuncIndex, SigIndex},
}; };
use serde_bench::{deserialize, serialize}; use serde_bench::{deserialize, serialize};
pub struct CacheGenerator {
backend_cache: BackendCache,
memory: Arc<Memory>,
}
impl CacheGenerator {
pub fn new(backend_cache: BackendCache, memory: Arc<Memory>) -> Self {
Self {
backend_cache,
memory,
}
}
}
impl CacheGen for CacheGenerator {
fn generate_cache(
&self,
module: &ModuleInner,
) -> Result<(Box<ModuleInfo>, Box<[u8]>, Memory), Error> {
let info = Box::new(module.info.clone());
// Clone the memory to a new location. This could take a long time,
// depending on the throughput of your memcpy implementation.
let compiled_code = (*self.memory).clone();
Ok((
info,
self.backend_cache.into_backend_data()?.into_boxed_slice(),
compiled_code,
))
}
}
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct TrampolineCache { pub struct TrampolineCache {
#[serde(with = "serde_bytes")] #[serde(with = "serde_bytes")]
@ -22,24 +56,24 @@ pub struct TrampolineCache {
pub struct BackendCache { pub struct BackendCache {
pub external_relocs: Map<LocalFuncIndex, Box<[ExternalRelocation]>>, pub external_relocs: Map<LocalFuncIndex, Box<[ExternalRelocation]>>,
pub offsets: Map<LocalFuncIndex, usize>, pub offsets: Map<LocalFuncIndex, usize>,
pub trap_sink: TrapSink, pub trap_sink: Arc<TrapSink>,
pub trampolines: TrampolineCache, pub trampolines: TrampolineCache,
} }
impl BackendCache { impl BackendCache {
pub fn from_cache(cache: Cache) -> Result<(ModuleInfo, Memory, Self), Error> { pub fn from_cache(cache: Artifact) -> Result<(ModuleInfo, Memory, Self), Error> {
let (info, backend_data, compiled_code) = cache.consume(); let (info, backend_data, compiled_code) = cache.consume();
let backend_cache = deserialize(backend_data.as_slice()) let backend_cache =
.map_err(|e| Error::DeserializeError(e.to_string()))?; deserialize(&backend_data).map_err(|e| Error::DeserializeError(e.to_string()))?;
Ok((info, compiled_code, backend_cache)) Ok((info, compiled_code, backend_cache))
} }
pub fn into_backend_data(self) -> Result<Vec<u8>, Error> { pub fn into_backend_data(&self) -> Result<Vec<u8>, Error> {
let mut buffer = Vec::new(); let mut buffer = Vec::new();
serialize(&mut buffer, &self).map_err(|e| Error::SerializeError(e.to_string()))?; serialize(&mut buffer, self).map_err(|e| Error::SerializeError(e.to_string()))?;
Ok(buffer) Ok(buffer)
} }

View File

@ -1,4 +1,3 @@
#[cfg(feature = "cache")]
mod cache; mod cache;
mod func_env; mod func_env;
mod libcalls; mod libcalls;
@ -14,21 +13,17 @@ use cranelift_codegen::{
settings::{self, Configurable}, settings::{self, Configurable},
}; };
use target_lexicon::Triple; use target_lexicon::Triple;
#[cfg(feature = "cache")]
use wasmer_runtime_core::{ use wasmer_runtime_core::cache::{Artifact, Error as CacheError};
backend::sys::Memory,
cache::{Cache, Error as CacheError},
module::ModuleInfo,
};
use wasmer_runtime_core::{ use wasmer_runtime_core::{
backend::{Compiler, Token}, backend::{Compiler, Token},
error::{CompileError, CompileResult}, error::{CompileError, CompileResult},
module::ModuleInner, module::ModuleInner,
}; };
#[cfg(feature = "cache")]
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
#[cfg(feature = "cache")]
extern crate serde; extern crate serde;
use wasmparser::{self, WasmDecoder}; use wasmparser::{self, WasmDecoder};
@ -48,7 +43,7 @@ impl Compiler for CraneliftCompiler {
let isa = get_isa(); let isa = get_isa();
let mut module = module::Module::empty(); let mut module = module::Module::new(wasm);
let module_env = module_env::ModuleEnv::new(&mut module, &*isa); let module_env = module_env::ModuleEnv::new(&mut module, &*isa);
let func_bodies = module_env.translate(wasm)?; let func_bodies = module_env.translate(wasm)?;
@ -57,41 +52,41 @@ impl Compiler for CraneliftCompiler {
} }
/// Create a wasmer Module from an already-compiled cache. /// Create a wasmer Module from an already-compiled cache.
#[cfg(feature = "cache")]
unsafe fn from_cache(&self, cache: Cache, _: Token) -> Result<ModuleInner, CacheError> { unsafe fn from_cache(&self, cache: Artifact, _: Token) -> Result<ModuleInner, CacheError> {
module::Module::from_cache(cache) module::Module::from_cache(cache)
} }
#[cfg(feature = "cache")] //
fn compile_to_backend_cache_data( // fn compile_to_backend_cache_data(
&self, // &self,
wasm: &[u8], // wasm: &[u8],
_: Token, // _: Token,
) -> CompileResult<(Box<ModuleInfo>, Vec<u8>, Memory)> { // ) -> CompileResult<(Box<ModuleInfo>, Vec<u8>, Memory)> {
validate(wasm)?; // validate(wasm)?;
let isa = get_isa(); // let isa = get_isa();
let mut module = module::Module::empty(); // let mut module = module::Module::new(wasm);
let module_env = module_env::ModuleEnv::new(&mut module, &*isa); // let module_env = module_env::ModuleEnv::new(&mut module, &*isa);
let func_bodies = module_env.translate(wasm)?; // let func_bodies = module_env.translate(wasm)?;
let (info, backend_cache, compiled_code) = module // let (info, backend_cache, compiled_code) = module
.compile_to_backend_cache(&*isa, func_bodies) // .compile_to_backend_cache(&*isa, func_bodies)
.map_err(|e| CompileError::InternalError { // .map_err(|e| CompileError::InternalError {
msg: format!("{:?}", e), // msg: format!("{:?}", e),
})?; // })?;
let buffer = // let buffer =
backend_cache // backend_cache
.into_backend_data() // .into_backend_data()
.map_err(|e| CompileError::InternalError { // .map_err(|e| CompileError::InternalError {
msg: format!("{:?}", e), // msg: format!("{:?}", e),
})?; // })?;
Ok((Box::new(info), buffer, compiled_code)) // Ok((Box::new(info), buffer, compiled_code))
} // }
} }
fn get_isa() -> Box<isa::TargetIsa> { fn get_isa() -> Box<isa::TargetIsa> {

View File

@ -1,75 +1,32 @@
#[cfg(feature = "cache")] use crate::cache::{BackendCache, CacheGenerator};
use crate::cache::BackendCache;
use crate::{resolver::FuncResolverBuilder, signal::Caller, trampoline::Trampolines}; use crate::{resolver::FuncResolverBuilder, signal::Caller, trampoline::Trampolines};
use cranelift_codegen::{ir, isa}; use cranelift_codegen::{ir, isa};
use cranelift_entity::EntityRef; use cranelift_entity::EntityRef;
use cranelift_wasm; use cranelift_wasm;
use hashbrown::HashMap; use hashbrown::HashMap;
use std::{ use std::sync::Arc;
ops::{Deref, DerefMut},
ptr::NonNull, use wasmer_runtime_core::cache::{Artifact, Error as CacheError, WasmHash};
};
#[cfg(feature = "cache")]
use wasmer_runtime_core::{ use wasmer_runtime_core::{
backend::sys::Memory, backend::Backend,
cache::{Cache, Error as CacheError}, error::CompileResult,
};
use wasmer_runtime_core::{
backend::{Backend, FuncResolver, ProtectedCaller, Token, UserTrapper},
error::{CompileResult, RuntimeResult},
module::{ModuleInfo, ModuleInner, StringTable}, module::{ModuleInfo, ModuleInner, StringTable},
structures::{Map, TypedIndex}, structures::{Map, TypedIndex},
types::{ types::{
FuncIndex, FuncSig, GlobalIndex, LocalFuncIndex, MemoryIndex, SigIndex, TableIndex, Type, FuncIndex, FuncSig, GlobalIndex, LocalFuncIndex, MemoryIndex, SigIndex, TableIndex, Type,
Value,
}, },
vm::{self, ImportBacking},
}; };
struct Placeholder;
impl FuncResolver for Placeholder {
fn get(
&self,
_module: &ModuleInner,
_local_func_index: LocalFuncIndex,
) -> Option<NonNull<vm::Func>> {
None
}
}
impl ProtectedCaller for Placeholder {
fn call(
&self,
_module: &ModuleInner,
_func_index: FuncIndex,
_params: &[Value],
_import_backing: &ImportBacking,
_vmctx: *mut vm::Ctx,
_: Token,
) -> RuntimeResult<Vec<Value>> {
Ok(vec![])
}
fn get_early_trapper(&self) -> Box<dyn UserTrapper> {
unimplemented!()
}
}
/// This contains all of the items in a `ModuleInner` except the `func_resolver`. /// This contains all of the items in a `ModuleInner` except the `func_resolver`.
pub struct Module { pub struct Module {
pub module: ModuleInner, pub info: ModuleInfo,
} }
impl Module { impl Module {
pub fn empty() -> Self { pub fn new(wasm: &[u8]) -> Self {
Self { Self {
module: ModuleInner {
// this is a placeholder
func_resolver: Box::new(Placeholder),
protected_caller: Box::new(Placeholder),
info: ModuleInfo { info: ModuleInfo {
memories: Map::new(), memories: Map::new(),
globals: Map::new(), globals: Map::new(),
@ -94,85 +51,72 @@ impl Module {
namespace_table: StringTable::new(), namespace_table: StringTable::new(),
name_table: StringTable::new(), name_table: StringTable::new(),
}, },
},
} }
} }
pub fn compile( pub fn compile(
mut self, self,
isa: &isa::TargetIsa, isa: &isa::TargetIsa,
functions: Map<LocalFuncIndex, ir::Function>, functions: Map<LocalFuncIndex, ir::Function>,
) -> CompileResult<ModuleInner> { ) -> CompileResult<ModuleInner> {
let (func_resolver_builder, handler_data) = let (func_resolver_builder, handler_data) =
FuncResolverBuilder::new(isa, functions, &self.module.info)?; FuncResolverBuilder::new(isa, functions, &self.info)?;
self.module.func_resolver = let trampolines = Arc::new(Trampolines::new(isa, &self.info));
Box::new(func_resolver_builder.finalize(&self.module.info.signatures)?);
let trampolines = Trampolines::new(isa, &self.module.info); let (func_resolver, backend_cache) = func_resolver_builder.finalize(
&self.info.signatures,
Arc::clone(&trampolines),
handler_data.clone(),
)?;
self.module.protected_caller = let protected_caller = Caller::new(&self.info, handler_data, trampolines);
Box::new(Caller::new(&self.module.info, handler_data, trampolines));
Ok(self.module) let cache_gen = Box::new(CacheGenerator::new(
backend_cache,
Arc::clone(&func_resolver.memory),
));
Ok(ModuleInner {
func_resolver: Box::new(func_resolver),
protected_caller: Box::new(protected_caller),
cache_gen,
info: self.info,
})
} }
#[cfg(feature = "cache")] pub fn from_cache(cache: Artifact) -> Result<ModuleInner, CacheError> {
pub fn compile_to_backend_cache(
self,
isa: &isa::TargetIsa,
functions: Map<LocalFuncIndex, ir::Function>,
) -> CompileResult<(ModuleInfo, BackendCache, Memory)> {
let (func_resolver_builder, handler_data) =
FuncResolverBuilder::new(isa, functions, &self.module.info)?;
let trampolines = Trampolines::new(isa, &self.module.info);
let trampoline_cache = trampolines.to_trampoline_cache();
let (backend_cache, compiled_code) =
func_resolver_builder.to_backend_cache(trampoline_cache, handler_data);
Ok((self.module.info, backend_cache, compiled_code))
}
#[cfg(feature = "cache")]
pub fn from_cache(cache: Cache) -> Result<ModuleInner, CacheError> {
let (info, compiled_code, backend_cache) = BackendCache::from_cache(cache)?; let (info, compiled_code, backend_cache) = BackendCache::from_cache(cache)?;
let (func_resolver_builder, trampolines, handler_data) = let (func_resolver_builder, trampolines, handler_data) =
FuncResolverBuilder::new_from_backend_cache(backend_cache, compiled_code, &info)?; FuncResolverBuilder::new_from_backend_cache(backend_cache, compiled_code, &info)?;
let func_resolver = Box::new( let (func_resolver, backend_cache) = func_resolver_builder
func_resolver_builder .finalize(
.finalize(&info.signatures) &info.signatures,
.map_err(|e| CacheError::Unknown(format!("{:?}", e)))?, Arc::clone(&trampolines),
); handler_data.clone(),
)
.map_err(|e| CacheError::Unknown(format!("{:?}", e)))?;
let protected_caller = Box::new(Caller::new(&info, handler_data, trampolines)); let protected_caller = Caller::new(&info, handler_data, trampolines);
let cache_gen = Box::new(CacheGenerator::new(
backend_cache,
Arc::clone(&func_resolver.memory),
));
Ok(ModuleInner { Ok(ModuleInner {
func_resolver, func_resolver: Box::new(func_resolver),
protected_caller, protected_caller: Box::new(protected_caller),
cache_gen,
info, info,
}) })
} }
} }
impl Deref for Module {
type Target = ModuleInner;
fn deref(&self) -> &ModuleInner {
&self.module
}
}
impl DerefMut for Module {
fn deref_mut(&mut self) -> &mut ModuleInner {
&mut self.module
}
}
pub struct Converter<T>(pub T); pub struct Converter<T>(pub T);
macro_rules! convert_clif_to_runtime_index { macro_rules! convert_clif_to_runtime_index {

View File

@ -386,7 +386,7 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa>
let name = ir::ExternalName::user(0, func_index.index() as u32); let name = ir::ExternalName::user(0, func_index.index() as u32);
let sig = func_env.generate_signature( let sig = func_env.generate_signature(
self.get_func_type(Converter(func_index.convert_up(self.module)).into()), self.get_func_type(Converter(func_index.convert_up(&self.module.info)).into()),
); );
let mut func = ir::Function::with_name_signature(name, sig); let mut func = ir::Function::with_name_signature(name, sig);

View File

@ -22,16 +22,14 @@ pub mod call_names {
pub const DYNAMIC_MEM_SIZE: u32 = 5; pub const DYNAMIC_MEM_SIZE: u32 = 5;
} }
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))] #[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Reloc { pub enum Reloc {
Abs8, Abs8,
X86PCRel4, X86PCRel4,
X86CallPCRel4, X86CallPCRel4,
} }
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))] #[derive(Serialize, Deserialize, Debug, Copy, Clone)]
#[derive(Debug, Copy, Clone)]
pub enum LibCall { pub enum LibCall {
Probestack, Probestack,
CeilF32, CeilF32,
@ -44,8 +42,7 @@ pub enum LibCall {
NearestF64, NearestF64,
} }
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))] #[derive(Serialize, Deserialize, Debug, Clone)]
#[derive(Debug, Clone)]
pub struct ExternalRelocation { pub struct ExternalRelocation {
/// The relocation code. /// The relocation code.
pub reloc: Reloc, pub reloc: Reloc,
@ -66,8 +63,7 @@ pub struct LocalRelocation {
pub target: FuncIndex, pub target: FuncIndex,
} }
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))] #[derive(Serialize, Deserialize, Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy)]
pub enum VmCallKind { pub enum VmCallKind {
StaticMemoryGrow, StaticMemoryGrow,
StaticMemorySize, StaticMemorySize,
@ -79,16 +75,14 @@ pub enum VmCallKind {
DynamicMemorySize, DynamicMemorySize,
} }
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))] #[derive(Serialize, Deserialize, Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy)]
pub enum VmCall { pub enum VmCall {
Local(VmCallKind), Local(VmCallKind),
Import(VmCallKind), Import(VmCallKind),
} }
/// Specify the type of relocation /// Specify the type of relocation
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))] #[derive(Serialize, Deserialize, Debug, Clone)]
#[derive(Debug, Clone)]
pub enum RelocationType { pub enum RelocationType {
Intrinsic(String), Intrinsic(String),
LibCall(LibCall), LibCall(LibCall),
@ -218,8 +212,7 @@ impl binemit::RelocSink for RelocSink {
} }
} }
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))] #[derive(Serialize, Deserialize, Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy)]
pub enum TrapCode { pub enum TrapCode {
StackOverflow, StackOverflow,
HeapOutOfBounds, HeapOutOfBounds,
@ -244,8 +237,7 @@ impl RelocSink {
} }
} }
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))] #[derive(Serialize, Deserialize, Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy)]
pub struct TrapData { pub struct TrapData {
pub trapcode: TrapCode, pub trapcode: TrapCode,
pub srcloc: u32, pub srcloc: u32,
@ -253,7 +245,7 @@ pub struct TrapData {
/// Simple implementation of a TrapSink /// Simple implementation of a TrapSink
/// that saves the info for later. /// that saves the info for later.
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))] #[derive(Serialize, Deserialize)]
pub struct TrapSink { pub struct TrapSink {
trap_datas: Vec<(usize, TrapData)>, trap_datas: Vec<(usize, TrapData)>,
} }

View File

@ -1,8 +1,4 @@
#[cfg(feature = "cache")] use crate::{cache::BackendCache, trampoline::Trampolines};
use crate::{
cache::{BackendCache, TrampolineCache},
trampoline::Trampolines,
};
use crate::{ use crate::{
libcalls, libcalls,
relocation::{ relocation::{
@ -19,7 +15,7 @@ use std::{
ptr::{write_unaligned, NonNull}, ptr::{write_unaligned, NonNull},
sync::Arc, sync::Arc,
}; };
#[cfg(feature = "cache")]
use wasmer_runtime_core::cache::Error as CacheError; use wasmer_runtime_core::cache::Error as CacheError;
use wasmer_runtime_core::{ use wasmer_runtime_core::{
self, self,
@ -42,21 +38,32 @@ extern "C" {
pub fn __chkstk(); pub fn __chkstk();
} }
fn lookup_func(
map: &SliceMap<LocalFuncIndex, usize>,
memory: &Memory,
local_func_index: LocalFuncIndex,
) -> Option<NonNull<vm::Func>> {
let offset = *map.get(local_func_index)?;
let ptr = unsafe { memory.as_ptr().add(offset) };
NonNull::new(ptr).map(|nonnull| nonnull.cast())
}
#[allow(dead_code)] #[allow(dead_code)]
pub struct FuncResolverBuilder { pub struct FuncResolverBuilder {
resolver: FuncResolver, map: Map<LocalFuncIndex, usize>,
memory: Memory,
local_relocs: Map<LocalFuncIndex, Box<[LocalRelocation]>>, local_relocs: Map<LocalFuncIndex, Box<[LocalRelocation]>>,
external_relocs: Map<LocalFuncIndex, Box<[ExternalRelocation]>>, external_relocs: Map<LocalFuncIndex, Box<[ExternalRelocation]>>,
import_len: usize, import_len: usize,
} }
impl FuncResolverBuilder { impl FuncResolverBuilder {
#[cfg(feature = "cache")]
pub fn new_from_backend_cache( pub fn new_from_backend_cache(
backend_cache: BackendCache, backend_cache: BackendCache,
mut code: Memory, mut code: Memory,
info: &ModuleInfo, info: &ModuleInfo,
) -> Result<(Self, Trampolines, HandlerData), CacheError> { ) -> Result<(Self, Arc<Trampolines>, HandlerData), CacheError> {
unsafe { unsafe {
code.protect(.., Protect::ReadWrite) code.protect(.., Protect::ReadWrite)
.map_err(|e| CacheError::Unknown(e.to_string()))?; .map_err(|e| CacheError::Unknown(e.to_string()))?;
@ -67,37 +74,19 @@ impl FuncResolverBuilder {
Ok(( Ok((
Self { Self {
resolver: FuncResolver {
map: backend_cache.offsets, map: backend_cache.offsets,
memory: code, memory: code,
},
local_relocs: Map::new(), local_relocs: Map::new(),
external_relocs: backend_cache.external_relocs, external_relocs: backend_cache.external_relocs,
import_len: info.imported_functions.len(), import_len: info.imported_functions.len(),
}, },
Trampolines::from_trampoline_cache(backend_cache.trampolines), Arc::new(Trampolines::from_trampoline_cache(
backend_cache.trampolines,
)),
handler_data, handler_data,
)) ))
} }
#[cfg(feature = "cache")]
pub fn to_backend_cache(
mut self,
trampolines: TrampolineCache,
handler_data: HandlerData,
) -> (BackendCache, Memory) {
self.relocate_locals();
(
BackendCache {
external_relocs: self.external_relocs,
offsets: self.resolver.map,
trap_sink: handler_data.trap_data,
trampolines,
},
self.resolver.memory,
)
}
pub fn new( pub fn new(
isa: &isa::TargetIsa, isa: &isa::TargetIsa,
function_bodies: Map<LocalFuncIndex, ir::Function>, function_bodies: Map<LocalFuncIndex, ir::Function>,
@ -169,10 +158,12 @@ impl FuncResolverBuilder {
previous_end = new_end; previous_end = new_end;
} }
let handler_data = HandlerData::new(trap_sink, memory.as_ptr() as _, memory.size()); let handler_data =
HandlerData::new(Arc::new(trap_sink), memory.as_ptr() as _, memory.size());
let mut func_resolver_builder = Self { let mut func_resolver_builder = Self {
resolver: FuncResolver { map, memory }, map,
memory,
local_relocs, local_relocs,
external_relocs, external_relocs,
import_len: info.imported_functions.len(), import_len: info.imported_functions.len(),
@ -187,12 +178,15 @@ impl FuncResolverBuilder {
for (index, relocs) in self.local_relocs.iter() { for (index, relocs) in self.local_relocs.iter() {
for ref reloc in relocs.iter() { for ref reloc in relocs.iter() {
let local_func_index = LocalFuncIndex::new(reloc.target.index() - self.import_len); let local_func_index = LocalFuncIndex::new(reloc.target.index() - self.import_len);
let target_func_address = let target_func_address = lookup_func(&self.map, &self.memory, local_func_index)
self.resolver.lookup(local_func_index).unwrap().as_ptr() as usize; .unwrap()
.as_ptr() as usize;
// We need the address of the current function // We need the address of the current function
// because these calls are relative. // because these calls are relative.
let func_addr = self.resolver.lookup(index).unwrap().as_ptr() as usize; let func_addr = lookup_func(&self.map, &self.memory, index)
.unwrap()
.as_ptr() as usize;
unsafe { unsafe {
let reloc_address = func_addr + reloc.offset as usize; let reloc_address = func_addr + reloc.offset as usize;
@ -208,8 +202,10 @@ impl FuncResolverBuilder {
pub fn finalize( pub fn finalize(
mut self, mut self,
signatures: &SliceMap<SigIndex, FuncSig>, signatures: &SliceMap<SigIndex, Arc<FuncSig>>,
) -> CompileResult<FuncResolver> { trampolines: Arc<Trampolines>,
handler_data: HandlerData,
) -> CompileResult<(FuncResolver, BackendCache)> {
for (index, relocs) in self.external_relocs.iter() { for (index, relocs) in self.external_relocs.iter() {
for ref reloc in relocs.iter() { for ref reloc in relocs.iter() {
let target_func_address: isize = match reloc.target { let target_func_address: isize = match reloc.target {
@ -281,7 +277,9 @@ impl FuncResolverBuilder {
// We need the address of the current function // We need the address of the current function
// because some of these calls are relative. // because some of these calls are relative.
let func_addr = self.resolver.lookup(index).unwrap().as_ptr(); let func_addr = lookup_func(&self.map, &self.memory, index)
.unwrap()
.as_ptr() as usize;
// Determine relocation type and apply relocation. // Determine relocation type and apply relocation.
match reloc.reloc { match reloc.reloc {
@ -289,9 +287,9 @@ impl FuncResolverBuilder {
let ptr_to_write = (target_func_address as u64) let ptr_to_write = (target_func_address as u64)
.checked_add(reloc.addend as u64) .checked_add(reloc.addend as u64)
.unwrap(); .unwrap();
let empty_space_offset = self.resolver.map[index] + reloc.offset as usize; let empty_space_offset = self.map[index] + reloc.offset as usize;
let ptr_slice = unsafe { let ptr_slice = unsafe {
&mut self.resolver.memory.as_slice_mut() &mut self.memory.as_slice_mut()
[empty_space_offset..empty_space_offset + 8] [empty_space_offset..empty_space_offset + 8]
}; };
LittleEndian::write_u64(ptr_slice, ptr_to_write); LittleEndian::write_u64(ptr_slice, ptr_to_write);
@ -309,29 +307,35 @@ impl FuncResolverBuilder {
} }
unsafe { unsafe {
self.resolver self.memory
.memory
.protect(.., Protect::ReadExec) .protect(.., Protect::ReadExec)
.map_err(|e| CompileError::InternalError { msg: e.to_string() })?; .map_err(|e| CompileError::InternalError { msg: e.to_string() })?;
} }
Ok(self.resolver) let backend_cache = BackendCache {
external_relocs: self.external_relocs.clone(),
offsets: self.map.clone(),
trap_sink: handler_data.trap_data,
trampolines: trampolines.to_trampoline_cache(),
};
Ok((
FuncResolver {
map: self.map,
memory: Arc::new(self.memory),
},
backend_cache,
))
} }
} }
unsafe impl Sync for FuncResolver {}
unsafe impl Send for FuncResolver {}
/// Resolves a function index to a function address. /// Resolves a function index to a function address.
pub struct FuncResolver { pub struct FuncResolver {
map: Map<LocalFuncIndex, usize>, map: Map<LocalFuncIndex, usize>,
memory: Memory, pub(crate) memory: Arc<Memory>,
}
impl FuncResolver {
fn lookup(&self, local_func_index: LocalFuncIndex) -> Option<NonNull<vm::Func>> {
let offset = *self.map.get(local_func_index)?;
let ptr = unsafe { self.memory.as_ptr().add(offset) };
NonNull::new(ptr).map(|nonnull| nonnull.cast())
}
} }
// Implements FuncResolver trait. // Implements FuncResolver trait.
@ -341,7 +345,7 @@ impl backend::FuncResolver for FuncResolver {
_module: &wasmer_runtime_core::module::ModuleInner, _module: &wasmer_runtime_core::module::ModuleInner,
index: LocalFuncIndex, index: LocalFuncIndex,
) -> Option<NonNull<vm::Func>> { ) -> Option<NonNull<vm::Func>> {
self.lookup(index) lookup_func(&self.map, &self.memory, index)
} }
} }

View File

@ -40,11 +40,15 @@ impl UserTrapper for Trapper {
pub struct Caller { pub struct Caller {
func_export_set: HashSet<FuncIndex>, func_export_set: HashSet<FuncIndex>,
handler_data: HandlerData, handler_data: HandlerData,
trampolines: Trampolines, trampolines: Arc<Trampolines>,
} }
impl Caller { impl Caller {
pub fn new(module: &ModuleInfo, handler_data: HandlerData, trampolines: Trampolines) -> Self { pub fn new(
module: &ModuleInfo,
handler_data: HandlerData,
trampolines: Arc<Trampolines>,
) -> Self {
let mut func_export_set = HashSet::new(); let mut func_export_set = HashSet::new();
for export_index in module.exports.values() { for export_index in module.exports.values() {
if let ExportIndex::Func(func_index) = export_index { if let ExportIndex::Func(func_index) = export_index {
@ -187,15 +191,16 @@ fn get_func_from_index<'a>(
unsafe impl Send for HandlerData {} unsafe impl Send for HandlerData {}
unsafe impl Sync for HandlerData {} unsafe impl Sync for HandlerData {}
#[derive(Clone)]
pub struct HandlerData { pub struct HandlerData {
pub trap_data: TrapSink, pub trap_data: Arc<TrapSink>,
exec_buffer_ptr: *const c_void, exec_buffer_ptr: *const c_void,
exec_buffer_size: usize, exec_buffer_size: usize,
} }
impl HandlerData { impl HandlerData {
pub fn new( pub fn new(
trap_data: TrapSink, trap_data: Arc<TrapSink>,
exec_buffer_ptr: *const c_void, exec_buffer_ptr: *const c_void,
exec_buffer_size: usize, exec_buffer_size: usize,
) -> Self { ) -> Self {

View File

@ -1,4 +1,3 @@
#[cfg(feature = "cache")]
use crate::cache::TrampolineCache; use crate::cache::TrampolineCache;
use cranelift_codegen::{ use cranelift_codegen::{
binemit::{NullTrapSink, Reloc, RelocSink}, binemit::{NullTrapSink, Reloc, RelocSink},
@ -33,7 +32,6 @@ pub struct Trampolines {
} }
impl Trampolines { impl Trampolines {
#[cfg(feature = "cache")]
pub fn from_trampoline_cache(cache: TrampolineCache) -> Self { pub fn from_trampoline_cache(cache: TrampolineCache) -> Self {
// pub struct TrampolineCache { // pub struct TrampolineCache {
// #[serde(with = "serde_bytes")] // #[serde(with = "serde_bytes")]
@ -57,8 +55,7 @@ impl Trampolines {
} }
} }
#[cfg(feature = "cache")] pub fn to_trampoline_cache(&self) -> TrampolineCache {
pub fn to_trampoline_cache(self) -> TrampolineCache {
let mut code = vec![0; self.memory.size()]; let mut code = vec![0; self.memory.size()];
unsafe { unsafe {
@ -67,7 +64,7 @@ impl Trampolines {
TrampolineCache { TrampolineCache {
code, code,
offsets: self.offsets, offsets: self.offsets.clone(),
} }
} }

View File

@ -10,10 +10,14 @@ build = "build/mod.rs"
[dependencies] [dependencies]
wasmer-runtime-core = { path = "../runtime-core", version = "0.1.0" } wasmer-runtime-core = { path = "../runtime-core", version = "0.1.0" }
lazy_static = "1.2.0"
libc = { git = "https://github.com/rust-lang/libc" } libc = { git = "https://github.com/rust-lang/libc" }
byteorder = "1" byteorder = "1"
time = "0.1.41" time = "0.1.41"
[target.'cfg(windows)'.dependencies]
rand = "0.6"
[dev-dependencies] [dev-dependencies]
wasmer-clif-backend = { path = "../clif-backend", version = "0.1.0" } wasmer-clif-backend = { path = "../clif-backend", version = "0.1.0" }
wabt = "0.7.2" wabt = "0.7.2"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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