mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-21 04:31:33 +00:00
Merge branch 'master' into atomic-transparent-repr
This commit is contained in:
@ -103,7 +103,7 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: Install Rust
|
name: Install Rust
|
||||||
command: |
|
command: |
|
||||||
curl https://sh.rustup.rs -sSf | sh -s -- -y
|
curl -sSf https://sh.rustup.rs | sh -s -- -y
|
||||||
export PATH="$HOME/.cargo/bin:$PATH"
|
export PATH="$HOME/.cargo/bin:$PATH"
|
||||||
cargo --version
|
cargo --version
|
||||||
- run:
|
- run:
|
||||||
@ -150,6 +150,11 @@ jobs:
|
|||||||
- image: circleci/rust:latest
|
- image: circleci/rust:latest
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
|
- run:
|
||||||
|
name: "Pull dependencies"
|
||||||
|
command: |
|
||||||
|
git submodule init
|
||||||
|
git submodule update --remote
|
||||||
- restore_cache:
|
- restore_cache:
|
||||||
keys:
|
keys:
|
||||||
- v8-cargo-cache-linux-nightly-{{ arch }}-{{ checksum "Cargo.lock" }}
|
- v8-cargo-cache-linux-nightly-{{ arch }}-{{ checksum "Cargo.lock" }}
|
||||||
@ -178,6 +183,7 @@ jobs:
|
|||||||
command: |
|
command: |
|
||||||
export LLVM_SYS_70_PREFIX="`pwd`/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04/"
|
export LLVM_SYS_70_PREFIX="`pwd`/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04/"
|
||||||
make production-release
|
make production-release
|
||||||
|
cargo build --release --manifest-path wapm-cli/Cargo.toml --features telemetry
|
||||||
mkdir -p artifacts
|
mkdir -p artifacts
|
||||||
VERSION=$(cargo pkgid | cut -d# -f2 | cut -d: -f2)
|
VERSION=$(cargo pkgid | cut -d# -f2 | cut -d: -f2)
|
||||||
# GIT_VERSION=$(git describe --exact-match --tags)
|
# GIT_VERSION=$(git describe --exact-match --tags)
|
||||||
@ -202,6 +208,9 @@ jobs:
|
|||||||
- target/release/.fingerprint
|
- target/release/.fingerprint
|
||||||
- target/release/build
|
- target/release/build
|
||||||
- target/release/deps
|
- target/release/deps
|
||||||
|
- wapm-cli/target/release/.fingerprint
|
||||||
|
- wapm-cli/target/release/build
|
||||||
|
- wapm-cli/target/release/deps
|
||||||
key: v8-cargo-cache-linux-nightly-{{ arch }}-{{ checksum "Cargo.lock" }}
|
key: v8-cargo-cache-linux-nightly-{{ arch }}-{{ checksum "Cargo.lock" }}
|
||||||
|
|
||||||
test-and-build-macos:
|
test-and-build-macos:
|
||||||
@ -209,6 +218,11 @@ jobs:
|
|||||||
xcode: "9.0"
|
xcode: "9.0"
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
|
- run:
|
||||||
|
name: "Pull dependencies"
|
||||||
|
command: |
|
||||||
|
git submodule init
|
||||||
|
git submodule update --remote
|
||||||
- restore_cache:
|
- restore_cache:
|
||||||
keys:
|
keys:
|
||||||
- v8-cargo-cache-darwin-nightly-{{ arch }}-{{ checksum "Cargo.lock" }}
|
- v8-cargo-cache-darwin-nightly-{{ arch }}-{{ checksum "Cargo.lock" }}
|
||||||
@ -226,7 +240,7 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: Install Rust
|
name: Install Rust
|
||||||
command: |
|
command: |
|
||||||
curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain nightly-2019-04-11
|
curl -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain nightly
|
||||||
export PATH="$HOME/.cargo/bin:$PATH"
|
export PATH="$HOME/.cargo/bin:$PATH"
|
||||||
cargo --version
|
cargo --version
|
||||||
# Use rust nightly (for singlepass, for now)
|
# Use rust nightly (for singlepass, for now)
|
||||||
@ -263,6 +277,7 @@ jobs:
|
|||||||
export PATH="$HOME/.cargo/bin:$PATH"
|
export PATH="$HOME/.cargo/bin:$PATH"
|
||||||
export LLVM_SYS_70_PREFIX="`pwd`/clang+llvm-7.0.0-x86_64-apple-darwin/"
|
export LLVM_SYS_70_PREFIX="`pwd`/clang+llvm-7.0.0-x86_64-apple-darwin/"
|
||||||
make production-release
|
make production-release
|
||||||
|
cargo build --release --manifest-path wapm-cli/Cargo.toml --features telemetry
|
||||||
mkdir -p artifacts
|
mkdir -p artifacts
|
||||||
make build-install
|
make build-install
|
||||||
cp ./wasmer.tar.gz ./artifacts/$(./binary-name.sh)
|
cp ./wasmer.tar.gz ./artifacts/$(./binary-name.sh)
|
||||||
@ -281,6 +296,9 @@ jobs:
|
|||||||
- target/release/.fingerprint
|
- target/release/.fingerprint
|
||||||
- target/release/build
|
- target/release/build
|
||||||
- target/release/deps
|
- target/release/deps
|
||||||
|
- wapm-cli/target/release/.fingerprint
|
||||||
|
- wapm-cli/target/release/build
|
||||||
|
- wapm-cli/target/release/deps
|
||||||
key: v8-cargo-cache-darwin-nightly-{ arch }}-{{ checksum "Cargo.lock" }}
|
key: v8-cargo-cache-darwin-nightly-{ arch }}-{{ checksum "Cargo.lock" }}
|
||||||
|
|
||||||
test-rust-nightly:
|
test-rust-nightly:
|
||||||
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "wapm-cli"]
|
||||||
|
path = wapm-cli
|
||||||
|
url = https://github.com/wasmerio/wapm-cli.git
|
26
CHANGELOG.md
26
CHANGELOG.md
@ -5,6 +5,18 @@ All PRs to the Wasmer repository must add to this file.
|
|||||||
Blocks of changes will separated by version increments.
|
Blocks of changes will separated by version increments.
|
||||||
|
|
||||||
## **[Unreleased]**
|
## **[Unreleased]**
|
||||||
|
- [#409](https://github.com/wasmerio/wasmer/pull/409) Improved Emscripten functions to run JavascriptCore compiled to wasm
|
||||||
|
- [#399](https://github.com/wasmerio/wasmer/pull/399) Add example of using a plugin extended from WASI
|
||||||
|
- [#397](https://github.com/wasmerio/wasmer/pull/397) Fix WASI fs abstraction to work on Windows
|
||||||
|
- [#390](https://github.com/wasmerio/wasmer/pull/390) Pin released wapm version and add it as a git submodule
|
||||||
|
- [#408](https://github.com/wasmerio/wasmer/pull/408) Add images to windows installer and update installer to add wapm bin directory to path
|
||||||
|
|
||||||
|
## 0.4.0 - 2018-04-23
|
||||||
|
|
||||||
|
- [#383](https://github.com/wasmerio/wasmer/pull/383) Hook up wasi exit code to wasmer cli.
|
||||||
|
- [#382](https://github.com/wasmerio/wasmer/pull/382) Improve error message on `--backend` flag to only suggest currently enabled backends
|
||||||
|
- [#381](https://github.com/wasmerio/wasmer/pull/381) Allow retrieving propagated user errors.
|
||||||
|
- [#379](https://github.com/wasmerio/wasmer/pull/379) Fix small return types from imported functions.
|
||||||
- [#371](https://github.com/wasmerio/wasmer/pull/371) Add more Debug impl for WASI types
|
- [#371](https://github.com/wasmerio/wasmer/pull/371) Add more Debug impl for WASI types
|
||||||
- [#368](https://github.com/wasmerio/wasmer/pull/368) Fix issue with write buffering
|
- [#368](https://github.com/wasmerio/wasmer/pull/368) Fix issue with write buffering
|
||||||
- [#343](https://github.com/wasmerio/wasmer/pull/343) Implement preopened files for WASI and fix aligment issue when accessing WASI memory
|
- [#343](https://github.com/wasmerio/wasmer/pull/343) Implement preopened files for WASI and fix aligment issue when accessing WASI memory
|
||||||
@ -16,3 +28,17 @@ Blocks of changes will separated by version increments.
|
|||||||
- [#351](https://github.com/wasmerio/wasmer/pull/351) Add hidden option to specify wasm program name (can be used to improve error messages)
|
- [#351](https://github.com/wasmerio/wasmer/pull/351) Add hidden option to specify wasm program name (can be used to improve error messages)
|
||||||
- [#350](https://github.com/wasmerio/wasmer/pull/350) Enforce that CHANGELOG.md is updated through CI.
|
- [#350](https://github.com/wasmerio/wasmer/pull/350) Enforce that CHANGELOG.md is updated through CI.
|
||||||
- [#349](https://github.com/wasmerio/wasmer/pull/349) Add [CHANGELOG.md](https://github.com/wasmerio/wasmer/blob/master/CHANGELOG.md).
|
- [#349](https://github.com/wasmerio/wasmer/pull/349) Add [CHANGELOG.md](https://github.com/wasmerio/wasmer/blob/master/CHANGELOG.md).
|
||||||
|
|
||||||
|
## 0.3.0 - 2018-04-12
|
||||||
|
|
||||||
|
- [#276](https://github.com/wasmerio/wasmer/pull/276) [#288](https://github.com/wasmerio/wasmer/pull/288) [#344](https://github.com/wasmerio/wasmer/pull/344) Use new singlepass backend (with the `--backend=singlepass` when running Wasmer)
|
||||||
|
- [#338](https://github.com/wasmerio/wasmer/pull/338) Actually catch traps/panics/etc when using a typed func.
|
||||||
|
- [#325](https://github.com/wasmerio/wasmer/pull/325) Fixed func_index in debug mode
|
||||||
|
- [#323](https://github.com/wasmerio/wasmer/pull/323) Add validate subcommand to validate Wasm files
|
||||||
|
- [#321](https://github.com/wasmerio/wasmer/pull/321) Upgrade to Cranelift 0.3.0
|
||||||
|
- [#319](https://github.com/wasmerio/wasmer/pull/319) Add Export and GlobalDescriptor to Runtime API
|
||||||
|
- [#310](https://github.com/wasmerio/wasmer/pull/310) Cleanup warnings
|
||||||
|
- [#299](https://github.com/wasmerio/wasmer/pull/299) [#300](https://github.com/wasmerio/wasmer/pull/300) [#301](https://github.com/wasmerio/wasmer/pull/301) [#303](https://github.com/wasmerio/wasmer/pull/303) [#304](https://github.com/wasmerio/wasmer/pull/304) [#305](https://github.com/wasmerio/wasmer/pull/305) [#306](https://github.com/wasmerio/wasmer/pull/306) [#307](https://github.com/wasmerio/wasmer/pull/307) Add support for WASI 🎉
|
||||||
|
- [#286](https://github.com/wasmerio/wasmer/pull/286) Add extend to imports
|
||||||
|
- [#278](https://github.com/wasmerio/wasmer/pull/278) Add versioning to cache
|
||||||
|
- [#250](https://github.com/wasmerio/wasmer/pull/250) Setup bors
|
||||||
|
27
Cargo.lock
generated
27
Cargo.lock
generated
@ -1317,6 +1317,10 @@ name = "plain"
|
|||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "plugin-for-example"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "podio"
|
name = "podio"
|
||||||
version = "0.1.6"
|
version = "0.1.6"
|
||||||
@ -2222,7 +2226,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer"
|
name = "wasmer"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
dependencies = [
|
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.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2260,7 +2264,7 @@ dependencies = [
|
|||||||
"target-lexicon 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"target-lexicon 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"wasmer-runtime-core 0.3.0",
|
"wasmer-runtime-core 0.3.0",
|
||||||
"wasmer-win-exception-handler 0.3.0",
|
"wasmer-win-exception-handler 0.3.0",
|
||||||
"wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasmparser 0.29.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2299,7 +2303,7 @@ dependencies = [
|
|||||||
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.6.9 (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-runtime-core 0.3.0",
|
"wasmer-runtime-core 0.3.0",
|
||||||
"wasmparser 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasmparser 0.29.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2327,7 +2331,7 @@ dependencies = [
|
|||||||
"tar 0.4.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tar 0.4.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"wasmer-runtime-core 0.3.0",
|
"wasmer-runtime-core 0.3.0",
|
||||||
"wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasmparser 0.29.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"zbox 0.6.1 (git+https://github.com/wasmerio/zbox?branch=bundle-libsodium)",
|
"zbox 0.6.1 (git+https://github.com/wasmerio/zbox?branch=bundle-libsodium)",
|
||||||
"zstd 0.4.22+zstd.1.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"zstd 0.4.22+zstd.1.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -2381,7 +2385,7 @@ dependencies = [
|
|||||||
"nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"wasmer-runtime-core 0.3.0",
|
"wasmer-runtime-core 0.3.0",
|
||||||
"wasmparser 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasmparser 0.29.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2406,7 +2410,6 @@ dependencies = [
|
|||||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"wasmer-runtime-core 0.3.0",
|
"wasmer-runtime-core 0.3.0",
|
||||||
"zbox 0.6.1 (git+https://github.com/wasmerio/zbox?branch=bundle-libsodium)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2421,16 +2424,6 @@ dependencies = [
|
|||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasmparser"
|
|
||||||
version = "0.23.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasmparser"
|
|
||||||
version = "0.28.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmparser"
|
name = "wasmparser"
|
||||||
version = "0.29.2"
|
version = "0.29.2"
|
||||||
@ -2824,8 +2817,6 @@ dependencies = [
|
|||||||
"checksum wabt-sys 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a6265b25719e82598d104b3717375e37661d41753e2c84cde3f51050c7ed7e3c"
|
"checksum wabt-sys 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a6265b25719e82598d104b3717375e37661d41753e2c84cde3f51050c7ed7e3c"
|
||||||
"checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1"
|
"checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1"
|
||||||
"checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3"
|
"checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3"
|
||||||
"checksum wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b5e01c420bc7d36e778bd242e1167b079562ba8b34087122cc9057187026d060"
|
|
||||||
"checksum wasmparser 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)" = "40f426b1929bd26517fb10702e2a8e520d1845c49567aa4d244f426f10b206c1"
|
|
||||||
"checksum wasmparser 0.29.2 (registry+https://github.com/rust-lang/crates.io-index)" = "981a8797cf89762e0233ec45fae731cb79a4dfaee12d9f0fe6cee01e4ac58d00"
|
"checksum wasmparser 0.29.2 (registry+https://github.com/rust-lang/crates.io-index)" = "981a8797cf89762e0233ec45fae731cb79a4dfaee12d9f0fe6cee01e4ac58d00"
|
||||||
"checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164"
|
"checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164"
|
||||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer"
|
name = "wasmer"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
repository = "https://github.com/wasmerio/wasmer"
|
repository = "https://github.com/wasmerio/wasmer"
|
||||||
@ -33,7 +33,7 @@ wasmer-llvm-backend = { path = "lib/llvm-backend", optional = true }
|
|||||||
wasmer-wasi = { path = "lib/wasi", optional = true }
|
wasmer-wasi = { path = "lib/wasi", optional = true }
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["lib/clif-backend", "lib/singlepass-backend", "lib/runtime", "lib/runtime-abi", "lib/runtime-core", "lib/emscripten", "lib/spectests", "lib/win-exception-handler", "lib/runtime-c-api", "lib/llvm-backend", "lib/wasi"]
|
members = ["lib/clif-backend", "lib/singlepass-backend", "lib/runtime", "lib/runtime-abi", "lib/runtime-core", "lib/emscripten", "lib/spectests", "lib/win-exception-handler", "lib/runtime-c-api", "lib/llvm-backend", "lib/wasi", "examples/plugin-for-example"]
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
wabt = "0.7.2"
|
wabt = "0.7.2"
|
||||||
@ -49,3 +49,7 @@ fast-tests = []
|
|||||||
"backend:singlepass" = ["wasmer-singlepass-backend"]
|
"backend:singlepass" = ["wasmer-singlepass-backend"]
|
||||||
wasi = ["wasmer-wasi"]
|
wasi = ["wasmer-wasi"]
|
||||||
vfs = ["wasmer-runtime-abi"]
|
vfs = ["wasmer-runtime-abi"]
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "plugin"
|
||||||
|
crate-type = ["bin"]
|
||||||
|
4
Makefile
4
Makefile
@ -25,6 +25,7 @@ integration-tests: release
|
|||||||
echo "Running Integration Tests"
|
echo "Running Integration Tests"
|
||||||
./integration_tests/lua/test.sh
|
./integration_tests/lua/test.sh
|
||||||
./integration_tests/nginx/test.sh
|
./integration_tests/nginx/test.sh
|
||||||
|
./integration_tests/cowsay/test.sh
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
cargo fmt --all -- --check
|
cargo fmt --all -- --check
|
||||||
@ -34,8 +35,9 @@ precommit: lint test
|
|||||||
|
|
||||||
build-install:
|
build-install:
|
||||||
mkdir -p ./install/bin
|
mkdir -p ./install/bin
|
||||||
|
cp ./wapm-cli/target/release/wapm ./install/bin/
|
||||||
cp ./target/release/wasmer ./install/bin/
|
cp ./target/release/wasmer ./install/bin/
|
||||||
tar -C ./install -zcvf wasmer.tar.gz bin/wasmer
|
tar -C ./install -zcvf wasmer.tar.gz bin/wapm bin/wasmer
|
||||||
|
|
||||||
# For installing the contents locally
|
# For installing the contents locally
|
||||||
do-install:
|
do-install:
|
||||||
|
@ -100,7 +100,7 @@ sudo port install cmake
|
|||||||
#### Debian-based Linuxes
|
#### Debian-based Linuxes
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo apt install cmake
|
sudo apt install cmake pkg-config libssl-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
#### FreeBSD
|
#### FreeBSD
|
||||||
@ -181,7 +181,7 @@ Below are some of the goals of this project (in order of priority):
|
|||||||
|
|
||||||
- [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 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 WASI _(in the works)_
|
- [x] Support WASI - released in [0.3.0](https://github.com/wasmerio/wasmer/releases/tag/0.3.0)
|
||||||
- [ ] 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
|
||||||
|
BIN
examples/cowsay.wasm
Executable file
BIN
examples/cowsay.wasm
Executable file
Binary file not shown.
11
examples/exit.wat
Normal file
11
examples/exit.wat
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
(module
|
||||||
|
(import "wasi_unstable" "proc_exit" (func $proc_exit (param i32)))
|
||||||
|
(export "_start" (func $_start))
|
||||||
|
|
||||||
|
(memory 10)
|
||||||
|
(export "memory" (memory 0))
|
||||||
|
|
||||||
|
(func $_start
|
||||||
|
(call $proc_exit (i32.const 7))
|
||||||
|
)
|
||||||
|
)
|
BIN
examples/plugin-for-example.wasm
Executable file
BIN
examples/plugin-for-example.wasm
Executable file
Binary file not shown.
7
examples/plugin-for-example/Cargo.toml
Normal file
7
examples/plugin-for-example/Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[package]
|
||||||
|
name = "plugin-for-example"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["The Wasmer Engineering Team <enigneering@wasmer.io>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
43
examples/plugin-for-example/README.md
Normal file
43
examples/plugin-for-example/README.md
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
# WASI plugin example
|
||||||
|
|
||||||
|
In this example we extend the imports of Wasmer's WASI ABI to demonstrate how custom plugins work.
|
||||||
|
|
||||||
|
See the `wasmer/examples/plugin.rs` file for the source code of the host system.
|
||||||
|
|
||||||
|
## Compiling
|
||||||
|
_Attention Windows users: WASI target only works with the `nightly-x86_64-pc-windows-gnu` toolchain._
|
||||||
|
```
|
||||||
|
# Install an up to date version of Rust nightly
|
||||||
|
# Add the target
|
||||||
|
rustup target add wasm32-unknown-wasi
|
||||||
|
# build it
|
||||||
|
cargo +nightly build --release --target=wasm32-unknown-wasi
|
||||||
|
# copy it to examples folder
|
||||||
|
cp ../../target/wasm32-unknown-wasi/release/plugin-for-example.wasm ../
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running
|
||||||
|
```
|
||||||
|
# Go back to top level Wasmer dir
|
||||||
|
cd ..
|
||||||
|
# Run the example
|
||||||
|
cargo run --example plugin
|
||||||
|
```
|
||||||
|
|
||||||
|
## Inspecting the plugin
|
||||||
|
```
|
||||||
|
# Install wabt via wapm; installed globally with the `g` flag
|
||||||
|
wapm install -g wabt
|
||||||
|
# Turn the binary WASM file in to a readable WAT text file
|
||||||
|
wapm run wasm2wat examples/plugin-for-example.wasm
|
||||||
|
```
|
||||||
|
|
||||||
|
At the top of the file we can see which functions this plugin expects. Most are covered by WASI, but we handle the rest.
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
In this example, we instantiate a system with an extended (WASI)[wasi] ABI, allowing our program to rely on Wasmer's implementation of the syscalls defined by WASI as well as our own that we made. This allows us to use the full power of an existing ABI, like WASI, and give it super-powers for our specific use case.
|
||||||
|
|
||||||
|
Because the Rust WASI doesn't support the crate type of `cdylib`, we have to include a main function which we don't use. This is being discussed [here](https://github.com/WebAssembly/WASI/issues/24).
|
||||||
|
|
||||||
|
[wasi]: https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/
|
12
examples/plugin-for-example/src/main.rs
Normal file
12
examples/plugin-for-example/src/main.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
extern "C" {
|
||||||
|
fn it_works() -> i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn plugin_entrypoint(n: i32) -> i32 {
|
||||||
|
println!("Hello from inside WASI");
|
||||||
|
let result = unsafe { it_works() };
|
||||||
|
result + n
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() {}
|
12
examples/plugin-for-example/wapm.toml
Normal file
12
examples/plugin-for-example/wapm.toml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[package]
|
||||||
|
name = "plugin-for-example"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "A plugin for our example system"
|
||||||
|
readme = "README.md"
|
||||||
|
repository = "https://github.com/wasmerio/wasmer/examples/plugin-for-example"
|
||||||
|
license = "MIT"
|
||||||
|
|
||||||
|
[[module]]
|
||||||
|
name = "plugin-for-example"
|
||||||
|
source = "../../target/wasm32-unknown-wasi/release/plugin-for-example.wasm"
|
||||||
|
abi = "none"
|
38
examples/plugin.rs
Normal file
38
examples/plugin.rs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
use wasmer_runtime::{func, imports, instantiate};
|
||||||
|
use wasmer_runtime_core::vm::Ctx;
|
||||||
|
use wasmer_wasi::generate_import_object;
|
||||||
|
|
||||||
|
static PLUGIN_LOCATION: &'static str = "examples/plugin-for-example.wasm";
|
||||||
|
|
||||||
|
fn it_works(_ctx: &mut Ctx) -> i32 {
|
||||||
|
println!("Hello from outside WASI");
|
||||||
|
5
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Load the plugin data
|
||||||
|
let wasm_bytes = std::fs::read(PLUGIN_LOCATION).expect(&format!(
|
||||||
|
"Could not read in WASM plugin at {}",
|
||||||
|
PLUGIN_LOCATION
|
||||||
|
));
|
||||||
|
|
||||||
|
// WASI imports
|
||||||
|
let mut base_imports = generate_import_object(vec![], vec![], vec![]);
|
||||||
|
// env is the default namespace for extern functions
|
||||||
|
let custom_imports = imports! {
|
||||||
|
"env" => {
|
||||||
|
"it_works" => func!(it_works),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
// The WASI imports object contains all required import functions for a WASI module to run.
|
||||||
|
// Extend this imports with our custom imports containing "it_works" function so that our custom wasm code may run.
|
||||||
|
base_imports.extend(custom_imports);
|
||||||
|
let instance =
|
||||||
|
instantiate(&wasm_bytes[..], &base_imports).expect("failed to instantiate wasm module");
|
||||||
|
|
||||||
|
// get a reference to the function "plugin_entrypoint" which takes an i32 and returns an i32
|
||||||
|
let entry_point = instance.func::<(i32), i32>("plugin_entrypoint").unwrap();
|
||||||
|
// call the "entry_point" function in WebAssembly with the number "2" as the i32 argument
|
||||||
|
let result = entry_point.call(2).expect("failed to execute plugin");
|
||||||
|
println!("result: {}", result);
|
||||||
|
}
|
@ -131,7 +131,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 WASMER_CACHE_DIR=\"\$WASMER_DIR/cache\"\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:\$HOME/.wasmer/globals/wapm_packages/.bin:\$PATH\"\n"
|
||||||
|
|
||||||
# We create the wasmer.sh file
|
# We create the wasmer.sh file
|
||||||
printf "$SOURCE_STR" > "$HOME/.wasmer/wasmer.sh"
|
printf "$SOURCE_STR" > "$HOME/.wasmer/wasmer.sh"
|
||||||
@ -162,7 +162,9 @@ wasmer_link() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
printf "$green> Successfully installed $version!\n\n${reset}If you want to have the command available now please execute:\nsource $HOME/.wasmer/wasmer.sh$reset\n"
|
printf "$green> Successfully installed $version!\n\n${reset}If you want to have the command available now please execute:\nsource $HOME/.wasmer/wasmer.sh$reset\n"
|
||||||
printf "\nOtherwise, wasmer will be available the next time you open the terminal.\n"
|
printf "\nOtherwise, wasmer and wapm will be available the next time you open the terminal.\n"
|
||||||
|
echo "Note: during the alpha release of wapm, telemetry is enabled by default; if you would like to opt out, run \`wapm config set telemetry.enabled false\`."
|
||||||
|
echo "If you notice anything wrong or have any issues, please file a bug at https://github.com/wasmerio/wapm-cli :)"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,7 +294,6 @@ wasmer_install() {
|
|||||||
# exit 0
|
# exit 0
|
||||||
# fi
|
# fi
|
||||||
# fi
|
# fi
|
||||||
|
|
||||||
wasmer_download # $1 $2
|
wasmer_download # $1 $2
|
||||||
wasmer_link
|
wasmer_link
|
||||||
wasmer_reset
|
wasmer_reset
|
||||||
|
9
integration_tests/cowsay/README.md
Normal file
9
integration_tests/cowsay/README.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# `cowsay` integration test
|
||||||
|
|
||||||
|
|
||||||
|
This starts Wasmer with the Cowsay WASI Wasm file. The test makes assertions on
|
||||||
|
the output of Wasmer. Run test with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./integration_tests/cowsay/test.sh
|
||||||
|
```
|
14
integration_tests/cowsay/test.sh
Executable file
14
integration_tests/cowsay/test.sh
Executable file
@ -0,0 +1,14 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
nohup ./target/release/wasmer run examples/cowsay.wasm --disable-cache -- "hello integration"
|
||||||
|
|
||||||
|
if grep "hello integration" ./nohup.out
|
||||||
|
then
|
||||||
|
echo "cowsay wasi integration test succeeded"
|
||||||
|
rm ./nohup.out
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "cowsay wasi integration test failed"
|
||||||
|
rm ./nohup.out
|
||||||
|
exit -1
|
||||||
|
fi
|
@ -15,7 +15,7 @@ cranelift-entity = "0.30.0"
|
|||||||
cranelift-wasm = "0.30.0"
|
cranelift-wasm = "0.30.0"
|
||||||
hashbrown = "0.1"
|
hashbrown = "0.1"
|
||||||
target-lexicon = "0.3.0"
|
target-lexicon = "0.3.0"
|
||||||
wasmparser = "0.23.0"
|
wasmparser = "0.29.2"
|
||||||
byteorder = "1"
|
byteorder = "1"
|
||||||
nix = "0.13.0"
|
nix = "0.13.0"
|
||||||
libc = "0.2.49"
|
libc = "0.2.49"
|
||||||
|
@ -5,7 +5,7 @@ use std::sync::Arc;
|
|||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
backend::{sys::Memory, CacheGen},
|
backend::{sys::Memory, CacheGen},
|
||||||
cache::{Artifact, Error},
|
cache::{Artifact, Error},
|
||||||
module::{ModuleInfo, ModuleInner},
|
module::ModuleInfo,
|
||||||
structures::Map,
|
structures::Map,
|
||||||
types::{LocalFuncIndex, SigIndex},
|
types::{LocalFuncIndex, SigIndex},
|
||||||
};
|
};
|
||||||
|
@ -27,6 +27,11 @@ thread_local! {
|
|||||||
pub static TRAP_EARLY_DATA: Cell<Option<Box<dyn Any>>> = Cell::new(None);
|
pub static TRAP_EARLY_DATA: Cell<Option<Box<dyn Any>>> = Cell::new(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum CallProtError {
|
||||||
|
Trap(WasmTrapInfo),
|
||||||
|
Error(Box<dyn Any>),
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Caller {
|
pub struct Caller {
|
||||||
handler_data: HandlerData,
|
handler_data: HandlerData,
|
||||||
trampolines: Arc<Trampolines>,
|
trampolines: Arc<Trampolines>,
|
||||||
@ -59,7 +64,8 @@ impl RunnableModule for Caller {
|
|||||||
func: NonNull<vm::Func>,
|
func: NonNull<vm::Func>,
|
||||||
args: *const u64,
|
args: *const u64,
|
||||||
rets: *mut u64,
|
rets: *mut u64,
|
||||||
_trap_info: *mut WasmTrapInfo,
|
trap_info: *mut WasmTrapInfo,
|
||||||
|
user_error: *mut Option<Box<dyn Any>>,
|
||||||
invoke_env: Option<NonNull<c_void>>,
|
invoke_env: Option<NonNull<c_void>>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let handler_data = &*invoke_env.unwrap().cast().as_ptr();
|
let handler_data = &*invoke_env.unwrap().cast().as_ptr();
|
||||||
@ -68,14 +74,22 @@ impl RunnableModule for Caller {
|
|||||||
let res = call_protected(handler_data, || {
|
let res = call_protected(handler_data, || {
|
||||||
// Leap of faith.
|
// Leap of faith.
|
||||||
trampoline(ctx, func, args, rets);
|
trampoline(ctx, func, args, rets);
|
||||||
})
|
});
|
||||||
.is_ok();
|
|
||||||
|
|
||||||
// the trampoline is called from C on windows
|
// the trampoline is called from C on windows
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
let res = call_protected(handler_data, trampoline, ctx, func, args, rets).is_ok();
|
let res = call_protected(handler_data, trampoline, ctx, func, args, rets);
|
||||||
|
|
||||||
res
|
match res {
|
||||||
|
Err(err) => {
|
||||||
|
match err {
|
||||||
|
CallProtError::Trap(info) => *trap_info = info,
|
||||||
|
CallProtError::Error(data) => *user_error = Some(data),
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
Ok(()) => true,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let trampoline = self
|
let trampoline = self
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
//! unless you have memory unsafety elsewhere in your code.
|
//! unless you have memory unsafety elsewhere in your code.
|
||||||
//!
|
//!
|
||||||
use crate::relocation::{TrapCode, TrapData};
|
use crate::relocation::{TrapCode, TrapData};
|
||||||
use crate::signal::HandlerData;
|
use crate::signal::{CallProtError, HandlerData};
|
||||||
use libc::{c_int, c_void, siginfo_t};
|
use libc::{c_int, c_void, siginfo_t};
|
||||||
use nix::sys::signal::{
|
use nix::sys::signal::{
|
||||||
sigaction, SaFlags, SigAction, SigHandler, SigSet, Signal, SIGBUS, SIGFPE, SIGILL, SIGSEGV,
|
sigaction, SaFlags, SigAction, SigHandler, SigSet, Signal, SIGBUS, SIGFPE, SIGILL, SIGSEGV,
|
||||||
@ -18,7 +18,7 @@ use nix::sys::signal::{
|
|||||||
use std::cell::{Cell, UnsafeCell};
|
use std::cell::{Cell, UnsafeCell};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::sync::Once;
|
use std::sync::Once;
|
||||||
use wasmer_runtime_core::error::{RuntimeError, RuntimeResult};
|
use wasmer_runtime_core::typed_func::WasmTrapInfo;
|
||||||
|
|
||||||
extern "C" fn signal_trap_handler(
|
extern "C" fn signal_trap_handler(
|
||||||
signum: ::nix::libc::c_int,
|
signum: ::nix::libc::c_int,
|
||||||
@ -62,7 +62,10 @@ pub unsafe fn trigger_trap() -> ! {
|
|||||||
longjmp(jmp_buf as *mut c_void, 0)
|
longjmp(jmp_buf as *mut c_void, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call_protected<T>(handler_data: &HandlerData, f: impl FnOnce() -> T) -> RuntimeResult<T> {
|
pub fn call_protected<T>(
|
||||||
|
handler_data: &HandlerData,
|
||||||
|
f: impl FnOnce() -> T,
|
||||||
|
) -> Result<T, CallProtError> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let jmp_buf = SETJMP_BUFFER.with(|buf| buf.get());
|
let jmp_buf = SETJMP_BUFFER.with(|buf| buf.get());
|
||||||
let prev_jmp_buf = *jmp_buf;
|
let prev_jmp_buf = *jmp_buf;
|
||||||
@ -76,7 +79,7 @@ pub fn call_protected<T>(handler_data: &HandlerData, f: impl FnOnce() -> T) -> R
|
|||||||
*jmp_buf = prev_jmp_buf;
|
*jmp_buf = prev_jmp_buf;
|
||||||
|
|
||||||
if let Some(data) = super::TRAP_EARLY_DATA.with(|cell| cell.replace(None)) {
|
if let Some(data) = super::TRAP_EARLY_DATA.with(|cell| cell.replace(None)) {
|
||||||
Err(RuntimeError::Panic { data })
|
Err(CallProtError::Error(data))
|
||||||
} else {
|
} else {
|
||||||
let (faulting_addr, inst_ptr) = CAUGHT_ADDRESSES.with(|cell| cell.get());
|
let (faulting_addr, inst_ptr) = CAUGHT_ADDRESSES.with(|cell| cell.get());
|
||||||
|
|
||||||
@ -85,33 +88,18 @@ pub fn call_protected<T>(handler_data: &HandlerData, f: impl FnOnce() -> T) -> R
|
|||||||
srcloc: _,
|
srcloc: _,
|
||||||
}) = handler_data.lookup(inst_ptr)
|
}) = handler_data.lookup(inst_ptr)
|
||||||
{
|
{
|
||||||
Err(match Signal::from_c_int(signum) {
|
Err(CallProtError::Trap(match Signal::from_c_int(signum) {
|
||||||
Ok(SIGILL) => match trapcode {
|
Ok(SIGILL) => match trapcode {
|
||||||
TrapCode::BadSignature => RuntimeError::Trap {
|
TrapCode::BadSignature => WasmTrapInfo::IncorrectCallIndirectSignature,
|
||||||
msg: "incorrect call_indirect signature".into(),
|
TrapCode::IndirectCallToNull => WasmTrapInfo::CallIndirectOOB,
|
||||||
},
|
TrapCode::HeapOutOfBounds => WasmTrapInfo::MemoryOutOfBounds,
|
||||||
TrapCode::IndirectCallToNull => RuntimeError::Trap {
|
TrapCode::TableOutOfBounds => WasmTrapInfo::CallIndirectOOB,
|
||||||
msg: "indirect call to null".into(),
|
_ => WasmTrapInfo::Unknown,
|
||||||
},
|
|
||||||
TrapCode::HeapOutOfBounds => RuntimeError::Trap {
|
|
||||||
msg: "memory out-of-bounds access".into(),
|
|
||||||
},
|
|
||||||
TrapCode::TableOutOfBounds => RuntimeError::Trap {
|
|
||||||
msg: "table out-of-bounds access".into(),
|
|
||||||
},
|
|
||||||
_ => RuntimeError::Trap {
|
|
||||||
msg: "unknown trap".into(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Ok(SIGSEGV) | Ok(SIGBUS) => RuntimeError::Trap {
|
|
||||||
msg: "memory out-of-bounds access".into(),
|
|
||||||
},
|
|
||||||
Ok(SIGFPE) => RuntimeError::Trap {
|
|
||||||
msg: "illegal arithmetic operation".into(),
|
|
||||||
},
|
},
|
||||||
|
Ok(SIGSEGV) | Ok(SIGBUS) => WasmTrapInfo::MemoryOutOfBounds,
|
||||||
|
Ok(SIGFPE) => WasmTrapInfo::IllegalArithmetic,
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
}
|
}))
|
||||||
.into())
|
|
||||||
} else {
|
} else {
|
||||||
let signal = match Signal::from_c_int(signum) {
|
let signal = match Signal::from_c_int(signum) {
|
||||||
Ok(SIGFPE) => "floating-point exception",
|
Ok(SIGFPE) => "floating-point exception",
|
||||||
@ -122,10 +110,8 @@ pub fn call_protected<T>(handler_data: &HandlerData, f: impl FnOnce() -> T) -> R
|
|||||||
_ => "unkown trapped signal",
|
_ => "unkown trapped signal",
|
||||||
};
|
};
|
||||||
// When the trap-handler is fully implemented, this will return more information.
|
// When the trap-handler is fully implemented, this will return more information.
|
||||||
Err(RuntimeError::Trap {
|
let s = format!("unknown trap at {:p} - {}", faulting_addr, signal);
|
||||||
msg: format!("unknown trap at {:p} - {}", faulting_addr, signal).into(),
|
Err(CallProtError::Error(Box::new(s)))
|
||||||
}
|
|
||||||
.into())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
use crate::relocation::{TrapCode, TrapData};
|
use crate::relocation::{TrapCode, TrapData};
|
||||||
use crate::signal::HandlerData;
|
use crate::signal::{CallProtError, HandlerData};
|
||||||
use crate::trampoline::Trampoline;
|
use crate::trampoline::Trampoline;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::ffi::c_void;
|
use std::ffi::c_void;
|
||||||
use std::ptr::{self, NonNull};
|
use std::ptr::{self, NonNull};
|
||||||
use wasmer_runtime_core::error::{RuntimeError, RuntimeResult};
|
use wasmer_runtime_core::error::{RuntimeError, RuntimeResult};
|
||||||
|
use wasmer_runtime_core::typed_func::WasmTrapInfo;
|
||||||
use wasmer_runtime_core::vm::Ctx;
|
use wasmer_runtime_core::vm::Ctx;
|
||||||
use wasmer_runtime_core::vm::Func;
|
use wasmer_runtime_core::vm::Func;
|
||||||
use wasmer_win_exception_handler::CallProtectedData;
|
use wasmer_win_exception_handler::CallProtectedData;
|
||||||
@ -28,7 +29,7 @@ pub fn call_protected(
|
|||||||
func: NonNull<Func>,
|
func: NonNull<Func>,
|
||||||
param_vec: *const u64,
|
param_vec: *const u64,
|
||||||
return_vec: *mut u64,
|
return_vec: *mut u64,
|
||||||
) -> RuntimeResult<()> {
|
) -> Result<(), CallProtError> {
|
||||||
// TODO: trap early
|
// TODO: trap early
|
||||||
// user code error
|
// user code error
|
||||||
// if let Some(msg) = super::TRAP_EARLY_DATA.with(|cell| cell.replace(None)) {
|
// if let Some(msg) = super::TRAP_EARLY_DATA.with(|cell| cell.replace(None)) {
|
||||||
@ -52,38 +53,22 @@ pub fn call_protected(
|
|||||||
srcloc: _,
|
srcloc: _,
|
||||||
}) = handler_data.lookup(instruction_pointer as _)
|
}) = handler_data.lookup(instruction_pointer as _)
|
||||||
{
|
{
|
||||||
Err(match signum as DWORD {
|
Err(CallProtError::Trap(match signum as DWORD {
|
||||||
EXCEPTION_ACCESS_VIOLATION => RuntimeError::Trap {
|
EXCEPTION_ACCESS_VIOLATION => WasmTrapInfo::MemoryOutOfBounds,
|
||||||
msg: "memory out-of-bounds access".into(),
|
|
||||||
},
|
|
||||||
EXCEPTION_ILLEGAL_INSTRUCTION => match trapcode {
|
EXCEPTION_ILLEGAL_INSTRUCTION => match trapcode {
|
||||||
TrapCode::BadSignature => RuntimeError::Trap {
|
TrapCode::BadSignature => WasmTrapInfo::IncorrectCallIndirectSignature,
|
||||||
msg: "incorrect call_indirect signature".into(),
|
TrapCode::IndirectCallToNull => WasmTrapInfo::CallIndirectOOB,
|
||||||
},
|
TrapCode::HeapOutOfBounds => WasmTrapInfo::MemoryOutOfBounds,
|
||||||
TrapCode::IndirectCallToNull => RuntimeError::Trap {
|
TrapCode::TableOutOfBounds => WasmTrapInfo::CallIndirectOOB,
|
||||||
msg: "indirect call to null".into(),
|
TrapCode::UnreachableCodeReached => WasmTrapInfo::Unreachable,
|
||||||
},
|
_ => WasmTrapInfo::Unknown,
|
||||||
TrapCode::HeapOutOfBounds => RuntimeError::Trap {
|
|
||||||
msg: "memory out-of-bounds access".into(),
|
|
||||||
},
|
|
||||||
TrapCode::TableOutOfBounds => RuntimeError::Trap {
|
|
||||||
msg: "table out-of-bounds access".into(),
|
|
||||||
},
|
|
||||||
_ => RuntimeError::Trap {
|
|
||||||
msg: "unknown trap".into(),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
EXCEPTION_STACK_OVERFLOW => RuntimeError::Trap {
|
EXCEPTION_STACK_OVERFLOW => WasmTrapInfo::Unknown,
|
||||||
msg: "stack overflow trap".into(),
|
EXCEPTION_INT_DIVIDE_BY_ZERO | EXCEPTION_INT_OVERFLOW => {
|
||||||
},
|
WasmTrapInfo::IllegalArithmetic
|
||||||
EXCEPTION_INT_DIVIDE_BY_ZERO | EXCEPTION_INT_OVERFLOW => RuntimeError::Trap {
|
}
|
||||||
msg: "illegal arithmetic operation".into(),
|
_ => WasmTrapInfo::Unknown,
|
||||||
},
|
}))
|
||||||
_ => RuntimeError::Trap {
|
|
||||||
msg: "unknown trap".into(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
.into())
|
|
||||||
} else {
|
} else {
|
||||||
let signal = match signum as DWORD {
|
let signal = match signum as DWORD {
|
||||||
EXCEPTION_FLT_DENORMAL_OPERAND
|
EXCEPTION_FLT_DENORMAL_OPERAND
|
||||||
@ -98,10 +83,9 @@ pub fn call_protected(
|
|||||||
_ => "unkown trapped signal",
|
_ => "unkown trapped signal",
|
||||||
};
|
};
|
||||||
|
|
||||||
Err(RuntimeError::Trap {
|
let s = format!("unknown trap at {} - {}", exception_address, signal);
|
||||||
msg: format!("unknown trap at {} - {}", exception_address, signal).into(),
|
|
||||||
}
|
Err(CallProtError::Error(Box::new(s)))
|
||||||
.into())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,15 @@ pub fn getTempRet0(ctx: &mut Ctx) -> i32 {
|
|||||||
get_emscripten_data(ctx).temp_ret_0
|
get_emscripten_data(ctx).temp_ret_0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn _atexit(_ctx: &mut Ctx, _func: i32) -> i32 {
|
||||||
|
debug!("emscripten::_atexit");
|
||||||
|
// TODO: implement atexit properly
|
||||||
|
// __ATEXIT__.unshift({
|
||||||
|
// func: func,
|
||||||
|
// arg: arg
|
||||||
|
// });
|
||||||
|
0
|
||||||
|
}
|
||||||
pub fn __Unwind_Backtrace(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
pub fn __Unwind_Backtrace(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||||
debug!("emscripten::__Unwind_Backtrace");
|
debug!("emscripten::__Unwind_Backtrace");
|
||||||
0
|
0
|
||||||
@ -45,14 +54,42 @@ pub fn _dladdr(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
|||||||
debug!("emscripten::_dladdr");
|
debug!("emscripten::_dladdr");
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
pub fn _pthread_attr_init(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||||
|
debug!("emscripten::_pthread_attr_init");
|
||||||
|
0
|
||||||
|
}
|
||||||
|
pub fn _pthread_attr_destroy(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||||
|
debug!("emscripten::_pthread_attr_destroy");
|
||||||
|
0
|
||||||
|
}
|
||||||
|
pub fn _pthread_attr_getstack(
|
||||||
|
_ctx: &mut Ctx,
|
||||||
|
_stackaddr: i32,
|
||||||
|
_stacksize: i32,
|
||||||
|
_other: i32,
|
||||||
|
) -> i32 {
|
||||||
|
debug!("emscripten::_pthread_attr_getstack");
|
||||||
|
// TODO: Translate from Emscripten
|
||||||
|
// HEAP32[stackaddr >> 2] = STACK_BASE;
|
||||||
|
// HEAP32[stacksize >> 2] = TOTAL_STACK;
|
||||||
|
0
|
||||||
|
}
|
||||||
pub fn _pthread_cond_destroy(_ctx: &mut Ctx, _a: i32) -> i32 {
|
pub fn _pthread_cond_destroy(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||||
debug!("emscripten::_pthread_cond_destroy");
|
debug!("emscripten::_pthread_cond_destroy");
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
pub fn _pthread_cond_timedwait(_ctx: &mut Ctx, _a: i32, _b: i32, _c: i32) -> i32 {
|
||||||
|
debug!("emscripten::_pthread_cond_timedwait");
|
||||||
|
0
|
||||||
|
}
|
||||||
pub fn _pthread_getspecific(_ctx: &mut Ctx, _a: i32) -> i32 {
|
pub fn _pthread_getspecific(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||||
debug!("emscripten::_pthread_getspecific");
|
debug!("emscripten::_pthread_getspecific");
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
pub fn _pthread_getattr_np(_ctx: &mut Ctx, _thread: i32, _attr: i32) -> i32 {
|
||||||
|
debug!("emscripten::_pthread_getattr_np");
|
||||||
|
0
|
||||||
|
}
|
||||||
pub fn _pthread_setspecific(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
pub fn _pthread_setspecific(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||||
debug!("emscripten::_pthread_setspecific");
|
debug!("emscripten::_pthread_setspecific");
|
||||||
0
|
0
|
||||||
@ -69,6 +106,10 @@ pub fn _pthread_create(_ctx: &mut Ctx, _a: i32, _b: i32, _c: i32, _d: i32) -> i3
|
|||||||
debug!("emscripten::_pthread_create");
|
debug!("emscripten::_pthread_create");
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
pub fn _pthread_detach(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||||
|
debug!("emscripten::_pthread_detach");
|
||||||
|
0
|
||||||
|
}
|
||||||
pub fn _pthread_join(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
pub fn _pthread_join(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||||
debug!("emscripten::_pthread_join");
|
debug!("emscripten::_pthread_join");
|
||||||
0
|
0
|
||||||
|
@ -28,3 +28,9 @@ pub fn ___cxa_uncaught_exception(_ctx: &mut Ctx) -> i32 {
|
|||||||
debug!("emscripten::___cxa_uncaught_exception");
|
debug!("emscripten::___cxa_uncaught_exception");
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ___cxa_pure_virtual(_ctx: &mut Ctx) {
|
||||||
|
debug!("emscripten::___cxa_pure_virtual");
|
||||||
|
// ABORT = true
|
||||||
|
panic!("Pure virtual function called!");
|
||||||
|
}
|
||||||
|
@ -619,6 +619,7 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
|||||||
"_llvm_eh_typeid_for" => func!(crate::process::_llvm_eh_typeid_for),
|
"_llvm_eh_typeid_for" => func!(crate::process::_llvm_eh_typeid_for),
|
||||||
"_raise" => func!(crate::process::_raise),
|
"_raise" => func!(crate::process::_raise),
|
||||||
"_sem_init" => func!(crate::process::_sem_init),
|
"_sem_init" => func!(crate::process::_sem_init),
|
||||||
|
"_sem_destroy" => func!(crate::process::_sem_destroy),
|
||||||
"_sem_post" => func!(crate::process::_sem_post),
|
"_sem_post" => func!(crate::process::_sem_post),
|
||||||
"_sem_wait" => func!(crate::process::_sem_wait),
|
"_sem_wait" => func!(crate::process::_sem_wait),
|
||||||
"_getgrent" => func!(crate::process::_getgrent),
|
"_getgrent" => func!(crate::process::_getgrent),
|
||||||
@ -646,6 +647,9 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
|||||||
"_emscripten_get_heap_size" => func!(crate::memory::_emscripten_get_heap_size),
|
"_emscripten_get_heap_size" => func!(crate::memory::_emscripten_get_heap_size),
|
||||||
"_emscripten_resize_heap" => func!(crate::memory::_emscripten_resize_heap),
|
"_emscripten_resize_heap" => func!(crate::memory::_emscripten_resize_heap),
|
||||||
"enlargeMemory" => func!(crate::memory::enlarge_memory),
|
"enlargeMemory" => func!(crate::memory::enlarge_memory),
|
||||||
|
"segfault" => func!(crate::memory::segfault),
|
||||||
|
"alignfault" => func!(crate::memory::alignfault),
|
||||||
|
"ftfault" => func!(crate::memory::ftfault),
|
||||||
"getTotalMemory" => func!(crate::memory::get_total_memory),
|
"getTotalMemory" => func!(crate::memory::get_total_memory),
|
||||||
"___map_file" => func!(crate::memory::___map_file),
|
"___map_file" => func!(crate::memory::___map_file),
|
||||||
|
|
||||||
@ -655,6 +659,7 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
|||||||
"___cxa_begin_catch" => func!(crate::exception::___cxa_begin_catch),
|
"___cxa_begin_catch" => func!(crate::exception::___cxa_begin_catch),
|
||||||
"___cxa_end_catch" => func!(crate::exception::___cxa_end_catch),
|
"___cxa_end_catch" => func!(crate::exception::___cxa_end_catch),
|
||||||
"___cxa_uncaught_exception" => func!(crate::exception::___cxa_uncaught_exception),
|
"___cxa_uncaught_exception" => func!(crate::exception::___cxa_uncaught_exception),
|
||||||
|
"___cxa_pure_virtual" => func!(crate::exception::___cxa_pure_virtual),
|
||||||
|
|
||||||
// Time
|
// Time
|
||||||
"_gettimeofday" => func!(crate::time::_gettimeofday),
|
"_gettimeofday" => func!(crate::time::_gettimeofday),
|
||||||
@ -683,6 +688,7 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
|||||||
"_llvm_cos_f64" => func!(crate::math::_llvm_cos_f64),
|
"_llvm_cos_f64" => func!(crate::math::_llvm_cos_f64),
|
||||||
"_llvm_exp2_f32" => func!(crate::math::_llvm_exp2_f32),
|
"_llvm_exp2_f32" => func!(crate::math::_llvm_exp2_f32),
|
||||||
"_llvm_exp2_f64" => func!(crate::math::_llvm_exp2_f64),
|
"_llvm_exp2_f64" => func!(crate::math::_llvm_exp2_f64),
|
||||||
|
"_llvm_trunc_f64" => func!(crate::math::_llvm_trunc_f64),
|
||||||
"_emscripten_random" => func!(crate::math::_emscripten_random),
|
"_emscripten_random" => func!(crate::math::_emscripten_random),
|
||||||
|
|
||||||
// Jump
|
// Jump
|
||||||
@ -701,6 +707,7 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
|||||||
"_dlsym" => func!(crate::linking::_dlsym),
|
"_dlsym" => func!(crate::linking::_dlsym),
|
||||||
|
|
||||||
// wasm32-unknown-emscripten
|
// wasm32-unknown-emscripten
|
||||||
|
"_atexit" => func!(crate::emscripten_target::_atexit),
|
||||||
"setTempRet0" => func!(crate::emscripten_target::setTempRet0),
|
"setTempRet0" => func!(crate::emscripten_target::setTempRet0),
|
||||||
"getTempRet0" => func!(crate::emscripten_target::getTempRet0),
|
"getTempRet0" => func!(crate::emscripten_target::getTempRet0),
|
||||||
"invoke_i" => func!(crate::emscripten_target::invoke_i),
|
"invoke_i" => func!(crate::emscripten_target::invoke_i),
|
||||||
@ -723,10 +730,15 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
|||||||
"___resumeException" => func!(crate::emscripten_target::___resumeException),
|
"___resumeException" => func!(crate::emscripten_target::___resumeException),
|
||||||
"_dladdr" => func!(crate::emscripten_target::_dladdr),
|
"_dladdr" => func!(crate::emscripten_target::_dladdr),
|
||||||
"_pthread_create" => func!(crate::emscripten_target::_pthread_create),
|
"_pthread_create" => func!(crate::emscripten_target::_pthread_create),
|
||||||
|
"_pthread_detach" => func!(crate::emscripten_target::_pthread_detach),
|
||||||
"_pthread_join" => func!(crate::emscripten_target::_pthread_join),
|
"_pthread_join" => func!(crate::emscripten_target::_pthread_join),
|
||||||
"_pthread_cond_destroy" => func!(crate::emscripten_target::_pthread_cond_destroy),
|
"_pthread_attr_init" => func!(crate::emscripten_target::_pthread_attr_init),
|
||||||
|
"_pthread_attr_destroy" => func!(crate::emscripten_target::_pthread_attr_destroy),
|
||||||
|
"_pthread_attr_getstack" => func!(crate::emscripten_target::_pthread_attr_getstack),
|
||||||
"_pthread_cond_init" => func!(crate::emscripten_target::_pthread_cond_init),
|
"_pthread_cond_init" => func!(crate::emscripten_target::_pthread_cond_init),
|
||||||
|
"_pthread_cond_destroy" => func!(crate::emscripten_target::_pthread_cond_destroy),
|
||||||
"_pthread_cond_signal" => func!(crate::emscripten_target::_pthread_cond_signal),
|
"_pthread_cond_signal" => func!(crate::emscripten_target::_pthread_cond_signal),
|
||||||
|
"_pthread_cond_timedwait" => func!(crate::emscripten_target::_pthread_cond_timedwait),
|
||||||
"_pthread_cond_wait" => func!(crate::emscripten_target::_pthread_cond_wait),
|
"_pthread_cond_wait" => func!(crate::emscripten_target::_pthread_cond_wait),
|
||||||
"_pthread_condattr_destroy" => func!(crate::emscripten_target::_pthread_condattr_destroy),
|
"_pthread_condattr_destroy" => func!(crate::emscripten_target::_pthread_condattr_destroy),
|
||||||
"_pthread_condattr_init" => func!(crate::emscripten_target::_pthread_condattr_init),
|
"_pthread_condattr_init" => func!(crate::emscripten_target::_pthread_condattr_init),
|
||||||
@ -740,6 +752,7 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
|||||||
"_pthread_rwlock_unlock" => func!(crate::emscripten_target::_pthread_rwlock_unlock),
|
"_pthread_rwlock_unlock" => func!(crate::emscripten_target::_pthread_rwlock_unlock),
|
||||||
"_pthread_setcancelstate" => func!(crate::emscripten_target::_pthread_setcancelstate),
|
"_pthread_setcancelstate" => func!(crate::emscripten_target::_pthread_setcancelstate),
|
||||||
"_pthread_getspecific" => func!(crate::emscripten_target::_pthread_getspecific),
|
"_pthread_getspecific" => func!(crate::emscripten_target::_pthread_getspecific),
|
||||||
|
"_pthread_getattr_np" => func!(crate::emscripten_target::_pthread_getattr_np),
|
||||||
"_pthread_setspecific" => func!(crate::emscripten_target::_pthread_setspecific),
|
"_pthread_setspecific" => func!(crate::emscripten_target::_pthread_setspecific),
|
||||||
"_pthread_once" => func!(crate::emscripten_target::_pthread_once),
|
"_pthread_once" => func!(crate::emscripten_target::_pthread_once),
|
||||||
"_pthread_key_create" => func!(crate::emscripten_target::_pthread_key_create),
|
"_pthread_key_create" => func!(crate::emscripten_target::_pthread_key_create),
|
||||||
|
@ -44,6 +44,11 @@ pub fn _llvm_exp2_f64(_ctx: &mut Ctx, value: f64) -> f64 {
|
|||||||
2f64.powf(value)
|
2f64.powf(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn _llvm_trunc_f64(_ctx: &mut Ctx, value: f64) -> f64 {
|
||||||
|
debug!("emscripten::_llvm_trunc_f64");
|
||||||
|
value.trunc()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn _emscripten_random(_ctx: &mut Ctx) -> f64 {
|
pub fn _emscripten_random(_ctx: &mut Ctx) -> f64 {
|
||||||
debug!("emscripten::_emscripten_random");
|
debug!("emscripten::_emscripten_random");
|
||||||
-1.0
|
-1.0
|
||||||
|
@ -95,6 +95,24 @@ pub fn abort_on_cannot_grow_memory_old(ctx: &mut Ctx) -> u32 {
|
|||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// emscripten: segfault
|
||||||
|
pub fn segfault(ctx: &mut Ctx) {
|
||||||
|
debug!("emscripten::segfault");
|
||||||
|
abort_with_message(ctx, "segmentation fault");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// emscripten: alignfault
|
||||||
|
pub fn alignfault(ctx: &mut Ctx) {
|
||||||
|
debug!("emscripten::alignfault");
|
||||||
|
abort_with_message(ctx, "alignment fault");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// emscripten: ftfault
|
||||||
|
pub fn ftfault(ctx: &mut Ctx) {
|
||||||
|
debug!("emscripten::ftfault");
|
||||||
|
abort_with_message(ctx, "Function table mask error");
|
||||||
|
}
|
||||||
|
|
||||||
/// emscripten: ___map_file
|
/// emscripten: ___map_file
|
||||||
pub fn ___map_file(_ctx: &mut Ctx, _one: u32, _two: u32) -> c_int {
|
pub fn ___map_file(_ctx: &mut Ctx, _one: u32, _two: u32) -> c_int {
|
||||||
debug!("emscripten::___map_file");
|
debug!("emscripten::___map_file");
|
||||||
|
@ -83,7 +83,12 @@ pub fn _raise(_ctx: &mut Ctx, _one: i32) -> i32 {
|
|||||||
|
|
||||||
pub fn _sem_init(_ctx: &mut Ctx, _one: i32, _two: i32, _three: i32) -> i32 {
|
pub fn _sem_init(_ctx: &mut Ctx, _one: i32, _two: i32, _three: i32) -> i32 {
|
||||||
debug!("emscripten::_sem_init");
|
debug!("emscripten::_sem_init");
|
||||||
-1
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _sem_destroy(_ctx: &mut Ctx, _one: i32) -> i32 {
|
||||||
|
debug!("emscripten::_sem_destroy");
|
||||||
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _sem_post(_ctx: &mut Ctx, _one: i32) -> i32 {
|
pub fn _sem_post(_ctx: &mut Ctx, _one: i32) -> i32 {
|
||||||
@ -159,7 +164,7 @@ pub fn _system(_ctx: &mut Ctx, _one: i32) -> c_int {
|
|||||||
debug!("emscripten::_system");
|
debug!("emscripten::_system");
|
||||||
// TODO: May need to change this Em impl to a working version
|
// TODO: May need to change this Em impl to a working version
|
||||||
eprintln!("Can't call external programs");
|
eprintln!("Can't call external programs");
|
||||||
return EAGAIN;
|
EAGAIN
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _popen(_ctx: &mut Ctx, _one: i32, _two: i32) -> c_int {
|
pub fn _popen(_ctx: &mut Ctx, _one: i32, _two: i32) -> c_int {
|
||||||
|
@ -345,7 +345,7 @@ pub fn _strftime(
|
|||||||
// pad for null?
|
// pad for null?
|
||||||
let bytes = result_str.chars().count();
|
let bytes = result_str.chars().count();
|
||||||
if bytes as u32 > maxsize {
|
if bytes as u32 > maxsize {
|
||||||
return 0;
|
0
|
||||||
} else {
|
} else {
|
||||||
// write output string
|
// write output string
|
||||||
for (i, c) in result_str.chars().enumerate() {
|
for (i, c) in result_str.chars().enumerate() {
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{types::WasmExternType, vm::Ctx};
|
||||||
types::{Type, WasmExternType},
|
|
||||||
vm::Ctx,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
@ -19,12 +16,12 @@ impl VarArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl WasmExternType for VarArgs {
|
unsafe impl WasmExternType for VarArgs {
|
||||||
const TYPE: Type = Type::I32;
|
type Native = i32;
|
||||||
|
|
||||||
fn to_bits(self) -> u64 {
|
fn to_native(self) -> Self::Native {
|
||||||
self.pointer as u64
|
self.pointer as _
|
||||||
}
|
}
|
||||||
fn from_bits(n: u64) -> Self {
|
fn from_native(n: Self::Native) -> Self {
|
||||||
Self { pointer: n as u32 }
|
Self { pointer: n as u32 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ edition = "2018"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.3.0" }
|
wasmer-runtime-core = { path = "../runtime-core", version = "0.3.0" }
|
||||||
inkwell = { git = "https://github.com/wasmerio/inkwell", branch = "llvm7-0" }
|
inkwell = { git = "https://github.com/wasmerio/inkwell", branch = "llvm7-0" }
|
||||||
wasmparser = "0.28.0"
|
wasmparser = "0.29.2"
|
||||||
hashbrown = "0.1.8"
|
hashbrown = "0.1.8"
|
||||||
smallvec = "0.6.8"
|
smallvec = "0.6.8"
|
||||||
goblin = "0.0.20"
|
goblin = "0.0.20"
|
||||||
|
@ -213,6 +213,8 @@ fn main() {
|
|||||||
|
|
||||||
println!("cargo:rustc-link-lib=static=llvm-backend");
|
println!("cargo:rustc-link-lib=static=llvm-backend");
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
|
println!("cargo:rerun-if-changed=cpp/object_loader.cpp");
|
||||||
|
println!("cargo:rerun-if-changed=cpp/object_loader.hh");
|
||||||
|
|
||||||
// Enable "nightly" cfg if the current compiler is nightly.
|
// Enable "nightly" cfg if the current compiler is nightly.
|
||||||
if rustc_version::version_meta().unwrap().channel == rustc_version::Channel::Nightly {
|
if rustc_version::version_meta().unwrap().channel == rustc_version::Channel::Nightly {
|
||||||
|
@ -43,6 +43,11 @@ typedef struct
|
|||||||
visit_fde_t visit_fde;
|
visit_fde_t visit_fde;
|
||||||
} callbacks_t;
|
} callbacks_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
size_t data, vtable;
|
||||||
|
} box_any_t;
|
||||||
|
|
||||||
struct WasmException
|
struct WasmException
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -61,7 +66,7 @@ struct UncatchableException : WasmException
|
|||||||
struct UserException : UncatchableException
|
struct UserException : UncatchableException
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UserException(size_t data, size_t vtable) : data(data), vtable(vtable) {}
|
UserException(size_t data, size_t vtable) : error_data({ data, vtable }) {}
|
||||||
|
|
||||||
virtual std::string description() const noexcept override
|
virtual std::string description() const noexcept override
|
||||||
{
|
{
|
||||||
@ -69,7 +74,7 @@ struct UserException : UncatchableException
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The parts of a `Box<dyn Any>`.
|
// The parts of a `Box<dyn Any>`.
|
||||||
size_t data, vtable;
|
box_any_t error_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WasmTrap : UncatchableException
|
struct WasmTrap : UncatchableException
|
||||||
@ -194,6 +199,7 @@ extern "C"
|
|||||||
void *params,
|
void *params,
|
||||||
void *results,
|
void *results,
|
||||||
WasmTrap::Type *trap_out,
|
WasmTrap::Type *trap_out,
|
||||||
|
box_any_t *user_error,
|
||||||
void *invoke_env) throw()
|
void *invoke_env) throw()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -206,6 +212,11 @@ extern "C"
|
|||||||
*trap_out = e.type;
|
*trap_out = e.type;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
catch (const UserException &e)
|
||||||
|
{
|
||||||
|
*user_error = e.error_data;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
catch (const WasmException &e)
|
catch (const WasmException &e)
|
||||||
{
|
{
|
||||||
*trap_out = WasmTrap::Type::Unknown;
|
*trap_out = WasmTrap::Type::Unknown;
|
||||||
|
@ -93,6 +93,7 @@ extern "C" {
|
|||||||
params: *const u64,
|
params: *const u64,
|
||||||
results: *mut u64,
|
results: *mut u64,
|
||||||
trap_out: *mut WasmTrapInfo,
|
trap_out: *mut WasmTrapInfo,
|
||||||
|
user_error: *mut Option<Box<dyn Any>>,
|
||||||
invoke_env: Option<NonNull<c_void>>,
|
invoke_env: Option<NonNull<c_void>>,
|
||||||
) -> bool;
|
) -> bool;
|
||||||
}
|
}
|
||||||
@ -297,7 +298,7 @@ impl LLVMBackend {
|
|||||||
let callbacks = get_callbacks();
|
let callbacks = get_callbacks();
|
||||||
let mut module: *mut LLVMModule = ptr::null_mut();
|
let mut module: *mut LLVMModule = ptr::null_mut();
|
||||||
|
|
||||||
let slice = unsafe { memory.as_slice() };
|
let slice = memory.as_slice();
|
||||||
|
|
||||||
let res = module_load(slice.as_ptr(), slice.len(), callbacks, &mut module);
|
let res = module_load(slice.as_ptr(), slice.len(), callbacks, &mut module);
|
||||||
|
|
||||||
@ -307,7 +308,7 @@ impl LLVMBackend {
|
|||||||
|
|
||||||
static SIGNAL_HANDLER_INSTALLED: Once = Once::new();
|
static SIGNAL_HANDLER_INSTALLED: Once = Once::new();
|
||||||
|
|
||||||
SIGNAL_HANDLER_INSTALLED.call_once(|| unsafe {
|
SIGNAL_HANDLER_INSTALLED.call_once(|| {
|
||||||
crate::platform::install_signal_handler();
|
crate::platform::install_signal_handler();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1468,7 +1468,7 @@ fn parse_function(
|
|||||||
context,
|
context,
|
||||||
&function,
|
&function,
|
||||||
-2147483904.0,
|
-2147483904.0,
|
||||||
2147483648.0,
|
2_147_483_648.0,
|
||||||
v1,
|
v1,
|
||||||
);
|
);
|
||||||
let res =
|
let res =
|
||||||
@ -1482,8 +1482,8 @@ fn parse_function(
|
|||||||
intrinsics,
|
intrinsics,
|
||||||
context,
|
context,
|
||||||
&function,
|
&function,
|
||||||
-2147483649.0,
|
-2_147_483_649.0,
|
||||||
2147483648.0,
|
2_147_483_648.0,
|
||||||
v1,
|
v1,
|
||||||
);
|
);
|
||||||
let res =
|
let res =
|
||||||
@ -1503,8 +1503,8 @@ fn parse_function(
|
|||||||
intrinsics,
|
intrinsics,
|
||||||
context,
|
context,
|
||||||
&function,
|
&function,
|
||||||
-9223373136366403584.0,
|
-9_223_373_136_366_403_584.0,
|
||||||
9223372036854775808.0,
|
9_223_372_036_854_775_808.0,
|
||||||
v1,
|
v1,
|
||||||
);
|
);
|
||||||
let res =
|
let res =
|
||||||
|
@ -13,7 +13,7 @@ wasmer-runtime-core = { path = "../runtime-core" }
|
|||||||
hashbrown = "0.1"
|
hashbrown = "0.1"
|
||||||
failure = "0.1"
|
failure = "0.1"
|
||||||
tar = "0.4"
|
tar = "0.4"
|
||||||
wasmparser = "0.23.0"
|
wasmparser = "0.29.2"
|
||||||
zstd = "0.4"
|
zstd = "0.4"
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies.zbox]
|
[target.'cfg(unix)'.dependencies.zbox]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::types::{FuncSig, GlobalDescriptor, MemoryDescriptor, TableDescriptor, Type, Value};
|
use crate::types::{FuncSig, GlobalDescriptor, MemoryDescriptor, TableDescriptor, Type};
|
||||||
use core::borrow::Borrow;
|
use core::borrow::Borrow;
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
|
|
||||||
@ -121,8 +121,7 @@ impl std::error::Error for LinkError {}
|
|||||||
/// Comparing two `RuntimeError`s always evaluates to false.
|
/// Comparing two `RuntimeError`s always evaluates to false.
|
||||||
pub enum RuntimeError {
|
pub enum RuntimeError {
|
||||||
Trap { msg: Box<str> },
|
Trap { msg: Box<str> },
|
||||||
Exception { data: Box<[Value]> },
|
Error { data: Box<dyn Any> },
|
||||||
Panic { data: Box<dyn Any> },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for RuntimeError {
|
impl PartialEq for RuntimeError {
|
||||||
@ -137,19 +136,14 @@ impl std::fmt::Display for RuntimeError {
|
|||||||
RuntimeError::Trap { ref msg } => {
|
RuntimeError::Trap { ref msg } => {
|
||||||
write!(f, "WebAssembly trap occured during runtime: {}", msg)
|
write!(f, "WebAssembly trap occured during runtime: {}", msg)
|
||||||
}
|
}
|
||||||
RuntimeError::Exception { ref data } => {
|
RuntimeError::Error { data } => {
|
||||||
write!(f, "Uncaught WebAssembly exception: {:?}", data)
|
if let Some(s) = data.downcast_ref::<String>() {
|
||||||
}
|
write!(f, "\"{}\"", s)
|
||||||
RuntimeError::Panic { data } => {
|
|
||||||
let msg = if let Some(s) = data.downcast_ref::<String>() {
|
|
||||||
s
|
|
||||||
} else if let Some(s) = data.downcast_ref::<&str>() {
|
} else if let Some(s) = data.downcast_ref::<&str>() {
|
||||||
s
|
write!(f, "\"{}\"", s)
|
||||||
} else {
|
} else {
|
||||||
"user-defined, opaque"
|
write!(f, "unknown error")
|
||||||
};
|
}
|
||||||
|
|
||||||
write!(f, "{}", msg)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -528,6 +528,7 @@ fn call_func_with_index(
|
|||||||
|
|
||||||
let run_wasm = |result_space: *mut u64| unsafe {
|
let run_wasm = |result_space: *mut u64| unsafe {
|
||||||
let mut trap_info = WasmTrapInfo::Unknown;
|
let mut trap_info = WasmTrapInfo::Unknown;
|
||||||
|
let mut user_error = None;
|
||||||
|
|
||||||
let success = invoke(
|
let success = invoke(
|
||||||
trampoline,
|
trampoline,
|
||||||
@ -536,15 +537,20 @@ fn call_func_with_index(
|
|||||||
raw_args.as_ptr(),
|
raw_args.as_ptr(),
|
||||||
result_space,
|
result_space,
|
||||||
&mut trap_info,
|
&mut trap_info,
|
||||||
|
&mut user_error,
|
||||||
invoke_env,
|
invoke_env,
|
||||||
);
|
);
|
||||||
|
|
||||||
if success {
|
if success {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(RuntimeError::Trap {
|
if let Some(data) = user_error {
|
||||||
msg: trap_info.to_string().into(),
|
Err(RuntimeError::Error { data })
|
||||||
})
|
} else {
|
||||||
|
Err(RuntimeError::Trap {
|
||||||
|
msg: trap_info.to_string().into(),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -651,10 +657,3 @@ impl<'a> DynFunc<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
impl Instance {
|
|
||||||
pub fn memory_offset_addr(&self, _: u32, _: usize) -> *const u8 {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -2,11 +2,12 @@ use crate::{
|
|||||||
error::RuntimeError,
|
error::RuntimeError,
|
||||||
export::{Context, Export, FuncPointer},
|
export::{Context, Export, FuncPointer},
|
||||||
import::IsExport,
|
import::IsExport,
|
||||||
types::{FuncSig, Type, WasmExternType},
|
types::{FuncSig, NativeWasmType, Type, WasmExternType},
|
||||||
vm::{self, Ctx},
|
vm::{self, Ctx},
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
|
convert::Infallible,
|
||||||
ffi::c_void,
|
ffi::c_void,
|
||||||
fmt,
|
fmt,
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
@ -57,6 +58,7 @@ pub type Invoke = unsafe extern "C" fn(
|
|||||||
*const u64,
|
*const u64,
|
||||||
*mut u64,
|
*mut u64,
|
||||||
*mut WasmTrapInfo,
|
*mut WasmTrapInfo,
|
||||||
|
*mut Option<Box<dyn Any>>,
|
||||||
Option<NonNull<c_void>>,
|
Option<NonNull<c_void>>,
|
||||||
) -> bool;
|
) -> bool;
|
||||||
|
|
||||||
@ -103,7 +105,7 @@ pub trait WasmTypeList {
|
|||||||
f: NonNull<vm::Func>,
|
f: NonNull<vm::Func>,
|
||||||
wasm: Wasm,
|
wasm: Wasm,
|
||||||
ctx: *mut Ctx,
|
ctx: *mut Ctx,
|
||||||
) -> Result<Rets, WasmTrapInfo>
|
) -> Result<Rets, RuntimeError>
|
||||||
where
|
where
|
||||||
Rets: WasmTypeList;
|
Rets: WasmTypeList;
|
||||||
}
|
}
|
||||||
@ -120,14 +122,16 @@ pub trait TrapEarly<Rets>
|
|||||||
where
|
where
|
||||||
Rets: WasmTypeList,
|
Rets: WasmTypeList,
|
||||||
{
|
{
|
||||||
fn report(self) -> Result<Rets, Box<dyn Any>>;
|
type Error: 'static;
|
||||||
|
fn report(self) -> Result<Rets, Self::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Rets> TrapEarly<Rets> for Rets
|
impl<Rets> TrapEarly<Rets> for Rets
|
||||||
where
|
where
|
||||||
Rets: WasmTypeList,
|
Rets: WasmTypeList,
|
||||||
{
|
{
|
||||||
fn report(self) -> Result<Rets, Box<dyn Any>> {
|
type Error = Infallible;
|
||||||
|
fn report(self) -> Result<Rets, Infallible> {
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -135,10 +139,11 @@ where
|
|||||||
impl<Rets, E> TrapEarly<Rets> for Result<Rets, E>
|
impl<Rets, E> TrapEarly<Rets> for Result<Rets, E>
|
||||||
where
|
where
|
||||||
Rets: WasmTypeList,
|
Rets: WasmTypeList,
|
||||||
E: Any,
|
E: 'static,
|
||||||
{
|
{
|
||||||
fn report(self) -> Result<Rets, Box<dyn Any>> {
|
type Error = E;
|
||||||
self.map_err(|err| Box::new(err) as Box<dyn Any>)
|
fn report(self) -> Result<Rets, E> {
|
||||||
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,26 +214,57 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl WasmTypeList for Infallible {
|
||||||
|
type CStruct = Infallible;
|
||||||
|
type RetArray = [u64; 0];
|
||||||
|
fn from_ret_array(_: Self::RetArray) -> Self {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
fn empty_ret_array() -> Self::RetArray {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
fn from_c_struct(_: Self::CStruct) -> Self {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
fn into_c_struct(self) -> Self::CStruct {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
fn types() -> &'static [Type] {
|
||||||
|
&[]
|
||||||
|
}
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
unsafe fn call<Rets: WasmTypeList>(
|
||||||
|
self,
|
||||||
|
_: NonNull<vm::Func>,
|
||||||
|
_: Wasm,
|
||||||
|
_: *mut Ctx,
|
||||||
|
) -> Result<Rets, RuntimeError> {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<A: WasmExternType> WasmTypeList for (A,) {
|
impl<A: WasmExternType> WasmTypeList for (A,) {
|
||||||
type CStruct = S1<A>;
|
type CStruct = S1<A>;
|
||||||
type RetArray = [u64; 1];
|
type RetArray = [u64; 1];
|
||||||
fn from_ret_array(array: Self::RetArray) -> Self {
|
fn from_ret_array(array: Self::RetArray) -> Self {
|
||||||
(WasmExternType::from_bits(array[0]),)
|
(WasmExternType::from_native(NativeWasmType::from_bits(
|
||||||
|
array[0],
|
||||||
|
)),)
|
||||||
}
|
}
|
||||||
fn empty_ret_array() -> Self::RetArray {
|
fn empty_ret_array() -> Self::RetArray {
|
||||||
[0u64]
|
[0u64]
|
||||||
}
|
}
|
||||||
fn from_c_struct(c_struct: Self::CStruct) -> Self {
|
fn from_c_struct(c_struct: Self::CStruct) -> Self {
|
||||||
let S1(a) = c_struct;
|
let S1(a) = c_struct;
|
||||||
(a,)
|
(WasmExternType::from_native(a),)
|
||||||
}
|
}
|
||||||
fn into_c_struct(self) -> Self::CStruct {
|
fn into_c_struct(self) -> Self::CStruct {
|
||||||
#[allow(unused_parens, non_snake_case)]
|
#[allow(unused_parens, non_snake_case)]
|
||||||
let (a,) = self;
|
let (a,) = self;
|
||||||
S1(a)
|
S1(WasmExternType::to_native(a))
|
||||||
}
|
}
|
||||||
fn types() -> &'static [Type] {
|
fn types() -> &'static [Type] {
|
||||||
&[A::TYPE]
|
&[A::Native::TYPE]
|
||||||
}
|
}
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
unsafe fn call<Rets: WasmTypeList>(
|
unsafe fn call<Rets: WasmTypeList>(
|
||||||
@ -236,14 +272,12 @@ impl<A: WasmExternType> WasmTypeList for (A,) {
|
|||||||
f: NonNull<vm::Func>,
|
f: NonNull<vm::Func>,
|
||||||
wasm: Wasm,
|
wasm: Wasm,
|
||||||
ctx: *mut Ctx,
|
ctx: *mut Ctx,
|
||||||
) -> Result<Rets, WasmTrapInfo> {
|
) -> Result<Rets, RuntimeError> {
|
||||||
// type Trampoline = extern "C" fn(*mut Ctx, *const c_void, *const u64, *mut u64);
|
|
||||||
// type Invoke = extern "C" fn(Trampoline, *mut Ctx, *const c_void, *const u64, *mut u64, &mut WasmTrapInfo) -> bool;
|
|
||||||
|
|
||||||
let (a,) = self;
|
let (a,) = self;
|
||||||
let args = [a.to_bits()];
|
let args = [a.to_native().to_bits()];
|
||||||
let mut rets = Rets::empty_ret_array();
|
let mut rets = Rets::empty_ret_array();
|
||||||
let mut trap = WasmTrapInfo::Unknown;
|
let mut trap = WasmTrapInfo::Unknown;
|
||||||
|
let mut user_error = None;
|
||||||
|
|
||||||
if (wasm.invoke)(
|
if (wasm.invoke)(
|
||||||
wasm.trampoline,
|
wasm.trampoline,
|
||||||
@ -252,11 +286,18 @@ impl<A: WasmExternType> WasmTypeList for (A,) {
|
|||||||
args.as_ptr(),
|
args.as_ptr(),
|
||||||
rets.as_mut().as_mut_ptr(),
|
rets.as_mut().as_mut_ptr(),
|
||||||
&mut trap,
|
&mut trap,
|
||||||
|
&mut user_error,
|
||||||
wasm.invoke_env,
|
wasm.invoke_env,
|
||||||
) {
|
) {
|
||||||
Ok(Rets::from_ret_array(rets))
|
Ok(Rets::from_ret_array(rets))
|
||||||
} else {
|
} else {
|
||||||
Err(trap)
|
if let Some(data) = user_error {
|
||||||
|
Err(RuntimeError::Error { data })
|
||||||
|
} else {
|
||||||
|
Err(RuntimeError::Trap {
|
||||||
|
msg: trap.to_string().into(),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -266,18 +307,14 @@ where
|
|||||||
Rets: WasmTypeList,
|
Rets: WasmTypeList,
|
||||||
{
|
{
|
||||||
pub fn call(&self, a: A) -> Result<Rets, RuntimeError> {
|
pub fn call(&self, a: A) -> Result<Rets, RuntimeError> {
|
||||||
unsafe { <A as WasmTypeList>::call(a, self.f, self.inner, self.ctx) }.map_err(|e| {
|
unsafe { <A as WasmTypeList>::call(a, self.f, self.inner, self.ctx) }
|
||||||
RuntimeError::Trap {
|
|
||||||
msg: e.to_string().into(),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_traits {
|
macro_rules! impl_traits {
|
||||||
( [$repr:ident] $struct_name:ident, $( $x:ident ),* ) => {
|
( [$repr:ident] $struct_name:ident, $( $x:ident ),* ) => {
|
||||||
#[repr($repr)]
|
#[repr($repr)]
|
||||||
pub struct $struct_name <$( $x ),*> ( $( $x ),* );
|
pub struct $struct_name <$( $x: WasmExternType ),*> ( $( <$x as WasmExternType>::Native ),* );
|
||||||
|
|
||||||
impl< $( $x: WasmExternType, )* > WasmTypeList for ( $( $x ),* ) {
|
impl< $( $x: WasmExternType, )* > WasmTypeList for ( $( $x ),* ) {
|
||||||
type CStruct = $struct_name<$( $x ),*>;
|
type CStruct = $struct_name<$( $x ),*>;
|
||||||
@ -285,7 +322,7 @@ macro_rules! impl_traits {
|
|||||||
fn from_ret_array(array: Self::RetArray) -> Self {
|
fn from_ret_array(array: Self::RetArray) -> Self {
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
let [ $( $x ),* ] = array;
|
let [ $( $x ),* ] = array;
|
||||||
( $( WasmExternType::from_bits($x) ),* )
|
( $( WasmExternType::from_native(NativeWasmType::from_bits($x)) ),* )
|
||||||
}
|
}
|
||||||
fn empty_ret_array() -> Self::RetArray {
|
fn empty_ret_array() -> Self::RetArray {
|
||||||
[0; count_idents!( $( $x ),* )]
|
[0; count_idents!( $( $x ),* )]
|
||||||
@ -293,38 +330,34 @@ macro_rules! impl_traits {
|
|||||||
fn from_c_struct(c_struct: Self::CStruct) -> Self {
|
fn from_c_struct(c_struct: Self::CStruct) -> Self {
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
let $struct_name ( $( $x ),* ) = c_struct;
|
let $struct_name ( $( $x ),* ) = c_struct;
|
||||||
( $( $x ),* )
|
( $( WasmExternType::from_native($x) ),* )
|
||||||
}
|
}
|
||||||
fn into_c_struct(self) -> Self::CStruct {
|
fn into_c_struct(self) -> Self::CStruct {
|
||||||
#[allow(unused_parens, non_snake_case)]
|
#[allow(unused_parens, non_snake_case)]
|
||||||
let ( $( $x ),* ) = self;
|
let ( $( $x ),* ) = self;
|
||||||
$struct_name ( $( $x ),* )
|
$struct_name ( $( WasmExternType::to_native($x) ),* )
|
||||||
}
|
}
|
||||||
fn types() -> &'static [Type] {
|
fn types() -> &'static [Type] {
|
||||||
&[$( $x::TYPE, )*]
|
&[$( $x::Native::TYPE, )*]
|
||||||
}
|
}
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
unsafe fn call<Rets: WasmTypeList>(self, f: NonNull<vm::Func>, wasm: Wasm, ctx: *mut Ctx) -> Result<Rets, WasmTrapInfo> {
|
unsafe fn call<Rets: WasmTypeList>(self, f: NonNull<vm::Func>, wasm: Wasm, ctx: *mut Ctx) -> Result<Rets, RuntimeError> {
|
||||||
// type Trampoline = extern "C" fn(*mut Ctx, *const c_void, *const u64, *mut u64);
|
|
||||||
// type Invoke = extern "C" fn(Trampoline, *mut Ctx, *const c_void, *const u64, *mut u64, &mut WasmTrapInfo) -> bool;
|
|
||||||
|
|
||||||
#[allow(unused_parens)]
|
#[allow(unused_parens)]
|
||||||
let ( $( $x ),* ) = self;
|
let ( $( $x ),* ) = self;
|
||||||
let args = [ $( $x.to_bits() ),* ];
|
let args = [ $( $x.to_native().to_bits() ),* ];
|
||||||
let mut rets = Rets::empty_ret_array();
|
let mut rets = Rets::empty_ret_array();
|
||||||
let mut trap = WasmTrapInfo::Unknown;
|
let mut trap = WasmTrapInfo::Unknown;
|
||||||
|
let mut user_error = None;
|
||||||
|
|
||||||
if (wasm.invoke)(wasm.trampoline, ctx, f, args.as_ptr(), rets.as_mut().as_mut_ptr(), &mut trap, wasm.invoke_env) {
|
if (wasm.invoke)(wasm.trampoline, ctx, f, args.as_ptr(), rets.as_mut().as_mut_ptr(), &mut trap, &mut user_error, wasm.invoke_env) {
|
||||||
Ok(Rets::from_ret_array(rets))
|
Ok(Rets::from_ret_array(rets))
|
||||||
} else {
|
} else {
|
||||||
Err(trap)
|
if let Some(data) = user_error {
|
||||||
|
Err(RuntimeError::Error { data })
|
||||||
|
} else {
|
||||||
|
Err(RuntimeError::Trap { msg: trap.to_string().into() })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// let f: extern fn(*mut Ctx $( ,$x )*) -> Rets::CStruct = mem::transmute(f);
|
|
||||||
// #[allow(unused_parens)]
|
|
||||||
// let ( $( $x ),* ) = self;
|
|
||||||
// let c_struct = f(ctx $( ,$x )*);
|
|
||||||
// Rets::from_c_struct(c_struct)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,15 +368,17 @@ macro_rules! impl_traits {
|
|||||||
|
|
||||||
/// This is required for the llvm backend to be able to unwind through this function.
|
/// This is required for the llvm backend to be able to unwind through this function.
|
||||||
#[cfg_attr(nightly, unwind(allowed))]
|
#[cfg_attr(nightly, unwind(allowed))]
|
||||||
extern fn wrap<$( $x: WasmExternType, )* Rets: WasmTypeList, Trap: TrapEarly<Rets>, FN: Fn( &mut Ctx $( ,$x )* ) -> Trap>( ctx: &mut Ctx $( ,$x: $x )* ) -> Rets::CStruct {
|
extern fn wrap<$( $x: WasmExternType, )* Rets: WasmTypeList, Trap: TrapEarly<Rets>, FN: Fn( &mut Ctx $( ,$x )* ) -> Trap>( ctx: &mut Ctx $( ,$x: <$x as WasmExternType>::Native )* ) -> Rets::CStruct {
|
||||||
let f: FN = unsafe { mem::transmute_copy(&()) };
|
let f: FN = unsafe { mem::transmute_copy(&()) };
|
||||||
|
|
||||||
let err = match panic::catch_unwind(panic::AssertUnwindSafe(|| {
|
let err = match panic::catch_unwind(panic::AssertUnwindSafe(|| {
|
||||||
let res = f( ctx $( ,$x )* ).report();
|
f( ctx $( ,WasmExternType::from_native($x) )* ).report()
|
||||||
res
|
|
||||||
})) {
|
})) {
|
||||||
Ok(Ok(returns)) => return returns.into_c_struct(),
|
Ok(Ok(returns)) => return returns.into_c_struct(),
|
||||||
Ok(Err(err)) => err,
|
Ok(Err(err)) => {
|
||||||
|
let b: Box<_> = err.into();
|
||||||
|
b as Box<dyn Any>
|
||||||
|
},
|
||||||
Err(err) => err,
|
Err(err) => err,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -363,11 +398,7 @@ macro_rules! impl_traits {
|
|||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn call(&self, $( $x: $x, )* ) -> Result<Rets, RuntimeError> {
|
pub fn call(&self, $( $x: $x, )* ) -> Result<Rets, RuntimeError> {
|
||||||
#[allow(unused_parens)]
|
#[allow(unused_parens)]
|
||||||
unsafe { <( $( $x ),* ) as WasmTypeList>::call(( $($x),* ), self.f, self.inner, self.ctx) }.map_err(|e| {
|
unsafe { <( $( $x ),* ) as WasmTypeList>::call(( $($x),* ), self.f, self.inner, self.ctx) }
|
||||||
RuntimeError::Trap {
|
|
||||||
msg: e.to_string().into(),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -71,103 +71,149 @@ impl From<f64> for Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe trait WasmExternType: Copy + Clone
|
pub unsafe trait NativeWasmType: Copy + Into<Value>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
const TYPE: Type;
|
const TYPE: Type;
|
||||||
|
fn from_bits(bits: u64) -> Self;
|
||||||
fn to_bits(self) -> u64;
|
fn to_bits(self) -> u64;
|
||||||
fn from_bits(n: u64) -> Self;
|
}
|
||||||
|
|
||||||
|
unsafe impl NativeWasmType for i32 {
|
||||||
|
const TYPE: Type = Type::I32;
|
||||||
|
fn from_bits(bits: u64) -> Self {
|
||||||
|
bits as _
|
||||||
|
}
|
||||||
|
fn to_bits(self) -> u64 {
|
||||||
|
self as _
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unsafe impl NativeWasmType for i64 {
|
||||||
|
const TYPE: Type = Type::I64;
|
||||||
|
fn from_bits(bits: u64) -> Self {
|
||||||
|
bits as _
|
||||||
|
}
|
||||||
|
fn to_bits(self) -> u64 {
|
||||||
|
self as _
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unsafe impl NativeWasmType for f32 {
|
||||||
|
const TYPE: Type = Type::F32;
|
||||||
|
fn from_bits(bits: u64) -> Self {
|
||||||
|
bits as _
|
||||||
|
}
|
||||||
|
fn to_bits(self) -> u64 {
|
||||||
|
self as _
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unsafe impl NativeWasmType for f64 {
|
||||||
|
const TYPE: Type = Type::F64;
|
||||||
|
fn from_bits(bits: u64) -> Self {
|
||||||
|
bits as _
|
||||||
|
}
|
||||||
|
fn to_bits(self) -> u64 {
|
||||||
|
self as _
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe trait WasmExternType: Copy
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
type Native: NativeWasmType;
|
||||||
|
fn from_native(native: Self::Native) -> Self;
|
||||||
|
fn to_native(self) -> Self::Native;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl WasmExternType for i8 {
|
unsafe impl WasmExternType for i8 {
|
||||||
const TYPE: Type = Type::I32;
|
type Native = i32;
|
||||||
fn to_bits(self) -> u64 {
|
fn from_native(native: Self::Native) -> Self {
|
||||||
self as u64
|
native as _
|
||||||
}
|
}
|
||||||
fn from_bits(n: u64) -> Self {
|
fn to_native(self) -> Self::Native {
|
||||||
n as _
|
self as _
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe impl WasmExternType for u8 {
|
unsafe impl WasmExternType for u8 {
|
||||||
const TYPE: Type = Type::I32;
|
type Native = i32;
|
||||||
fn to_bits(self) -> u64 {
|
fn from_native(native: Self::Native) -> Self {
|
||||||
self as u64
|
native as _
|
||||||
}
|
}
|
||||||
fn from_bits(n: u64) -> Self {
|
fn to_native(self) -> Self::Native {
|
||||||
n as _
|
self as _
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe impl WasmExternType for i16 {
|
unsafe impl WasmExternType for i16 {
|
||||||
const TYPE: Type = Type::I32;
|
type Native = i32;
|
||||||
fn to_bits(self) -> u64 {
|
fn from_native(native: Self::Native) -> Self {
|
||||||
self as u64
|
native as _
|
||||||
}
|
}
|
||||||
fn from_bits(n: u64) -> Self {
|
fn to_native(self) -> Self::Native {
|
||||||
n as _
|
self as _
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe impl WasmExternType for u16 {
|
unsafe impl WasmExternType for u16 {
|
||||||
const TYPE: Type = Type::I32;
|
type Native = i32;
|
||||||
fn to_bits(self) -> u64 {
|
fn from_native(native: Self::Native) -> Self {
|
||||||
self as u64
|
native as _
|
||||||
}
|
}
|
||||||
fn from_bits(n: u64) -> Self {
|
fn to_native(self) -> Self::Native {
|
||||||
n as _
|
self as _
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe impl WasmExternType for i32 {
|
unsafe impl WasmExternType for i32 {
|
||||||
const TYPE: Type = Type::I32;
|
type Native = i32;
|
||||||
fn to_bits(self) -> u64 {
|
fn from_native(native: Self::Native) -> Self {
|
||||||
self as u64
|
native
|
||||||
}
|
}
|
||||||
fn from_bits(n: u64) -> Self {
|
fn to_native(self) -> Self::Native {
|
||||||
n as _
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe impl WasmExternType for u32 {
|
unsafe impl WasmExternType for u32 {
|
||||||
const TYPE: Type = Type::I32;
|
type Native = i32;
|
||||||
fn to_bits(self) -> u64 {
|
fn from_native(native: Self::Native) -> Self {
|
||||||
self as u64
|
native as _
|
||||||
}
|
}
|
||||||
fn from_bits(n: u64) -> Self {
|
fn to_native(self) -> Self::Native {
|
||||||
n as _
|
self as _
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe impl WasmExternType for i64 {
|
unsafe impl WasmExternType for i64 {
|
||||||
const TYPE: Type = Type::I64;
|
type Native = i64;
|
||||||
fn to_bits(self) -> u64 {
|
fn from_native(native: Self::Native) -> Self {
|
||||||
self as u64
|
native
|
||||||
}
|
}
|
||||||
fn from_bits(n: u64) -> Self {
|
fn to_native(self) -> Self::Native {
|
||||||
n as _
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe impl WasmExternType for u64 {
|
unsafe impl WasmExternType for u64 {
|
||||||
const TYPE: Type = Type::I64;
|
type Native = i64;
|
||||||
fn to_bits(self) -> u64 {
|
fn from_native(native: Self::Native) -> Self {
|
||||||
self
|
native as _
|
||||||
}
|
}
|
||||||
fn from_bits(n: u64) -> Self {
|
fn to_native(self) -> Self::Native {
|
||||||
n
|
self as _
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe impl WasmExternType for f32 {
|
unsafe impl WasmExternType for f32 {
|
||||||
const TYPE: Type = Type::F32;
|
type Native = f32;
|
||||||
fn to_bits(self) -> u64 {
|
fn from_native(native: Self::Native) -> Self {
|
||||||
self.to_bits() as u64
|
native
|
||||||
}
|
}
|
||||||
fn from_bits(n: u64) -> Self {
|
fn to_native(self) -> Self::Native {
|
||||||
f32::from_bits(n as u32)
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe impl WasmExternType for f64 {
|
unsafe impl WasmExternType for f64 {
|
||||||
const TYPE: Type = Type::F64;
|
type Native = f64;
|
||||||
fn to_bits(self) -> u64 {
|
fn from_native(native: Self::Native) -> Self {
|
||||||
self.to_bits()
|
native
|
||||||
}
|
}
|
||||||
fn from_bits(n: u64) -> Self {
|
fn to_native(self) -> Self::Native {
|
||||||
f64::from_bits(n)
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use wasmer_runtime::{compile, error, imports, Ctx, Func, Value};
|
use wasmer_runtime::{compile, error, error::RuntimeError, imports, Ctx, Func, Value};
|
||||||
|
|
||||||
use wabt::wat2wasm;
|
use wabt::wat2wasm;
|
||||||
|
|
||||||
@ -7,6 +7,8 @@ static WAT: &'static str = r#"
|
|||||||
(type (;0;) (func (result i32)))
|
(type (;0;) (func (result i32)))
|
||||||
(import "env" "do_panic" (func $do_panic (type 0)))
|
(import "env" "do_panic" (func $do_panic (type 0)))
|
||||||
(func $dbz (result i32)
|
(func $dbz (result i32)
|
||||||
|
call $do_panic
|
||||||
|
drop
|
||||||
i32.const 42
|
i32.const 42
|
||||||
i32.const 0
|
i32.const 0
|
||||||
i32.div_u
|
i32.div_u
|
||||||
@ -34,8 +36,13 @@ fn foobar(_ctx: &mut Ctx) -> i32 {
|
|||||||
42
|
42
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_panic(_ctx: &mut Ctx) -> Result<i32, String> {
|
#[derive(Debug)]
|
||||||
Err("error".to_string())
|
struct ExitCode {
|
||||||
|
code: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_panic(_ctx: &mut Ctx) -> Result<i32, ExitCode> {
|
||||||
|
Err(ExitCode { code: 42 })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<(), error::Error> {
|
fn main() -> Result<(), error::Error> {
|
||||||
@ -63,5 +70,11 @@ fn main() -> Result<(), error::Error> {
|
|||||||
|
|
||||||
println!("result: {:?}", result);
|
println!("result: {:?}", result);
|
||||||
|
|
||||||
|
if let Err(RuntimeError::Error { data }) = result {
|
||||||
|
if let Ok(exit_code) = data.downcast::<ExitCode>() {
|
||||||
|
println!("exit code: {:?}", exit_code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
49
lib/runtime/tests/error_propagation.rs
Normal file
49
lib/runtime/tests/error_propagation.rs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#[test]
|
||||||
|
fn error_propagation() {
|
||||||
|
use std::convert::Infallible;
|
||||||
|
use wabt::wat2wasm;
|
||||||
|
use wasmer_runtime::{compile, error::RuntimeError, imports, Ctx, Func};
|
||||||
|
|
||||||
|
static WAT: &'static str = r#"
|
||||||
|
(module
|
||||||
|
(type (;0;) (func))
|
||||||
|
(import "env" "ret_err" (func $ret_err (type 0)))
|
||||||
|
(func $call_panic
|
||||||
|
call $ret_err
|
||||||
|
)
|
||||||
|
(export "call_err" (func $call_panic))
|
||||||
|
)
|
||||||
|
"#;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct ExitCode {
|
||||||
|
code: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ret_err(_ctx: &mut Ctx) -> Result<Infallible, ExitCode> {
|
||||||
|
Err(ExitCode { code: 42 })
|
||||||
|
}
|
||||||
|
|
||||||
|
let wasm = wat2wasm(WAT).unwrap();
|
||||||
|
|
||||||
|
let module = compile(&wasm).unwrap();
|
||||||
|
|
||||||
|
let instance = module
|
||||||
|
.instantiate(&imports! {
|
||||||
|
"env" => {
|
||||||
|
"ret_err" => Func::new(ret_err),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let foo: Func<(), ()> = instance.func("call_err").unwrap();
|
||||||
|
|
||||||
|
let result = foo.call();
|
||||||
|
|
||||||
|
if let Err(RuntimeError::Error { data }) = result {
|
||||||
|
let exit_code = data.downcast::<ExitCode>().unwrap();
|
||||||
|
assert_eq!(exit_code.code, 42);
|
||||||
|
} else {
|
||||||
|
panic!("didn't return RuntimeError::Error")
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,7 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.3.0" }
|
wasmer-runtime-core = { path = "../runtime-core", version = "0.3.0" }
|
||||||
wasmparser = "0.28.0"
|
wasmparser = "0.29.2"
|
||||||
dynasm = "0.3.1"
|
dynasm = "0.3.1"
|
||||||
dynasmrt = "0.3.1"
|
dynasmrt = "0.3.1"
|
||||||
lazy_static = "1.2.0"
|
lazy_static = "1.2.0"
|
||||||
|
@ -205,7 +205,8 @@ impl RunnableModule for X64ExecutionContext {
|
|||||||
func: NonNull<vm::Func>,
|
func: NonNull<vm::Func>,
|
||||||
args: *const u64,
|
args: *const u64,
|
||||||
rets: *mut u64,
|
rets: *mut u64,
|
||||||
_trap_info: *mut WasmTrapInfo,
|
trap_info: *mut WasmTrapInfo,
|
||||||
|
user_error: *mut Option<Box<dyn Any>>,
|
||||||
num_params_plus_one: Option<NonNull<c_void>>,
|
num_params_plus_one: Option<NonNull<c_void>>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let args = ::std::slice::from_raw_parts(
|
let args = ::std::slice::from_raw_parts(
|
||||||
@ -227,7 +228,13 @@ impl RunnableModule for X64ExecutionContext {
|
|||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
Err(_) => false,
|
Err(err) => {
|
||||||
|
match err {
|
||||||
|
protect_unix::CallProtError::Trap(info) => *trap_info = info,
|
||||||
|
protect_unix::CallProtError::Error(data) => *user_error = Some(data),
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ use wasmer_runtime_core::{
|
|||||||
backend::{sys::Memory, Backend, CacheGen, Compiler, CompilerConfig, Token},
|
backend::{sys::Memory, Backend, CacheGen, Compiler, CompilerConfig, Token},
|
||||||
cache::{Artifact, Error as CacheError},
|
cache::{Artifact, Error as CacheError},
|
||||||
error::{CompileError, CompileResult},
|
error::{CompileError, CompileResult},
|
||||||
module::{ModuleInfo, ModuleInner},
|
module::ModuleInner,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Placeholder;
|
struct Placeholder;
|
||||||
|
@ -15,8 +15,7 @@ use wasmer_runtime_core::{
|
|||||||
units::Pages,
|
units::Pages,
|
||||||
};
|
};
|
||||||
use wasmparser::{
|
use wasmparser::{
|
||||||
BinaryReaderError, Data, DataKind, Element, ElementKind, Export, ExternalKind, FuncType,
|
BinaryReaderError, ExternalKind, FuncType, ImportSectionEntryType, Operator, Type as WpType,
|
||||||
Import, ImportSectionEntryType, InitExpr, ModuleReader, Operator, SectionCode, Type as WpType,
|
|
||||||
WasmDecoder,
|
WasmDecoder,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,13 +11,13 @@
|
|||||||
//!
|
//!
|
||||||
use libc::{c_int, c_void, siginfo_t};
|
use libc::{c_int, c_void, siginfo_t};
|
||||||
use nix::sys::signal::{
|
use nix::sys::signal::{
|
||||||
sigaction, SaFlags, SigAction, SigHandler, SigSet, Signal, SIGBUS, SIGFPE, SIGILL, SIGSEGV,
|
sigaction, SaFlags, SigAction, SigHandler, SigSet, SIGBUS, SIGFPE, SIGILL, SIGSEGV,
|
||||||
};
|
};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::cell::{Cell, UnsafeCell};
|
use std::cell::{Cell, UnsafeCell};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::sync::Once;
|
use std::sync::Once;
|
||||||
use wasmer_runtime_core::error::{RuntimeError, RuntimeResult};
|
use wasmer_runtime_core::typed_func::WasmTrapInfo;
|
||||||
|
|
||||||
extern "C" fn signal_trap_handler(
|
extern "C" fn signal_trap_handler(
|
||||||
signum: ::nix::libc::c_int,
|
signum: ::nix::libc::c_int,
|
||||||
@ -62,7 +62,12 @@ pub unsafe fn trigger_trap() -> ! {
|
|||||||
longjmp(jmp_buf as *mut c_void, 0)
|
longjmp(jmp_buf as *mut c_void, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call_protected<T>(f: impl FnOnce() -> T) -> RuntimeResult<T> {
|
pub enum CallProtError {
|
||||||
|
Trap(WasmTrapInfo),
|
||||||
|
Error(Box<dyn Any>),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn call_protected<T>(f: impl FnOnce() -> T) -> Result<T, CallProtError> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let jmp_buf = SETJMP_BUFFER.with(|buf| buf.get());
|
let jmp_buf = SETJMP_BUFFER.with(|buf| buf.get());
|
||||||
let prev_jmp_buf = *jmp_buf;
|
let prev_jmp_buf = *jmp_buf;
|
||||||
@ -76,23 +81,24 @@ pub fn call_protected<T>(f: impl FnOnce() -> T) -> RuntimeResult<T> {
|
|||||||
*jmp_buf = prev_jmp_buf;
|
*jmp_buf = prev_jmp_buf;
|
||||||
|
|
||||||
if let Some(data) = TRAP_EARLY_DATA.with(|cell| cell.replace(None)) {
|
if let Some(data) = TRAP_EARLY_DATA.with(|cell| cell.replace(None)) {
|
||||||
Err(RuntimeError::Panic { data })
|
Err(CallProtError::Error(data))
|
||||||
} else {
|
} else {
|
||||||
let (faulting_addr, _inst_ptr) = CAUGHT_ADDRESSES.with(|cell| cell.get());
|
// let (faulting_addr, _inst_ptr) = CAUGHT_ADDRESSES.with(|cell| cell.get());
|
||||||
|
|
||||||
let signal = match Signal::from_c_int(signum) {
|
// let signal = match Signal::from_c_int(signum) {
|
||||||
Ok(SIGFPE) => "floating-point exception",
|
// Ok(SIGFPE) => "floating-point exception",
|
||||||
Ok(SIGILL) => "illegal instruction",
|
// Ok(SIGILL) => "illegal instruction",
|
||||||
Ok(SIGSEGV) => "segmentation violation",
|
// Ok(SIGSEGV) => "segmentation violation",
|
||||||
Ok(SIGBUS) => "bus error",
|
// Ok(SIGBUS) => "bus error",
|
||||||
Err(_) => "error while getting the Signal",
|
// Err(_) => "error while getting the Signal",
|
||||||
_ => "unkown trapped signal",
|
// _ => "unkown trapped signal",
|
||||||
};
|
// };
|
||||||
// When the trap-handler is fully implemented, this will return more information.
|
// // When the trap-handler is fully implemented, this will return more information.
|
||||||
Err(RuntimeError::Trap {
|
// Err(RuntimeError::Trap {
|
||||||
msg: format!("unknown trap at {:p} - {}", faulting_addr, signal).into(),
|
// msg: format!("unknown trap at {:p} - {}", faulting_addr, signal).into(),
|
||||||
}
|
// }
|
||||||
.into())
|
// .into())
|
||||||
|
Err(CallProtError::Trap(WasmTrapInfo::Unknown))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let ret = f(); // TODO: Switch stack?
|
let ret = f(); // TODO: Switch stack?
|
||||||
|
@ -16,8 +16,3 @@ hashbrown = "0.1.8"
|
|||||||
generational-arena = "0.2.2"
|
generational-arena = "0.2.2"
|
||||||
log = "0.4.6"
|
log = "0.4.6"
|
||||||
byteorder = "1.3.1"
|
byteorder = "1.3.1"
|
||||||
|
|
||||||
[dependencies.zbox]
|
|
||||||
git = "https://github.com/wasmerio/zbox"
|
|
||||||
branch = "bundle-libsodium"
|
|
||||||
features = ["libsodium-bundled"]
|
|
||||||
|
@ -17,6 +17,12 @@ pub use self::utils::is_wasi_module;
|
|||||||
|
|
||||||
use wasmer_runtime_core::{func, import::ImportObject, imports};
|
use wasmer_runtime_core::{func, import::ImportObject, imports};
|
||||||
|
|
||||||
|
/// This is returned in the Box<dyn Any> RuntimeError::Error variant.
|
||||||
|
/// Use `downcast` or `downcast_ref` to retrieve the `ExitCode`.
|
||||||
|
pub struct ExitCode {
|
||||||
|
pub code: syscalls::types::__wasi_exitcode_t,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn generate_import_object(
|
pub fn generate_import_object(
|
||||||
args: Vec<Vec<u8>>,
|
args: Vec<Vec<u8>>,
|
||||||
envs: Vec<Vec<u8>>,
|
envs: Vec<Vec<u8>>,
|
||||||
|
@ -2,7 +2,7 @@ use crate::syscalls::types::{__wasi_errno_t, __WASI_EFAULT};
|
|||||||
use std::{cell::Cell, fmt, marker::PhantomData, mem};
|
use std::{cell::Cell, fmt, marker::PhantomData, mem};
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
memory::Memory,
|
memory::Memory,
|
||||||
types::{Type, ValueType, WasmExternType},
|
types::{ValueType, WasmExternType},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Array;
|
pub struct Array;
|
||||||
@ -73,12 +73,12 @@ impl<T: Copy + ValueType> WasmPtr<T, Array> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T: Copy, Ty> WasmExternType for WasmPtr<T, Ty> {
|
unsafe impl<T: Copy, Ty> WasmExternType for WasmPtr<T, Ty> {
|
||||||
const TYPE: Type = Type::I32;
|
type Native = i32;
|
||||||
|
|
||||||
fn to_bits(self) -> u64 {
|
fn to_native(self) -> Self::Native {
|
||||||
self.offset as u64
|
self.offset as i32
|
||||||
}
|
}
|
||||||
fn from_bits(n: u64) -> Self {
|
fn from_native(n: Self::Native) -> Self {
|
||||||
Self {
|
Self {
|
||||||
offset: n as u32,
|
offset: n as u32,
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
|
@ -9,45 +9,39 @@ use std::{
|
|||||||
cell::Cell,
|
cell::Cell,
|
||||||
fs,
|
fs,
|
||||||
io::{self, Read, Seek, Write},
|
io::{self, Read, Seek, Write},
|
||||||
|
path::PathBuf,
|
||||||
time::SystemTime,
|
time::SystemTime,
|
||||||
};
|
};
|
||||||
use wasmer_runtime_core::debug;
|
use wasmer_runtime_core::debug;
|
||||||
use zbox::init_env as zbox_init_env;
|
|
||||||
|
|
||||||
pub const MAX_SYMLINKS: usize = 100;
|
pub const MAX_SYMLINKS: usize = 100;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum WasiFile {
|
pub enum WasiFile {
|
||||||
#[allow(dead_code)]
|
|
||||||
ZboxFile(zbox::File),
|
|
||||||
HostFile(fs::File),
|
HostFile(fs::File),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Write for WasiFile {
|
impl Write for WasiFile {
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
match self {
|
match self {
|
||||||
WasiFile::ZboxFile(zbf) => zbf.write(buf),
|
|
||||||
WasiFile::HostFile(hf) => hf.write(buf),
|
WasiFile::HostFile(hf) => hf.write(buf),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&mut self) -> io::Result<()> {
|
fn flush(&mut self) -> io::Result<()> {
|
||||||
match self {
|
match self {
|
||||||
WasiFile::ZboxFile(zbf) => zbf.flush(),
|
|
||||||
WasiFile::HostFile(hf) => hf.flush(),
|
WasiFile::HostFile(hf) => hf.flush(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
||||||
match self {
|
match self {
|
||||||
WasiFile::ZboxFile(zbf) => zbf.write_all(buf),
|
|
||||||
WasiFile::HostFile(hf) => hf.write_all(buf),
|
WasiFile::HostFile(hf) => hf.write_all(buf),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_fmt(&mut self, fmt: ::std::fmt::Arguments) -> io::Result<()> {
|
fn write_fmt(&mut self, fmt: ::std::fmt::Arguments) -> io::Result<()> {
|
||||||
match self {
|
match self {
|
||||||
WasiFile::ZboxFile(zbf) => zbf.write_fmt(fmt),
|
|
||||||
WasiFile::HostFile(hf) => hf.write_fmt(fmt),
|
WasiFile::HostFile(hf) => hf.write_fmt(fmt),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -56,28 +50,24 @@ impl Write for WasiFile {
|
|||||||
impl Read for WasiFile {
|
impl Read for WasiFile {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
match self {
|
match self {
|
||||||
WasiFile::ZboxFile(zbf) => zbf.read(buf),
|
|
||||||
WasiFile::HostFile(hf) => hf.read(buf),
|
WasiFile::HostFile(hf) => hf.read(buf),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||||
match self {
|
match self {
|
||||||
WasiFile::ZboxFile(zbf) => zbf.read_to_end(buf),
|
|
||||||
WasiFile::HostFile(hf) => hf.read_to_end(buf),
|
WasiFile::HostFile(hf) => hf.read_to_end(buf),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
|
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
|
||||||
match self {
|
match self {
|
||||||
WasiFile::ZboxFile(zbf) => zbf.read_to_string(buf),
|
|
||||||
WasiFile::HostFile(hf) => hf.read_to_string(buf),
|
WasiFile::HostFile(hf) => hf.read_to_string(buf),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
|
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
|
||||||
match self {
|
match self {
|
||||||
WasiFile::ZboxFile(zbf) => zbf.read_exact(buf),
|
|
||||||
WasiFile::HostFile(hf) => hf.read_exact(buf),
|
WasiFile::HostFile(hf) => hf.read_exact(buf),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,7 +76,6 @@ impl Read for WasiFile {
|
|||||||
impl Seek for WasiFile {
|
impl Seek for WasiFile {
|
||||||
fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
|
fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
|
||||||
match self {
|
match self {
|
||||||
WasiFile::ZboxFile(zbf) => zbf.seek(pos),
|
|
||||||
WasiFile::HostFile(hf) => hf.seek(pos),
|
WasiFile::HostFile(hf) => hf.seek(pos),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,7 +139,9 @@ pub enum Kind {
|
|||||||
handle: WasiFile,
|
handle: WasiFile,
|
||||||
},
|
},
|
||||||
Dir {
|
Dir {
|
||||||
handle: WasiFile,
|
// TODO: wrap it like WasiFile
|
||||||
|
/// The path on the host system where the directory is located
|
||||||
|
path: PathBuf,
|
||||||
/// The entries of a directory are lazily filled.
|
/// The entries of a directory are lazily filled.
|
||||||
entries: HashMap<String, Inode>,
|
entries: HashMap<String, Inode>,
|
||||||
},
|
},
|
||||||
@ -182,10 +173,7 @@ pub struct WasiFs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl WasiFs {
|
impl WasiFs {
|
||||||
pub fn new(preopened_files: &[String]) -> Result<Self, String> {
|
pub fn new(preopened_dirs: &[String]) -> Result<Self, String> {
|
||||||
debug!("wasi::fs::init");
|
|
||||||
zbox_init_env();
|
|
||||||
debug!("wasi::fs::repo");
|
|
||||||
/*let repo = RepoOpener::new()
|
/*let repo = RepoOpener::new()
|
||||||
.create(true)
|
.create(true)
|
||||||
.open("mem://wasmer-test-fs", "")
|
.open("mem://wasmer-test-fs", "")
|
||||||
@ -200,29 +188,26 @@ impl WasiFs {
|
|||||||
next_fd: Cell::new(3),
|
next_fd: Cell::new(3),
|
||||||
inode_counter: Cell::new(1000),
|
inode_counter: Cell::new(1000),
|
||||||
};
|
};
|
||||||
for file in preopened_files {
|
for dir in preopened_dirs {
|
||||||
debug!("Attempting to preopen {}", &file);
|
debug!("Attempting to preopen {}", &dir);
|
||||||
// TODO: think about this
|
// TODO: think about this
|
||||||
let default_rights = 0x1FFFFFFF; // all rights
|
let default_rights = 0x1FFFFFFF; // all rights
|
||||||
let cur_file: fs::File = fs::OpenOptions::new()
|
let cur_dir = PathBuf::from(dir);
|
||||||
.read(true)
|
let cur_dir_metadata = cur_dir.metadata().expect("Could not find directory");
|
||||||
.open(file)
|
let kind = if cur_dir_metadata.is_dir() {
|
||||||
.expect("Could not find file");
|
|
||||||
let cur_file_metadata = cur_file.metadata().unwrap();
|
|
||||||
let kind = if cur_file_metadata.is_dir() {
|
|
||||||
Kind::Dir {
|
Kind::Dir {
|
||||||
handle: WasiFile::HostFile(cur_file),
|
path: cur_dir.clone(),
|
||||||
entries: Default::default(),
|
entries: Default::default(),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"WASI only supports pre-opened directories right now; found \"{}\"",
|
"WASI only supports pre-opened directories right now; found \"{}\"",
|
||||||
file
|
&dir
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
// TODO: handle nested pats in `file`
|
// TODO: handle nested pats in `file`
|
||||||
let inode_val =
|
let inode_val =
|
||||||
InodeVal::from_file_metadata(&cur_file_metadata, file.clone(), true, kind);
|
InodeVal::from_file_metadata(&cur_dir_metadata, dir.clone(), true, kind);
|
||||||
|
|
||||||
let inode = wasi_fs.inodes.insert(inode_val);
|
let inode = wasi_fs.inodes.insert(inode_val);
|
||||||
wasi_fs.inodes[inode].stat.st_ino = wasi_fs.inode_counter.get();
|
wasi_fs.inodes[inode].stat.st_ino = wasi_fs.inode_counter.get();
|
||||||
|
@ -9,9 +9,11 @@ use self::types::*;
|
|||||||
use crate::{
|
use crate::{
|
||||||
ptr::{Array, WasmPtr},
|
ptr::{Array, WasmPtr},
|
||||||
state::{Fd, InodeVal, Kind, WasiFile, WasiState, MAX_SYMLINKS},
|
state::{Fd, InodeVal, Kind, WasiFile, WasiState, MAX_SYMLINKS},
|
||||||
|
ExitCode,
|
||||||
};
|
};
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
use std::convert::Infallible;
|
||||||
use std::io::{self, Read, Seek, Write};
|
use std::io::{self, Read, Seek, Write};
|
||||||
use wasmer_runtime_core::{debug, memory::Memory, vm::Ctx};
|
use wasmer_runtime_core::{debug, memory::Memory, vm::Ctx};
|
||||||
|
|
||||||
@ -1240,15 +1242,12 @@ pub fn path_open(
|
|||||||
};
|
};
|
||||||
// TODO: handle __WASI_O_TRUNC on directories
|
// TODO: handle __WASI_O_TRUNC on directories
|
||||||
|
|
||||||
let cur_dir = wasi_try!(open_options
|
|
||||||
.open(&cumulative_path)
|
|
||||||
.map_err(|_| __WASI_EINVAL));
|
|
||||||
|
|
||||||
// TODO: refactor and reuse
|
// TODO: refactor and reuse
|
||||||
let cur_file_metadata = cur_dir.metadata().unwrap();
|
let cur_file_metadata =
|
||||||
|
wasi_try!(cumulative_path.metadata().map_err(|_| __WASI_EINVAL));
|
||||||
let kind = if cur_file_metadata.is_dir() {
|
let kind = if cur_file_metadata.is_dir() {
|
||||||
Kind::Dir {
|
Kind::Dir {
|
||||||
handle: WasiFile::HostFile(cur_dir),
|
path: cumulative_path.clone(),
|
||||||
entries: Default::default(),
|
entries: Default::default(),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1430,9 +1429,9 @@ pub fn poll_oneoff(
|
|||||||
debug!("wasi::poll_oneoff");
|
debug!("wasi::poll_oneoff");
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
pub fn proc_exit(ctx: &mut Ctx, rval: __wasi_exitcode_t) -> Result<(), &'static str> {
|
pub fn proc_exit(ctx: &mut Ctx, code: __wasi_exitcode_t) -> Result<Infallible, ExitCode> {
|
||||||
debug!("wasi::proc_exit, {}", rval);
|
debug!("wasi::proc_exit, {}", code);
|
||||||
Err("Instance exited")
|
Err(ExitCode { code })
|
||||||
}
|
}
|
||||||
pub fn proc_raise(ctx: &mut Ctx, sig: __wasi_signal_t) -> __wasi_errno_t {
|
pub fn proc_raise(ctx: &mut Ctx, sig: __wasi_signal_t) -> __wasi_errno_t {
|
||||||
debug!("wasi::proc_raise");
|
debug!("wasi::proc_raise");
|
||||||
|
@ -43,84 +43,84 @@ pub struct __wasi_dirent_t {
|
|||||||
pub d_type: __wasi_filetype_t,
|
pub d_type: __wasi_filetype_t,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type __wasi_errno_t = u32;
|
pub type __wasi_errno_t = u16;
|
||||||
pub const __WASI_ESUCCESS: u32 = 0;
|
pub const __WASI_ESUCCESS: u16 = 0;
|
||||||
pub const __WASI_E2BIG: u32 = 1;
|
pub const __WASI_E2BIG: u16 = 1;
|
||||||
pub const __WASI_EACCES: u32 = 2;
|
pub const __WASI_EACCES: u16 = 2;
|
||||||
pub const __WASI_EADDRINUSE: u32 = 3;
|
pub const __WASI_EADDRINUSE: u16 = 3;
|
||||||
pub const __WASI_EADDRNOTAVAIL: u32 = 4;
|
pub const __WASI_EADDRNOTAVAIL: u16 = 4;
|
||||||
pub const __WASI_EAFNOSUPPORT: u32 = 5;
|
pub const __WASI_EAFNOSUPPORT: u16 = 5;
|
||||||
pub const __WASI_EAGAIN: u32 = 6;
|
pub const __WASI_EAGAIN: u16 = 6;
|
||||||
pub const __WASI_EALREADY: u32 = 7;
|
pub const __WASI_EALREADY: u16 = 7;
|
||||||
pub const __WASI_EBADF: u32 = 8;
|
pub const __WASI_EBADF: u16 = 8;
|
||||||
pub const __WASI_EBADMSG: u32 = 9;
|
pub const __WASI_EBADMSG: u16 = 9;
|
||||||
pub const __WASI_EBUSY: u32 = 10;
|
pub const __WASI_EBUSY: u16 = 10;
|
||||||
pub const __WASI_ECANCELED: u32 = 11;
|
pub const __WASI_ECANCELED: u16 = 11;
|
||||||
pub const __WASI_ECHILD: u32 = 12;
|
pub const __WASI_ECHILD: u16 = 12;
|
||||||
pub const __WASI_ECONNABORTED: u32 = 13;
|
pub const __WASI_ECONNABORTED: u16 = 13;
|
||||||
pub const __WASI_ECONNREFUSED: u32 = 14;
|
pub const __WASI_ECONNREFUSED: u16 = 14;
|
||||||
pub const __WASI_ECONNRESET: u32 = 15;
|
pub const __WASI_ECONNRESET: u16 = 15;
|
||||||
pub const __WASI_EDEADLK: u32 = 16;
|
pub const __WASI_EDEADLK: u16 = 16;
|
||||||
pub const __WASI_EDESTADDRREQ: u32 = 17;
|
pub const __WASI_EDESTADDRREQ: u16 = 17;
|
||||||
pub const __WASI_EDOM: u32 = 18;
|
pub const __WASI_EDOM: u16 = 18;
|
||||||
pub const __WASI_EDQUOT: u32 = 19;
|
pub const __WASI_EDQUOT: u16 = 19;
|
||||||
pub const __WASI_EEXIST: u32 = 20;
|
pub const __WASI_EEXIST: u16 = 20;
|
||||||
pub const __WASI_EFAULT: u32 = 21;
|
pub const __WASI_EFAULT: u16 = 21;
|
||||||
pub const __WASI_EFBIG: u32 = 22;
|
pub const __WASI_EFBIG: u16 = 22;
|
||||||
pub const __WASI_EHOSTUNREACH: u32 = 23;
|
pub const __WASI_EHOSTUNREACH: u16 = 23;
|
||||||
pub const __WASI_EIDRM: u32 = 24;
|
pub const __WASI_EIDRM: u16 = 24;
|
||||||
pub const __WASI_EILSEQ: u32 = 25;
|
pub const __WASI_EILSEQ: u16 = 25;
|
||||||
pub const __WASI_EINPROGRESS: u32 = 26;
|
pub const __WASI_EINPROGRESS: u16 = 26;
|
||||||
pub const __WASI_EINTR: u32 = 27;
|
pub const __WASI_EINTR: u16 = 27;
|
||||||
pub const __WASI_EINVAL: u32 = 28;
|
pub const __WASI_EINVAL: u16 = 28;
|
||||||
pub const __WASI_EIO: u32 = 29;
|
pub const __WASI_EIO: u16 = 29;
|
||||||
pub const __WASI_EISCONN: u32 = 30;
|
pub const __WASI_EISCONN: u16 = 30;
|
||||||
pub const __WASI_EISDIR: u32 = 31;
|
pub const __WASI_EISDIR: u16 = 31;
|
||||||
pub const __WASI_ELOOP: u32 = 32;
|
pub const __WASI_ELOOP: u16 = 32;
|
||||||
pub const __WASI_EMFILE: u32 = 33;
|
pub const __WASI_EMFILE: u16 = 33;
|
||||||
pub const __WASI_EMLINK: u32 = 34;
|
pub const __WASI_EMLINK: u16 = 34;
|
||||||
pub const __WASI_EMSGSIZE: u32 = 35;
|
pub const __WASI_EMSGSIZE: u16 = 35;
|
||||||
pub const __WASI_EMULTIHOP: u32 = 36;
|
pub const __WASI_EMULTIHOP: u16 = 36;
|
||||||
pub const __WASI_ENAMETOOLONG: u32 = 37;
|
pub const __WASI_ENAMETOOLONG: u16 = 37;
|
||||||
pub const __WASI_ENETDOWN: u32 = 38;
|
pub const __WASI_ENETDOWN: u16 = 38;
|
||||||
pub const __WASI_ENETRESET: u32 = 39;
|
pub const __WASI_ENETRESET: u16 = 39;
|
||||||
pub const __WASI_ENETUNREACH: u32 = 40;
|
pub const __WASI_ENETUNREACH: u16 = 40;
|
||||||
pub const __WASI_ENFILE: u32 = 41;
|
pub const __WASI_ENFILE: u16 = 41;
|
||||||
pub const __WASI_ENOBUFS: u32 = 42;
|
pub const __WASI_ENOBUFS: u16 = 42;
|
||||||
pub const __WASI_ENODEV: u32 = 43;
|
pub const __WASI_ENODEV: u16 = 43;
|
||||||
pub const __WASI_ENOENT: u32 = 44;
|
pub const __WASI_ENOENT: u16 = 44;
|
||||||
pub const __WASI_ENOEXEC: u32 = 45;
|
pub const __WASI_ENOEXEC: u16 = 45;
|
||||||
pub const __WASI_ENOLCK: u32 = 46;
|
pub const __WASI_ENOLCK: u16 = 46;
|
||||||
pub const __WASI_ENOLINK: u32 = 47;
|
pub const __WASI_ENOLINK: u16 = 47;
|
||||||
pub const __WASI_ENOMEM: u32 = 48;
|
pub const __WASI_ENOMEM: u16 = 48;
|
||||||
pub const __WASI_ENOMSG: u32 = 49;
|
pub const __WASI_ENOMSG: u16 = 49;
|
||||||
pub const __WASI_ENOPROTOOPT: u32 = 50;
|
pub const __WASI_ENOPROTOOPT: u16 = 50;
|
||||||
pub const __WASI_ENOSPC: u32 = 51;
|
pub const __WASI_ENOSPC: u16 = 51;
|
||||||
pub const __WASI_ENOSYS: u32 = 52;
|
pub const __WASI_ENOSYS: u16 = 52;
|
||||||
pub const __WASI_ENOTCONN: u32 = 53;
|
pub const __WASI_ENOTCONN: u16 = 53;
|
||||||
pub const __WASI_ENOTDIR: u32 = 54;
|
pub const __WASI_ENOTDIR: u16 = 54;
|
||||||
pub const __WASI_ENOTEMPTY: u32 = 55;
|
pub const __WASI_ENOTEMPTY: u16 = 55;
|
||||||
pub const __WASI_ENOTRECOVERABLE: u32 = 56;
|
pub const __WASI_ENOTRECOVERABLE: u16 = 56;
|
||||||
pub const __WASI_ENOTSOCK: u32 = 57;
|
pub const __WASI_ENOTSOCK: u16 = 57;
|
||||||
pub const __WASI_ENOTSUP: u32 = 58;
|
pub const __WASI_ENOTSUP: u16 = 58;
|
||||||
pub const __WASI_ENOTTY: u32 = 59;
|
pub const __WASI_ENOTTY: u16 = 59;
|
||||||
pub const __WASI_ENXIO: u32 = 60;
|
pub const __WASI_ENXIO: u16 = 60;
|
||||||
pub const __WASI_EOVERFLOW: u32 = 61;
|
pub const __WASI_EOVERFLOW: u16 = 61;
|
||||||
pub const __WASI_EOWNERDEAD: u32 = 62;
|
pub const __WASI_EOWNERDEAD: u16 = 62;
|
||||||
pub const __WASI_EPERM: u32 = 63;
|
pub const __WASI_EPERM: u16 = 63;
|
||||||
pub const __WASI_EPIPE: u32 = 64;
|
pub const __WASI_EPIPE: u16 = 64;
|
||||||
pub const __WASI_EPROTO: u32 = 65;
|
pub const __WASI_EPROTO: u16 = 65;
|
||||||
pub const __WASI_EPROTONOSUPPORT: u32 = 66;
|
pub const __WASI_EPROTONOSUPPORT: u16 = 66;
|
||||||
pub const __WASI_EPROTOTYPE: u32 = 67;
|
pub const __WASI_EPROTOTYPE: u16 = 67;
|
||||||
pub const __WASI_ERANGE: u32 = 68;
|
pub const __WASI_ERANGE: u16 = 68;
|
||||||
pub const __WASI_EROFS: u32 = 69;
|
pub const __WASI_EROFS: u16 = 69;
|
||||||
pub const __WASI_ESPIPE: u32 = 70;
|
pub const __WASI_ESPIPE: u16 = 70;
|
||||||
pub const __WASI_ESRCH: u32 = 71;
|
pub const __WASI_ESRCH: u16 = 71;
|
||||||
pub const __WASI_ESTALE: u32 = 72;
|
pub const __WASI_ESTALE: u16 = 72;
|
||||||
pub const __WASI_ETIMEDOUT: u32 = 73;
|
pub const __WASI_ETIMEDOUT: u16 = 73;
|
||||||
pub const __WASI_ETXTBSY: u32 = 74;
|
pub const __WASI_ETXTBSY: u16 = 74;
|
||||||
pub const __WASI_EXDEV: u32 = 75;
|
pub const __WASI_EXDEV: u16 = 75;
|
||||||
pub const __WASI_ENOTCAPABLE: u32 = 76;
|
pub const __WASI_ENOTCAPABLE: u16 = 76;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -174,8 +174,8 @@ impl __wasi_event_t {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type __wasi_eventrwflags_t = u32;
|
pub type __wasi_eventrwflags_t = u16;
|
||||||
pub const __WASI_EVENT_FD_READWRITE_HANGUP: u32 = 1 << 0;
|
pub const __WASI_EVENT_FD_READWRITE_HANGUP: u16 = 1 << 0;
|
||||||
|
|
||||||
pub type __wasi_eventtype_t = u8;
|
pub type __wasi_eventtype_t = u8;
|
||||||
pub const __WASI_EVENTTYPE_CLOCK: u8 = 0;
|
pub const __WASI_EVENTTYPE_CLOCK: u8 = 0;
|
||||||
@ -189,12 +189,12 @@ pub const __WASI_STDIN_FILENO: u32 = 0;
|
|||||||
pub const __WASI_STDOUT_FILENO: u32 = 1;
|
pub const __WASI_STDOUT_FILENO: u32 = 1;
|
||||||
pub const __WASI_STDERR_FILENO: u32 = 2;
|
pub const __WASI_STDERR_FILENO: u32 = 2;
|
||||||
|
|
||||||
pub type __wasi_fdflags_t = u32;
|
pub type __wasi_fdflags_t = u16;
|
||||||
pub const __WASI_FDFLAG_APPEND: u32 = 1 << 0;
|
pub const __WASI_FDFLAG_APPEND: u16 = 1 << 0;
|
||||||
pub const __WASI_FDFLAG_DSYNC: u32 = 1 << 1;
|
pub const __WASI_FDFLAG_DSYNC: u16 = 1 << 1;
|
||||||
pub const __WASI_FDFLAG_NONBLOCK: u32 = 1 << 2;
|
pub const __WASI_FDFLAG_NONBLOCK: u16 = 1 << 2;
|
||||||
pub const __WASI_FDFLAG_RSYNC: u32 = 1 << 3;
|
pub const __WASI_FDFLAG_RSYNC: u16 = 1 << 3;
|
||||||
pub const __WASI_FDFLAG_SYNC: u32 = 1 << 4;
|
pub const __WASI_FDFLAG_SYNC: u16 = 1 << 4;
|
||||||
|
|
||||||
pub type __wasi_preopentype_t = u8;
|
pub type __wasi_preopentype_t = u8;
|
||||||
pub const __WASI_PREOPENTYPE_DIR: u8 = 0;
|
pub const __WASI_PREOPENTYPE_DIR: u8 = 0;
|
||||||
@ -296,11 +296,11 @@ pub const __WASI_FILETYPE_SOCKET_DGRAM: u8 = 5;
|
|||||||
pub const __WASI_FILETYPE_SOCKET_STREAM: u8 = 6;
|
pub const __WASI_FILETYPE_SOCKET_STREAM: u8 = 6;
|
||||||
pub const __WASI_FILETYPE_SYMBOLIC_LINK: u8 = 7;
|
pub const __WASI_FILETYPE_SYMBOLIC_LINK: u8 = 7;
|
||||||
|
|
||||||
pub type __wasi_fstflags_t = u32;
|
pub type __wasi_fstflags_t = u16;
|
||||||
pub const __WASI_FILESTAT_SET_ATIM: u32 = 1 << 0;
|
pub const __WASI_FILESTAT_SET_ATIM: u16 = 1 << 0;
|
||||||
pub const __WASI_FILESTAT_SET_ATIM_NOW: u32 = 1 << 1;
|
pub const __WASI_FILESTAT_SET_ATIM_NOW: u16 = 1 << 1;
|
||||||
pub const __WASI_FILESTAT_SET_MTIM: u32 = 1 << 2;
|
pub const __WASI_FILESTAT_SET_MTIM: u16 = 1 << 2;
|
||||||
pub const __WASI_FILESTAT_SET_MTIM_NOW: u32 = 1 << 3;
|
pub const __WASI_FILESTAT_SET_MTIM_NOW: u16 = 1 << 3;
|
||||||
|
|
||||||
pub type __wasi_inode_t = u64;
|
pub type __wasi_inode_t = u64;
|
||||||
|
|
||||||
@ -318,15 +318,15 @@ pub type __wasi_linkcount_t = u32;
|
|||||||
pub type __wasi_lookupflags_t = u32;
|
pub type __wasi_lookupflags_t = u32;
|
||||||
pub const __WASI_LOOKUP_SYMLINK_FOLLOW: u32 = 1 << 0;
|
pub const __WASI_LOOKUP_SYMLINK_FOLLOW: u32 = 1 << 0;
|
||||||
|
|
||||||
pub type __wasi_oflags_t = u32;
|
pub type __wasi_oflags_t = u16;
|
||||||
pub const __WASI_O_CREAT: u32 = 1 << 0;
|
pub const __WASI_O_CREAT: u16 = 1 << 0;
|
||||||
pub const __WASI_O_DIRECTORY: u32 = 1 << 1;
|
pub const __WASI_O_DIRECTORY: u16 = 1 << 1;
|
||||||
pub const __WASI_O_EXCL: u32 = 1 << 2;
|
pub const __WASI_O_EXCL: u16 = 1 << 2;
|
||||||
pub const __WASI_O_TRUNC: u32 = 1 << 3;
|
pub const __WASI_O_TRUNC: u16 = 1 << 3;
|
||||||
|
|
||||||
pub type __wasi_riflags_t = u32;
|
pub type __wasi_riflags_t = u16;
|
||||||
pub const __WASI_SOCK_RECV_PEEK: u32 = 1 << 0;
|
pub const __WASI_SOCK_RECV_PEEK: u16 = 1 << 0;
|
||||||
pub const __WASI_SOCK_RECV_WAITALL: u32 = 1 << 1;
|
pub const __WASI_SOCK_RECV_WAITALL: u16 = 1 << 1;
|
||||||
|
|
||||||
pub type __wasi_rights_t = u64;
|
pub type __wasi_rights_t = u64;
|
||||||
pub const __WASI_RIGHT_FD_DATASYNC: u64 = 1 << 0;
|
pub const __WASI_RIGHT_FD_DATASYNC: u64 = 1 << 0;
|
||||||
@ -359,14 +359,14 @@ pub const __WASI_RIGHT_PATH_REMOVE_DIRECTORY: u64 = 1 << 26;
|
|||||||
pub const __WASI_RIGHT_POLL_FD_READWRITE: u64 = 1 << 27;
|
pub const __WASI_RIGHT_POLL_FD_READWRITE: u64 = 1 << 27;
|
||||||
pub const __WASI_RIGHT_SOCK_SHUTDOWN: u64 = 1 << 28;
|
pub const __WASI_RIGHT_SOCK_SHUTDOWN: u64 = 1 << 28;
|
||||||
|
|
||||||
pub type __wasi_roflags_t = u32;
|
pub type __wasi_roflags_t = u16;
|
||||||
pub const __WASI_SOCK_RECV_DATA_TRUNCATED: u32 = 1 << 0;
|
pub const __WASI_SOCK_RECV_DATA_TRUNCATED: u16 = 1 << 0;
|
||||||
|
|
||||||
pub type __wasi_sdflags_t = u8;
|
pub type __wasi_sdflags_t = u8;
|
||||||
pub const __WASI_SHUT_RD: u8 = 1 << 0;
|
pub const __WASI_SHUT_RD: u8 = 1 << 0;
|
||||||
pub const __WASI_SHUT_WR: u8 = 1 << 1;
|
pub const __WASI_SHUT_WR: u8 = 1 << 1;
|
||||||
|
|
||||||
pub type __wasi_siflags_t = u32;
|
pub type __wasi_siflags_t = u16;
|
||||||
|
|
||||||
pub type __wasi_signal_t = u8;
|
pub type __wasi_signal_t = u8;
|
||||||
pub const __WASI_SIGABRT: u8 = 0;
|
pub const __WASI_SIGABRT: u8 = 0;
|
||||||
@ -396,8 +396,8 @@ pub const __WASI_SIGVTALRM: u8 = 23;
|
|||||||
pub const __WASI_SIGXCPU: u8 = 24;
|
pub const __WASI_SIGXCPU: u8 = 24;
|
||||||
pub const __WASI_SIGXFSZ: u8 = 25;
|
pub const __WASI_SIGXFSZ: u8 = 25;
|
||||||
|
|
||||||
pub type __wasi_subclockflags_t = u32;
|
pub type __wasi_subclockflags_t = u16;
|
||||||
pub const __WASI_SUBSCRIPTION_CLOCK_ABSTIME: u32 = 1 << 0;
|
pub const __WASI_SUBSCRIPTION_CLOCK_ABSTIME: u16 = 1 << 0;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
use cmake::Config;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
{
|
{
|
||||||
|
use cmake::Config;
|
||||||
let project_name = "exception_handling";
|
let project_name = "exception_handling";
|
||||||
let dst = Config::new(project_name).build();
|
let dst = Config::new(project_name).build();
|
||||||
println!("cargo:rustc-link-search=native={}", dst.display());
|
println!("cargo:rustc-link-search=native={}", dst.display());
|
||||||
|
BIN
media/wizard_logo.ico
Normal file
BIN
media/wizard_logo.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
BIN
media/wizard_logo_2.bmp
Normal file
BIN
media/wizard_logo_2.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 958 KiB |
BIN
media/wizard_logo_small.bmp
Normal file
BIN
media/wizard_logo_small.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
@ -11,12 +11,15 @@ use std::str::FromStr;
|
|||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
use wasmer::webassembly::InstanceABI;
|
|
||||||
use wasmer::*;
|
use wasmer::*;
|
||||||
use wasmer_clif_backend::CraneliftCompiler;
|
use wasmer_clif_backend::CraneliftCompiler;
|
||||||
#[cfg(feature = "backend:llvm")]
|
#[cfg(feature = "backend:llvm")]
|
||||||
use wasmer_llvm_backend::LLVMCompiler;
|
use wasmer_llvm_backend::LLVMCompiler;
|
||||||
use wasmer_runtime::cache::{Cache as BaseCache, FileSystemCache, WasmHash, WASMER_VERSION_HASH};
|
use wasmer_runtime::{
|
||||||
|
cache::{Cache as BaseCache, FileSystemCache, WasmHash, WASMER_VERSION_HASH},
|
||||||
|
error::RuntimeError,
|
||||||
|
Func, Value,
|
||||||
|
};
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
self,
|
self,
|
||||||
backend::{Compiler, CompilerConfig},
|
backend::{Compiler, CompilerConfig},
|
||||||
@ -105,7 +108,13 @@ enum Backend {
|
|||||||
|
|
||||||
impl Backend {
|
impl Backend {
|
||||||
pub fn variants() -> &'static [&'static str] {
|
pub fn variants() -> &'static [&'static str] {
|
||||||
&["singlepass", "cranelift", "llvm"]
|
&[
|
||||||
|
"cranelift",
|
||||||
|
#[cfg(feature = "backend:singlepass")]
|
||||||
|
"singlepass",
|
||||||
|
#[cfg(feature = "backend:llvm")]
|
||||||
|
"llvm",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,60 +304,81 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// TODO: refactor this
|
// TODO: refactor this
|
||||||
let (abi, import_object, _em_globals) = if wasmer_emscripten::is_emscripten_module(&module) {
|
if wasmer_emscripten::is_emscripten_module(&module) {
|
||||||
let mut emscripten_globals = wasmer_emscripten::EmscriptenGlobals::new(&module);
|
let mut emscripten_globals = wasmer_emscripten::EmscriptenGlobals::new(&module);
|
||||||
(
|
let import_object = wasmer_emscripten::generate_emscripten_env(&mut emscripten_globals);
|
||||||
InstanceABI::Emscripten,
|
let mut instance = module
|
||||||
wasmer_emscripten::generate_emscripten_env(&mut emscripten_globals),
|
.instantiate(&import_object)
|
||||||
Some(emscripten_globals), // TODO Em Globals is here to extend, lifetime, find better solution
|
.map_err(|e| format!("Can't instantiate module: {:?}", e))?;
|
||||||
|
|
||||||
|
wasmer_emscripten::run_emscripten_instance(
|
||||||
|
&module,
|
||||||
|
&mut instance,
|
||||||
|
if let Some(cn) = &options.command_name {
|
||||||
|
cn
|
||||||
|
} else {
|
||||||
|
options.path.to_str().unwrap()
|
||||||
|
},
|
||||||
|
options.args.iter().map(|arg| arg.as_str()).collect(),
|
||||||
)
|
)
|
||||||
|
.map_err(|e| format!("{:?}", e))?;
|
||||||
} else {
|
} else {
|
||||||
if cfg!(feature = "wasi") && wasmer_wasi::is_wasi_module(&module) {
|
if cfg!(feature = "wasi") && wasmer_wasi::is_wasi_module(&module) {
|
||||||
(
|
let import_object = wasmer_wasi::generate_import_object(
|
||||||
InstanceABI::WASI,
|
if let Some(cn) = &options.command_name {
|
||||||
wasmer_wasi::generate_import_object(
|
[cn.clone()]
|
||||||
if let Some(cn) = &options.command_name {
|
} else {
|
||||||
[cn.clone()]
|
[options.path.to_str().unwrap().to_owned()]
|
||||||
} else {
|
}
|
||||||
[options.path.to_str().unwrap().to_owned()]
|
.iter()
|
||||||
}
|
.chain(options.args.iter())
|
||||||
.iter()
|
.cloned()
|
||||||
.chain(options.args.iter())
|
.map(|arg| arg.into_bytes())
|
||||||
.cloned()
|
.collect(),
|
||||||
.map(|arg| arg.into_bytes())
|
env::vars()
|
||||||
|
.map(|(k, v)| format!("{}={}", k, v).into_bytes())
|
||||||
.collect(),
|
.collect(),
|
||||||
env::vars()
|
options.pre_opened_directories.clone(),
|
||||||
.map(|(k, v)| format!("{}={}", k, v).into_bytes())
|
);
|
||||||
.collect(),
|
|
||||||
options.pre_opened_directories.clone(),
|
let instance = module
|
||||||
),
|
.instantiate(&import_object)
|
||||||
None,
|
.map_err(|e| format!("Can't instantiate module: {:?}", e))?;
|
||||||
)
|
|
||||||
|
let start: Func<(), ()> = instance.func("_start").map_err(|e| format!("{:?}", e))?;
|
||||||
|
|
||||||
|
let result = start.call();
|
||||||
|
|
||||||
|
if let Err(ref err) = result {
|
||||||
|
match err {
|
||||||
|
RuntimeError::Trap { msg } => panic!("wasm trap occured: {}", msg),
|
||||||
|
RuntimeError::Error { data } => {
|
||||||
|
if let Some(error_code) = data.downcast_ref::<wasmer_wasi::ExitCode>() {
|
||||||
|
std::process::exit(error_code.code as i32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic!("error: {:?}", err)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
(
|
let import_object = wasmer_runtime_core::import::ImportObject::new();
|
||||||
InstanceABI::None,
|
let instance = module
|
||||||
wasmer_runtime_core::import::ImportObject::new(),
|
.instantiate(&import_object)
|
||||||
None,
|
.map_err(|e| format!("Can't instantiate module: {:?}", e))?;
|
||||||
)
|
|
||||||
|
let args: Vec<Value> = options
|
||||||
|
.args
|
||||||
|
.iter()
|
||||||
|
.map(|arg| arg.as_str())
|
||||||
|
.map(|x| Value::I32(x.parse().unwrap()))
|
||||||
|
.collect();
|
||||||
|
instance
|
||||||
|
.dyn_func("main")
|
||||||
|
.map_err(|e| format!("{:?}", e))?
|
||||||
|
.call(&args)
|
||||||
|
.map_err(|e| format!("{:?}", e))?;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
let mut instance = module
|
|
||||||
.instantiate(&import_object)
|
|
||||||
.map_err(|e| format!("Can't instantiate module: {:?}", e))?;
|
|
||||||
|
|
||||||
webassembly::run_instance(
|
|
||||||
&module,
|
|
||||||
&mut instance,
|
|
||||||
abi,
|
|
||||||
if let Some(cn) = &options.command_name {
|
|
||||||
cn
|
|
||||||
} else {
|
|
||||||
options.path.to_str().unwrap()
|
|
||||||
},
|
|
||||||
options.args.iter().map(|arg| arg.as_str()).collect(),
|
|
||||||
)
|
|
||||||
.map_err(|e| format!("{:?}", e))?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[Setup]
|
[Setup]
|
||||||
AppName=Wasmer
|
AppName=Wasmer
|
||||||
AppVersion=1.5
|
AppVersion=0.4.0
|
||||||
DefaultDirName={pf}\Wasmer
|
DefaultDirName={pf}\Wasmer
|
||||||
DefaultGroupName=Wasmer
|
DefaultGroupName=Wasmer
|
||||||
Compression=lzma2
|
Compression=lzma2
|
||||||
@ -9,9 +9,14 @@ OutputDir=.\
|
|||||||
DisableProgramGroupPage=yes
|
DisableProgramGroupPage=yes
|
||||||
ChangesEnvironment=yes
|
ChangesEnvironment=yes
|
||||||
OutputBaseFilename=WasmerInstaller
|
OutputBaseFilename=WasmerInstaller
|
||||||
|
WizardImageFile=..\..\media\wizard_logo_2.bmp
|
||||||
|
WizardSmallImageFile=..\..\media\wizard_logo_small.bmp
|
||||||
|
SetupIconFile=..\..\media\wizard_logo.ico
|
||||||
|
DisableWelcomePage=no
|
||||||
|
|
||||||
[Files]
|
[Files]
|
||||||
Source: "..\..\target\release\wasmer.exe"; DestDir: "{app}\bin"
|
Source: "..\..\target\release\wasmer.exe"; DestDir: "{app}\bin"
|
||||||
|
Source: "..\..\wapm-cli\target\release\wapm.exe"; DestDir: "{app}\bin"
|
||||||
|
|
||||||
[Code]
|
[Code]
|
||||||
const EnvironmentKey = 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment';
|
const EnvironmentKey = 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment';
|
||||||
@ -61,11 +66,17 @@ end;
|
|||||||
procedure CurStepChanged(CurStep: TSetupStep);
|
procedure CurStepChanged(CurStep: TSetupStep);
|
||||||
begin
|
begin
|
||||||
if CurStep = ssPostInstall
|
if CurStep = ssPostInstall
|
||||||
then EnvAddPath(ExpandConstant('{app}') +'\bin');
|
then begin
|
||||||
|
EnvAddPath(ExpandConstant('{app}') +'\bin');
|
||||||
|
EnvAddPath(ExpandConstant('{app}') +'\globals\wapm_packages\.bin');
|
||||||
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
|
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
|
||||||
begin
|
begin
|
||||||
if CurUninstallStep = usPostUninstall
|
if CurUninstallStep = usPostUninstall
|
||||||
then EnvRemovePath(ExpandConstant('{app}') +'\bin');
|
then begin
|
||||||
|
EnvRemovePath(ExpandConstant('{app}') +'\bin');
|
||||||
|
EnvAddPath(ExpandConstant('{app}') +'\globals\wapm_packages\.bin');
|
||||||
|
end
|
||||||
end;
|
end;
|
@ -1,13 +1,6 @@
|
|||||||
use std::panic;
|
use std::panic;
|
||||||
pub use wasmer_runtime::compile_with_config_with;
|
pub use wasmer_runtime::compile_with_config_with;
|
||||||
use wasmer_runtime::{
|
use wasmer_runtime::{self as runtime, error::Result, ImportObject, Instance, Module};
|
||||||
self as runtime,
|
|
||||||
error::{CallResult, Result},
|
|
||||||
ImportObject, Instance, Module,
|
|
||||||
};
|
|
||||||
use wasmer_runtime_core::types::Value;
|
|
||||||
|
|
||||||
use wasmer_emscripten::run_emscripten_instance;
|
|
||||||
|
|
||||||
pub struct ResultObject {
|
pub struct ResultObject {
|
||||||
/// A webassembly::Module object representing the compiled WebAssembly module.
|
/// A webassembly::Module object representing the compiled WebAssembly module.
|
||||||
@ -77,40 +70,3 @@ pub fn compile(buffer_source: &[u8]) -> Result<Module> {
|
|||||||
let module = runtime::compile(buffer_source)?;
|
let module = runtime::compile(buffer_source)?;
|
||||||
Ok(module)
|
Ok(module)
|
||||||
}
|
}
|
||||||
|
|
||||||
// /// The same as `compile` but takes a `CompilerConfig` for the purpose of
|
|
||||||
// /// changing the compiler's behavior
|
|
||||||
// pub fn compile_with_config_with(
|
|
||||||
// buffer_source: &[u8],
|
|
||||||
// compiler_config: CompilerConfig,
|
|
||||||
// ) -> Result<Module> {
|
|
||||||
// let module = runtime::compile_with_config(buffer_source, compiler_config)?;
|
|
||||||
// Ok(module)
|
|
||||||
// }
|
|
||||||
|
|
||||||
/// Performs common instance operations needed when an instance is first run
|
|
||||||
/// including data setup, handling arguments and calling a main function
|
|
||||||
pub fn run_instance(
|
|
||||||
module: &Module,
|
|
||||||
instance: &mut Instance,
|
|
||||||
abi: InstanceABI,
|
|
||||||
path: &str,
|
|
||||||
args: Vec<&str>,
|
|
||||||
) -> CallResult<()> {
|
|
||||||
match abi {
|
|
||||||
InstanceABI::Emscripten => {
|
|
||||||
run_emscripten_instance(module, instance, path, args)?;
|
|
||||||
}
|
|
||||||
InstanceABI::WASI => {
|
|
||||||
instance.call("_start", &[])?;
|
|
||||||
}
|
|
||||||
InstanceABI::None => {
|
|
||||||
let args: Vec<Value> = args
|
|
||||||
.into_iter()
|
|
||||||
.map(|x| Value::I32(x.parse().unwrap()))
|
|
||||||
.collect();
|
|
||||||
instance.call("main", &args)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
1
wapm-cli
Submodule
1
wapm-cli
Submodule
Submodule wapm-cli added at c9399f3fb1
Reference in New Issue
Block a user