mirror of
https://github.com/fluencelabs/wasmer
synced 2025-05-28 01:21:19 +00:00
Merge branch 'master' into feat-interface-types-better-error
This commit is contained in:
commit
03910a51fb
13
CHANGELOG.md
13
CHANGELOG.md
@ -3,6 +3,19 @@
|
|||||||
## **[Unreleased]**
|
## **[Unreleased]**
|
||||||
|
|
||||||
- [#1285](https://github.com/wasmerio/wasmer/pull/1285) Greatly improve errors in `wasmer-interface-types`
|
- [#1285](https://github.com/wasmerio/wasmer/pull/1285) Greatly improve errors in `wasmer-interface-types`
|
||||||
|
- [#1283](https://github.com/wasmerio/wasmer/pull/1283) Workaround for floating point arguments and return values in `DynamicFunc`s.
|
||||||
|
|
||||||
|
## 0.16.2 - 2020-03-11
|
||||||
|
|
||||||
|
- [#1294](https://github.com/wasmerio/wasmer/pull/1294) Fix bug related to system calls in WASI that rely on reading from WasmPtrs as arrays of length 0. `WasmPtr` will now succeed on length 0 arrays again.
|
||||||
|
|
||||||
|
## 0.16.1 - 2020-03-11
|
||||||
|
|
||||||
|
- [#1291](https://github.com/wasmerio/wasmer/pull/1291) Fix installation packaging script to package the `wax` command.
|
||||||
|
|
||||||
|
## 0.16.0 - 2020-03-11
|
||||||
|
|
||||||
|
- [#1286](https://github.com/wasmerio/wasmer/pull/1286) Updated Windows Wasmer icons. Add wax
|
||||||
- [#1284](https://github.com/wasmerio/wasmer/pull/1284) Implement string and memory instructions in `wasmer-interface-types`
|
- [#1284](https://github.com/wasmerio/wasmer/pull/1284) Implement string and memory instructions in `wasmer-interface-types`
|
||||||
- [#1272](https://github.com/wasmerio/wasmer/pull/1272) Fix off-by-one error bug when accessing memory with a `WasmPtr` that contains the last valid byte of memory. Also changes the behavior of `WasmPtr<T, Array>` with a length of 0 and `WasmPtr<T>` where `std::mem::size_of::<T>()` is 0 to always return `None`
|
- [#1272](https://github.com/wasmerio/wasmer/pull/1272) Fix off-by-one error bug when accessing memory with a `WasmPtr` that contains the last valid byte of memory. Also changes the behavior of `WasmPtr<T, Array>` with a length of 0 and `WasmPtr<T>` where `std::mem::size_of::<T>()` is 0 to always return `None`
|
||||||
|
|
||||||
|
38
Cargo.lock
generated
38
Cargo.lock
generated
@ -1820,7 +1820,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer"
|
name = "wasmer"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
@ -1851,7 +1851,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-clif-backend"
|
name = "wasmer-clif-backend"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
@ -1902,14 +1902,14 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-dev-utils"
|
name = "wasmer-dev-utils"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-emscripten"
|
name = "wasmer-emscripten"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"getrandom",
|
"getrandom",
|
||||||
@ -1922,7 +1922,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-emscripten-tests"
|
name = "wasmer-emscripten-tests"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glob 0.3.0",
|
"glob 0.3.0",
|
||||||
"wabt",
|
"wabt",
|
||||||
@ -1936,7 +1936,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-interface-types"
|
name = "wasmer-interface-types"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nom",
|
"nom",
|
||||||
"wast",
|
"wast",
|
||||||
@ -1952,7 +1952,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-llvm-backend"
|
name = "wasmer-llvm-backend"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"cc",
|
"cc",
|
||||||
@ -1983,14 +1983,14 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-middleware-common"
|
name = "wasmer-middleware-common"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wasmer-runtime-core",
|
"wasmer-runtime-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-middleware-common-tests"
|
name = "wasmer-middleware-common-tests"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"criterion",
|
"criterion",
|
||||||
"wabt",
|
"wabt",
|
||||||
@ -2003,7 +2003,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-runtime"
|
name = "wasmer-runtime"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"criterion",
|
"criterion",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
@ -2020,7 +2020,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-runtime-c-api"
|
name = "wasmer-runtime-c-api"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cbindgen",
|
"cbindgen",
|
||||||
"libc",
|
"libc",
|
||||||
@ -2032,7 +2032,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-runtime-core"
|
name = "wasmer-runtime-core"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"blake3",
|
"blake3",
|
||||||
@ -2060,7 +2060,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-runtime-core-tests"
|
name = "wasmer-runtime-core-tests"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wabt",
|
"wabt",
|
||||||
"wasmer-clif-backend",
|
"wasmer-clif-backend",
|
||||||
@ -2071,7 +2071,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-singlepass-backend"
|
name = "wasmer-singlepass-backend"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
@ -2088,7 +2088,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-spectests"
|
name = "wasmer-spectests"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glob 0.3.0",
|
"glob 0.3.0",
|
||||||
"wabt",
|
"wabt",
|
||||||
@ -2100,7 +2100,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-wasi"
|
name = "wasmer-wasi"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
@ -2117,7 +2117,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-wasi-experimental-io-devices"
|
name = "wasmer-wasi-experimental-io-devices"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"minifb",
|
"minifb",
|
||||||
@ -2130,7 +2130,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-wasi-tests"
|
name = "wasmer-wasi-tests"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glob 0.3.0",
|
"glob 0.3.0",
|
||||||
"wasmer-clif-backend",
|
"wasmer-clif-backend",
|
||||||
@ -2143,7 +2143,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-win-exception-handler"
|
name = "wasmer-win-exception-handler"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cmake",
|
"cmake",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer"
|
name = "wasmer"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
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"
|
||||||
|
6
Makefile
6
Makefile
@ -287,7 +287,9 @@ build-install-package:
|
|||||||
mkdir -p ./install/bin
|
mkdir -p ./install/bin
|
||||||
cp ./wapm-cli/target/release/wapm ./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/wapm bin/wasmer
|
# Create the wax binary as symlink to wapm
|
||||||
|
cd ./install/bin/ && ln -sf wapm wax && chmod +x wax
|
||||||
|
tar -C ./install -zcvf wasmer.tar.gz bin
|
||||||
|
|
||||||
UNAME_S := $(shell uname -s)
|
UNAME_S := $(shell uname -s)
|
||||||
|
|
||||||
@ -315,7 +317,7 @@ endif
|
|||||||
cp lib/runtime-c-api/doc/index.md ./capi/README.md
|
cp lib/runtime-c-api/doc/index.md ./capi/README.md
|
||||||
tar -C ./capi -zcvf wasmer-c-api.tar.gz lib include README.md LICENSE
|
tar -C ./capi -zcvf wasmer-c-api.tar.gz lib include README.md LICENSE
|
||||||
|
|
||||||
WAPM_VERSION = 0.4.3
|
WAPM_VERSION = v0.5.0
|
||||||
build-wapm:
|
build-wapm:
|
||||||
git clone --branch $(WAPM_VERSION) https://github.com/wasmerio/wapm-cli.git
|
git clone --branch $(WAPM_VERSION) https://github.com/wasmerio/wapm-cli.git
|
||||||
cargo build --release --manifest-path wapm-cli/Cargo.toml --features "telemetry update-notifications"
|
cargo build --release --manifest-path wapm-cli/Cargo.toml --features "telemetry update-notifications"
|
||||||
|
@ -300,6 +300,7 @@ jobs:
|
|||||||
isDraft: false
|
isDraft: false
|
||||||
isPreRelease: false
|
isPreRelease: false
|
||||||
assets: '$(Build.ArtifactStagingDirectory)/**'
|
assets: '$(Build.ArtifactStagingDirectory)/**'
|
||||||
|
assetUploadMode: 'replace' # Don't delete previously uploaded assets (default)
|
||||||
|
|
||||||
- job: Publish_Docs
|
- job: Publish_Docs
|
||||||
dependsOn:
|
dependsOn:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-clif-backend"
|
name = "wasmer-clif-backend"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
description = "Wasmer runtime Cranelift compiler backend"
|
description = "Wasmer runtime Cranelift compiler backend"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||||
@ -11,7 +11,7 @@ edition = "2018"
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.15.0" }
|
wasmer-runtime-core = { path = "../runtime-core", version = "0.16.2" }
|
||||||
cranelift-native = "0.59.0"
|
cranelift-native = "0.59.0"
|
||||||
cranelift-codegen = "0.59.0"
|
cranelift-codegen = "0.59.0"
|
||||||
cranelift-entity = "0.59.0"
|
cranelift-entity = "0.59.0"
|
||||||
@ -38,7 +38,7 @@ version = "0.0.7"
|
|||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = { version = "0.3", features = ["errhandlingapi", "minwindef", "minwinbase", "winnt"] }
|
winapi = { version = "0.3", features = ["errhandlingapi", "minwindef", "minwinbase", "winnt"] }
|
||||||
wasmer-win-exception-handler = { path = "../win-exception-handler", version = "0.15.0" }
|
wasmer-win-exception-handler = { path = "../win-exception-handler", version = "0.16.2" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
generate-debug-information = ["wasm-debug"]
|
generate-debug-information = ["wasm-debug"]
|
||||||
|
@ -209,7 +209,7 @@ impl ModuleCodeGenerator<CraneliftFunctionCodeGenerator, Caller, CodegenError>
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn feed_import_function(&mut self) -> Result<(), CodegenError> {
|
fn feed_import_function(&mut self, _sigindex: SigIndex) -> Result<(), CodegenError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-dev-utils"
|
name = "wasmer-dev-utils"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
description = "Wasmer runtime core library"
|
description = "Wasmer runtime core library"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-emscripten-tests"
|
name = "wasmer-emscripten-tests"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
description = "Tests for our Emscripten implementation"
|
description = "Tests for our Emscripten implementation"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||||
@ -9,15 +9,15 @@ publish = false
|
|||||||
build = "build/mod.rs"
|
build = "build/mod.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasmer-emscripten = { path = "../emscripten", version = "0.15.0" }
|
wasmer-emscripten = { path = "../emscripten", version = "0.16.2" }
|
||||||
wasmer-runtime = { path = "../runtime", version = "0.15.0", default-features = false }
|
wasmer-runtime = { path = "../runtime", version = "0.16.2", default-features = false }
|
||||||
wasmer-clif-backend = { path = "../clif-backend", version = "0.15.0", optional = true}
|
wasmer-clif-backend = { path = "../clif-backend", version = "0.16.2", optional = true}
|
||||||
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.15.0", optional = true, features = ["test"] }
|
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.16.2", optional = true, features = ["test"] }
|
||||||
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.15.0", optional = true }
|
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.16.2", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
wabt = "0.9.1"
|
wabt = "0.9.1"
|
||||||
wasmer-dev-utils = { path = "../dev-utils", version = "0.15.0"}
|
wasmer-dev-utils = { path = "../dev-utils", version = "0.16.2"}
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
glob = "0.3"
|
glob = "0.3"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-emscripten"
|
name = "wasmer-emscripten"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
description = "Wasmer runtime emscripten implementation library"
|
description = "Wasmer runtime emscripten implementation library"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||||
@ -15,7 +15,7 @@ lazy_static = "1.4"
|
|||||||
libc = "0.2.60"
|
libc = "0.2.60"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.15.0" }
|
wasmer-runtime-core = { path = "../runtime-core", version = "0.16.2" }
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
getrandom = "0.1"
|
getrandom = "0.1"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-interface-types"
|
name = "wasmer-interface-types"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
description = "WebAssembly Interface Types library for Wasmer"
|
description = "WebAssembly Interface Types library for Wasmer"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||||
|
@ -9,8 +9,8 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wabt = "0.9.1"
|
wabt = "0.9.1"
|
||||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.15.0" }
|
wasmer-runtime-core = { path = "../runtime-core", version = "0.16.2" }
|
||||||
wasmer-runtime = { path = "../runtime", version = "0.15.0" }
|
wasmer-runtime = { path = "../runtime", version = "0.16.2" }
|
||||||
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.15.0", features = ["test"] }
|
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.16.2", features = ["test"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-llvm-backend"
|
name = "wasmer-llvm-backend"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||||
repository = "https://github.com/wasmerio/wasmer"
|
repository = "https://github.com/wasmerio/wasmer"
|
||||||
@ -10,7 +10,7 @@ edition = "2018"
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.15.0", features = ["generate-debug-information-no-export-symbols"] }
|
wasmer-runtime-core = { path = "../runtime-core", version = "0.16.2", features = ["generate-debug-information-no-export-symbols"] }
|
||||||
wasmparser = "0.51.3"
|
wasmparser = "0.51.3"
|
||||||
smallvec = "0.6"
|
smallvec = "0.6"
|
||||||
goblin = "0.0.24"
|
goblin = "0.0.24"
|
||||||
|
@ -8984,7 +8984,7 @@ impl<'ctx> ModuleCodeGenerator<LLVMFunctionCodeGenerator<'ctx>, LLVMBackend, Cod
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn feed_import_function(&mut self) -> Result<(), CodegenError> {
|
fn feed_import_function(&mut self, _sigindex: SigIndex) -> Result<(), CodegenError> {
|
||||||
self.func_import_count += 1;
|
self.func_import_count += 1;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-middleware-common-tests"
|
name = "wasmer-middleware-common-tests"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
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"
|
||||||
@ -8,11 +8,11 @@ license = "MIT"
|
|||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.15.0" }
|
wasmer-runtime-core = { path = "../runtime-core", version = "0.16.2" }
|
||||||
wasmer-middleware-common = { path = "../middleware-common", version = "0.15.0" }
|
wasmer-middleware-common = { path = "../middleware-common", version = "0.16.2" }
|
||||||
wasmer-clif-backend = { path = "../clif-backend", version = "0.15.0", optional = true }
|
wasmer-clif-backend = { path = "../clif-backend", version = "0.16.2", optional = true }
|
||||||
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.15.0", features = ["test"], optional = true }
|
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.16.2", features = ["test"], optional = true }
|
||||||
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.15.0", optional = true }
|
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.16.2", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
clif = ["wasmer-clif-backend"]
|
clif = ["wasmer-clif-backend"]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-middleware-common"
|
name = "wasmer-middleware-common"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
repository = "https://github.com/wasmerio/wasmer"
|
repository = "https://github.com/wasmerio/wasmer"
|
||||||
description = "Wasmer runtime common middlewares"
|
description = "Wasmer runtime common middlewares"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
@ -10,4 +10,4 @@ categories = ["wasm"]
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.15.0" }
|
wasmer-runtime-core = { path = "../runtime-core", version = "0.16.2" }
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-runtime-c-api"
|
name = "wasmer-runtime-c-api"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
description = "Wasmer C API library"
|
description = "Wasmer C API library"
|
||||||
documentation = "https://wasmerio.github.io/wasmer/c/runtime-c-api/"
|
documentation = "https://wasmerio.github.io/wasmer/c/runtime-c-api/"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
@ -20,22 +20,22 @@ libc = "0.2.60"
|
|||||||
[dependencies.wasmer-runtime]
|
[dependencies.wasmer-runtime]
|
||||||
default-features = false
|
default-features = false
|
||||||
path = "../runtime"
|
path = "../runtime"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
|
|
||||||
[dependencies.wasmer-runtime-core]
|
[dependencies.wasmer-runtime-core]
|
||||||
default-features = false
|
default-features = false
|
||||||
path = "../runtime-core"
|
path = "../runtime-core"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
|
|
||||||
[dependencies.wasmer-wasi]
|
[dependencies.wasmer-wasi]
|
||||||
default-features = false
|
default-features = false
|
||||||
path = "../wasi"
|
path = "../wasi"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[dependencies.wasmer-emscripten]
|
[dependencies.wasmer-emscripten]
|
||||||
path = "../emscripten"
|
path = "../emscripten"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
@ -34,6 +34,8 @@ pub unsafe extern "C" fn wasmer_trampoline_buffer_builder_add_context_trampoline
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a callinfo trampoline to the builder.
|
/// Adds a callinfo trampoline to the builder.
|
||||||
|
///
|
||||||
|
/// Deprecated. In a future version `DynamicFunc::new` will be exposed to the C API and should be used instead of this function.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
pub unsafe extern "C" fn wasmer_trampoline_buffer_builder_add_callinfo_trampoline(
|
pub unsafe extern "C" fn wasmer_trampoline_buffer_builder_add_callinfo_trampoline(
|
||||||
@ -42,8 +44,14 @@ pub unsafe extern "C" fn wasmer_trampoline_buffer_builder_add_callinfo_trampolin
|
|||||||
ctx: *const c_void,
|
ctx: *const c_void,
|
||||||
num_params: u32,
|
num_params: u32,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
|
use wasmer_runtime_core::types::Type;
|
||||||
let builder = &mut *(builder as *mut TrampolineBufferBuilder);
|
let builder = &mut *(builder as *mut TrampolineBufferBuilder);
|
||||||
builder.add_callinfo_trampoline(mem::transmute(func), ctx as *const CallContext, num_params)
|
builder.add_callinfo_trampoline(
|
||||||
|
mem::transmute(func),
|
||||||
|
ctx as *const CallContext,
|
||||||
|
&vec![Type::I64; num_params as usize],
|
||||||
|
&[Type::I64],
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finalizes the trampoline builder into an executable buffer.
|
/// Finalizes the trampoline builder into an executable buffer.
|
||||||
|
@ -1386,6 +1386,8 @@ wasmer_result_t wasmer_table_new(wasmer_table_t **table, wasmer_limits_t limits)
|
|||||||
#if (!defined(_WIN32) && defined(ARCH_X86_64))
|
#if (!defined(_WIN32) && defined(ARCH_X86_64))
|
||||||
/**
|
/**
|
||||||
* Adds a callinfo trampoline to the builder.
|
* Adds a callinfo trampoline to the builder.
|
||||||
|
*
|
||||||
|
* Deprecated. In a future version `DynamicFunc::new` will be exposed to the C API and should be used instead of this function.
|
||||||
*/
|
*/
|
||||||
uintptr_t wasmer_trampoline_buffer_builder_add_callinfo_trampoline(wasmer_trampoline_buffer_builder_t *builder,
|
uintptr_t wasmer_trampoline_buffer_builder_add_callinfo_trampoline(wasmer_trampoline_buffer_builder_t *builder,
|
||||||
const wasmer_trampoline_callable_t *func,
|
const wasmer_trampoline_callable_t *func,
|
||||||
|
@ -1146,6 +1146,8 @@ wasmer_result_t wasmer_table_new(wasmer_table_t **table, wasmer_limits_t limits)
|
|||||||
|
|
||||||
#if (!defined(_WIN32) && defined(ARCH_X86_64))
|
#if (!defined(_WIN32) && defined(ARCH_X86_64))
|
||||||
/// Adds a callinfo trampoline to the builder.
|
/// Adds a callinfo trampoline to the builder.
|
||||||
|
///
|
||||||
|
/// Deprecated. In a future version `DynamicFunc::new` will be exposed to the C API and should be used instead of this function.
|
||||||
uintptr_t wasmer_trampoline_buffer_builder_add_callinfo_trampoline(wasmer_trampoline_buffer_builder_t *builder,
|
uintptr_t wasmer_trampoline_buffer_builder_add_callinfo_trampoline(wasmer_trampoline_buffer_builder_t *builder,
|
||||||
const wasmer_trampoline_callable_t *func,
|
const wasmer_trampoline_callable_t *func,
|
||||||
const void *ctx,
|
const void *ctx,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-runtime-core-tests"
|
name = "wasmer-runtime-core-tests"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
description = "Tests for the Wasmer runtime core crate"
|
description = "Tests for the Wasmer runtime core crate"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||||
@ -9,10 +9,10 @@ publish = false
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wabt = "0.9.1"
|
wabt = "0.9.1"
|
||||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.15.0" }
|
wasmer-runtime-core = { path = "../runtime-core", version = "0.16.2" }
|
||||||
wasmer-clif-backend = { path = "../clif-backend", version = "0.15.0", optional = true }
|
wasmer-clif-backend = { path = "../clif-backend", version = "0.16.2", optional = true }
|
||||||
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.15.0", optional = true }
|
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.16.2", optional = true }
|
||||||
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.15.0", features = ["test"], optional = true }
|
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.16.2", features = ["test"], optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["backend-cranelift"]
|
default = ["backend-cranelift"]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::sync::Arc;
|
use std::{convert::TryInto, sync::Arc};
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
compile_with,
|
compile_with,
|
||||||
error::RuntimeError,
|
error::RuntimeError,
|
||||||
@ -12,10 +12,11 @@ use wasmer_runtime_core::{
|
|||||||
use wasmer_runtime_core_tests::{get_compiler, wat2wasm};
|
use wasmer_runtime_core_tests::{get_compiler, wat2wasm};
|
||||||
|
|
||||||
macro_rules! call_and_assert {
|
macro_rules! call_and_assert {
|
||||||
($instance:ident, $function:ident, $expected_value:expr) => {
|
($instance:ident, $function:ident( $( $inputs:ty ),* ) -> $output:ty, ( $( $arguments:expr ),* ) == $expected_value:expr) => {
|
||||||
let $function: Func<i32, i32> = $instance.func(stringify!($function)).unwrap();
|
#[allow(unused_parens)]
|
||||||
|
let $function: Func<( $( $inputs ),* ), $output> = $instance.func(stringify!($function)).expect(concat!("Failed to get the `", stringify!($function), "` export function."));
|
||||||
|
|
||||||
let result = $function.call(1);
|
let result = $function.call( $( $arguments ),* );
|
||||||
|
|
||||||
match (result, $expected_value) {
|
match (result, $expected_value) {
|
||||||
(Ok(value), expected_value) => assert_eq!(
|
(Ok(value), expected_value) => assert_eq!(
|
||||||
@ -75,7 +76,12 @@ fn imported_functions_forms(test: &dyn Fn(&Instance)) {
|
|||||||
(import "env" "memory" (memory 1 1))
|
(import "env" "memory" (memory 1 1))
|
||||||
(import "env" "callback_fn" (func $callback_fn (type $type)))
|
(import "env" "callback_fn" (func $callback_fn (type $type)))
|
||||||
(import "env" "callback_closure" (func $callback_closure (type $type)))
|
(import "env" "callback_closure" (func $callback_closure (type $type)))
|
||||||
(import "env" "callback_closure_dynamic" (func $callback_closure_dynamic (type $type)))
|
(import "env" "callback_fn_dynamic" (func $callback_fn_dynamic (type $type)))
|
||||||
|
(import "env" "callback_closure_dynamic_0" (func $callback_closure_dynamic_0))
|
||||||
|
(import "env" "callback_closure_dynamic_1" (func $callback_closure_dynamic_1 (param i32) (result i32)))
|
||||||
|
(import "env" "callback_closure_dynamic_2" (func $callback_closure_dynamic_2 (param i32 i64) (result i64)))
|
||||||
|
(import "env" "callback_closure_dynamic_3" (func $callback_closure_dynamic_3 (param i32 i64 f32) (result f32)))
|
||||||
|
(import "env" "callback_closure_dynamic_4" (func $callback_closure_dynamic_4 (param i32 i64 f32 f64) (result f64)))
|
||||||
(import "env" "callback_closure_with_env" (func $callback_closure_with_env (type $type)))
|
(import "env" "callback_closure_with_env" (func $callback_closure_with_env (type $type)))
|
||||||
(import "env" "callback_fn_with_vmctx" (func $callback_fn_with_vmctx (type $type)))
|
(import "env" "callback_fn_with_vmctx" (func $callback_fn_with_vmctx (type $type)))
|
||||||
(import "env" "callback_closure_with_vmctx" (func $callback_closure_with_vmctx (type $type)))
|
(import "env" "callback_closure_with_vmctx" (func $callback_closure_with_vmctx (type $type)))
|
||||||
@ -94,9 +100,34 @@ fn imported_functions_forms(test: &dyn Fn(&Instance)) {
|
|||||||
get_local 0
|
get_local 0
|
||||||
call $callback_closure)
|
call $callback_closure)
|
||||||
|
|
||||||
(func (export "function_closure_dynamic") (type $type)
|
(func (export "function_fn_dynamic") (type $type)
|
||||||
get_local 0
|
get_local 0
|
||||||
call $callback_closure_dynamic)
|
call $callback_fn_dynamic)
|
||||||
|
|
||||||
|
(func (export "function_closure_dynamic_0")
|
||||||
|
call $callback_closure_dynamic_0)
|
||||||
|
|
||||||
|
(func (export "function_closure_dynamic_1") (param i32) (result i32)
|
||||||
|
get_local 0
|
||||||
|
call $callback_closure_dynamic_1)
|
||||||
|
|
||||||
|
(func (export "function_closure_dynamic_2") (param i32 i64) (result i64)
|
||||||
|
get_local 0
|
||||||
|
get_local 1
|
||||||
|
call $callback_closure_dynamic_2)
|
||||||
|
|
||||||
|
(func (export "function_closure_dynamic_3") (param i32 i64 f32) (result f32)
|
||||||
|
get_local 0
|
||||||
|
get_local 1
|
||||||
|
get_local 2
|
||||||
|
call $callback_closure_dynamic_3)
|
||||||
|
|
||||||
|
(func (export "function_closure_dynamic_4") (param i32 i64 f32 f64) (result f64)
|
||||||
|
get_local 0
|
||||||
|
get_local 1
|
||||||
|
get_local 2
|
||||||
|
get_local 3
|
||||||
|
call $callback_closure_dynamic_4)
|
||||||
|
|
||||||
(func (export "function_closure_with_env") (type $type)
|
(func (export "function_closure_with_env") (type $type)
|
||||||
get_local 0
|
get_local 0
|
||||||
@ -154,13 +185,73 @@ fn imported_functions_forms(test: &dyn Fn(&Instance)) {
|
|||||||
Ok(n + 1)
|
Ok(n + 1)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
"callback_closure_dynamic" => DynamicFunc::new(
|
// Regular polymorphic function.
|
||||||
|
"callback_fn_dynamic" => DynamicFunc::new(
|
||||||
Arc::new(FuncSig::new(vec![Type::I32], vec![Type::I32])),
|
Arc::new(FuncSig::new(vec![Type::I32], vec![Type::I32])),
|
||||||
|_, params| -> Vec<Value> {
|
callback_fn_dynamic,
|
||||||
match params[0] {
|
),
|
||||||
Value::I32(x) => vec![Value::I32(x + 1)],
|
|
||||||
_ => unreachable!()
|
// Polymorphic closure “closures”.
|
||||||
|
"callback_closure_dynamic_0" => DynamicFunc::new(
|
||||||
|
Arc::new(FuncSig::new(vec![], vec![])),
|
||||||
|
|_, inputs: &[Value]| -> Vec<Value> {
|
||||||
|
assert!(inputs.is_empty());
|
||||||
|
|
||||||
|
vec![]
|
||||||
}
|
}
|
||||||
|
),
|
||||||
|
"callback_closure_dynamic_1" => DynamicFunc::new(
|
||||||
|
Arc::new(FuncSig::new(vec![Type::I32], vec![Type::I32])),
|
||||||
|
move |vmctx: &mut vm::Ctx, inputs: &[Value]| -> Vec<Value> {
|
||||||
|
assert_eq!(inputs.len(), 1);
|
||||||
|
|
||||||
|
let memory = vmctx.memory(0);
|
||||||
|
let shift_ = shift + memory.view::<i32>()[0].get();
|
||||||
|
let n: i32 = (&inputs[0]).try_into().unwrap();
|
||||||
|
|
||||||
|
vec![Value::I32(shift_ + n)]
|
||||||
|
}
|
||||||
|
),
|
||||||
|
"callback_closure_dynamic_2" => DynamicFunc::new(
|
||||||
|
Arc::new(FuncSig::new(vec![Type::I32, Type::I64], vec![Type::I64])),
|
||||||
|
move |vmctx: &mut vm::Ctx, inputs: &[Value]| -> Vec<Value> {
|
||||||
|
assert_eq!(inputs.len(), 2);
|
||||||
|
|
||||||
|
let memory = vmctx.memory(0);
|
||||||
|
let shift_ = shift + memory.view::<i32>()[0].get();
|
||||||
|
let i: i32 = (&inputs[0]).try_into().unwrap();
|
||||||
|
let j: i64 = (&inputs[1]).try_into().unwrap();
|
||||||
|
|
||||||
|
vec![Value::I64(shift_ as i64 + i as i64 + j)]
|
||||||
|
}
|
||||||
|
),
|
||||||
|
"callback_closure_dynamic_3" => DynamicFunc::new(
|
||||||
|
Arc::new(FuncSig::new(vec![Type::I32, Type::I64, Type::F32], vec![Type::F32])),
|
||||||
|
move |vmctx: &mut vm::Ctx, inputs: &[Value]| -> Vec<Value> {
|
||||||
|
assert_eq!(inputs.len(), 3);
|
||||||
|
|
||||||
|
let memory = vmctx.memory(0);
|
||||||
|
let shift_ = shift + memory.view::<i32>()[0].get();
|
||||||
|
let i: i32 = (&inputs[0]).try_into().unwrap();
|
||||||
|
let j: i64 = (&inputs[1]).try_into().unwrap();
|
||||||
|
let k: f32 = (&inputs[2]).try_into().unwrap();
|
||||||
|
|
||||||
|
vec![Value::F32(shift_ as f32 + i as f32 + j as f32 + k)]
|
||||||
|
}
|
||||||
|
),
|
||||||
|
"callback_closure_dynamic_4" => DynamicFunc::new(
|
||||||
|
Arc::new(FuncSig::new(vec![Type::I32, Type::I64, Type::F32, Type::F64], vec![Type::F64])),
|
||||||
|
move |vmctx: &mut vm::Ctx, inputs: &[Value]| -> Vec<Value> {
|
||||||
|
assert_eq!(inputs.len(), 4);
|
||||||
|
|
||||||
|
let memory = vmctx.memory(0);
|
||||||
|
let shift_ = shift + memory.view::<i32>()[0].get();
|
||||||
|
let i: i32 = (&inputs[0]).try_into().unwrap();
|
||||||
|
let j: i64 = (&inputs[1]).try_into().unwrap();
|
||||||
|
let k: f32 = (&inputs[2]).try_into().unwrap();
|
||||||
|
let l: f64 = (&inputs[3]).try_into().unwrap();
|
||||||
|
|
||||||
|
vec![Value::F64(shift_ as f64 + i as f64 + j as f64 + k as f64 + l)]
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -227,6 +318,13 @@ fn callback_fn(n: i32) -> Result<i32, ()> {
|
|||||||
Ok(n + 1)
|
Ok(n + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn callback_fn_dynamic(_: &mut vm::Ctx, inputs: &[Value]) -> Vec<Value> {
|
||||||
|
match inputs[0] {
|
||||||
|
Value::I32(x) => vec![Value::I32(x + 1)],
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn callback_fn_with_vmctx(vmctx: &mut vm::Ctx, n: i32) -> Result<i32, ()> {
|
fn callback_fn_with_vmctx(vmctx: &mut vm::Ctx, n: i32) -> Result<i32, ()> {
|
||||||
let memory = vmctx.memory(0);
|
let memory = vmctx.memory(0);
|
||||||
let shift_: i32 = memory.view()[0].get();
|
let shift_: i32 = memory.view()[0].get();
|
||||||
@ -246,57 +344,82 @@ fn callback_fn_trap_with_vmctx(vmctx: &mut vm::Ctx, n: i32) -> Result<i32, Strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! test {
|
macro_rules! test {
|
||||||
($test_name:ident, $function:ident, $expected_value:expr) => {
|
($test_name:ident, $function:ident( $( $inputs:ty ),* ) -> $output:ty, ( $( $arguments:expr ),* ) == $expected_value:expr) => {
|
||||||
#[test]
|
#[test]
|
||||||
fn $test_name() {
|
fn $test_name() {
|
||||||
imported_functions_forms(&|instance| {
|
imported_functions_forms(&|instance| {
|
||||||
call_and_assert!(instance, $function, $expected_value);
|
call_and_assert!(instance, $function( $( $inputs ),* ) -> $output, ( $( $arguments ),* ) == $expected_value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
test!(test_fn, function_fn, Ok(2));
|
test!(test_fn, function_fn(i32) -> i32, (1) == Ok(2));
|
||||||
test!(test_closure, function_closure, Ok(2));
|
test!(test_closure, function_closure(i32) -> i32, (1) == Ok(2));
|
||||||
test!(test_closure_dynamic, function_closure_dynamic, Ok(2));
|
test!(test_fn_dynamic, function_fn_dynamic(i32) -> i32, (1) == Ok(2));
|
||||||
|
test!(
|
||||||
|
test_closure_dynamic_0,
|
||||||
|
function_closure_dynamic_0(()) -> (),
|
||||||
|
() == Ok(())
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
test_closure_dynamic_1,
|
||||||
|
function_closure_dynamic_1(i32) -> i32,
|
||||||
|
(1) == Ok(1 + shift + SHIFT)
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
test_closure_dynamic_2,
|
||||||
|
function_closure_dynamic_2(i32, i64) -> i64,
|
||||||
|
(1, 2) == Ok(1 + 2 + shift as i64 + SHIFT as i64)
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
test_closure_dynamic_3,
|
||||||
|
function_closure_dynamic_3(i32, i64, f32) -> f32,
|
||||||
|
(1, 2, 3.) == Ok(1. + 2. + 3. + shift as f32 + SHIFT as f32)
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
test_closure_dynamic_4,
|
||||||
|
function_closure_dynamic_4(i32, i64, f32, f64) -> f64,
|
||||||
|
(1, 2, 3., 4.) == Ok(1. + 2. + 3. + 4. + shift as f64 + SHIFT as f64)
|
||||||
|
);
|
||||||
test!(
|
test!(
|
||||||
test_closure_with_env,
|
test_closure_with_env,
|
||||||
function_closure_with_env,
|
function_closure_with_env(i32) -> i32,
|
||||||
Ok(2 + shift + SHIFT)
|
(1) == Ok(2 + shift + SHIFT)
|
||||||
);
|
);
|
||||||
test!(test_fn_with_vmctx, function_fn_with_vmctx, Ok(2 + SHIFT));
|
test!(test_fn_with_vmctx, function_fn_with_vmctx(i32) -> i32, (1) == Ok(2 + SHIFT));
|
||||||
test!(
|
test!(
|
||||||
test_closure_with_vmctx,
|
test_closure_with_vmctx,
|
||||||
function_closure_with_vmctx,
|
function_closure_with_vmctx(i32) -> i32,
|
||||||
Ok(2 + SHIFT)
|
(1) == Ok(2 + SHIFT)
|
||||||
);
|
);
|
||||||
test!(
|
test!(
|
||||||
test_closure_with_vmctx_and_env,
|
test_closure_with_vmctx_and_env,
|
||||||
function_closure_with_vmctx_and_env,
|
function_closure_with_vmctx_and_env(i32) -> i32,
|
||||||
Ok(2 + shift + SHIFT)
|
(1) == Ok(2 + shift + SHIFT)
|
||||||
);
|
);
|
||||||
test!(
|
test!(
|
||||||
test_fn_trap,
|
test_fn_trap,
|
||||||
function_fn_trap,
|
function_fn_trap(i32) -> i32,
|
||||||
Err(RuntimeError(Box::new(format!("foo {}", 2))))
|
(1) == Err(RuntimeError(Box::new(format!("foo {}", 2))))
|
||||||
);
|
);
|
||||||
test!(
|
test!(
|
||||||
test_closure_trap,
|
test_closure_trap,
|
||||||
function_closure_trap,
|
function_closure_trap(i32) -> i32,
|
||||||
Err(RuntimeError(Box::new(format!("bar {}", 2))))
|
(1) == Err(RuntimeError(Box::new(format!("bar {}", 2))))
|
||||||
);
|
);
|
||||||
test!(
|
test!(
|
||||||
test_fn_trap_with_vmctx,
|
test_fn_trap_with_vmctx,
|
||||||
function_fn_trap_with_vmctx,
|
function_fn_trap_with_vmctx(i32) -> i32,
|
||||||
Err(RuntimeError(Box::new(format!("baz {}", 2 + SHIFT))))
|
(1) == Err(RuntimeError(Box::new(format!("baz {}", 2 + SHIFT))))
|
||||||
);
|
);
|
||||||
test!(
|
test!(
|
||||||
test_closure_trap_with_vmctx,
|
test_closure_trap_with_vmctx,
|
||||||
function_closure_trap_with_vmctx,
|
function_closure_trap_with_vmctx(i32) -> i32,
|
||||||
Err(RuntimeError(Box::new(format!("qux {}", 2 + SHIFT))))
|
(1) == Err(RuntimeError(Box::new(format!("qux {}", 2 + SHIFT))))
|
||||||
);
|
);
|
||||||
test!(
|
test!(
|
||||||
test_closure_trap_with_vmctx_and_env,
|
test_closure_trap_with_vmctx_and_env,
|
||||||
function_closure_trap_with_vmctx_and_env,
|
function_closure_trap_with_vmctx_and_env(i32) -> i32,
|
||||||
Err(RuntimeError(Box::new(format!("! {}", 2 + shift + SHIFT))))
|
(1) == Err(RuntimeError(Box::new(format!("! {}", 2 + shift + SHIFT))))
|
||||||
);
|
);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-runtime-core"
|
name = "wasmer-runtime-core"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
description = "Wasmer runtime core library"
|
description = "Wasmer runtime core library"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||||
@ -59,3 +59,5 @@ generate-debug-information = ["wasm-debug"]
|
|||||||
# don't export symbols related to the GDB JIT interafce, LLVM or some other native
|
# don't export symbols related to the GDB JIT interafce, LLVM or some other native
|
||||||
# code will be providing them
|
# code will be providing them
|
||||||
generate-debug-information-no-export-symbols = []
|
generate-debug-information-no-export-symbols = []
|
||||||
|
# enable DynamicFunc's for closures with captured environment.
|
||||||
|
dynamicfunc-fat-closures = []
|
||||||
|
@ -143,7 +143,7 @@ pub trait ModuleCodeGenerator<FCG: FunctionCodeGenerator<E>, RM: RunnableModule,
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
/// Adds an import function.
|
/// Adds an import function.
|
||||||
fn feed_import_function(&mut self) -> Result<(), E>;
|
fn feed_import_function(&mut self, _sigindex: SigIndex) -> Result<(), E>;
|
||||||
/// Sets the signatures.
|
/// Sets the signatures.
|
||||||
fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), E>;
|
fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), E>;
|
||||||
/// Sets function signatures.
|
/// Sets function signatures.
|
||||||
|
@ -130,9 +130,10 @@ impl<T: Copy + ValueType> WasmPtr<T, Array> {
|
|||||||
// for any index, we will always result an aligned memory access
|
// for any index, we will always result an aligned memory access
|
||||||
let item_size = mem::size_of::<T>() + (mem::size_of::<T>() % mem::align_of::<T>());
|
let item_size = mem::size_of::<T>() + (mem::size_of::<T>() % mem::align_of::<T>());
|
||||||
let slice_full_len = index as usize + length as usize;
|
let slice_full_len = index as usize + length as usize;
|
||||||
|
let memory_size = memory.size().bytes().0;
|
||||||
|
|
||||||
if (self.offset as usize) + (item_size * slice_full_len) > memory.size().bytes().0
|
if (self.offset as usize) + (item_size * slice_full_len) > memory_size
|
||||||
|| length == 0
|
|| self.offset as usize >= memory_size
|
||||||
|| mem::size_of::<T>() == 0
|
|| mem::size_of::<T>() == 0
|
||||||
{
|
{
|
||||||
return None;
|
return None;
|
||||||
@ -167,9 +168,10 @@ impl<T: Copy + ValueType> WasmPtr<T, Array> {
|
|||||||
// for any index, we will always result an aligned memory access
|
// for any index, we will always result an aligned memory access
|
||||||
let item_size = mem::size_of::<T>() + (mem::size_of::<T>() % mem::align_of::<T>());
|
let item_size = mem::size_of::<T>() + (mem::size_of::<T>() % mem::align_of::<T>());
|
||||||
let slice_full_len = index as usize + length as usize;
|
let slice_full_len = index as usize + length as usize;
|
||||||
|
let memory_size = memory.size().bytes().0;
|
||||||
|
|
||||||
if (self.offset as usize) + (item_size * slice_full_len) > memory.size().bytes().0
|
if (self.offset as usize) + (item_size * slice_full_len) > memory.size().bytes().0
|
||||||
|| length == 0
|
|| self.offset as usize >= memory_size
|
||||||
|| mem::size_of::<T>() == 0
|
|| mem::size_of::<T>() == 0
|
||||||
{
|
{
|
||||||
return None;
|
return None;
|
||||||
@ -190,7 +192,11 @@ impl<T: Copy + ValueType> WasmPtr<T, Array> {
|
|||||||
/// underlying data can be mutated if the Wasm is allowed to execute or
|
/// underlying data can be mutated if the Wasm is allowed to execute or
|
||||||
/// an aliasing `WasmPtr` is used to mutate memory.
|
/// an aliasing `WasmPtr` is used to mutate memory.
|
||||||
pub fn get_utf8_string(self, memory: &Memory, str_len: u32) -> Option<&str> {
|
pub fn get_utf8_string(self, memory: &Memory, str_len: u32) -> Option<&str> {
|
||||||
if self.offset as usize + str_len as usize > memory.size().bytes().0 || str_len == 0 {
|
let memory_size = memory.size().bytes().0;
|
||||||
|
|
||||||
|
if self.offset as usize + str_len as usize > memory.size().bytes().0
|
||||||
|
|| self.offset as usize >= memory_size
|
||||||
|
{
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let ptr = unsafe { memory.view::<u8>().as_ptr().add(self.offset as usize) as *const u8 };
|
let ptr = unsafe { memory.view::<u8>().as_ptr().add(self.offset as usize) as *const u8 };
|
||||||
@ -271,15 +277,15 @@ mod test {
|
|||||||
memory::MemoryDescriptor::new(Pages(1), Some(Pages(1)), false).unwrap();
|
memory::MemoryDescriptor::new(Pages(1), Some(Pages(1)), false).unwrap();
|
||||||
let memory = memory::Memory::new(memory_descriptor).unwrap();
|
let memory = memory::Memory::new(memory_descriptor).unwrap();
|
||||||
|
|
||||||
// test that basic access works and that len = 0 is caught correctly
|
// test that basic access works and that len = 0 works, but oob does not
|
||||||
let start_wasm_ptr: WasmPtr<u8> = WasmPtr::new(0);
|
let start_wasm_ptr: WasmPtr<u8> = WasmPtr::new(0);
|
||||||
let start_wasm_ptr_array: WasmPtr<u8, Array> = WasmPtr::new(0);
|
let start_wasm_ptr_array: WasmPtr<u8, Array> = WasmPtr::new(0);
|
||||||
|
|
||||||
assert!(start_wasm_ptr.deref(&memory).is_some());
|
assert!(start_wasm_ptr.deref(&memory).is_some());
|
||||||
assert!(unsafe { start_wasm_ptr.deref_mut(&memory).is_some() });
|
assert!(unsafe { start_wasm_ptr.deref_mut(&memory).is_some() });
|
||||||
assert!(start_wasm_ptr_array.deref(&memory, 0, 0).is_none());
|
assert!(start_wasm_ptr_array.deref(&memory, 0, 0).is_some());
|
||||||
assert!(start_wasm_ptr_array.get_utf8_string(&memory, 0).is_none());
|
assert!(start_wasm_ptr_array.get_utf8_string(&memory, 0).is_some());
|
||||||
assert!(unsafe { start_wasm_ptr_array.deref_mut(&memory, 0, 0).is_none() });
|
assert!(unsafe { start_wasm_ptr_array.deref_mut(&memory, 0, 0).is_some() });
|
||||||
assert!(start_wasm_ptr_array.deref(&memory, 0, 1).is_some());
|
assert!(start_wasm_ptr_array.deref(&memory, 0, 1).is_some());
|
||||||
assert!(unsafe { start_wasm_ptr_array.deref_mut(&memory, 0, 1).is_some() });
|
assert!(unsafe { start_wasm_ptr_array.deref_mut(&memory, 0, 1).is_some() });
|
||||||
|
|
||||||
@ -293,7 +299,8 @@ mod test {
|
|||||||
|
|
||||||
assert!(end_wasm_ptr_array.deref(&memory, 0, 1).is_some());
|
assert!(end_wasm_ptr_array.deref(&memory, 0, 1).is_some());
|
||||||
assert!(unsafe { end_wasm_ptr_array.deref_mut(&memory, 0, 1).is_some() });
|
assert!(unsafe { end_wasm_ptr_array.deref_mut(&memory, 0, 1).is_some() });
|
||||||
let invalid_idx_len_combos: [(u32, u32); 3] = [(0, 0), (0, 2), (1, 1)];
|
let invalid_idx_len_combos: [(u32, u32); 3] =
|
||||||
|
[(last_valid_address_for_u8 + 1, 0), (0, 2), (1, 1)];
|
||||||
for &(idx, len) in invalid_idx_len_combos.into_iter() {
|
for &(idx, len) in invalid_idx_len_combos.into_iter() {
|
||||||
assert!(end_wasm_ptr_array.deref(&memory, idx, len).is_none());
|
assert!(end_wasm_ptr_array.deref(&memory, idx, len).is_none());
|
||||||
assert!(unsafe { end_wasm_ptr_array.deref_mut(&memory, idx, len).is_none() });
|
assert!(unsafe { end_wasm_ptr_array.deref_mut(&memory, idx, len).is_none() });
|
||||||
@ -323,7 +330,8 @@ mod test {
|
|||||||
assert!(end_wasm_ptr_array.deref(&memory, 0, 1).is_some());
|
assert!(end_wasm_ptr_array.deref(&memory, 0, 1).is_some());
|
||||||
assert!(unsafe { end_wasm_ptr_array.deref_mut(&memory, 0, 1).is_some() });
|
assert!(unsafe { end_wasm_ptr_array.deref_mut(&memory, 0, 1).is_some() });
|
||||||
|
|
||||||
let invalid_idx_len_combos: [(u32, u32); 4] = [(0, 0), (1, 0), (0, 2), (1, 1)];
|
let invalid_idx_len_combos: [(u32, u32); 3] =
|
||||||
|
[(last_valid_address_for_u32 + 1, 0), (0, 2), (1, 1)];
|
||||||
for &(idx, len) in invalid_idx_len_combos.into_iter() {
|
for &(idx, len) in invalid_idx_len_combos.into_iter() {
|
||||||
assert!(end_wasm_ptr_array.deref(&memory, idx, len).is_none());
|
assert!(end_wasm_ptr_array.deref(&memory, idx, len).is_none());
|
||||||
assert!(unsafe { end_wasm_ptr_array.deref_mut(&memory, idx, len).is_none() });
|
assert!(unsafe { end_wasm_ptr_array.deref_mut(&memory, idx, len).is_none() });
|
||||||
@ -339,8 +347,6 @@ mod test {
|
|||||||
for oob_end_array_ptr in end_wasm_ptr_array_oob_array.into_iter() {
|
for oob_end_array_ptr in end_wasm_ptr_array_oob_array.into_iter() {
|
||||||
assert!(oob_end_array_ptr.deref(&memory, 0, 1).is_none());
|
assert!(oob_end_array_ptr.deref(&memory, 0, 1).is_none());
|
||||||
assert!(unsafe { oob_end_array_ptr.deref_mut(&memory, 0, 1).is_none() });
|
assert!(unsafe { oob_end_array_ptr.deref_mut(&memory, 0, 1).is_none() });
|
||||||
assert!(oob_end_array_ptr.deref(&memory, 0, 0).is_none());
|
|
||||||
assert!(unsafe { oob_end_array_ptr.deref_mut(&memory, 0, 0).is_none() });
|
|
||||||
assert!(oob_end_array_ptr.deref(&memory, 1, 0).is_none());
|
assert!(oob_end_array_ptr.deref(&memory, 1, 0).is_none());
|
||||||
assert!(unsafe { oob_end_array_ptr.deref_mut(&memory, 1, 0).is_none() });
|
assert!(unsafe { oob_end_array_ptr.deref_mut(&memory, 1, 0).is_none() });
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,8 @@ use crate::{
|
|||||||
backend::{CompilerConfig, RunnableModule},
|
backend::{CompilerConfig, RunnableModule},
|
||||||
error::CompileError,
|
error::CompileError,
|
||||||
module::{
|
module::{
|
||||||
DataInitializer, ExportIndex, ImportName, ModuleInfo, StringTable, StringTableBuilder,
|
DataInitializer, ExportIndex, ImportName, ModuleInfo, NameIndex, NamespaceIndex,
|
||||||
TableInitializer,
|
StringTable, StringTableBuilder, TableInitializer,
|
||||||
},
|
},
|
||||||
structures::{Map, TypedIndex},
|
structures::{Map, TypedIndex},
|
||||||
types::{
|
types::{
|
||||||
@ -110,11 +110,36 @@ pub fn read_module<
|
|||||||
let mut namespace_builder = Some(StringTableBuilder::new());
|
let mut namespace_builder = Some(StringTableBuilder::new());
|
||||||
let mut name_builder = Some(StringTableBuilder::new());
|
let mut name_builder = Some(StringTableBuilder::new());
|
||||||
let mut func_count: usize = 0;
|
let mut func_count: usize = 0;
|
||||||
let mut mcg_info_fed = false;
|
|
||||||
|
let mut feed_mcg_signatures: Option<_> = Some(|mcg: &mut MCG| -> Result<(), LoadError> {
|
||||||
|
let info_read = info.read().unwrap();
|
||||||
|
mcg.feed_signatures(info_read.signatures.clone())
|
||||||
|
.map_err(|x| LoadError::Codegen(format!("{:?}", x)))?;
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
let mut feed_mcg_info: Option<_> = Some(
|
||||||
|
|mcg: &mut MCG,
|
||||||
|
ns_builder: StringTableBuilder<NamespaceIndex>,
|
||||||
|
name_builder: StringTableBuilder<NameIndex>|
|
||||||
|
-> Result<(), LoadError> {
|
||||||
|
{
|
||||||
|
let mut info_write = info.write().unwrap();
|
||||||
|
info_write.namespace_table = ns_builder.finish();
|
||||||
|
info_write.name_table = name_builder.finish();
|
||||||
|
}
|
||||||
|
let info_read = info.read().unwrap();
|
||||||
|
mcg.feed_function_signatures(info_read.func_assoc.clone())
|
||||||
|
.map_err(|x| LoadError::Codegen(format!("{:?}", x)))?;
|
||||||
|
mcg.check_precondition(&info_read)
|
||||||
|
.map_err(|x| LoadError::Codegen(format!("{:?}", x)))?;
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
use wasmparser::ParserState;
|
use wasmparser::ParserState;
|
||||||
let state = parser.read();
|
let state = parser.read();
|
||||||
|
|
||||||
match *state {
|
match *state {
|
||||||
ParserState::Error(ref err) => return Err(err.clone().into()),
|
ParserState::Error(ref err) => return Err(err.clone().into()),
|
||||||
ParserState::TypeSectionEntry(ref ty) => {
|
ParserState::TypeSectionEntry(ref ty) => {
|
||||||
@ -124,6 +149,10 @@ pub fn read_module<
|
|||||||
.push(func_type_to_func_sig(ty)?);
|
.push(func_type_to_func_sig(ty)?);
|
||||||
}
|
}
|
||||||
ParserState::ImportSectionEntry { module, field, ty } => {
|
ParserState::ImportSectionEntry { module, field, ty } => {
|
||||||
|
if let Some(f) = feed_mcg_signatures.take() {
|
||||||
|
f(mcg)?;
|
||||||
|
}
|
||||||
|
|
||||||
let namespace_index = namespace_builder.as_mut().unwrap().register(module);
|
let namespace_index = namespace_builder.as_mut().unwrap().register(module);
|
||||||
let name_index = name_builder.as_mut().unwrap().register(field);
|
let name_index = name_builder.as_mut().unwrap().register(field);
|
||||||
let import_name = ImportName {
|
let import_name = ImportName {
|
||||||
@ -136,7 +165,7 @@ pub fn read_module<
|
|||||||
let sigindex = SigIndex::new(sigindex as usize);
|
let sigindex = SigIndex::new(sigindex as usize);
|
||||||
info.write().unwrap().imported_functions.push(import_name);
|
info.write().unwrap().imported_functions.push(import_name);
|
||||||
info.write().unwrap().func_assoc.push(sigindex);
|
info.write().unwrap().func_assoc.push(sigindex);
|
||||||
mcg.feed_import_function()
|
mcg.feed_import_function(sigindex)
|
||||||
.map_err(|x| LoadError::Codegen(format!("{:?}", x)))?;
|
.map_err(|x| LoadError::Codegen(format!("{:?}", x)))?;
|
||||||
}
|
}
|
||||||
ImportSectionEntryType::Table(table_ty) => {
|
ImportSectionEntryType::Table(table_ty) => {
|
||||||
@ -217,23 +246,17 @@ pub fn read_module<
|
|||||||
info.write().unwrap().start_func = Some(FuncIndex::new(start_index as usize));
|
info.write().unwrap().start_func = Some(FuncIndex::new(start_index as usize));
|
||||||
}
|
}
|
||||||
ParserState::BeginFunctionBody { range } => {
|
ParserState::BeginFunctionBody { range } => {
|
||||||
|
if let Some(f) = feed_mcg_signatures.take() {
|
||||||
|
f(mcg)?;
|
||||||
|
}
|
||||||
|
if let Some(f) = feed_mcg_info.take() {
|
||||||
|
f(
|
||||||
|
mcg,
|
||||||
|
namespace_builder.take().unwrap(),
|
||||||
|
name_builder.take().unwrap(),
|
||||||
|
)?;
|
||||||
|
}
|
||||||
let id = func_count;
|
let id = func_count;
|
||||||
if !mcg_info_fed {
|
|
||||||
mcg_info_fed = true;
|
|
||||||
{
|
|
||||||
let mut info_write = info.write().unwrap();
|
|
||||||
info_write.namespace_table = namespace_builder.take().unwrap().finish();
|
|
||||||
info_write.name_table = name_builder.take().unwrap().finish();
|
|
||||||
}
|
|
||||||
let info_read = info.read().unwrap();
|
|
||||||
mcg.feed_signatures(info_read.signatures.clone())
|
|
||||||
.map_err(|x| LoadError::Codegen(format!("{:?}", x)))?;
|
|
||||||
mcg.feed_function_signatures(info_read.func_assoc.clone())
|
|
||||||
.map_err(|x| LoadError::Codegen(format!("{:?}", x)))?;
|
|
||||||
mcg.check_precondition(&info_read)
|
|
||||||
.map_err(|x| LoadError::Codegen(format!("{:?}", x)))?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let fcg = mcg
|
let fcg = mcg
|
||||||
.next_function(
|
.next_function(
|
||||||
Arc::clone(&info),
|
Arc::clone(&info),
|
||||||
@ -432,17 +455,15 @@ pub fn read_module<
|
|||||||
info.write().unwrap().globals.push(global_init);
|
info.write().unwrap().globals.push(global_init);
|
||||||
}
|
}
|
||||||
ParserState::EndWasm => {
|
ParserState::EndWasm => {
|
||||||
// TODO Consolidate with BeginFunction body if possible
|
if let Some(f) = feed_mcg_signatures.take() {
|
||||||
if !mcg_info_fed {
|
f(mcg)?;
|
||||||
info.write().unwrap().namespace_table =
|
}
|
||||||
namespace_builder.take().unwrap().finish();
|
if let Some(f) = feed_mcg_info.take() {
|
||||||
info.write().unwrap().name_table = name_builder.take().unwrap().finish();
|
f(
|
||||||
mcg.feed_signatures(info.read().unwrap().signatures.clone())
|
mcg,
|
||||||
.map_err(|x| LoadError::Codegen(format!("{:?}", x)))?;
|
namespace_builder.take().unwrap(),
|
||||||
mcg.feed_function_signatures(info.read().unwrap().func_assoc.clone())
|
name_builder.take().unwrap(),
|
||||||
.map_err(|x| LoadError::Codegen(format!("{:?}", x)))?;
|
)?;
|
||||||
mcg.check_precondition(&info.read().unwrap())
|
|
||||||
.map_err(|x| LoadError::Codegen(format!("{:?}", x)))?;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -480,10 +480,11 @@ impl InstanceImage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Declarations for x86-64 registers.
|
/// X64-specific structures and methods that do not depend on an x64 machine to run.
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub mod x64_decl {
|
pub mod x64_decl {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::types::Type;
|
||||||
|
|
||||||
/// General-purpose registers.
|
/// General-purpose registers.
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
@ -610,9 +611,88 @@ pub mod x64_decl {
|
|||||||
_ => return None,
|
_ => return None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the instruction prefix for `movq %this_reg, ?(%rsp)`.
|
||||||
|
///
|
||||||
|
/// To build an instruction, append the memory location as a 32-bit
|
||||||
|
/// offset to the stack pointer to this prefix.
|
||||||
|
pub fn prefix_mov_to_stack(&self) -> Option<&'static [u8]> {
|
||||||
|
Some(match *self {
|
||||||
|
X64Register::GPR(gpr) => match gpr {
|
||||||
|
GPR::RDI => &[0x48, 0x89, 0xbc, 0x24],
|
||||||
|
GPR::RSI => &[0x48, 0x89, 0xb4, 0x24],
|
||||||
|
GPR::RDX => &[0x48, 0x89, 0x94, 0x24],
|
||||||
|
GPR::RCX => &[0x48, 0x89, 0x8c, 0x24],
|
||||||
|
GPR::R8 => &[0x4c, 0x89, 0x84, 0x24],
|
||||||
|
GPR::R9 => &[0x4c, 0x89, 0x8c, 0x24],
|
||||||
|
_ => return None,
|
||||||
|
},
|
||||||
|
X64Register::XMM(xmm) => match xmm {
|
||||||
|
XMM::XMM0 => &[0x66, 0x0f, 0xd6, 0x84, 0x24],
|
||||||
|
XMM::XMM1 => &[0x66, 0x0f, 0xd6, 0x8c, 0x24],
|
||||||
|
XMM::XMM2 => &[0x66, 0x0f, 0xd6, 0x94, 0x24],
|
||||||
|
XMM::XMM3 => &[0x66, 0x0f, 0xd6, 0x9c, 0x24],
|
||||||
|
XMM::XMM4 => &[0x66, 0x0f, 0xd6, 0xa4, 0x24],
|
||||||
|
XMM::XMM5 => &[0x66, 0x0f, 0xd6, 0xac, 0x24],
|
||||||
|
XMM::XMM6 => &[0x66, 0x0f, 0xd6, 0xb4, 0x24],
|
||||||
|
XMM::XMM7 => &[0x66, 0x0f, 0xd6, 0xbc, 0x24],
|
||||||
|
_ => return None,
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An allocator that allocates registers for function arguments according to the System V ABI.
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct ArgumentRegisterAllocator {
|
||||||
|
n_gprs: usize,
|
||||||
|
n_xmms: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ArgumentRegisterAllocator {
|
||||||
|
/// Allocates a register for argument type `ty`. Returns `None` if no register is available for this type.
|
||||||
|
pub fn next(&mut self, ty: Type) -> Option<X64Register> {
|
||||||
|
static GPR_SEQ: &'static [GPR] =
|
||||||
|
&[GPR::RDI, GPR::RSI, GPR::RDX, GPR::RCX, GPR::R8, GPR::R9];
|
||||||
|
static XMM_SEQ: &'static [XMM] = &[
|
||||||
|
XMM::XMM0,
|
||||||
|
XMM::XMM1,
|
||||||
|
XMM::XMM2,
|
||||||
|
XMM::XMM3,
|
||||||
|
XMM::XMM4,
|
||||||
|
XMM::XMM5,
|
||||||
|
XMM::XMM6,
|
||||||
|
XMM::XMM7,
|
||||||
|
];
|
||||||
|
match ty {
|
||||||
|
Type::I32 | Type::I64 => {
|
||||||
|
if self.n_gprs < GPR_SEQ.len() {
|
||||||
|
let gpr = GPR_SEQ[self.n_gprs];
|
||||||
|
self.n_gprs += 1;
|
||||||
|
Some(X64Register::GPR(gpr))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Type::F32 | Type::F64 => {
|
||||||
|
if self.n_xmms < XMM_SEQ.len() {
|
||||||
|
let xmm = XMM_SEQ[self.n_xmms];
|
||||||
|
self.n_xmms += 1;
|
||||||
|
Some(X64Register::XMM(xmm))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => todo!(
|
||||||
|
"ArgumentRegisterAllocator::next: Unsupported type: {:?}",
|
||||||
|
ty
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// X64-specific structures and methods that only work on an x64 machine.
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub mod x64 {
|
pub mod x64 {
|
||||||
//! The x64 state module contains functions to generate state and code for x64 targets.
|
//! The x64 state module contains functions to generate state and code for x64 targets.
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
//! Variadic functions are not supported because `rax` is used by the trampoline code.
|
//! Variadic functions are not supported because `rax` is used by the trampoline code.
|
||||||
|
|
||||||
use crate::loader::CodeMemory;
|
use crate::loader::CodeMemory;
|
||||||
|
use crate::state::x64_decl::ArgumentRegisterAllocator;
|
||||||
|
use crate::types::Type;
|
||||||
use crate::vm::Ctx;
|
use crate::vm::Ctx;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -246,44 +248,50 @@ impl TrampolineBufferBuilder {
|
|||||||
&mut self,
|
&mut self,
|
||||||
target: unsafe extern "C" fn(*const CallContext, *const u64) -> u64,
|
target: unsafe extern "C" fn(*const CallContext, *const u64) -> u64,
|
||||||
context: *const CallContext,
|
context: *const CallContext,
|
||||||
num_params: u32,
|
params: &[Type],
|
||||||
|
_returns: &[Type],
|
||||||
) -> usize {
|
) -> usize {
|
||||||
let idx = self.offsets.len();
|
let idx = self.offsets.len();
|
||||||
self.offsets.push(self.code.len());
|
self.offsets.push(self.code.len());
|
||||||
|
|
||||||
let mut stack_offset: u32 = num_params.checked_mul(8).unwrap();
|
let mut stack_offset: u32 = params.len().checked_mul(8).unwrap() as u32;
|
||||||
if stack_offset % 16 == 0 {
|
if stack_offset % 16 == 0 {
|
||||||
stack_offset += 8;
|
stack_offset += 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.code.extend_from_slice(&[0x48, 0x81, 0xec]); // sub ?, %rsp
|
self.code.extend_from_slice(&[0x48, 0x81, 0xec]); // sub ?, %rsp
|
||||||
self.code.extend_from_slice(value_to_bytes(&stack_offset));
|
self.code.extend_from_slice(value_to_bytes(&stack_offset));
|
||||||
for i in 0..num_params {
|
|
||||||
match i {
|
let mut allocator = ArgumentRegisterAllocator::default();
|
||||||
0..=5 => {
|
|
||||||
// mov %?, ?(%rsp)
|
let mut source_stack_count: u32 = 0; // # of allocated slots in the source stack.
|
||||||
let prefix: &[u8] = match i {
|
|
||||||
0 => &[0x48, 0x89, 0xbc, 0x24], // rdi
|
for (i, ty) in params.iter().enumerate() {
|
||||||
1 => &[0x48, 0x89, 0xb4, 0x24], // rsi
|
match allocator.next(*ty) {
|
||||||
2 => &[0x48, 0x89, 0x94, 0x24], // rdx
|
Some(reg) => {
|
||||||
3 => &[0x48, 0x89, 0x8c, 0x24], // rcx
|
// This argument is allocated to a register.
|
||||||
4 => &[0x4c, 0x89, 0x84, 0x24], // r8
|
|
||||||
5 => &[0x4c, 0x89, 0x8c, 0x24], // r9
|
let prefix = reg
|
||||||
_ => unreachable!(),
|
.prefix_mov_to_stack()
|
||||||
};
|
.expect("cannot get instruction prefix for argument register");
|
||||||
self.code.extend_from_slice(prefix);
|
self.code.extend_from_slice(prefix);
|
||||||
self.code.extend_from_slice(value_to_bytes(&(i * 8u32)));
|
self.code
|
||||||
|
.extend_from_slice(value_to_bytes(&((i as u32) * 8u32)));
|
||||||
}
|
}
|
||||||
_ => {
|
None => {
|
||||||
|
// This argument is allocated to the stack.
|
||||||
|
|
||||||
self.code.extend_from_slice(&[
|
self.code.extend_from_slice(&[
|
||||||
0x48, 0x8b, 0x84, 0x24, // mov ?(%rsp), %rax
|
0x48, 0x8b, 0x84, 0x24, // mov ?(%rsp), %rax
|
||||||
]);
|
]);
|
||||||
self.code.extend_from_slice(value_to_bytes(
|
self.code.extend_from_slice(value_to_bytes(
|
||||||
&((i - 6) * 8u32 + stack_offset + 8/* ret addr */),
|
&(source_stack_count * 8u32 + stack_offset + 8/* ret addr */),
|
||||||
));
|
));
|
||||||
// mov %rax, ?(%rsp)
|
// mov %rax, ?(%rsp)
|
||||||
self.code.extend_from_slice(&[0x48, 0x89, 0x84, 0x24]);
|
self.code.extend_from_slice(&[0x48, 0x89, 0x84, 0x24]);
|
||||||
self.code.extend_from_slice(value_to_bytes(&(i * 8u32)));
|
self.code
|
||||||
|
.extend_from_slice(value_to_bytes(&((i as u32) * 8u32)));
|
||||||
|
source_stack_count += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -395,8 +403,13 @@ mod tests {
|
|||||||
}
|
}
|
||||||
let mut builder = TrampolineBufferBuilder::new();
|
let mut builder = TrampolineBufferBuilder::new();
|
||||||
let ctx = TestContext { value: 100 };
|
let ctx = TestContext { value: 100 };
|
||||||
let idx =
|
let param_types: Vec<Type> = vec![Type::I32; 8];
|
||||||
builder.add_callinfo_trampoline(do_add, &ctx as *const TestContext as *const _, 8);
|
let idx = builder.add_callinfo_trampoline(
|
||||||
|
do_add,
|
||||||
|
&ctx as *const TestContext as *const _,
|
||||||
|
¶m_types,
|
||||||
|
&[Type::I32],
|
||||||
|
);
|
||||||
let buf = builder.build();
|
let buf = builder.build();
|
||||||
let t = buf.get_trampoline(idx);
|
let t = buf.get_trampoline(idx);
|
||||||
let ret = unsafe {
|
let ret = unsafe {
|
||||||
@ -407,9 +420,49 @@ mod tests {
|
|||||||
assert_eq!(ret, 136);
|
assert_eq!(ret, 136);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_trampolines_with_floating_point() {
|
||||||
|
unsafe extern "C" fn inner(n: *const CallContext, args: *const u64) -> u64 {
|
||||||
|
// `n` is not really a pointer. It is the length of the argument list, casted into the pointer type.
|
||||||
|
let n = n as usize;
|
||||||
|
let mut result: u64 = 0;
|
||||||
|
for i in 0..n {
|
||||||
|
result += *args.offset(i as _);
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
let buffer = TrampBuffer::new(4096);
|
||||||
|
let mut builder = TrampolineBufferBuilder::new();
|
||||||
|
builder.add_callinfo_trampoline(
|
||||||
|
inner,
|
||||||
|
8 as _,
|
||||||
|
&[
|
||||||
|
Type::I32,
|
||||||
|
Type::I32,
|
||||||
|
Type::I32,
|
||||||
|
Type::F32,
|
||||||
|
Type::I32,
|
||||||
|
Type::I32,
|
||||||
|
Type::I32,
|
||||||
|
Type::I32,
|
||||||
|
],
|
||||||
|
&[Type::I32],
|
||||||
|
);
|
||||||
|
let ptr = buffer.insert(builder.code()).unwrap();
|
||||||
|
let ret = unsafe {
|
||||||
|
let f = std::mem::transmute::<
|
||||||
|
_,
|
||||||
|
extern "C" fn(i32, i32, i32, f32, i32, i32, i32, i32) -> i32,
|
||||||
|
>(ptr);
|
||||||
|
f(1, 2, 3, f32::from_bits(4), 5, 6, 7, 8)
|
||||||
|
};
|
||||||
|
assert_eq!(ret, 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_many_global_trampolines() {
|
fn test_many_global_trampolines() {
|
||||||
unsafe extern "C" fn inner(n: *const CallContext, args: *const u64) -> u64 {
|
unsafe extern "C" fn inner(n: *const CallContext, args: *const u64) -> u64 {
|
||||||
|
// `n` is not really a pointer. It is the length of the argument list, casted into the pointer type.
|
||||||
let n = n as usize;
|
let n = n as usize;
|
||||||
let mut result: u64 = 0;
|
let mut result: u64 = 0;
|
||||||
for i in 0..n {
|
for i in 0..n {
|
||||||
@ -427,7 +480,8 @@ mod tests {
|
|||||||
for i in 0..5000usize {
|
for i in 0..5000usize {
|
||||||
let mut builder = TrampolineBufferBuilder::new();
|
let mut builder = TrampolineBufferBuilder::new();
|
||||||
let n = i % 8;
|
let n = i % 8;
|
||||||
builder.add_callinfo_trampoline(inner, n as _, n as _);
|
let param_types: Vec<_> = (0..n).map(|_| Type::I64).collect();
|
||||||
|
builder.add_callinfo_trampoline(inner, n as _, ¶m_types, &[Type::I64]);
|
||||||
let ptr = buffer
|
let ptr = buffer
|
||||||
.insert(builder.code())
|
.insert(builder.code())
|
||||||
.expect("cannot insert new code into global buffer");
|
.expect("cannot insert new code into global buffer");
|
||||||
|
@ -306,16 +306,15 @@ impl<'a> DynamicFunc<'a> {
|
|||||||
{
|
{
|
||||||
use crate::trampoline_x64::{CallContext, TrampolineBufferBuilder};
|
use crate::trampoline_x64::{CallContext, TrampolineBufferBuilder};
|
||||||
use crate::types::Value;
|
use crate::types::Value;
|
||||||
use std::convert::TryFrom;
|
|
||||||
|
|
||||||
struct PolymorphicContext {
|
struct PolymorphicContext {
|
||||||
arg_types: Vec<Type>,
|
arg_types: Vec<Type>,
|
||||||
func: Box<dyn Fn(&mut vm::Ctx, &[Value]) -> Vec<Value>>,
|
func: Box<dyn Fn(&mut vm::Ctx, &[Value]) -> Vec<Value>>,
|
||||||
}
|
}
|
||||||
unsafe extern "C" fn enter_host_polymorphic(
|
unsafe fn do_enter_host_polymorphic(
|
||||||
ctx: *const CallContext,
|
ctx: *const CallContext,
|
||||||
args: *const u64,
|
args: *const u64,
|
||||||
) -> u64 {
|
) -> Vec<Value> {
|
||||||
let ctx = &*(ctx as *const PolymorphicContext);
|
let ctx = &*(ctx as *const PolymorphicContext);
|
||||||
let vmctx = &mut *(*args.offset(0) as *mut vm::Ctx);
|
let vmctx = &mut *(*args.offset(0) as *mut vm::Ctx);
|
||||||
let args: Vec<Value> = ctx
|
let args: Vec<Value> = ctx
|
||||||
@ -335,13 +334,40 @@ impl<'a> DynamicFunc<'a> {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let rets = (ctx.func)(vmctx, &args);
|
(ctx.func)(vmctx, &args)
|
||||||
|
}
|
||||||
|
unsafe extern "C" fn enter_host_polymorphic_i(
|
||||||
|
ctx: *const CallContext,
|
||||||
|
args: *const u64,
|
||||||
|
) -> u64 {
|
||||||
|
let rets = do_enter_host_polymorphic(ctx, args);
|
||||||
if rets.len() == 0 {
|
if rets.len() == 0 {
|
||||||
0
|
0
|
||||||
} else if rets.len() == 1 {
|
} else if rets.len() == 1 {
|
||||||
u64::try_from(rets[0].to_u128()).expect(
|
match rets[0] {
|
||||||
"128-bit return value from polymorphic host functions is not yet supported",
|
Value::I32(x) => x as u64,
|
||||||
)
|
Value::I64(x) => x as u64,
|
||||||
|
_ => panic!("enter_host_polymorphic_i: invalid return type"),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!(
|
||||||
|
"multiple return values from polymorphic host functions is not yet supported"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unsafe extern "C" fn enter_host_polymorphic_f(
|
||||||
|
ctx: *const CallContext,
|
||||||
|
args: *const u64,
|
||||||
|
) -> f64 {
|
||||||
|
let rets = do_enter_host_polymorphic(ctx, args);
|
||||||
|
if rets.len() == 0 {
|
||||||
|
0.0
|
||||||
|
} else if rets.len() == 1 {
|
||||||
|
match rets[0] {
|
||||||
|
Value::F32(x) => f64::from_bits(x.to_bits() as u64),
|
||||||
|
Value::F64(x) => x,
|
||||||
|
_ => panic!("enter_host_polymorphic_f: invalid return type"),
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
panic!(
|
panic!(
|
||||||
"multiple return values from polymorphic host functions is not yet supported"
|
"multiple return values from polymorphic host functions is not yet supported"
|
||||||
@ -349,9 +375,8 @@ impl<'a> DynamicFunc<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable "fat" closures for possible future changes.
|
if cfg!(not(feature = "dynamicfunc-fat-closures")) && mem::size_of::<F>() != 0 {
|
||||||
if mem::size_of::<F>() != 0 {
|
unimplemented!("DynamicFunc with captured environment is disabled");
|
||||||
unimplemented!("DynamicFunc with captured environment is not yet supported");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut builder = TrampolineBufferBuilder::new();
|
let mut builder = TrampolineBufferBuilder::new();
|
||||||
@ -360,11 +385,29 @@ impl<'a> DynamicFunc<'a> {
|
|||||||
func: Box::new(func),
|
func: Box::new(func),
|
||||||
});
|
});
|
||||||
let ctx = Box::into_raw(ctx);
|
let ctx = Box::into_raw(ctx);
|
||||||
|
|
||||||
|
let mut native_param_types = vec![Type::I64]; // vm::Ctx is the first parameter.
|
||||||
|
native_param_types.extend_from_slice(signature.params());
|
||||||
|
|
||||||
|
match signature.returns() {
|
||||||
|
[x] if *x == Type::F32 || *x == Type::F64 => {
|
||||||
builder.add_callinfo_trampoline(
|
builder.add_callinfo_trampoline(
|
||||||
enter_host_polymorphic,
|
unsafe { std::mem::transmute(enter_host_polymorphic_f as usize) },
|
||||||
ctx as *const _,
|
ctx as *const _,
|
||||||
(signature.params().len() + 1) as u32, // +vmctx
|
&native_param_types,
|
||||||
|
signature.returns(),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
builder.add_callinfo_trampoline(
|
||||||
|
enter_host_polymorphic_i,
|
||||||
|
ctx as *const _,
|
||||||
|
&native_param_types,
|
||||||
|
signature.returns(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let ptr = builder
|
let ptr = builder
|
||||||
.insert_global()
|
.insert_global()
|
||||||
.expect("cannot bump-allocate global trampoline memory");
|
.expect("cannot bump-allocate global trampoline memory");
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-runtime"
|
name = "wasmer-runtime"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
description = "Wasmer runtime library"
|
description = "Wasmer runtime library"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||||
@ -11,17 +11,17 @@ edition = "2018"
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.15.0", optional = true }
|
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.16.2", optional = true }
|
||||||
lazy_static = "1.4"
|
lazy_static = "1.4"
|
||||||
memmap = "0.7"
|
memmap = "0.7"
|
||||||
|
|
||||||
[dependencies.wasmer-runtime-core]
|
[dependencies.wasmer-runtime-core]
|
||||||
path = "../runtime-core"
|
path = "../runtime-core"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
|
|
||||||
[dependencies.wasmer-clif-backend]
|
[dependencies.wasmer-clif-backend]
|
||||||
path = "../clif-backend"
|
path = "../clif-backend"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
# Dependencies for caching.
|
# Dependencies for caching.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-singlepass-backend"
|
name = "wasmer-singlepass-backend"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
repository = "https://github.com/wasmerio/wasmer"
|
repository = "https://github.com/wasmerio/wasmer"
|
||||||
description = "Wasmer runtime single pass compiler backend"
|
description = "Wasmer runtime single pass compiler backend"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
@ -11,7 +11,7 @@ edition = "2018"
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.15.0" }
|
wasmer-runtime-core = { path = "../runtime-core", version = "0.16.2" }
|
||||||
dynasm = "0.5"
|
dynasm = "0.5"
|
||||||
dynasmrt = "0.5"
|
dynasmrt = "0.5"
|
||||||
lazy_static = "1.4"
|
lazy_static = "1.4"
|
||||||
|
@ -32,8 +32,9 @@ use wasmer_runtime_core::{
|
|||||||
memory::MemoryType,
|
memory::MemoryType,
|
||||||
module::{ModuleInfo, ModuleInner},
|
module::{ModuleInfo, ModuleInner},
|
||||||
state::{
|
state::{
|
||||||
x64::new_machine_state, x64::X64Register, FunctionStateMap, MachineState, MachineValue,
|
x64::new_machine_state, x64::X64Register, x64_decl::ArgumentRegisterAllocator,
|
||||||
ModuleStateMap, OffsetInfo, SuspendOffset, WasmAbstractValue,
|
FunctionStateMap, MachineState, MachineValue, ModuleStateMap, OffsetInfo, SuspendOffset,
|
||||||
|
WasmAbstractValue,
|
||||||
},
|
},
|
||||||
structures::{Map, TypedIndex},
|
structures::{Map, TypedIndex},
|
||||||
typed_func::{Trampoline, Wasm},
|
typed_func::{Trampoline, Wasm},
|
||||||
@ -204,6 +205,7 @@ pub struct X64FunctionCode {
|
|||||||
|
|
||||||
signatures: Arc<Map<SigIndex, FuncSig>>,
|
signatures: Arc<Map<SigIndex, FuncSig>>,
|
||||||
function_signatures: Arc<Map<FuncIndex, SigIndex>>,
|
function_signatures: Arc<Map<FuncIndex, SigIndex>>,
|
||||||
|
signature: FuncSig,
|
||||||
fsm: FunctionStateMap,
|
fsm: FunctionStateMap,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
|
|
||||||
@ -712,11 +714,22 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, CodegenError>
|
|||||||
machine.track_state = self.config.as_ref().unwrap().track_state;
|
machine.track_state = self.config.as_ref().unwrap().track_state;
|
||||||
|
|
||||||
assembler.emit_label(begin_label);
|
assembler.emit_label(begin_label);
|
||||||
|
|
||||||
|
let signatures = self.signatures.as_ref().unwrap();
|
||||||
|
let function_signatures = self.function_signatures.as_ref().unwrap();
|
||||||
|
let sig_index = function_signatures
|
||||||
|
.get(FuncIndex::new(
|
||||||
|
self.functions.len() + self.func_import_count,
|
||||||
|
))
|
||||||
|
.unwrap()
|
||||||
|
.clone();
|
||||||
|
let sig = signatures.get(sig_index).unwrap().clone();
|
||||||
let code = X64FunctionCode {
|
let code = X64FunctionCode {
|
||||||
local_function_id: self.functions.len(),
|
local_function_id: self.functions.len(),
|
||||||
|
|
||||||
signatures: self.signatures.as_ref().unwrap().clone(),
|
signatures: signatures.clone(),
|
||||||
function_signatures: self.function_signatures.as_ref().unwrap().clone(),
|
function_signatures: function_signatures.clone(),
|
||||||
|
signature: sig,
|
||||||
fsm: FunctionStateMap::new(new_machine_state(), self.functions.len(), 32, vec![]), // only a placeholder; this is initialized later in `begin_body`
|
fsm: FunctionStateMap::new(new_machine_state(), self.functions.len(), 32, vec![]), // only a placeholder; this is initialized later in `begin_body`
|
||||||
offset: begin_offset.0,
|
offset: begin_offset.0,
|
||||||
|
|
||||||
@ -869,7 +882,7 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, CodegenError>
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn feed_import_function(&mut self) -> Result<(), CodegenError> {
|
fn feed_import_function(&mut self, sigindex: SigIndex) -> Result<(), CodegenError> {
|
||||||
let labels = self.function_labels.as_mut().unwrap();
|
let labels = self.function_labels.as_mut().unwrap();
|
||||||
let id = labels.len();
|
let id = labels.len();
|
||||||
|
|
||||||
@ -880,6 +893,92 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, CodegenError>
|
|||||||
a.emit_label(label);
|
a.emit_label(label);
|
||||||
labels.insert(id, (label, Some(offset)));
|
labels.insert(id, (label, Some(offset)));
|
||||||
|
|
||||||
|
// Singlepass internally treats all arguments as integers, but the standard System V calling convention requires
|
||||||
|
// floating point arguments to be passed in XMM registers.
|
||||||
|
//
|
||||||
|
// FIXME: This is only a workaround. We should fix singlepass to use the standard CC.
|
||||||
|
let sig = self
|
||||||
|
.signatures
|
||||||
|
.as_ref()
|
||||||
|
.expect("signatures itself")
|
||||||
|
.get(sigindex)
|
||||||
|
.expect("signatures");
|
||||||
|
// Translation is expensive, so only do it if needed.
|
||||||
|
if sig
|
||||||
|
.params()
|
||||||
|
.iter()
|
||||||
|
.find(|&&x| x == Type::F32 || x == Type::F64)
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
let mut param_locations: Vec<Location> = vec![];
|
||||||
|
|
||||||
|
// Allocate stack space for arguments.
|
||||||
|
let stack_offset: i32 = if sig.params().len() > 5 {
|
||||||
|
5 * 8
|
||||||
|
} else {
|
||||||
|
(sig.params().len() as i32) * 8
|
||||||
|
};
|
||||||
|
if stack_offset > 0 {
|
||||||
|
a.emit_sub(
|
||||||
|
Size::S64,
|
||||||
|
Location::Imm32(stack_offset as u32),
|
||||||
|
Location::GPR(GPR::RSP),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store all arguments to the stack to prevent overwrite.
|
||||||
|
for i in 0..sig.params().len() {
|
||||||
|
let loc = match i {
|
||||||
|
0..=4 => {
|
||||||
|
static PARAM_REGS: &'static [GPR] =
|
||||||
|
&[GPR::RSI, GPR::RDX, GPR::RCX, GPR::R8, GPR::R9];
|
||||||
|
let loc = Location::Memory(GPR::RSP, (i * 8) as i32);
|
||||||
|
a.emit_mov(Size::S64, Location::GPR(PARAM_REGS[i]), loc);
|
||||||
|
loc
|
||||||
|
}
|
||||||
|
_ => Location::Memory(GPR::RSP, stack_offset + 8 + ((i - 5) * 8) as i32),
|
||||||
|
};
|
||||||
|
param_locations.push(loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy arguments.
|
||||||
|
let mut argalloc = ArgumentRegisterAllocator::default();
|
||||||
|
argalloc.next(Type::I32).unwrap(); // skip vm::Ctx
|
||||||
|
let mut caller_stack_offset: i32 = 0;
|
||||||
|
for (i, ty) in sig.params().iter().enumerate() {
|
||||||
|
let prev_loc = param_locations[i];
|
||||||
|
let target = match argalloc.next(*ty) {
|
||||||
|
Some(X64Register::GPR(gpr)) => Location::GPR(gpr),
|
||||||
|
Some(X64Register::XMM(xmm)) => Location::XMM(xmm),
|
||||||
|
None => {
|
||||||
|
// No register can be allocated. Put this argument on the stack.
|
||||||
|
//
|
||||||
|
// Since here we never use fewer registers than by the original call, on the caller's frame
|
||||||
|
// we always have enough space to store the rearranged arguments, and the copy "backward" between different
|
||||||
|
// slots in the caller argument region will always work.
|
||||||
|
a.emit_mov(Size::S64, prev_loc, Location::GPR(GPR::RAX));
|
||||||
|
a.emit_mov(
|
||||||
|
Size::S64,
|
||||||
|
Location::GPR(GPR::RAX),
|
||||||
|
Location::Memory(GPR::RSP, stack_offset + 8 + caller_stack_offset),
|
||||||
|
);
|
||||||
|
caller_stack_offset += 8;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
a.emit_mov(Size::S64, prev_loc, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore stack pointer.
|
||||||
|
if stack_offset > 0 {
|
||||||
|
a.emit_add(
|
||||||
|
Size::S64,
|
||||||
|
Location::Imm32(stack_offset as u32),
|
||||||
|
Location::GPR(GPR::RSP),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Emits a tail call trampoline that loads the address of the target import function
|
// Emits a tail call trampoline that loads the address of the target import function
|
||||||
// from Ctx and jumps to it.
|
// from Ctx and jumps to it.
|
||||||
|
|
||||||
@ -6260,9 +6359,16 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
|
|||||||
false,
|
false,
|
||||||
)[0];
|
)[0];
|
||||||
self.value_stack.push(ret);
|
self.value_stack.push(ret);
|
||||||
|
match return_types[0] {
|
||||||
|
WpType::F32 | WpType::F64 => {
|
||||||
|
a.emit_mov(Size::S64, Location::XMM(XMM::XMM0), ret);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
a.emit_mov(Size::S64, Location::GPR(GPR::RAX), ret);
|
a.emit_mov(Size::S64, Location::GPR(GPR::RAX), ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Operator::CallIndirect { index, table_index } => {
|
Operator::CallIndirect { index, table_index } => {
|
||||||
if table_index != 0 {
|
if table_index != 0 {
|
||||||
return Err(CodegenError {
|
return Err(CodegenError {
|
||||||
@ -6399,9 +6505,16 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
|
|||||||
false,
|
false,
|
||||||
)[0];
|
)[0];
|
||||||
self.value_stack.push(ret);
|
self.value_stack.push(ret);
|
||||||
|
match return_types[0] {
|
||||||
|
WpType::F32 | WpType::F64 => {
|
||||||
|
a.emit_mov(Size::S64, Location::XMM(XMM::XMM0), ret);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
a.emit_mov(Size::S64, Location::GPR(GPR::RAX), ret);
|
a.emit_mov(Size::S64, Location::GPR(GPR::RAX), ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Operator::If { ty } => {
|
Operator::If { ty } => {
|
||||||
let label_end = a.get_label();
|
let label_end = a.get_label();
|
||||||
let label_else = a.get_label();
|
let label_else = a.get_label();
|
||||||
@ -7614,6 +7727,18 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
|
|||||||
self.machine.finalize_locals(a, &self.locals);
|
self.machine.finalize_locals(a, &self.locals);
|
||||||
a.emit_mov(Size::S64, Location::GPR(GPR::RBP), Location::GPR(GPR::RSP));
|
a.emit_mov(Size::S64, Location::GPR(GPR::RBP), Location::GPR(GPR::RSP));
|
||||||
a.emit_pop(Size::S64, Location::GPR(GPR::RBP));
|
a.emit_pop(Size::S64, Location::GPR(GPR::RBP));
|
||||||
|
|
||||||
|
// Make a copy of the return value in XMM0, as required by the SysV CC.
|
||||||
|
match self.signature.returns() {
|
||||||
|
[x] if *x == Type::F32 || *x == Type::F64 => {
|
||||||
|
a.emit_mov(
|
||||||
|
Size::S64,
|
||||||
|
Location::GPR(GPR::RAX),
|
||||||
|
Location::XMM(XMM::XMM0),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
a.emit_ret();
|
a.emit_ret();
|
||||||
} else {
|
} else {
|
||||||
let released = &self.value_stack[frame.value_stack_depth..];
|
let released = &self.value_stack[frame.value_stack_depth..];
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-spectests"
|
name = "wasmer-spectests"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
description = "Wasmer spectests library"
|
description = "Wasmer spectests library"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||||
@ -9,10 +9,10 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
glob = "0.3"
|
glob = "0.3"
|
||||||
wasmer-runtime = { path = "../runtime", version = "0.15.0", default-features = false}
|
wasmer-runtime = { path = "../runtime", version = "0.16.2", default-features = false}
|
||||||
wasmer-clif-backend = { path = "../clif-backend", version = "0.15.0", optional = true}
|
wasmer-clif-backend = { path = "../clif-backend", version = "0.16.2", optional = true}
|
||||||
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.15.0", features = ["test"], optional = true }
|
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.16.2", features = ["test"], optional = true }
|
||||||
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.15.0", optional = true }
|
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.16.2", optional = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
wabt = "0.9.1"
|
wabt = "0.9.1"
|
||||||
|
@ -256,6 +256,16 @@ mod tests {
|
|||||||
Memory, Table,
|
Memory, Table,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fn format_panic(e: &dyn std::any::Any) -> String {
|
||||||
|
if let Some(s) = e.downcast_ref::<&str>() {
|
||||||
|
format!("{}", s)
|
||||||
|
} else if let Some(s) = e.downcast_ref::<String>() {
|
||||||
|
format!("{}", s)
|
||||||
|
} else {
|
||||||
|
"(unknown)".into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_and_run(
|
fn parse_and_run(
|
||||||
path: &PathBuf,
|
path: &PathBuf,
|
||||||
file_excludes: &HashSet<String>,
|
file_excludes: &HashSet<String>,
|
||||||
@ -342,7 +352,7 @@ mod tests {
|
|||||||
file: filename.to_string(),
|
file: filename.to_string(),
|
||||||
line: line,
|
line: line,
|
||||||
kind: format!("{}", "Module"),
|
kind: format!("{}", "Module"),
|
||||||
message: format!("caught panic {:?}", e),
|
message: format!("caught panic {}", format_panic(&e)),
|
||||||
},
|
},
|
||||||
&test_key,
|
&test_key,
|
||||||
excludes,
|
excludes,
|
||||||
@ -798,7 +808,7 @@ mod tests {
|
|||||||
file: filename.to_string(),
|
file: filename.to_string(),
|
||||||
line: line,
|
line: line,
|
||||||
kind: format!("{}", "AssertInvalid"),
|
kind: format!("{}", "AssertInvalid"),
|
||||||
message: format!("caught panic {:?}", p),
|
message: format!("caught panic {}", format_panic(&p)),
|
||||||
},
|
},
|
||||||
&test_key,
|
&test_key,
|
||||||
excludes,
|
excludes,
|
||||||
@ -851,7 +861,7 @@ mod tests {
|
|||||||
file: filename.to_string(),
|
file: filename.to_string(),
|
||||||
line: line,
|
line: line,
|
||||||
kind: format!("{}", "AssertMalformed"),
|
kind: format!("{}", "AssertMalformed"),
|
||||||
message: format!("caught panic {:?}", p),
|
message: format!("caught panic {}", format_panic(&p)),
|
||||||
},
|
},
|
||||||
&test_key,
|
&test_key,
|
||||||
excludes,
|
excludes,
|
||||||
@ -975,7 +985,7 @@ mod tests {
|
|||||||
file: filename.to_string(),
|
file: filename.to_string(),
|
||||||
line: line,
|
line: line,
|
||||||
kind: format!("{}", "AssertUnlinkable"),
|
kind: format!("{}", "AssertUnlinkable"),
|
||||||
message: format!("caught panic {:?}", e),
|
message: format!("caught panic {}", format_panic(&e)),
|
||||||
},
|
},
|
||||||
&test_key,
|
&test_key,
|
||||||
excludes,
|
excludes,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-wasi-experimental-io-devices"
|
name = "wasmer-wasi-experimental-io-devices"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
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"
|
||||||
@ -14,8 +14,8 @@ maintenance = { status = "experimental" }
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
minifb = "0.13"
|
minifb = "0.13"
|
||||||
wasmer-wasi = { version = "0.15.0", path = "../wasi" }
|
wasmer-wasi = { version = "0.16.2", path = "../wasi" }
|
||||||
wasmer-runtime-core = { version = "0.15.0", path = "../runtime-core" }
|
wasmer-runtime-core = { version = "0.16.2", path = "../runtime-core" }
|
||||||
ref_thread_local = "0.0"
|
ref_thread_local = "0.0"
|
||||||
serde = "1"
|
serde = "1"
|
||||||
typetag = "0.1"
|
typetag = "0.1"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-wasi-tests"
|
name = "wasmer-wasi-tests"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
description = "Tests for our WASI implementation"
|
description = "Tests for our WASI implementation"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||||
@ -10,18 +10,18 @@ build = "build/mod.rs"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# We set default features to false to be able to use the singlepass backend properly
|
# We set default features to false to be able to use the singlepass backend properly
|
||||||
wasmer-runtime = { path = "../runtime", version = "0.15.0", default-features = false }
|
wasmer-runtime = { path = "../runtime", version = "0.16.2", default-features = false }
|
||||||
wasmer-wasi = { path = "../wasi", version = "0.15.0" }
|
wasmer-wasi = { path = "../wasi", version = "0.16.2" }
|
||||||
# hack to get tests to work
|
# hack to get tests to work
|
||||||
wasmer-clif-backend = { path = "../clif-backend", version = "0.15.0", optional = true}
|
wasmer-clif-backend = { path = "../clif-backend", version = "0.16.2", optional = true}
|
||||||
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.15.0", optional = true }
|
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.16.2", optional = true }
|
||||||
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.15.0", features = ["test"], optional = true }
|
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.16.2", features = ["test"], optional = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
glob = "0.3"
|
glob = "0.3"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
wasmer-dev-utils = { path = "../dev-utils", version = "0.15.0"}
|
wasmer-dev-utils = { path = "../dev-utils", version = "0.16.2"}
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
clif = ["wasmer-clif-backend", "wasmer-runtime/default-backend-cranelift"]
|
clif = ["wasmer-clif-backend", "wasmer-runtime/default-backend-cranelift"]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-wasi"
|
name = "wasmer-wasi"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
description = "Wasmer runtime WASI implementation library"
|
description = "Wasmer runtime WASI implementation library"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||||
@ -19,7 +19,7 @@ getrandom = "0.1"
|
|||||||
time = "0.1"
|
time = "0.1"
|
||||||
typetag = "0.1"
|
typetag = "0.1"
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.15.0" }
|
wasmer-runtime-core = { path = "../runtime-core", version = "0.16.2" }
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = "0.3"
|
winapi = "0.3"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-win-exception-handler"
|
name = "wasmer-win-exception-handler"
|
||||||
version = "0.15.0"
|
version = "0.16.2"
|
||||||
description = "Wasmer runtime exception handling for Windows"
|
description = "Wasmer runtime exception handling for Windows"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||||
@ -8,7 +8,7 @@ repository = "https://github.com/wasmerio/wasmer"
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.15.0" }
|
wasmer-runtime-core = { path = "../runtime-core", version = "0.16.2" }
|
||||||
winapi = { version = "0.3.8", features = ["winbase", "errhandlingapi", "minwindef", "minwinbase", "winnt"] }
|
winapi = { version = "0.3.8", features = ["winbase", "errhandlingapi", "minwindef", "minwinbase", "winnt"] }
|
||||||
libc = "0.2.60"
|
libc = "0.2.60"
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
PREVIOUS_VERSION='0.14.1'
|
PREVIOUS_VERSION='0.16.1'
|
||||||
NEXT_VERSION='0.15.0'
|
NEXT_VERSION='0.16.2'
|
||||||
|
|
||||||
# quick hack
|
# quick hack
|
||||||
fd Cargo.toml --exec sed -i '' "s/version = \"$PREVIOUS_VERSION\"/version = \"$NEXT_VERSION\"/"
|
fd Cargo.toml --exec sed -i '' "s/version = \"$PREVIOUS_VERSION\"/version = \"$NEXT_VERSION\"/"
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 22 KiB |
Binary file not shown.
Before Width: | Height: | Size: 958 KiB After Width: | Height: | Size: 1.2 MiB |
Binary file not shown.
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 12 KiB |
@ -1,6 +1,6 @@
|
|||||||
[Setup]
|
[Setup]
|
||||||
AppName=Wasmer
|
AppName=Wasmer
|
||||||
AppVersion=0.15.0
|
AppVersion=0.16.2
|
||||||
DefaultDirName={pf}\Wasmer
|
DefaultDirName={pf}\Wasmer
|
||||||
DefaultGroupName=Wasmer
|
DefaultGroupName=Wasmer
|
||||||
Compression=lzma2
|
Compression=lzma2
|
||||||
@ -23,6 +23,7 @@ Root: HKCU; Subkey: "Environment"; ValueType:string; ValueName: "WASMER_CACHE_DI
|
|||||||
[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"
|
Source: "..\..\wapm-cli\target\release\wapm.exe"; DestDir: "{app}\bin"
|
||||||
|
Source: "wax.cmd"; DestDir: "{app}\bin"
|
||||||
|
|
||||||
[Dirs]
|
[Dirs]
|
||||||
Name: "{%USERPROFILE}\.wasmer"
|
Name: "{%USERPROFILE}\.wasmer"
|
||||||
|
2
src/installer/wax.cmd
Normal file
2
src/installer/wax.cmd
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
@echo off
|
||||||
|
wapm.exe execute %*
|
Loading…
x
Reference in New Issue
Block a user