mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-23 13:41:32 +00:00
Merge remote-tracking branch 'origin/master' into fix/fpcc-workaround
This commit is contained in:
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
## **[Unreleased]**
|
## **[Unreleased]**
|
||||||
|
|
||||||
|
## 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`
|
||||||
- [#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`
|
||||||
|
|
||||||
## 0.15.0 - 2020-03-04
|
## 0.15.0 - 2020-03-04
|
||||||
|
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.0"
|
||||||
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.0"
|
||||||
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.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-emscripten"
|
name = "wasmer-emscripten"
|
||||||
version = "0.15.0"
|
version = "0.16.0"
|
||||||
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.0"
|
||||||
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.0"
|
||||||
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.0"
|
||||||
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.0"
|
||||||
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.0"
|
||||||
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.0"
|
||||||
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.0"
|
||||||
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.0"
|
||||||
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.0"
|
||||||
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.0"
|
||||||
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.0"
|
||||||
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.0"
|
||||||
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.0"
|
||||||
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.0"
|
||||||
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.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cmake",
|
"cmake",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer"
|
name = "wasmer"
|
||||||
version = "0.15.0"
|
version = "0.16.0"
|
||||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
repository = "https://github.com/wasmerio/wasmer"
|
repository = "https://github.com/wasmerio/wasmer"
|
||||||
|
4
Makefile
4
Makefile
@ -287,6 +287,8 @@ 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/
|
||||||
|
# Create the wax binary as symlink to wapm
|
||||||
|
cd ./install/bin/ && ln -s wapm wax
|
||||||
tar -C ./install -zcvf wasmer.tar.gz bin/wapm bin/wasmer
|
tar -C ./install -zcvf wasmer.tar.gz bin/wapm bin/wasmer
|
||||||
|
|
||||||
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"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-clif-backend"
|
name = "wasmer-clif-backend"
|
||||||
version = "0.15.0"
|
version = "0.16.0"
|
||||||
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.0" }
|
||||||
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.0" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
generate-debug-information = ["wasm-debug"]
|
generate-debug-information = ["wasm-debug"]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-dev-utils"
|
name = "wasmer-dev-utils"
|
||||||
version = "0.15.0"
|
version = "0.16.0"
|
||||||
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.0"
|
||||||
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.0" }
|
||||||
wasmer-runtime = { path = "../runtime", version = "0.15.0", default-features = false }
|
wasmer-runtime = { path = "../runtime", version = "0.16.0", default-features = false }
|
||||||
wasmer-clif-backend = { path = "../clif-backend", version = "0.15.0", optional = true}
|
wasmer-clif-backend = { path = "../clif-backend", version = "0.16.0", 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.0", 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.0", 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.0"}
|
||||||
|
|
||||||
[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.0"
|
||||||
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.0" }
|
||||||
|
|
||||||
[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.0"
|
||||||
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>"]
|
||||||
|
@ -30,3 +30,68 @@ more](https://github.com/wasmerio/wasmer).
|
|||||||
|
|
||||||
This crate is an implementation of [the living WebAssembly Interface
|
This crate is an implementation of [the living WebAssembly Interface
|
||||||
Types standard](https://github.com/WebAssembly/interface-types).
|
Types standard](https://github.com/WebAssembly/interface-types).
|
||||||
|
|
||||||
|
## Encoders and decoders
|
||||||
|
|
||||||
|
The `wasmer-interface-types` crate comes with an encoder and a decoder
|
||||||
|
for the WAT format, and the binary format, for the WebAssembly
|
||||||
|
Interface Types. An encoder writes an AST into another format, like
|
||||||
|
WAT or binary. A decoder reads an AST from another format, like WAT or
|
||||||
|
binary.
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
Very basically, WebAssembly Interface Types defines a set of
|
||||||
|
instructions, used by adapters to transform the data between
|
||||||
|
WebAssembly core and the outside world ([learn
|
||||||
|
mode](https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md)).
|
||||||
|
|
||||||
|
Here is the instructions that are implemented:
|
||||||
|
|
||||||
|
| Instruction | WAT encoder | Binary encoder | WAT decoder | Binary decoder | Interpreter |
|
||||||
|
|-|-|-|-|-|-|
|
||||||
|
| `arg.get` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `call-core` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `memory-to-string` | ❌ | ❌ | ❌ | ❌ | ❌ |
|
||||||
|
| `string-to-memory` | ❌ | ❌ | ❌ | ❌ | ❌ |
|
||||||
|
| `call-adapter` | ❌ | ❌ | ❌ | ❌ | ❌ |
|
||||||
|
| `defer-call-core` | ❌ | ❌ | ❌ | ❌ | ❌ |
|
||||||
|
| `i32-to-s8` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `i32-to-s8x` | ✅ | ✅ | ✅ | ✅ | ❌ |
|
||||||
|
| `i32-to-u8` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `i32-to-s16` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `i32-to-s16x` | ✅ | ✅ | ✅ | ✅ | ❌ |
|
||||||
|
| `i32-to-u16` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `i32-to-s32` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `i32-to-u32` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `i32-to-s64` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `i32-to-u64` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `i64-to-s8` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `i64-to-s8x` | ✅ | ✅ | ✅ | ✅ | ❌ |
|
||||||
|
| `i64-to-u8` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `i64-to-s16` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `i64-to-s16x` | ✅ | ✅ | ✅ | ✅ | ❌ |
|
||||||
|
| `i64-to-u16` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `i64-to-s32` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `i64-to-s32x` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `i64-to-u32` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `i64-to-s64` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `i64-to-u64` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `s8-to-i32` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `u8-to-i32` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `s16-to-i32` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `u16-to-i32` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `s32-to-i32` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `u32-to-i32` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `s64-to-i32` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `s64-to-i32x` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `u64-to-i32` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `u64-to-i32x` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `s8-to-i64` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `u8-to-i64` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `s16-to-i64` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `u16-to-i64` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `s32-to-i64` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `u32-to-i64` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `s64-to-i64` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| `u64-to-i64` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
@ -51,12 +51,16 @@ pub enum InterfaceType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Represents a type signature.
|
/// Represents a type signature.
|
||||||
|
///
|
||||||
|
/// ```wasm,ignore
|
||||||
|
/// (@interface type (param i32 i32) (result string))
|
||||||
|
/// ```
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub struct Type {
|
pub struct Type {
|
||||||
/// Types for the parameters.
|
/// Types for the parameters (`(param …)`).
|
||||||
pub inputs: Vec<InterfaceType>,
|
pub inputs: Vec<InterfaceType>,
|
||||||
|
|
||||||
/// Types for the results.
|
/// Types for the results (`(result …)`).
|
||||||
pub outputs: Vec<InterfaceType>,
|
pub outputs: Vec<InterfaceType>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,12 +89,12 @@ pub struct Export<'input> {
|
|||||||
|
|
||||||
/// Represents an adapter.
|
/// Represents an adapter.
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub struct Adapter<'input> {
|
pub struct Adapter {
|
||||||
/// The adapter function type.
|
/// The adapter function type.
|
||||||
pub function_type: u32,
|
pub function_type: u32,
|
||||||
|
|
||||||
/// The instructions.
|
/// The instructions.
|
||||||
pub instructions: Vec<Instruction<'input>>,
|
pub instructions: Vec<Instruction>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents an implementation.
|
/// Represents an implementation.
|
||||||
@ -133,7 +137,7 @@ pub struct Interfaces<'input> {
|
|||||||
pub imports: Vec<Import<'input>>,
|
pub imports: Vec<Import<'input>>,
|
||||||
|
|
||||||
/// All the adapters.
|
/// All the adapters.
|
||||||
pub adapters: Vec<Adapter<'input>>,
|
pub adapters: Vec<Adapter>,
|
||||||
|
|
||||||
/// All the exported functions.
|
/// All the exported functions.
|
||||||
pub exports: Vec<Export<'input>>,
|
pub exports: Vec<Export<'input>>,
|
||||||
|
@ -168,30 +168,20 @@ fn instruction<'input, E: ParseError<&'input [u8]>>(
|
|||||||
consume!((input, argument_0) = uleb(input)?);
|
consume!((input, argument_0) = uleb(input)?);
|
||||||
(
|
(
|
||||||
input,
|
input,
|
||||||
Instruction::Call {
|
Instruction::CallCore {
|
||||||
function_index: argument_0 as usize,
|
function_index: argument_0 as usize,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
0x02 => {
|
0x03 => (input, Instruction::MemoryToString),
|
||||||
consume!((input, argument_0) = string(input)?);
|
|
||||||
(
|
|
||||||
input,
|
|
||||||
Instruction::CallExport {
|
|
||||||
export_name: argument_0,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
0x03 => (input, Instruction::ReadUtf8),
|
|
||||||
|
|
||||||
0x04 => {
|
0x04 => {
|
||||||
consume!((input, argument_0) = string(input)?);
|
consume!((input, argument_0) = uleb(input)?);
|
||||||
(
|
(
|
||||||
input,
|
input,
|
||||||
Instruction::WriteUtf8 {
|
Instruction::StringToMemory {
|
||||||
allocator_name: argument_0,
|
allocator_index: argument_0 as u32,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -637,12 +627,11 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_instructions() {
|
fn test_instructions() {
|
||||||
let input = &[
|
let input = &[
|
||||||
0x2c, // list of 44 items
|
0x2b, // list of 43 items
|
||||||
0x00, 0x01, // ArgumentGet { index: 1 }
|
0x00, 0x01, // ArgumentGet { index: 1 }
|
||||||
0x01, 0x01, // Call { function_index: 1 }
|
0x01, 0x01, // CallCore { function_index: 1 }
|
||||||
0x02, 0x03, 0x61, 0x62, 0x63, // CallExport { export_name: "abc" }
|
0x03, // MemoryToString
|
||||||
0x03, // ReadUtf8
|
0x04, 0x01, // StringToMemory { allocator_index: 1 }
|
||||||
0x04, 0x03, 0x61, 0x62, 0x63, // WriteUtf8 { allocator_name: "abc" }
|
|
||||||
0x07, // I32ToS8
|
0x07, // I32ToS8
|
||||||
0x08, // I32ToS8X
|
0x08, // I32ToS8X
|
||||||
0x09, // I32ToU8
|
0x09, // I32ToU8
|
||||||
@ -688,12 +677,9 @@ mod tests {
|
|||||||
&[0x0a][..],
|
&[0x0a][..],
|
||||||
vec![
|
vec![
|
||||||
Instruction::ArgumentGet { index: 1 },
|
Instruction::ArgumentGet { index: 1 },
|
||||||
Instruction::Call { function_index: 1 },
|
Instruction::CallCore { function_index: 1 },
|
||||||
Instruction::CallExport { export_name: "abc" },
|
Instruction::MemoryToString,
|
||||||
Instruction::ReadUtf8,
|
Instruction::StringToMemory { allocator_index: 1 },
|
||||||
Instruction::WriteUtf8 {
|
|
||||||
allocator_name: "abc",
|
|
||||||
},
|
|
||||||
Instruction::I32ToS8,
|
Instruction::I32ToS8,
|
||||||
Instruction::I32ToS8X,
|
Instruction::I32ToS8X,
|
||||||
Instruction::I32ToU8,
|
Instruction::I32ToU8,
|
||||||
|
@ -27,10 +27,9 @@ mod keyword {
|
|||||||
|
|
||||||
// Instructions.
|
// Instructions.
|
||||||
custom_keyword!(argument_get = "arg.get");
|
custom_keyword!(argument_get = "arg.get");
|
||||||
custom_keyword!(call);
|
custom_keyword!(call_core = "call-core");
|
||||||
custom_keyword!(call_export = "call-export");
|
custom_keyword!(memory_to_string = "memory-to-string");
|
||||||
custom_keyword!(read_utf8 = "read-utf8");
|
custom_keyword!(string_to_memory = "string-to-memory");
|
||||||
custom_keyword!(write_utf8 = "write-utf8");
|
|
||||||
custom_keyword!(i32_to_s8 = "i32-to-s8");
|
custom_keyword!(i32_to_s8 = "i32-to-s8");
|
||||||
custom_keyword!(i32_to_s8x = "i32-to-s8x");
|
custom_keyword!(i32_to_s8x = "i32-to-s8x");
|
||||||
custom_keyword!(i32_to_u8 = "i32-to-u8");
|
custom_keyword!(i32_to_u8 = "i32-to-u8");
|
||||||
@ -138,7 +137,7 @@ impl Parse<'_> for InterfaceType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Parse<'a> for Instruction<'a> {
|
impl<'a> Parse<'a> for Instruction {
|
||||||
#[allow(clippy::cognitive_complexity)]
|
#[allow(clippy::cognitive_complexity)]
|
||||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||||
let mut lookahead = parser.lookahead1();
|
let mut lookahead = parser.lookahead1();
|
||||||
@ -149,27 +148,21 @@ impl<'a> Parse<'a> for Instruction<'a> {
|
|||||||
Ok(Instruction::ArgumentGet {
|
Ok(Instruction::ArgumentGet {
|
||||||
index: parser.parse()?,
|
index: parser.parse()?,
|
||||||
})
|
})
|
||||||
} else if lookahead.peek::<keyword::call>() {
|
} else if lookahead.peek::<keyword::call_core>() {
|
||||||
parser.parse::<keyword::call>()?;
|
parser.parse::<keyword::call_core>()?;
|
||||||
|
|
||||||
Ok(Instruction::Call {
|
Ok(Instruction::CallCore {
|
||||||
function_index: parser.parse::<u64>()? as usize,
|
function_index: parser.parse::<u64>()? as usize,
|
||||||
})
|
})
|
||||||
} else if lookahead.peek::<keyword::call_export>() {
|
} else if lookahead.peek::<keyword::memory_to_string>() {
|
||||||
parser.parse::<keyword::call_export>()?;
|
parser.parse::<keyword::memory_to_string>()?;
|
||||||
|
|
||||||
Ok(Instruction::CallExport {
|
Ok(Instruction::MemoryToString)
|
||||||
export_name: parser.parse()?,
|
} else if lookahead.peek::<keyword::string_to_memory>() {
|
||||||
})
|
parser.parse::<keyword::string_to_memory>()?;
|
||||||
} else if lookahead.peek::<keyword::read_utf8>() {
|
|
||||||
parser.parse::<keyword::read_utf8>()?;
|
|
||||||
|
|
||||||
Ok(Instruction::ReadUtf8)
|
Ok(Instruction::StringToMemory {
|
||||||
} else if lookahead.peek::<keyword::write_utf8>() {
|
allocator_index: parser.parse()?,
|
||||||
parser.parse::<keyword::write_utf8>()?;
|
|
||||||
|
|
||||||
Ok(Instruction::WriteUtf8 {
|
|
||||||
allocator_name: parser.parse()?,
|
|
||||||
})
|
})
|
||||||
} else if lookahead.peek::<keyword::i32_to_s8>() {
|
} else if lookahead.peek::<keyword::i32_to_s8>() {
|
||||||
parser.parse::<keyword::i32_to_s8>()?;
|
parser.parse::<keyword::i32_to_s8>()?;
|
||||||
@ -399,7 +392,7 @@ impl Parse<'_> for FunctionType {
|
|||||||
enum Interface<'a> {
|
enum Interface<'a> {
|
||||||
Type(Type),
|
Type(Type),
|
||||||
Import(Import<'a>),
|
Import(Import<'a>),
|
||||||
Adapter(Adapter<'a>),
|
Adapter(Adapter),
|
||||||
Export(Export<'a>),
|
Export(Export<'a>),
|
||||||
Implementation(Implementation),
|
Implementation(Implementation),
|
||||||
}
|
}
|
||||||
@ -527,7 +520,7 @@ impl<'a> Parse<'a> for Implementation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Parse<'a> for Adapter<'a> {
|
impl<'a> Parse<'a> for Adapter {
|
||||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||||
parser.parse::<keyword::func>()?;
|
parser.parse::<keyword::func>()?;
|
||||||
|
|
||||||
@ -673,10 +666,9 @@ mod tests {
|
|||||||
fn test_instructions() {
|
fn test_instructions() {
|
||||||
let inputs = vec![
|
let inputs = vec![
|
||||||
"arg.get 7",
|
"arg.get 7",
|
||||||
"call 7",
|
"call-core 7",
|
||||||
r#"call-export "foo""#,
|
"memory-to-string",
|
||||||
"read-utf8",
|
"string-to-memory 42",
|
||||||
r#"write-utf8 "foo""#,
|
|
||||||
"i32-to-s8",
|
"i32-to-s8",
|
||||||
"i32-to-s8x",
|
"i32-to-s8x",
|
||||||
"i32-to-u8",
|
"i32-to-u8",
|
||||||
@ -719,11 +711,10 @@ mod tests {
|
|||||||
];
|
];
|
||||||
let outputs = vec![
|
let outputs = vec![
|
||||||
Instruction::ArgumentGet { index: 7 },
|
Instruction::ArgumentGet { index: 7 },
|
||||||
Instruction::Call { function_index: 7 },
|
Instruction::CallCore { function_index: 7 },
|
||||||
Instruction::CallExport { export_name: "foo" },
|
Instruction::MemoryToString,
|
||||||
Instruction::ReadUtf8,
|
Instruction::StringToMemory {
|
||||||
Instruction::WriteUtf8 {
|
allocator_index: 42,
|
||||||
allocator_name: "foo",
|
|
||||||
},
|
},
|
||||||
Instruction::I32ToS8,
|
Instruction::I32ToS8,
|
||||||
Instruction::I32ToS8X,
|
Instruction::I32ToS8X,
|
||||||
|
@ -162,7 +162,7 @@ where
|
|||||||
/// Encode an `Adapter` into bytes.
|
/// Encode an `Adapter` into bytes.
|
||||||
///
|
///
|
||||||
/// Decoder is in `decoders::binary::adapters`.
|
/// Decoder is in `decoders::binary::adapters`.
|
||||||
impl<W> ToBytes<W> for Adapter<'_>
|
impl<W> ToBytes<W> for Adapter
|
||||||
where
|
where
|
||||||
W: Write,
|
W: Write,
|
||||||
{
|
{
|
||||||
@ -244,7 +244,7 @@ where
|
|||||||
/// Encode an `Instruction` into bytes.
|
/// Encode an `Instruction` into bytes.
|
||||||
///
|
///
|
||||||
/// Decoder is `decoders::binary::instruction`.
|
/// Decoder is `decoders::binary::instruction`.
|
||||||
impl<W> ToBytes<W> for Instruction<'_>
|
impl<W> ToBytes<W> for Instruction
|
||||||
where
|
where
|
||||||
W: Write,
|
W: Write,
|
||||||
{
|
{
|
||||||
@ -255,21 +255,16 @@ where
|
|||||||
(*index as u64).to_bytes(writer)?;
|
(*index as u64).to_bytes(writer)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Instruction::Call { function_index } => {
|
Instruction::CallCore { function_index } => {
|
||||||
0x01_u8.to_bytes(writer)?;
|
0x01_u8.to_bytes(writer)?;
|
||||||
(*function_index as u64).to_bytes(writer)?;
|
(*function_index as u64).to_bytes(writer)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Instruction::CallExport { export_name } => {
|
Instruction::MemoryToString => 0x03_u8.to_bytes(writer)?,
|
||||||
0x02_u8.to_bytes(writer)?;
|
|
||||||
export_name.to_bytes(writer)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Instruction::ReadUtf8 => 0x03_u8.to_bytes(writer)?,
|
Instruction::StringToMemory { allocator_index } => {
|
||||||
|
|
||||||
Instruction::WriteUtf8 { allocator_name } => {
|
|
||||||
0x04_u8.to_bytes(writer)?;
|
0x04_u8.to_bytes(writer)?;
|
||||||
allocator_name.to_bytes(writer)?;
|
(*allocator_index as u64).to_bytes(writer)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Instruction::I32ToS8 => 0x07_u8.to_bytes(writer)?,
|
Instruction::I32ToS8 => 0x07_u8.to_bytes(writer)?,
|
||||||
@ -554,12 +549,9 @@ mod tests {
|
|||||||
assert_to_bytes!(
|
assert_to_bytes!(
|
||||||
vec![
|
vec![
|
||||||
Instruction::ArgumentGet { index: 1 },
|
Instruction::ArgumentGet { index: 1 },
|
||||||
Instruction::Call { function_index: 1 },
|
Instruction::CallCore { function_index: 1 },
|
||||||
Instruction::CallExport { export_name: "abc" },
|
Instruction::MemoryToString,
|
||||||
Instruction::ReadUtf8,
|
Instruction::StringToMemory { allocator_index: 1 },
|
||||||
Instruction::WriteUtf8 {
|
|
||||||
allocator_name: "abc",
|
|
||||||
},
|
|
||||||
Instruction::I32ToS8,
|
Instruction::I32ToS8,
|
||||||
Instruction::I32ToS8X,
|
Instruction::I32ToS8X,
|
||||||
Instruction::I32ToU8,
|
Instruction::I32ToU8,
|
||||||
@ -601,12 +593,11 @@ mod tests {
|
|||||||
Instruction::U64ToI64,
|
Instruction::U64ToI64,
|
||||||
],
|
],
|
||||||
&[
|
&[
|
||||||
0x2c, // list of 44 items
|
0x2b, // list of 43 items
|
||||||
0x00, 0x01, // ArgumentGet { index: 1 }
|
0x00, 0x01, // ArgumentGet { index: 1 }
|
||||||
0x01, 0x01, // Call { function_index: 1 }
|
0x01, 0x01, // CallCore { function_index: 1 }
|
||||||
0x02, 0x03, 0x61, 0x62, 0x63, // CallExport { export_name: "abc" }
|
0x03, // MemoryToString
|
||||||
0x03, // ReadUtf8
|
0x04, 0x01, // StringToMemory { allocator_index: 1 }
|
||||||
0x04, 0x03, 0x61, 0x62, 0x63, // WriteUtf8 { allocator_name: "abc" }
|
|
||||||
0x07, // I32ToS8
|
0x07, // I32ToS8
|
||||||
0x08, // I32ToS8X
|
0x08, // I32ToS8X
|
||||||
0x09, // I32ToU8
|
0x09, // I32ToU8
|
||||||
|
@ -80,15 +80,14 @@ impl ToString for &InterfaceType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Encode an `Instruction` into a string.
|
/// Encode an `Instruction` into a string.
|
||||||
impl<'input> ToString for &Instruction<'input> {
|
impl ToString for &Instruction {
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
Instruction::ArgumentGet { index } => format!("arg.get {}", index),
|
Instruction::ArgumentGet { index } => format!("arg.get {}", index),
|
||||||
Instruction::Call { function_index } => format!("call {}", function_index),
|
Instruction::CallCore { function_index } => format!("call-core {}", function_index),
|
||||||
Instruction::CallExport { export_name } => format!(r#"call-export "{}""#, export_name),
|
Instruction::MemoryToString => "memory-to-string".into(),
|
||||||
Instruction::ReadUtf8 => "read-utf8".into(),
|
Instruction::StringToMemory { allocator_index } => {
|
||||||
Instruction::WriteUtf8 { allocator_name } => {
|
format!(r#"string-to-memory {}"#, allocator_index)
|
||||||
format!(r#"write-utf8 "{}""#, allocator_name)
|
|
||||||
}
|
}
|
||||||
Instruction::I32ToS8 => "i32-to-s8".into(),
|
Instruction::I32ToS8 => "i32-to-s8".into(),
|
||||||
Instruction::I32ToS8X => "i32-to-s8x".into(),
|
Instruction::I32ToS8X => "i32-to-s8x".into(),
|
||||||
@ -195,7 +194,7 @@ impl<'input> ToString for &Import<'input> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Encode an `Adapter` into a string.
|
/// Encode an `Adapter` into a string.
|
||||||
impl<'input> ToString for &Adapter<'input> {
|
impl ToString for &Adapter {
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
format!(
|
format!(
|
||||||
r#"(@interface func (type {function_type}){instructions})"#,
|
r#"(@interface func (type {function_type}){instructions})"#,
|
||||||
@ -361,11 +360,10 @@ mod tests {
|
|||||||
fn test_instructions() {
|
fn test_instructions() {
|
||||||
let inputs: Vec<String> = vec![
|
let inputs: Vec<String> = vec![
|
||||||
(&Instruction::ArgumentGet { index: 7 }).to_string(),
|
(&Instruction::ArgumentGet { index: 7 }).to_string(),
|
||||||
(&Instruction::Call { function_index: 7 }).to_string(),
|
(&Instruction::CallCore { function_index: 7 }).to_string(),
|
||||||
(&Instruction::CallExport { export_name: "foo" }).to_string(),
|
(&Instruction::MemoryToString).to_string(),
|
||||||
(&Instruction::ReadUtf8).to_string(),
|
(&Instruction::StringToMemory {
|
||||||
(&Instruction::WriteUtf8 {
|
allocator_index: 42,
|
||||||
allocator_name: "foo",
|
|
||||||
})
|
})
|
||||||
.to_string(),
|
.to_string(),
|
||||||
(&Instruction::I32ToS8).to_string(),
|
(&Instruction::I32ToS8).to_string(),
|
||||||
@ -410,10 +408,9 @@ mod tests {
|
|||||||
];
|
];
|
||||||
let outputs = vec![
|
let outputs = vec![
|
||||||
"arg.get 7",
|
"arg.get 7",
|
||||||
"call 7",
|
"call-core 7",
|
||||||
r#"call-export "foo""#,
|
"memory-to-string",
|
||||||
"read-utf8",
|
"string-to-memory 42",
|
||||||
r#"write-utf8 "foo""#,
|
|
||||||
"i32-to-s8",
|
"i32-to-s8",
|
||||||
"i32-to-s8x",
|
"i32-to-s8x",
|
||||||
"i32-to-u8",
|
"i32-to-u8",
|
||||||
|
@ -2,32 +2,26 @@
|
|||||||
|
|
||||||
/// Represents all the possible WIT instructions.
|
/// Represents all the possible WIT instructions.
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub enum Instruction<'input> {
|
pub enum Instruction {
|
||||||
/// The `arg.get` instruction.
|
/// The `arg.get` instruction.
|
||||||
ArgumentGet {
|
ArgumentGet {
|
||||||
/// The argument index.
|
/// The argument index.
|
||||||
index: u32,
|
index: u32,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// The `call` instruction.
|
/// The `call-core` instruction.
|
||||||
Call {
|
CallCore {
|
||||||
/// The function index.
|
/// The function index.
|
||||||
function_index: usize,
|
function_index: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// The `call-export` instruction.
|
/// The `memory-to-string` instruction.
|
||||||
CallExport {
|
MemoryToString,
|
||||||
/// The exported function name.
|
|
||||||
export_name: &'input str,
|
|
||||||
},
|
|
||||||
|
|
||||||
/// The `read-utf8` instruction.
|
/// The `string-to-memory` instruction.
|
||||||
ReadUtf8,
|
StringToMemory {
|
||||||
|
/// The allocator function index.
|
||||||
/// The `write-utf8` instruction.
|
allocator_index: u32,
|
||||||
WriteUtf8 {
|
|
||||||
/// The allocator function name.
|
|
||||||
allocator_name: &'input str,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/// The `i32-to-s8,` instruction.
|
/// The `i32-to-s8,` instruction.
|
||||||
|
@ -4,7 +4,7 @@ use crate::interpreter::wasm::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
executable_instruction!(
|
executable_instruction!(
|
||||||
call(function_index: usize, instruction_name: String) -> _ {
|
call_core(function_index: usize, instruction_name: String) -> _ {
|
||||||
move |runtime| -> _ {
|
move |runtime| -> _ {
|
||||||
let instance = &mut runtime.wasm_instance;
|
let instance = &mut runtime.wasm_instance;
|
||||||
let index = FunctionIndex::new(function_index);
|
let index = FunctionIndex::new(function_index);
|
||||||
@ -65,11 +65,11 @@ executable_instruction!(
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
test_executable_instruction!(
|
test_executable_instruction!(
|
||||||
test_call =
|
test_call_core =
|
||||||
instructions: [
|
instructions: [
|
||||||
Instruction::ArgumentGet { index: 1 },
|
Instruction::ArgumentGet { index: 1 },
|
||||||
Instruction::ArgumentGet { index: 0 },
|
Instruction::ArgumentGet { index: 0 },
|
||||||
Instruction::Call { function_index: 42 },
|
Instruction::CallCore { function_index: 42 },
|
||||||
],
|
],
|
||||||
invocation_inputs: [
|
invocation_inputs: [
|
||||||
InterfaceValue::I32(3),
|
InterfaceValue::I32(3),
|
||||||
@ -80,23 +80,23 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
test_executable_instruction!(
|
test_executable_instruction!(
|
||||||
test_call__invalid_local_import_index =
|
test_call_core__invalid_local_import_index =
|
||||||
instructions: [
|
instructions: [
|
||||||
Instruction::Call { function_index: 42 },
|
Instruction::CallCore { function_index: 42 },
|
||||||
],
|
],
|
||||||
invocation_inputs: [
|
invocation_inputs: [
|
||||||
InterfaceValue::I32(3),
|
InterfaceValue::I32(3),
|
||||||
InterfaceValue::I32(4),
|
InterfaceValue::I32(4),
|
||||||
],
|
],
|
||||||
instance: Default::default(),
|
instance: Default::default(),
|
||||||
error: r#"`call 42` cannot call the local or imported function `42` because it doesn't exist."#,
|
error: r#"`call-core 42` cannot call the local or imported function `42` because it doesn't exist."#,
|
||||||
);
|
);
|
||||||
|
|
||||||
test_executable_instruction!(
|
test_executable_instruction!(
|
||||||
test_call__stack_is_too_small =
|
test_call_core__stack_is_too_small =
|
||||||
instructions: [
|
instructions: [
|
||||||
Instruction::ArgumentGet { index: 0 },
|
Instruction::ArgumentGet { index: 0 },
|
||||||
Instruction::Call { function_index: 42 },
|
Instruction::CallCore { function_index: 42 },
|
||||||
// ^^ `42` expects 2 values on the stack, only one is present
|
// ^^ `42` expects 2 values on the stack, only one is present
|
||||||
],
|
],
|
||||||
invocation_inputs: [
|
invocation_inputs: [
|
||||||
@ -104,15 +104,15 @@ mod tests {
|
|||||||
InterfaceValue::I32(4),
|
InterfaceValue::I32(4),
|
||||||
],
|
],
|
||||||
instance: Instance::new(),
|
instance: Instance::new(),
|
||||||
error: r#"`call 42` cannot call the local or imported function `42` because there is not enough data on the stack for the arguments (needs 2)."#,
|
error: r#"`call-core 42` cannot call the local or imported function `42` because there is not enough data on the stack for the arguments (needs 2)."#,
|
||||||
);
|
);
|
||||||
|
|
||||||
test_executable_instruction!(
|
test_executable_instruction!(
|
||||||
test_call__invalid_types_in_the_stack =
|
test_call_core__invalid_types_in_the_stack =
|
||||||
instructions: [
|
instructions: [
|
||||||
Instruction::ArgumentGet { index: 1 },
|
Instruction::ArgumentGet { index: 1 },
|
||||||
Instruction::ArgumentGet { index: 0 },
|
Instruction::ArgumentGet { index: 0 },
|
||||||
Instruction::Call { function_index: 42 },
|
Instruction::CallCore { function_index: 42 },
|
||||||
],
|
],
|
||||||
invocation_inputs: [
|
invocation_inputs: [
|
||||||
InterfaceValue::I32(3),
|
InterfaceValue::I32(3),
|
||||||
@ -120,15 +120,15 @@ mod tests {
|
|||||||
// ^^^ mismatch with `42` signature
|
// ^^^ mismatch with `42` signature
|
||||||
],
|
],
|
||||||
instance: Instance::new(),
|
instance: Instance::new(),
|
||||||
error: r#"`call 42` cannot call the local or imported function `42` because the value types on the stack mismatch the function signature (expects [I32, I32])."#,
|
error: r#"`call-core 42` cannot call the local or imported function `42` because the value types on the stack mismatch the function signature (expects [I32, I32])."#,
|
||||||
);
|
);
|
||||||
|
|
||||||
test_executable_instruction!(
|
test_executable_instruction!(
|
||||||
test_call__failure_when_calling =
|
test_call_core__failure_when_calling =
|
||||||
instructions: [
|
instructions: [
|
||||||
Instruction::ArgumentGet { index: 1 },
|
Instruction::ArgumentGet { index: 1 },
|
||||||
Instruction::ArgumentGet { index: 0 },
|
Instruction::ArgumentGet { index: 0 },
|
||||||
Instruction::Call { function_index: 42 },
|
Instruction::CallCore { function_index: 42 },
|
||||||
],
|
],
|
||||||
invocation_inputs: [
|
invocation_inputs: [
|
||||||
InterfaceValue::I32(3),
|
InterfaceValue::I32(3),
|
||||||
@ -151,15 +151,15 @@ mod tests {
|
|||||||
},
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
error: r#"`call 42` failed when calling the local or imported function `42`."#,
|
error: r#"`call-core 42` failed when calling the local or imported function `42`."#,
|
||||||
);
|
);
|
||||||
|
|
||||||
test_executable_instruction!(
|
test_executable_instruction!(
|
||||||
test_call__void =
|
test_call_core__void =
|
||||||
instructions: [
|
instructions: [
|
||||||
Instruction::ArgumentGet { index: 1 },
|
Instruction::ArgumentGet { index: 1 },
|
||||||
Instruction::ArgumentGet { index: 0 },
|
Instruction::ArgumentGet { index: 0 },
|
||||||
Instruction::Call { function_index: 42 },
|
Instruction::CallCore { function_index: 42 },
|
||||||
],
|
],
|
||||||
invocation_inputs: [
|
invocation_inputs: [
|
||||||
InterfaceValue::I32(3),
|
InterfaceValue::I32(3),
|
@ -1,177 +0,0 @@
|
|||||||
use crate::interpreter::wasm::values::InterfaceType;
|
|
||||||
|
|
||||||
executable_instruction!(
|
|
||||||
call_export(export_name: String, instruction_name: String) -> _ {
|
|
||||||
move |runtime| -> _ {
|
|
||||||
let instance = &mut runtime.wasm_instance;
|
|
||||||
|
|
||||||
match instance.export(&export_name) {
|
|
||||||
Some(export) => {
|
|
||||||
let inputs_cardinality = export.inputs_cardinality();
|
|
||||||
|
|
||||||
match runtime.stack.pop(inputs_cardinality) {
|
|
||||||
Some(inputs) => {
|
|
||||||
let input_types = inputs
|
|
||||||
.iter()
|
|
||||||
.map(Into::into)
|
|
||||||
.collect::<Vec<InterfaceType>>();
|
|
||||||
|
|
||||||
if input_types != export.inputs() {
|
|
||||||
return Err(format!(
|
|
||||||
"`{}` cannot call the exported function `{}` because the value types on the stack mismatch the function signature (expects {:?}).",
|
|
||||||
instruction_name,
|
|
||||||
export_name,
|
|
||||||
export.inputs(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
match export.call(&inputs) {
|
|
||||||
Ok(outputs) => {
|
|
||||||
for output in outputs.iter() {
|
|
||||||
runtime.stack.push(output.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
Err(_) => Err(format!(
|
|
||||||
"`{}` failed when calling the exported function `{}`.",
|
|
||||||
instruction_name,
|
|
||||||
export_name
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => Err(format!(
|
|
||||||
"`{}` cannot call the exported function `{}` because there is not enough data on the stack for the arguments (needs {}).",
|
|
||||||
instruction_name,
|
|
||||||
export_name,
|
|
||||||
inputs_cardinality,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => Err(format!(
|
|
||||||
"`{}` cannot call the exported function `{}` because it doesn't exist.",
|
|
||||||
instruction_name,
|
|
||||||
export_name,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
test_executable_instruction!(
|
|
||||||
test_call_export =
|
|
||||||
instructions: [
|
|
||||||
Instruction::ArgumentGet { index: 1 },
|
|
||||||
Instruction::ArgumentGet { index: 0 },
|
|
||||||
Instruction::CallExport { export_name: "sum" },
|
|
||||||
],
|
|
||||||
invocation_inputs: [
|
|
||||||
InterfaceValue::I32(3),
|
|
||||||
InterfaceValue::I32(4),
|
|
||||||
],
|
|
||||||
instance: Instance::new(),
|
|
||||||
stack: [InterfaceValue::I32(7)],
|
|
||||||
);
|
|
||||||
|
|
||||||
test_executable_instruction!(
|
|
||||||
test_call_export__invalid_export_name =
|
|
||||||
instructions: [Instruction::CallExport { export_name: "bar" }],
|
|
||||||
invocation_inputs: [],
|
|
||||||
instance: Instance::new(),
|
|
||||||
error: r#"`call-export "bar"` cannot call the exported function `bar` because it doesn't exist."#,
|
|
||||||
);
|
|
||||||
|
|
||||||
test_executable_instruction!(
|
|
||||||
test_call_export__stack_is_too_small =
|
|
||||||
instructions: [
|
|
||||||
Instruction::ArgumentGet { index: 0 },
|
|
||||||
Instruction::CallExport { export_name: "sum" },
|
|
||||||
],
|
|
||||||
invocation_inputs: [
|
|
||||||
InterfaceValue::I32(3),
|
|
||||||
InterfaceValue::I32(4),
|
|
||||||
],
|
|
||||||
instance: Instance::new(),
|
|
||||||
error: r#"`call-export "sum"` cannot call the exported function `sum` because there is not enough data on the stack for the arguments (needs 2)."#,
|
|
||||||
);
|
|
||||||
|
|
||||||
test_executable_instruction!(
|
|
||||||
test_call_export__invalid_types_in_the_stack =
|
|
||||||
instructions: [
|
|
||||||
Instruction::ArgumentGet { index: 1 },
|
|
||||||
Instruction::ArgumentGet { index: 0 },
|
|
||||||
Instruction::CallExport { export_name: "sum" },
|
|
||||||
],
|
|
||||||
invocation_inputs: [
|
|
||||||
InterfaceValue::I32(3),
|
|
||||||
InterfaceValue::I64(4),
|
|
||||||
// ^^^ mismatch with `sum` signature
|
|
||||||
],
|
|
||||||
instance: Instance::new(),
|
|
||||||
error: r#"`call-export "sum"` cannot call the exported function `sum` because the value types on the stack mismatch the function signature (expects [I32, I32])."#,
|
|
||||||
);
|
|
||||||
|
|
||||||
test_executable_instruction!(
|
|
||||||
test_call_export__failure_when_calling =
|
|
||||||
instructions: [
|
|
||||||
Instruction::ArgumentGet { index: 1 },
|
|
||||||
Instruction::ArgumentGet { index: 0 },
|
|
||||||
Instruction::CallExport { export_name: "sum" },
|
|
||||||
],
|
|
||||||
invocation_inputs: [
|
|
||||||
InterfaceValue::I32(3),
|
|
||||||
InterfaceValue::I32(4),
|
|
||||||
],
|
|
||||||
instance: Instance {
|
|
||||||
exports: {
|
|
||||||
let mut hashmap = HashMap::new();
|
|
||||||
hashmap.insert(
|
|
||||||
"sum".into(),
|
|
||||||
Export {
|
|
||||||
inputs: vec![InterfaceType::I32, InterfaceType::I32],
|
|
||||||
outputs: vec![InterfaceType::I32],
|
|
||||||
function: |_| Err(()),
|
|
||||||
// ^^^^^^^ function fails
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
hashmap
|
|
||||||
},
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
error: r#"`call-export "sum"` failed when calling the exported function `sum`."#,
|
|
||||||
);
|
|
||||||
|
|
||||||
test_executable_instruction!(
|
|
||||||
test_call_export__void =
|
|
||||||
instructions: [
|
|
||||||
Instruction::ArgumentGet { index: 1 },
|
|
||||||
Instruction::ArgumentGet { index: 0 },
|
|
||||||
Instruction::CallExport { export_name: "sum" },
|
|
||||||
],
|
|
||||||
invocation_inputs: [
|
|
||||||
InterfaceValue::I32(3),
|
|
||||||
InterfaceValue::I32(4),
|
|
||||||
],
|
|
||||||
instance: Instance {
|
|
||||||
exports: {
|
|
||||||
let mut hashmap = HashMap::new();
|
|
||||||
hashmap.insert(
|
|
||||||
"sum".into(),
|
|
||||||
Export {
|
|
||||||
inputs: vec![InterfaceType::I32, InterfaceType::I32],
|
|
||||||
outputs: vec![InterfaceType::I32],
|
|
||||||
function: |_| Ok(vec![]),
|
|
||||||
// ^^^^^^^^^^ void function
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
hashmap
|
|
||||||
},
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
stack: [],
|
|
||||||
);
|
|
||||||
}
|
|
@ -2,7 +2,7 @@ use crate::interpreter::wasm::values::InterfaceValue;
|
|||||||
use std::{cell::Cell, convert::TryFrom};
|
use std::{cell::Cell, convert::TryFrom};
|
||||||
|
|
||||||
executable_instruction!(
|
executable_instruction!(
|
||||||
read_utf8(instruction_name: String) -> _ {
|
memory_to_string(instruction_name: String) -> _ {
|
||||||
move |runtime| -> _ {
|
move |runtime| -> _ {
|
||||||
match runtime.stack.pop(2) {
|
match runtime.stack.pop(2) {
|
||||||
Some(inputs) => match runtime.wasm_instance.memory(0) {
|
Some(inputs) => match runtime.wasm_instance.memory(0) {
|
||||||
@ -55,11 +55,11 @@ executable_instruction!(
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
test_executable_instruction!(
|
test_executable_instruction!(
|
||||||
test_read_utf8 =
|
test_memory_to_string =
|
||||||
instructions: [
|
instructions: [
|
||||||
Instruction::ArgumentGet { index: 1 },
|
Instruction::ArgumentGet { index: 1 },
|
||||||
Instruction::ArgumentGet { index: 0 },
|
Instruction::ArgumentGet { index: 0 },
|
||||||
Instruction::ReadUtf8,
|
Instruction::MemoryToString,
|
||||||
],
|
],
|
||||||
invocation_inputs: [
|
invocation_inputs: [
|
||||||
InterfaceValue::I32(13),
|
InterfaceValue::I32(13),
|
||||||
@ -75,11 +75,11 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
test_executable_instruction!(
|
test_executable_instruction!(
|
||||||
test_read_utf8__read_out_of_memory =
|
test_memory_to_string__read_out_of_memory =
|
||||||
instructions: [
|
instructions: [
|
||||||
Instruction::ArgumentGet { index: 1 },
|
Instruction::ArgumentGet { index: 1 },
|
||||||
Instruction::ArgumentGet { index: 0 },
|
Instruction::ArgumentGet { index: 0 },
|
||||||
Instruction::ReadUtf8,
|
Instruction::MemoryToString,
|
||||||
],
|
],
|
||||||
invocation_inputs: [
|
invocation_inputs: [
|
||||||
InterfaceValue::I32(13),
|
InterfaceValue::I32(13),
|
||||||
@ -91,15 +91,15 @@ mod tests {
|
|||||||
memory: Memory::new("Hello!".as_bytes().iter().map(|u| Cell::new(*u)).collect()),
|
memory: Memory::new("Hello!".as_bytes().iter().map(|u| Cell::new(*u)).collect()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
error: r#"`read-utf8` failed because it has to read out of the memory bounds (index 13 > memory length 6)."#,
|
error: r#"`memory-to-string` failed because it has to read out of the memory bounds (index 13 > memory length 6)."#,
|
||||||
);
|
);
|
||||||
|
|
||||||
test_executable_instruction!(
|
test_executable_instruction!(
|
||||||
test_read_utf8__invalid_encoding =
|
test_memory_to_string__invalid_encoding =
|
||||||
instructions: [
|
instructions: [
|
||||||
Instruction::ArgumentGet { index: 1 },
|
Instruction::ArgumentGet { index: 1 },
|
||||||
Instruction::ArgumentGet { index: 0 },
|
Instruction::ArgumentGet { index: 0 },
|
||||||
Instruction::ReadUtf8,
|
Instruction::MemoryToString,
|
||||||
],
|
],
|
||||||
invocation_inputs: [
|
invocation_inputs: [
|
||||||
InterfaceValue::I32(4),
|
InterfaceValue::I32(4),
|
||||||
@ -111,21 +111,21 @@ mod tests {
|
|||||||
memory: Memory::new(vec![0, 159, 146, 150].iter().map(|b| Cell::new(*b)).collect::<Vec<Cell<u8>>>()),
|
memory: Memory::new(vec![0, 159, 146, 150].iter().map(|b| Cell::new(*b)).collect::<Vec<Cell<u8>>>()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
error: r#"`read-utf8` failed because the read string isn't UTF-8 valid (invalid utf-8 sequence of 1 bytes from index 1)."#,
|
error: r#"`memory-to-string` failed because the read string isn't UTF-8 valid (invalid utf-8 sequence of 1 bytes from index 1)."#,
|
||||||
);
|
);
|
||||||
|
|
||||||
test_executable_instruction!(
|
test_executable_instruction!(
|
||||||
test_read_utf8__stack_is_too_small =
|
test_memory_to_string__stack_is_too_small =
|
||||||
instructions: [
|
instructions: [
|
||||||
Instruction::ArgumentGet { index: 0 },
|
Instruction::ArgumentGet { index: 0 },
|
||||||
Instruction::ReadUtf8,
|
Instruction::MemoryToString,
|
||||||
// ^^^^^^^^ `read-utf8` expects 2 values on the stack, only one is present.
|
// ^^^^^^^^^^^^^^ `memory-to-string` expects 2 values on the stack, only one is present.
|
||||||
],
|
],
|
||||||
invocation_inputs: [
|
invocation_inputs: [
|
||||||
InterfaceValue::I32(13),
|
InterfaceValue::I32(13),
|
||||||
InterfaceValue::I32(0),
|
InterfaceValue::I32(0),
|
||||||
],
|
],
|
||||||
instance: Instance::new(),
|
instance: Instance::new(),
|
||||||
error: r#"`read-utf8` failed because there is not enough data on the stack (needs 2)."#,
|
error: r#"`memory-to-string` failed because there is not enough data on the stack (needs 2)."#,
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -1,16 +1,14 @@
|
|||||||
mod argument_get;
|
mod argument_get;
|
||||||
mod call;
|
mod call_core;
|
||||||
mod call_export;
|
|
||||||
mod lowering_lifting;
|
mod lowering_lifting;
|
||||||
mod read_utf8;
|
mod memory_to_string;
|
||||||
mod write_utf8;
|
mod string_to_memory;
|
||||||
|
|
||||||
pub(crate) use argument_get::argument_get;
|
pub(crate) use argument_get::argument_get;
|
||||||
pub(crate) use call::call;
|
pub(crate) use call_core::call_core;
|
||||||
pub(crate) use call_export::call_export;
|
|
||||||
pub(crate) use lowering_lifting::*;
|
pub(crate) use lowering_lifting::*;
|
||||||
pub(crate) use read_utf8::read_utf8;
|
pub(crate) use memory_to_string::memory_to_string;
|
||||||
pub(crate) use write_utf8::write_utf8;
|
pub(crate) use string_to_memory::string_to_memory;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) mod tests {
|
pub(crate) mod tests {
|
||||||
@ -133,23 +131,12 @@ pub(crate) mod tests {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
hashmap.insert(
|
|
||||||
"alloc".into(),
|
|
||||||
Export {
|
|
||||||
inputs: vec![InterfaceType::I32],
|
|
||||||
outputs: vec![InterfaceType::I32],
|
|
||||||
function: |arguments: &[InterfaceValue]| {
|
|
||||||
let _size: i32 = (&arguments[0]).try_into().unwrap();
|
|
||||||
|
|
||||||
Ok(vec![InterfaceValue::I32(0)])
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
hashmap
|
hashmap
|
||||||
},
|
},
|
||||||
locals_or_imports: {
|
locals_or_imports: {
|
||||||
let mut hashmap = HashMap::new();
|
let mut hashmap = HashMap::new();
|
||||||
|
// sum
|
||||||
hashmap.insert(
|
hashmap.insert(
|
||||||
42,
|
42,
|
||||||
LocalImport {
|
LocalImport {
|
||||||
@ -163,6 +150,19 @@ pub(crate) mod tests {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
// string allocator
|
||||||
|
hashmap.insert(
|
||||||
|
43,
|
||||||
|
LocalImport {
|
||||||
|
inputs: vec![InterfaceType::I32],
|
||||||
|
outputs: vec![InterfaceType::I32],
|
||||||
|
function: |arguments: &[InterfaceValue]| {
|
||||||
|
let _size: i32 = (&arguments[0]).try_into().unwrap();
|
||||||
|
|
||||||
|
Ok(vec![InterfaceValue::I32(0)])
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
hashmap
|
hashmap
|
||||||
},
|
},
|
||||||
|
@ -0,0 +1,169 @@
|
|||||||
|
use crate::interpreter::wasm::{
|
||||||
|
structures::{FunctionIndex, TypedIndex},
|
||||||
|
values::{InterfaceType, InterfaceValue},
|
||||||
|
};
|
||||||
|
use std::convert::TryInto;
|
||||||
|
|
||||||
|
executable_instruction!(
|
||||||
|
string_to_memory(allocator_index: u32, instruction_name: String) -> _ {
|
||||||
|
move |runtime| -> _ {
|
||||||
|
let instance = &mut runtime.wasm_instance;
|
||||||
|
let index = FunctionIndex::new(allocator_index as usize);
|
||||||
|
|
||||||
|
let allocator = instance.local_or_import(index).ok_or_else(|| {
|
||||||
|
format!(
|
||||||
|
"`{}` failed because the function `{}` (the allocator) doesn't exist.",
|
||||||
|
instruction_name,
|
||||||
|
allocator_index
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if allocator.inputs() != [InterfaceType::I32] || allocator.outputs() != [InterfaceType::I32] {
|
||||||
|
return Err(format!(
|
||||||
|
"`{}` failed because the allocator `{}` has an invalid signature (expects [I32] -> [I32]).",
|
||||||
|
instruction_name,
|
||||||
|
allocator_index,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let string = runtime.stack.pop1().ok_or_else(|| {
|
||||||
|
format!(
|
||||||
|
"`{}` cannot call the allocator `{}` because there is not enough data on the stack for the arguments (needs {}).",
|
||||||
|
instruction_name,
|
||||||
|
allocator_index,
|
||||||
|
1
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let string: String = (&string).try_into()?;
|
||||||
|
let string_bytes = string.as_bytes();
|
||||||
|
let string_length = (string_bytes.len() as i32)
|
||||||
|
.try_into()
|
||||||
|
.map_err(|error| format!("{}", error))?;
|
||||||
|
|
||||||
|
let outputs = allocator.call(&[InterfaceValue::I32(string_length)]).map_err(|_| format!(
|
||||||
|
"`{}` failed when calling the allocator `{}`.",
|
||||||
|
instruction_name,
|
||||||
|
allocator_index,
|
||||||
|
))?;
|
||||||
|
|
||||||
|
let string_pointer: i32 = (&outputs[0]).try_into()?;
|
||||||
|
|
||||||
|
let memory_view = instance
|
||||||
|
.memory(0)
|
||||||
|
.ok_or_else(|| {
|
||||||
|
format!(
|
||||||
|
"`{}` failed because there is no memory to write into.",
|
||||||
|
instruction_name
|
||||||
|
)
|
||||||
|
})?
|
||||||
|
.view();
|
||||||
|
|
||||||
|
for (nth, byte) in string_bytes.iter().enumerate() {
|
||||||
|
memory_view[string_pointer as usize + nth].set(*byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
runtime.stack.push(InterfaceValue::I32(string_pointer));
|
||||||
|
runtime.stack.push(InterfaceValue::I32(string_length));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
test_executable_instruction!(
|
||||||
|
test_string_to_memory =
|
||||||
|
instructions: [
|
||||||
|
Instruction::ArgumentGet { index: 0 },
|
||||||
|
Instruction::StringToMemory { allocator_index: 43 },
|
||||||
|
],
|
||||||
|
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
||||||
|
instance: Instance::new(),
|
||||||
|
stack: [
|
||||||
|
InterfaceValue::I32(0),
|
||||||
|
// ^^^^^^ pointer
|
||||||
|
InterfaceValue::I32(13),
|
||||||
|
// ^^^^^^^ length
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
test_executable_instruction!(
|
||||||
|
test_string_to_memory__roundtrip_with_memory_to_string =
|
||||||
|
instructions: [
|
||||||
|
Instruction::ArgumentGet { index: 0 },
|
||||||
|
Instruction::StringToMemory { allocator_index: 43 },
|
||||||
|
Instruction::MemoryToString,
|
||||||
|
],
|
||||||
|
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
||||||
|
instance: Instance::new(),
|
||||||
|
stack: [InterfaceValue::String("Hello, World!".into())],
|
||||||
|
);
|
||||||
|
|
||||||
|
test_executable_instruction!(
|
||||||
|
test_string_to_memory__allocator_does_not_exist =
|
||||||
|
instructions: [Instruction::StringToMemory { allocator_index: 43 }],
|
||||||
|
invocation_inputs: [],
|
||||||
|
instance: Instance { ..Default::default() },
|
||||||
|
error: r#"`string-to-memory 43` failed because the function `43` (the allocator) doesn't exist."#,
|
||||||
|
);
|
||||||
|
|
||||||
|
test_executable_instruction!(
|
||||||
|
test_string_to_memory__stack_is_too_small =
|
||||||
|
instructions: [
|
||||||
|
Instruction::StringToMemory { allocator_index: 43 }
|
||||||
|
// ^^ `43` expects 1 value on the stack, none is present
|
||||||
|
],
|
||||||
|
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
||||||
|
instance: Instance::new(),
|
||||||
|
error: r#"`string-to-memory 43` cannot call the allocator `43` because there is not enough data on the stack for the arguments (needs 1)."#,
|
||||||
|
);
|
||||||
|
|
||||||
|
test_executable_instruction!(
|
||||||
|
test_string_to_memory__failure_when_calling_the_allocator =
|
||||||
|
instructions: [
|
||||||
|
Instruction::ArgumentGet { index: 0 },
|
||||||
|
Instruction::StringToMemory { allocator_index: 153 }
|
||||||
|
],
|
||||||
|
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
||||||
|
instance: {
|
||||||
|
let mut instance = Instance::new();
|
||||||
|
instance.locals_or_imports.insert(
|
||||||
|
153,
|
||||||
|
LocalImport {
|
||||||
|
inputs: vec![InterfaceType::I32],
|
||||||
|
outputs: vec![InterfaceType::I32],
|
||||||
|
function: |_| Err(()),
|
||||||
|
// ^^^^^^^ function fails
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
instance
|
||||||
|
},
|
||||||
|
error: r#"`string-to-memory 153` failed when calling the allocator `153`."#,
|
||||||
|
);
|
||||||
|
|
||||||
|
test_executable_instruction!(
|
||||||
|
test_string_to_memory__invalid_allocator_signature =
|
||||||
|
instructions: [
|
||||||
|
Instruction::ArgumentGet { index: 0 },
|
||||||
|
Instruction::StringToMemory { allocator_index: 153 }
|
||||||
|
],
|
||||||
|
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
||||||
|
instance: {
|
||||||
|
let mut instance = Instance::new();
|
||||||
|
instance.locals_or_imports.insert(
|
||||||
|
153,
|
||||||
|
LocalImport {
|
||||||
|
inputs: vec![InterfaceType::I32, InterfaceType::I32],
|
||||||
|
outputs: vec![],
|
||||||
|
function: |_| Err(()),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
instance
|
||||||
|
},
|
||||||
|
error: r#"`string-to-memory 153` failed because the allocator `153` has an invalid signature (expects [I32] -> [I32])."#,
|
||||||
|
);
|
||||||
|
}
|
@ -1,169 +0,0 @@
|
|||||||
use crate::interpreter::wasm::values::{InterfaceType, InterfaceValue};
|
|
||||||
use std::convert::TryInto;
|
|
||||||
|
|
||||||
executable_instruction!(
|
|
||||||
write_utf8(allocator_name: String, instruction_name: String) -> _ {
|
|
||||||
move |runtime| -> _ {
|
|
||||||
let instance = &mut runtime.wasm_instance;
|
|
||||||
|
|
||||||
match instance.export(&allocator_name) {
|
|
||||||
Some(allocator) => {
|
|
||||||
if allocator.inputs() != [InterfaceType::I32] ||
|
|
||||||
allocator.outputs() != [InterfaceType::I32] {
|
|
||||||
return Err(format!(
|
|
||||||
"`{}` failed because the allocator `{}` has an invalid signature (expects [I32] -> [I32]).",
|
|
||||||
instruction_name,
|
|
||||||
allocator_name,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
match instance.memory(0) {
|
|
||||||
Some(memory) => match runtime.stack.pop1() {
|
|
||||||
Some(string) => {
|
|
||||||
let memory_view = memory.view();
|
|
||||||
|
|
||||||
let string: String = (&string).try_into()?;
|
|
||||||
let string_bytes = string.as_bytes();
|
|
||||||
let string_length = (string_bytes.len() as i32)
|
|
||||||
.try_into()
|
|
||||||
.map_err(|error| format!("{}", error))?;
|
|
||||||
|
|
||||||
match allocator.call(&[InterfaceValue::I32(string_length)]) {
|
|
||||||
Ok(outputs) => {
|
|
||||||
let string_pointer: i32 = (&outputs[0]).try_into()?;
|
|
||||||
|
|
||||||
for (nth, byte) in string_bytes.iter().enumerate() {
|
|
||||||
memory_view[string_pointer as usize + nth].set(*byte);
|
|
||||||
}
|
|
||||||
|
|
||||||
runtime.stack.push(InterfaceValue::I32(string_pointer));
|
|
||||||
runtime.stack.push(InterfaceValue::I32(string_length));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
Err(_) => Err(format!(
|
|
||||||
"`{}` failed when calling the allocator `{}`.",
|
|
||||||
instruction_name,
|
|
||||||
allocator_name,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => Err(format!(
|
|
||||||
"`{}` cannot call the allocator `{}` because there is not enough data on the stack for the arguments (needs {}).",
|
|
||||||
instruction_name,
|
|
||||||
allocator_name,
|
|
||||||
1
|
|
||||||
))
|
|
||||||
}
|
|
||||||
None => Err(format!(
|
|
||||||
"`{}` failed because there is no memory to write into.",
|
|
||||||
instruction_name
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => Err(format!(
|
|
||||||
"`{}` failed because the exported function `{}` (the allocator) doesn't exist.",
|
|
||||||
instruction_name,
|
|
||||||
allocator_name
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
test_executable_instruction!(
|
|
||||||
test_write_utf8 =
|
|
||||||
instructions: [
|
|
||||||
Instruction::ArgumentGet { index: 0 },
|
|
||||||
Instruction::WriteUtf8 { allocator_name: "alloc" },
|
|
||||||
],
|
|
||||||
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
|
||||||
instance: Instance::new(),
|
|
||||||
stack: [
|
|
||||||
InterfaceValue::I32(0),
|
|
||||||
// ^^^^^^ pointer
|
|
||||||
InterfaceValue::I32(13),
|
|
||||||
// ^^^^^^^ length
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
test_executable_instruction!(
|
|
||||||
test_write_utf8__roundtrip_with_read_utf8 =
|
|
||||||
instructions: [
|
|
||||||
Instruction::ArgumentGet { index: 0 },
|
|
||||||
Instruction::WriteUtf8 { allocator_name: "alloc" },
|
|
||||||
Instruction::ReadUtf8,
|
|
||||||
],
|
|
||||||
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
|
||||||
instance: Instance::new(),
|
|
||||||
stack: [InterfaceValue::String("Hello, World!".into())],
|
|
||||||
);
|
|
||||||
|
|
||||||
test_executable_instruction!(
|
|
||||||
test_write_utf8__allocator_does_not_exist =
|
|
||||||
instructions: [Instruction::WriteUtf8 { allocator_name: "alloc" }],
|
|
||||||
invocation_inputs: [],
|
|
||||||
instance: Instance { ..Default::default() },
|
|
||||||
error: r#"`write-utf8 "alloc"` failed because the exported function `alloc` (the allocator) doesn't exist."#,
|
|
||||||
);
|
|
||||||
|
|
||||||
test_executable_instruction!(
|
|
||||||
test_write_utf8__stack_is_too_small =
|
|
||||||
instructions: [
|
|
||||||
Instruction::WriteUtf8 { allocator_name: "alloc" }
|
|
||||||
// ^^^^^ `alloc` expects 1 value on the stack, none is present
|
|
||||||
],
|
|
||||||
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
|
||||||
instance: Instance::new(),
|
|
||||||
error: r#"`write-utf8 "alloc"` cannot call the allocator `alloc` because there is not enough data on the stack for the arguments (needs 1)."#,
|
|
||||||
);
|
|
||||||
|
|
||||||
test_executable_instruction!(
|
|
||||||
test_write_utf8__failure_when_calling_the_allocator =
|
|
||||||
instructions: [
|
|
||||||
Instruction::ArgumentGet { index: 0 },
|
|
||||||
Instruction::WriteUtf8 { allocator_name: "alloc-fail" }
|
|
||||||
],
|
|
||||||
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
|
||||||
instance: {
|
|
||||||
let mut instance = Instance::new();
|
|
||||||
instance.exports.insert(
|
|
||||||
"alloc-fail".into(),
|
|
||||||
Export {
|
|
||||||
inputs: vec![InterfaceType::I32],
|
|
||||||
outputs: vec![InterfaceType::I32],
|
|
||||||
function: |_| Err(()),
|
|
||||||
// ^^^^^^^ function fails
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
instance
|
|
||||||
},
|
|
||||||
error: r#"`write-utf8 "alloc-fail"` failed when calling the allocator `alloc-fail`."#,
|
|
||||||
);
|
|
||||||
|
|
||||||
test_executable_instruction!(
|
|
||||||
test_write_utf8__invalid_allocator_signature =
|
|
||||||
instructions: [
|
|
||||||
Instruction::ArgumentGet { index: 0 },
|
|
||||||
Instruction::WriteUtf8 { allocator_name: "alloc-fail" }
|
|
||||||
],
|
|
||||||
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
|
||||||
instance: {
|
|
||||||
let mut instance = Instance::new();
|
|
||||||
instance.exports.insert(
|
|
||||||
"alloc-fail".into(),
|
|
||||||
Export {
|
|
||||||
inputs: vec![InterfaceType::I32, InterfaceType::I32],
|
|
||||||
outputs: vec![],
|
|
||||||
function: |_| Err(()),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
instance
|
|
||||||
},
|
|
||||||
error: r#"`write-utf8 "alloc-fail"` failed because the allocator `alloc-fail` has an invalid signature (expects [I32] -> [I32])."#,
|
|
||||||
);
|
|
||||||
}
|
|
@ -71,7 +71,7 @@ pub(crate) type ExecutableInstruction<Instance, Export, LocalImport, Memory, Mem
|
|||||||
/// let interpreter: Interpreter<Instance, Export, LocalImport, Memory, MemoryView> = (&vec![
|
/// let interpreter: Interpreter<Instance, Export, LocalImport, Memory, MemoryView> = (&vec![
|
||||||
/// Instruction::ArgumentGet { index: 1 },
|
/// Instruction::ArgumentGet { index: 1 },
|
||||||
/// Instruction::ArgumentGet { index: 0 },
|
/// Instruction::ArgumentGet { index: 0 },
|
||||||
/// Instruction::CallExport { export_name: "sum" },
|
/// Instruction::CallCore { function_index: 42 },
|
||||||
/// ])
|
/// ])
|
||||||
/// .try_into()
|
/// .try_into()
|
||||||
/// .unwrap();
|
/// .unwrap();
|
||||||
@ -81,12 +81,12 @@ pub(crate) type ExecutableInstruction<Instance, Export, LocalImport, Memory, Mem
|
|||||||
///
|
///
|
||||||
/// // 3. Creates a WebAssembly instance.
|
/// // 3. Creates a WebAssembly instance.
|
||||||
/// let mut instance = Instance {
|
/// let mut instance = Instance {
|
||||||
/// // 3.1. Defines one exported function: `fn sum(a: i32, b: i32) -> i32 { a + b }`.
|
/// // 3.1. Defines one function: `fn sum(a: i32, b: i32) -> i32 { a + b }`.
|
||||||
/// exports: {
|
/// locals_or_imports: {
|
||||||
/// let mut hashmap = HashMap::new();
|
/// let mut hashmap = HashMap::new();
|
||||||
/// hashmap.insert(
|
/// hashmap.insert(
|
||||||
/// "sum".into(),
|
/// 42,
|
||||||
/// Export {
|
/// LocalImport {
|
||||||
/// // Defines the argument types of the function.
|
/// // Defines the argument types of the function.
|
||||||
/// inputs: vec![InterfaceType::I32, InterfaceType::I32],
|
/// inputs: vec![InterfaceType::I32, InterfaceType::I32],
|
||||||
///
|
///
|
||||||
@ -174,8 +174,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Transforms a `Vec<Instruction>` into an `Interpreter`.
|
/// Transforms a `Vec<Instruction>` into an `Interpreter`.
|
||||||
impl<'binary_input, Instance, Export, LocalImport, Memory, MemoryView>
|
impl<Instance, Export, LocalImport, Memory, MemoryView> TryFrom<&Vec<Instruction>>
|
||||||
TryFrom<&Vec<Instruction<'binary_input>>>
|
|
||||||
for Interpreter<Instance, Export, LocalImport, Memory, MemoryView>
|
for Interpreter<Instance, Export, LocalImport, Memory, MemoryView>
|
||||||
where
|
where
|
||||||
Export: wasm::structures::Export,
|
Export: wasm::structures::Export,
|
||||||
@ -196,15 +195,12 @@ where
|
|||||||
Instruction::ArgumentGet { index } => {
|
Instruction::ArgumentGet { index } => {
|
||||||
instructions::argument_get(*index, instruction_name)
|
instructions::argument_get(*index, instruction_name)
|
||||||
}
|
}
|
||||||
Instruction::Call { function_index } => {
|
Instruction::CallCore { function_index } => {
|
||||||
instructions::call(*function_index, instruction_name)
|
instructions::call_core(*function_index, instruction_name)
|
||||||
}
|
}
|
||||||
Instruction::CallExport { export_name } => {
|
Instruction::MemoryToString => instructions::memory_to_string(instruction_name),
|
||||||
instructions::call_export((*export_name).to_owned(), instruction_name)
|
Instruction::StringToMemory { allocator_index } => {
|
||||||
}
|
instructions::string_to_memory(*allocator_index, instruction_name)
|
||||||
Instruction::ReadUtf8 => instructions::read_utf8(instruction_name),
|
|
||||||
Instruction::WriteUtf8 { allocator_name } => {
|
|
||||||
instructions::write_utf8((*allocator_name).to_owned(), instruction_name)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Instruction::I32ToS8 => instructions::i32_to_s8(),
|
Instruction::I32ToS8 => instructions::i32_to_s8(),
|
||||||
@ -253,24 +249,3 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::{wasm::structures::EmptyMemoryView, Instruction, Interpreter};
|
|
||||||
use std::convert::TryInto;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_interpreter_from_instructions() {
|
|
||||||
let instructions = vec![
|
|
||||||
Instruction::ArgumentGet { index: 0 },
|
|
||||||
Instruction::ArgumentGet { index: 0 },
|
|
||||||
Instruction::CallExport { export_name: "foo" },
|
|
||||||
Instruction::ReadUtf8,
|
|
||||||
Instruction::Call { function_index: 7 },
|
|
||||||
];
|
|
||||||
let interpreter: Interpreter<(), (), (), (), EmptyMemoryView> =
|
|
||||||
(&instructions).try_into().unwrap();
|
|
||||||
|
|
||||||
assert_eq!(interpreter.executable_instructions.len(), 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -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.0" }
|
||||||
wasmer-runtime = { path = "../runtime", version = "0.15.0" }
|
wasmer-runtime = { path = "../runtime", version = "0.16.0" }
|
||||||
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.15.0", features = ["test"] }
|
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.16.0", 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.0"
|
||||||
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.0", 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"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-middleware-common-tests"
|
name = "wasmer-middleware-common-tests"
|
||||||
version = "0.15.0"
|
version = "0.16.0"
|
||||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
repository = "https://github.com/wasmerio/wasmer"
|
repository = "https://github.com/wasmerio/wasmer"
|
||||||
@ -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.0" }
|
||||||
wasmer-middleware-common = { path = "../middleware-common", version = "0.15.0" }
|
wasmer-middleware-common = { path = "../middleware-common", version = "0.16.0" }
|
||||||
wasmer-clif-backend = { path = "../clif-backend", version = "0.15.0", optional = true }
|
wasmer-clif-backend = { path = "../clif-backend", version = "0.16.0", 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.0", 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.0", 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.0"
|
||||||
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.0" }
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-runtime-c-api"
|
name = "wasmer-runtime-c-api"
|
||||||
version = "0.15.0"
|
version = "0.16.0"
|
||||||
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.0"
|
||||||
|
|
||||||
[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.0"
|
||||||
|
|
||||||
[dependencies.wasmer-wasi]
|
[dependencies.wasmer-wasi]
|
||||||
default-features = false
|
default-features = false
|
||||||
path = "../wasi"
|
path = "../wasi"
|
||||||
version = "0.15.0"
|
version = "0.16.0"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[dependencies.wasmer-emscripten]
|
[dependencies.wasmer-emscripten]
|
||||||
path = "../emscripten"
|
path = "../emscripten"
|
||||||
version = "0.15.0"
|
version = "0.16.0"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-runtime-core-tests"
|
name = "wasmer-runtime-core-tests"
|
||||||
version = "0.15.0"
|
version = "0.16.0"
|
||||||
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.0" }
|
||||||
wasmer-clif-backend = { path = "../clif-backend", version = "0.15.0", optional = true }
|
wasmer-clif-backend = { path = "../clif-backend", version = "0.16.0", optional = true }
|
||||||
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.15.0", optional = true }
|
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.16.0", 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.0", features = ["test"], optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["backend-cranelift"]
|
default = ["backend-cranelift"]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-runtime-core"
|
name = "wasmer-runtime-core"
|
||||||
version = "0.15.0"
|
version = "0.16.0"
|
||||||
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-runtime"
|
name = "wasmer-runtime"
|
||||||
version = "0.15.0"
|
version = "0.16.0"
|
||||||
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.0", 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.0"
|
||||||
|
|
||||||
[dependencies.wasmer-clif-backend]
|
[dependencies.wasmer-clif-backend]
|
||||||
path = "../clif-backend"
|
path = "../clif-backend"
|
||||||
version = "0.15.0"
|
version = "0.16.0"
|
||||||
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.0"
|
||||||
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.0" }
|
||||||
dynasm = "0.5"
|
dynasm = "0.5"
|
||||||
dynasmrt = "0.5"
|
dynasmrt = "0.5"
|
||||||
lazy_static = "1.4"
|
lazy_static = "1.4"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wasmer-spectests"
|
name = "wasmer-spectests"
|
||||||
version = "0.15.0"
|
version = "0.16.0"
|
||||||
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.0", default-features = false}
|
||||||
wasmer-clif-backend = { path = "../clif-backend", version = "0.15.0", optional = true}
|
wasmer-clif-backend = { path = "../clif-backend", version = "0.16.0", 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.0", 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.0", optional = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
wabt = "0.9.1"
|
wabt = "0.9.1"
|
||||||
|
@ -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.0"
|
||||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
repository = "https://github.com/wasmerio/wasmer"
|
repository = "https://github.com/wasmerio/wasmer"
|
||||||
@ -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.0", path = "../wasi" }
|
||||||
wasmer-runtime-core = { version = "0.15.0", path = "../runtime-core" }
|
wasmer-runtime-core = { version = "0.16.0", 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.0"
|
||||||
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.0", default-features = false }
|
||||||
wasmer-wasi = { path = "../wasi", version = "0.15.0" }
|
wasmer-wasi = { path = "../wasi", version = "0.16.0" }
|
||||||
# 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.0", optional = true}
|
||||||
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.15.0", optional = true }
|
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.16.0", 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.0", 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.0"}
|
||||||
|
|
||||||
[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.0"
|
||||||
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.0" }
|
||||||
|
|
||||||
[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.0"
|
||||||
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.0" }
|
||||||
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.15.0'
|
||||||
NEXT_VERSION='0.15.0'
|
NEXT_VERSION='0.16.0'
|
||||||
|
|
||||||
# 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.0
|
||||||
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 %*
|
Reference in New Issue
Block a user