diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a8de2687..38fab56b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,19 @@ ## **[Unreleased]** - [#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` - [#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` with a length of 0 and `WasmPtr` where `std::mem::size_of::()` is 0 to always return `None` diff --git a/Cargo.lock b/Cargo.lock index ee781d901..3cd09fa0d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1820,7 +1820,7 @@ dependencies = [ [[package]] name = "wasmer" -version = "0.15.0" +version = "0.16.2" dependencies = [ "atty", "byteorder", @@ -1851,7 +1851,7 @@ dependencies = [ [[package]] name = "wasmer-clif-backend" -version = "0.15.0" +version = "0.16.2" dependencies = [ "byteorder", "cranelift-codegen", @@ -1902,14 +1902,14 @@ dependencies = [ [[package]] name = "wasmer-dev-utils" -version = "0.15.0" +version = "0.16.2" dependencies = [ "libc", ] [[package]] name = "wasmer-emscripten" -version = "0.15.0" +version = "0.16.2" dependencies = [ "byteorder", "getrandom", @@ -1922,7 +1922,7 @@ dependencies = [ [[package]] name = "wasmer-emscripten-tests" -version = "0.15.0" +version = "0.16.2" dependencies = [ "glob 0.3.0", "wabt", @@ -1936,7 +1936,7 @@ dependencies = [ [[package]] name = "wasmer-interface-types" -version = "0.15.0" +version = "0.16.2" dependencies = [ "nom", "wast", @@ -1952,7 +1952,7 @@ dependencies = [ [[package]] name = "wasmer-llvm-backend" -version = "0.15.0" +version = "0.16.2" dependencies = [ "byteorder", "cc", @@ -1983,14 +1983,14 @@ dependencies = [ [[package]] name = "wasmer-middleware-common" -version = "0.15.0" +version = "0.16.2" dependencies = [ "wasmer-runtime-core", ] [[package]] name = "wasmer-middleware-common-tests" -version = "0.15.0" +version = "0.16.2" dependencies = [ "criterion", "wabt", @@ -2003,7 +2003,7 @@ dependencies = [ [[package]] name = "wasmer-runtime" -version = "0.15.0" +version = "0.16.2" dependencies = [ "criterion", "lazy_static", @@ -2020,7 +2020,7 @@ dependencies = [ [[package]] name = "wasmer-runtime-c-api" -version = "0.15.0" +version = "0.16.2" dependencies = [ "cbindgen", "libc", @@ -2032,7 +2032,7 @@ dependencies = [ [[package]] name = "wasmer-runtime-core" -version = "0.15.0" +version = "0.16.2" dependencies = [ "bincode", "blake3", @@ -2060,7 +2060,7 @@ dependencies = [ [[package]] name = "wasmer-runtime-core-tests" -version = "0.15.0" +version = "0.16.2" dependencies = [ "wabt", "wasmer-clif-backend", @@ -2071,7 +2071,7 @@ dependencies = [ [[package]] name = "wasmer-singlepass-backend" -version = "0.15.0" +version = "0.16.2" dependencies = [ "bincode", "byteorder", @@ -2088,7 +2088,7 @@ dependencies = [ [[package]] name = "wasmer-spectests" -version = "0.15.0" +version = "0.16.2" dependencies = [ "glob 0.3.0", "wabt", @@ -2100,7 +2100,7 @@ dependencies = [ [[package]] name = "wasmer-wasi" -version = "0.15.0" +version = "0.16.2" dependencies = [ "bincode", "byteorder", @@ -2117,7 +2117,7 @@ dependencies = [ [[package]] name = "wasmer-wasi-experimental-io-devices" -version = "0.15.0" +version = "0.16.2" dependencies = [ "log", "minifb", @@ -2130,7 +2130,7 @@ dependencies = [ [[package]] name = "wasmer-wasi-tests" -version = "0.15.0" +version = "0.16.2" dependencies = [ "glob 0.3.0", "wasmer-clif-backend", @@ -2143,7 +2143,7 @@ dependencies = [ [[package]] name = "wasmer-win-exception-handler" -version = "0.15.0" +version = "0.16.2" dependencies = [ "cmake", "libc", diff --git a/Cargo.toml b/Cargo.toml index b3f532d57..0bb2e9a82 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer" -version = "0.15.0" +version = "0.16.2" authors = ["The Wasmer Engineering Team "] edition = "2018" repository = "https://github.com/wasmerio/wasmer" diff --git a/Makefile b/Makefile index c8f755538..7365279ab 100644 --- a/Makefile +++ b/Makefile @@ -287,7 +287,9 @@ build-install-package: mkdir -p ./install/bin cp ./wapm-cli/target/release/wapm ./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) @@ -315,7 +317,7 @@ endif 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 -WAPM_VERSION = 0.4.3 +WAPM_VERSION = v0.5.0 build-wapm: 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" diff --git a/azure-pipelines.yml b/azure-pipelines.yml index bccae7ddd..07f720e86 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -300,6 +300,7 @@ jobs: isDraft: false isPreRelease: false assets: '$(Build.ArtifactStagingDirectory)/**' + assetUploadMode: 'replace' # Don't delete previously uploaded assets (default) - job: Publish_Docs dependsOn: diff --git a/lib/clif-backend/Cargo.toml b/lib/clif-backend/Cargo.toml index 282f4e2d1..fa24d5ed4 100644 --- a/lib/clif-backend/Cargo.toml +++ b/lib/clif-backend/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-clif-backend" -version = "0.15.0" +version = "0.16.2" description = "Wasmer runtime Cranelift compiler backend" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -11,7 +11,7 @@ edition = "2018" readme = "README.md" [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-codegen = "0.59.0" cranelift-entity = "0.59.0" @@ -38,7 +38,7 @@ version = "0.0.7" [target.'cfg(windows)'.dependencies] 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] generate-debug-information = ["wasm-debug"] diff --git a/lib/clif-backend/src/code.rs b/lib/clif-backend/src/code.rs index 67506f931..ada71d0a3 100644 --- a/lib/clif-backend/src/code.rs +++ b/lib/clif-backend/src/code.rs @@ -209,7 +209,7 @@ impl ModuleCodeGenerator Ok(()) } - fn feed_import_function(&mut self) -> Result<(), CodegenError> { + fn feed_import_function(&mut self, _sigindex: SigIndex) -> Result<(), CodegenError> { Ok(()) } diff --git a/lib/dev-utils/Cargo.toml b/lib/dev-utils/Cargo.toml index 1c06313ba..07800ed61 100644 --- a/lib/dev-utils/Cargo.toml +++ b/lib/dev-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-dev-utils" -version = "0.15.0" +version = "0.16.2" description = "Wasmer runtime core library" license = "MIT" authors = ["The Wasmer Engineering Team "] diff --git a/lib/emscripten-tests/Cargo.toml b/lib/emscripten-tests/Cargo.toml index 2e6e68a6f..5065de08a 100644 --- a/lib/emscripten-tests/Cargo.toml +++ b/lib/emscripten-tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-emscripten-tests" -version = "0.15.0" +version = "0.16.2" description = "Tests for our Emscripten implementation" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -9,15 +9,15 @@ publish = false build = "build/mod.rs" [dependencies] -wasmer-emscripten = { path = "../emscripten", version = "0.15.0" } -wasmer-runtime = { path = "../runtime", version = "0.15.0", default-features = false } -wasmer-clif-backend = { path = "../clif-backend", version = "0.15.0", optional = true} -wasmer-llvm-backend = { path = "../llvm-backend", version = "0.15.0", optional = true, features = ["test"] } -wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.15.0", optional = true } +wasmer-emscripten = { path = "../emscripten", version = "0.16.2" } +wasmer-runtime = { path = "../runtime", version = "0.16.2", default-features = false } +wasmer-clif-backend = { path = "../clif-backend", version = "0.16.2", optional = true} +wasmer-llvm-backend = { path = "../llvm-backend", version = "0.16.2", optional = true, features = ["test"] } +wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.16.2", optional = true } [dev-dependencies] 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] glob = "0.3" diff --git a/lib/emscripten/Cargo.toml b/lib/emscripten/Cargo.toml index 25091e89b..3fb904902 100644 --- a/lib/emscripten/Cargo.toml +++ b/lib/emscripten/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-emscripten" -version = "0.15.0" +version = "0.16.2" description = "Wasmer runtime emscripten implementation library" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -15,7 +15,7 @@ lazy_static = "1.4" libc = "0.2.60" log = "0.4" 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] getrandom = "0.1" diff --git a/lib/interface-types/Cargo.toml b/lib/interface-types/Cargo.toml index 44758c1fe..3bcebd337 100644 --- a/lib/interface-types/Cargo.toml +++ b/lib/interface-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-interface-types" -version = "0.15.0" +version = "0.16.2" description = "WebAssembly Interface Types library for Wasmer" license = "MIT" authors = ["The Wasmer Engineering Team "] diff --git a/lib/llvm-backend-tests/Cargo.toml b/lib/llvm-backend-tests/Cargo.toml index 4a5e7e80c..e916850aa 100644 --- a/lib/llvm-backend-tests/Cargo.toml +++ b/lib/llvm-backend-tests/Cargo.toml @@ -9,8 +9,8 @@ edition = "2018" [dependencies] wabt = "0.9.1" -wasmer-runtime-core = { path = "../runtime-core", version = "0.15.0" } -wasmer-runtime = { path = "../runtime", version = "0.15.0" } -wasmer-llvm-backend = { path = "../llvm-backend", version = "0.15.0", features = ["test"] } +wasmer-runtime-core = { path = "../runtime-core", version = "0.16.2" } +wasmer-runtime = { path = "../runtime", version = "0.16.2" } +wasmer-llvm-backend = { path = "../llvm-backend", version = "0.16.2", features = ["test"] } [features] diff --git a/lib/llvm-backend/Cargo.toml b/lib/llvm-backend/Cargo.toml index cfe2834a8..129d7e374 100644 --- a/lib/llvm-backend/Cargo.toml +++ b/lib/llvm-backend/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-llvm-backend" -version = "0.15.0" +version = "0.16.2" license = "MIT" authors = ["The Wasmer Engineering Team "] repository = "https://github.com/wasmerio/wasmer" @@ -10,7 +10,7 @@ edition = "2018" readme = "README.md" [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" smallvec = "0.6" goblin = "0.0.24" diff --git a/lib/llvm-backend/src/code.rs b/lib/llvm-backend/src/code.rs index 954e0c405..cebde5dae 100644 --- a/lib/llvm-backend/src/code.rs +++ b/lib/llvm-backend/src/code.rs @@ -8984,7 +8984,7 @@ impl<'ctx> ModuleCodeGenerator, LLVMBackend, Cod Ok(()) } - fn feed_import_function(&mut self) -> Result<(), CodegenError> { + fn feed_import_function(&mut self, _sigindex: SigIndex) -> Result<(), CodegenError> { self.func_import_count += 1; Ok(()) } diff --git a/lib/middleware-common-tests/Cargo.toml b/lib/middleware-common-tests/Cargo.toml index f83da0256..22b3d723e 100644 --- a/lib/middleware-common-tests/Cargo.toml +++ b/lib/middleware-common-tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-middleware-common-tests" -version = "0.15.0" +version = "0.16.2" authors = ["The Wasmer Engineering Team "] edition = "2018" repository = "https://github.com/wasmerio/wasmer" @@ -8,11 +8,11 @@ license = "MIT" publish = false [dependencies] -wasmer-runtime-core = { path = "../runtime-core", version = "0.15.0" } -wasmer-middleware-common = { path = "../middleware-common", version = "0.15.0" } -wasmer-clif-backend = { path = "../clif-backend", version = "0.15.0", optional = true } -wasmer-llvm-backend = { path = "../llvm-backend", version = "0.15.0", features = ["test"], optional = true } -wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.15.0", optional = true } +wasmer-runtime-core = { path = "../runtime-core", version = "0.16.2" } +wasmer-middleware-common = { path = "../middleware-common", version = "0.16.2" } +wasmer-clif-backend = { path = "../clif-backend", version = "0.16.2", optional = true } +wasmer-llvm-backend = { path = "../llvm-backend", version = "0.16.2", features = ["test"], optional = true } +wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.16.2", optional = true } [features] clif = ["wasmer-clif-backend"] diff --git a/lib/middleware-common/Cargo.toml b/lib/middleware-common/Cargo.toml index c44fba176..345fff897 100644 --- a/lib/middleware-common/Cargo.toml +++ b/lib/middleware-common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-middleware-common" -version = "0.15.0" +version = "0.16.2" repository = "https://github.com/wasmerio/wasmer" description = "Wasmer runtime common middlewares" license = "MIT" @@ -10,4 +10,4 @@ categories = ["wasm"] edition = "2018" [dependencies] -wasmer-runtime-core = { path = "../runtime-core", version = "0.15.0" } +wasmer-runtime-core = { path = "../runtime-core", version = "0.16.2" } diff --git a/lib/runtime-c-api/Cargo.toml b/lib/runtime-c-api/Cargo.toml index 38c099375..618ba71ba 100644 --- a/lib/runtime-c-api/Cargo.toml +++ b/lib/runtime-c-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-runtime-c-api" -version = "0.15.0" +version = "0.16.2" description = "Wasmer C API library" documentation = "https://wasmerio.github.io/wasmer/c/runtime-c-api/" license = "MIT" @@ -20,22 +20,22 @@ libc = "0.2.60" [dependencies.wasmer-runtime] default-features = false path = "../runtime" -version = "0.15.0" +version = "0.16.2" [dependencies.wasmer-runtime-core] default-features = false path = "../runtime-core" -version = "0.15.0" +version = "0.16.2" [dependencies.wasmer-wasi] default-features = false path = "../wasi" -version = "0.15.0" +version = "0.16.2" optional = true [dependencies.wasmer-emscripten] path = "../emscripten" -version = "0.15.0" +version = "0.16.2" optional = true [features] diff --git a/lib/runtime-c-api/src/trampoline.rs b/lib/runtime-c-api/src/trampoline.rs index ed7b8971b..9555927ea 100644 --- a/lib/runtime-c-api/src/trampoline.rs +++ b/lib/runtime-c-api/src/trampoline.rs @@ -34,6 +34,8 @@ pub unsafe extern "C" fn wasmer_trampoline_buffer_builder_add_context_trampoline } /// 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] #[allow(clippy::cast_ptr_alignment)] 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, num_params: u32, ) -> usize { + use wasmer_runtime_core::types::Type; 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. diff --git a/lib/runtime-c-api/wasmer.h b/lib/runtime-c-api/wasmer.h index 94b2fbb34..7a872f65c 100644 --- a/lib/runtime-c-api/wasmer.h +++ b/lib/runtime-c-api/wasmer.h @@ -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)) /** * 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, const wasmer_trampoline_callable_t *func, diff --git a/lib/runtime-c-api/wasmer.hh b/lib/runtime-c-api/wasmer.hh index 047f8bebb..6bd66d40b 100644 --- a/lib/runtime-c-api/wasmer.hh +++ b/lib/runtime-c-api/wasmer.hh @@ -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)) /// 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, const wasmer_trampoline_callable_t *func, const void *ctx, diff --git a/lib/runtime-core-tests/Cargo.toml b/lib/runtime-core-tests/Cargo.toml index a97b44b08..7ea842d8c 100644 --- a/lib/runtime-core-tests/Cargo.toml +++ b/lib/runtime-core-tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-runtime-core-tests" -version = "0.15.0" +version = "0.16.2" description = "Tests for the Wasmer runtime core crate" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -9,10 +9,10 @@ publish = false [dependencies] wabt = "0.9.1" -wasmer-runtime-core = { path = "../runtime-core", version = "0.15.0" } -wasmer-clif-backend = { path = "../clif-backend", version = "0.15.0", optional = true } -wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.15.0", optional = true } -wasmer-llvm-backend = { path = "../llvm-backend", version = "0.15.0", features = ["test"], optional = true } +wasmer-runtime-core = { path = "../runtime-core", version = "0.16.2" } +wasmer-clif-backend = { path = "../clif-backend", version = "0.16.2", optional = true } +wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.16.2", optional = true } +wasmer-llvm-backend = { path = "../llvm-backend", version = "0.16.2", features = ["test"], optional = true } [features] default = ["backend-cranelift"] diff --git a/lib/runtime-core-tests/tests/imports.rs b/lib/runtime-core-tests/tests/imports.rs index 1af995368..e44d5159f 100644 --- a/lib/runtime-core-tests/tests/imports.rs +++ b/lib/runtime-core-tests/tests/imports.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use std::{convert::TryInto, sync::Arc}; use wasmer_runtime_core::{ compile_with, error::RuntimeError, @@ -12,10 +12,11 @@ use wasmer_runtime_core::{ use wasmer_runtime_core_tests::{get_compiler, wat2wasm}; macro_rules! call_and_assert { - ($instance:ident, $function:ident, $expected_value:expr) => { - let $function: Func = $instance.func(stringify!($function)).unwrap(); + ($instance:ident, $function:ident( $( $inputs:ty ),* ) -> $output:ty, ( $( $arguments:expr ),* ) == $expected_value:expr) => { + #[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) { (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" "callback_fn" (func $callback_fn (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_fn_with_vmctx" (func $callback_fn_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 call $callback_closure) - (func (export "function_closure_dynamic") (type $type) + (func (export "function_fn_dynamic") (type $type) 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) get_local 0 @@ -154,13 +185,73 @@ fn imported_functions_forms(test: &dyn Fn(&Instance)) { 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])), - |_, params| -> Vec { - match params[0] { - Value::I32(x) => vec![Value::I32(x + 1)], - _ => unreachable!() - } + callback_fn_dynamic, + ), + + // Polymorphic closure “closures”. + "callback_closure_dynamic_0" => DynamicFunc::new( + Arc::new(FuncSig::new(vec![], vec![])), + |_, inputs: &[Value]| -> Vec { + 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 { + assert_eq!(inputs.len(), 1); + + let memory = vmctx.memory(0); + let shift_ = shift + memory.view::()[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 { + assert_eq!(inputs.len(), 2); + + let memory = vmctx.memory(0); + let shift_ = shift + memory.view::()[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 { + assert_eq!(inputs.len(), 3); + + let memory = vmctx.memory(0); + let shift_ = shift + memory.view::()[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 { + assert_eq!(inputs.len(), 4); + + let memory = vmctx.memory(0); + let shift_ = shift + memory.view::()[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 { Ok(n + 1) } +fn callback_fn_dynamic(_: &mut vm::Ctx, inputs: &[Value]) -> Vec { + match inputs[0] { + Value::I32(x) => vec![Value::I32(x + 1)], + _ => unreachable!(), + } +} + fn callback_fn_with_vmctx(vmctx: &mut vm::Ctx, n: i32) -> Result { let memory = vmctx.memory(0); let shift_: i32 = memory.view()[0].get(); @@ -246,57 +344,82 @@ fn callback_fn_trap_with_vmctx(vmctx: &mut vm::Ctx, n: i32) -> Result { + ($test_name:ident, $function:ident( $( $inputs:ty ),* ) -> $output:ty, ( $( $arguments:expr ),* ) == $expected_value:expr) => { #[test] fn $test_name() { 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_closure, function_closure, Ok(2)); -test!(test_closure_dynamic, function_closure_dynamic, Ok(2)); +test!(test_fn, function_fn(i32) -> i32, (1) == Ok(2)); +test!(test_closure, function_closure(i32) -> i32, (1) == 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_closure_with_env, - function_closure_with_env, - Ok(2 + shift + SHIFT) + function_closure_with_env(i32) -> i32, + (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_closure_with_vmctx, - function_closure_with_vmctx, - Ok(2 + SHIFT) + function_closure_with_vmctx(i32) -> i32, + (1) == Ok(2 + SHIFT) ); test!( test_closure_with_vmctx_and_env, - function_closure_with_vmctx_and_env, - Ok(2 + shift + SHIFT) + function_closure_with_vmctx_and_env(i32) -> i32, + (1) == Ok(2 + shift + SHIFT) ); test!( test_fn_trap, - function_fn_trap, - Err(RuntimeError(Box::new(format!("foo {}", 2)))) + function_fn_trap(i32) -> i32, + (1) == Err(RuntimeError(Box::new(format!("foo {}", 2)))) ); test!( test_closure_trap, - function_closure_trap, - Err(RuntimeError(Box::new(format!("bar {}", 2)))) + function_closure_trap(i32) -> i32, + (1) == Err(RuntimeError(Box::new(format!("bar {}", 2)))) ); test!( test_fn_trap_with_vmctx, - function_fn_trap_with_vmctx, - Err(RuntimeError(Box::new(format!("baz {}", 2 + SHIFT)))) + function_fn_trap_with_vmctx(i32) -> i32, + (1) == Err(RuntimeError(Box::new(format!("baz {}", 2 + SHIFT)))) ); test!( test_closure_trap_with_vmctx, - function_closure_trap_with_vmctx, - Err(RuntimeError(Box::new(format!("qux {}", 2 + SHIFT)))) + function_closure_trap_with_vmctx(i32) -> i32, + (1) == Err(RuntimeError(Box::new(format!("qux {}", 2 + SHIFT)))) ); test!( test_closure_trap_with_vmctx_and_env, - function_closure_trap_with_vmctx_and_env, - Err(RuntimeError(Box::new(format!("! {}", 2 + shift + SHIFT)))) + function_closure_trap_with_vmctx_and_env(i32) -> i32, + (1) == Err(RuntimeError(Box::new(format!("! {}", 2 + shift + SHIFT)))) ); diff --git a/lib/runtime-core/Cargo.toml b/lib/runtime-core/Cargo.toml index b309a552d..7f6d6a58a 100644 --- a/lib/runtime-core/Cargo.toml +++ b/lib/runtime-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-runtime-core" -version = "0.15.0" +version = "0.16.2" description = "Wasmer runtime core library" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -59,3 +59,5 @@ generate-debug-information = ["wasm-debug"] # don't export symbols related to the GDB JIT interafce, LLVM or some other native # code will be providing them generate-debug-information-no-export-symbols = [] +# enable DynamicFunc's for closures with captured environment. +dynamicfunc-fat-closures = [] diff --git a/lib/runtime-core/src/codegen.rs b/lib/runtime-core/src/codegen.rs index b65234cf4..d3ae27583 100644 --- a/lib/runtime-core/src/codegen.rs +++ b/lib/runtime-core/src/codegen.rs @@ -143,7 +143,7 @@ pub trait ModuleCodeGenerator, RM: RunnableModule, Ok(()) } /// 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. fn feed_signatures(&mut self, signatures: Map) -> Result<(), E>; /// Sets function signatures. diff --git a/lib/runtime-core/src/memory/ptr.rs b/lib/runtime-core/src/memory/ptr.rs index f9c798af1..9e991cb85 100644 --- a/lib/runtime-core/src/memory/ptr.rs +++ b/lib/runtime-core/src/memory/ptr.rs @@ -130,9 +130,10 @@ impl WasmPtr { // for any index, we will always result an aligned memory access let item_size = mem::size_of::() + (mem::size_of::() % mem::align_of::()); 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 - || length == 0 + if (self.offset as usize) + (item_size * slice_full_len) > memory_size + || self.offset as usize >= memory_size || mem::size_of::() == 0 { return None; @@ -167,9 +168,10 @@ impl WasmPtr { // for any index, we will always result an aligned memory access let item_size = mem::size_of::() + (mem::size_of::() % mem::align_of::()); 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 - || length == 0 + || self.offset as usize >= memory_size || mem::size_of::() == 0 { return None; @@ -190,7 +192,11 @@ impl WasmPtr { /// underlying data can be mutated if the Wasm is allowed to execute or /// an aliasing `WasmPtr` is used to mutate memory. 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; } let ptr = unsafe { memory.view::().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(); 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 = WasmPtr::new(0); let start_wasm_ptr_array: WasmPtr = WasmPtr::new(0); assert!(start_wasm_ptr.deref(&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.get_utf8_string(&memory, 0).is_none()); - assert!(unsafe { start_wasm_ptr_array.deref_mut(&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_some()); + 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!(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!(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() { assert!(end_wasm_ptr_array.deref(&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!(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() { assert!(end_wasm_ptr_array.deref(&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() { 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!(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!(unsafe { oob_end_array_ptr.deref_mut(&memory, 1, 0).is_none() }); } diff --git a/lib/runtime-core/src/parse.rs b/lib/runtime-core/src/parse.rs index d2b88f07a..fffb7e4a9 100644 --- a/lib/runtime-core/src/parse.rs +++ b/lib/runtime-core/src/parse.rs @@ -6,8 +6,8 @@ use crate::{ backend::{CompilerConfig, RunnableModule}, error::CompileError, module::{ - DataInitializer, ExportIndex, ImportName, ModuleInfo, StringTable, StringTableBuilder, - TableInitializer, + DataInitializer, ExportIndex, ImportName, ModuleInfo, NameIndex, NamespaceIndex, + StringTable, StringTableBuilder, TableInitializer, }, structures::{Map, TypedIndex}, types::{ @@ -110,11 +110,36 @@ pub fn read_module< let mut namespace_builder = Some(StringTableBuilder::new()); let mut name_builder = Some(StringTableBuilder::new()); 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, + name_builder: StringTableBuilder| + -> 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 { use wasmparser::ParserState; let state = parser.read(); + match *state { ParserState::Error(ref err) => return Err(err.clone().into()), ParserState::TypeSectionEntry(ref ty) => { @@ -124,6 +149,10 @@ pub fn read_module< .push(func_type_to_func_sig(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 name_index = name_builder.as_mut().unwrap().register(field); let import_name = ImportName { @@ -136,7 +165,7 @@ pub fn read_module< let sigindex = SigIndex::new(sigindex as usize); info.write().unwrap().imported_functions.push(import_name); info.write().unwrap().func_assoc.push(sigindex); - mcg.feed_import_function() + mcg.feed_import_function(sigindex) .map_err(|x| LoadError::Codegen(format!("{:?}", x)))?; } ImportSectionEntryType::Table(table_ty) => { @@ -217,23 +246,17 @@ pub fn read_module< info.write().unwrap().start_func = Some(FuncIndex::new(start_index as usize)); } ParserState::BeginFunctionBody { range } => { - 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)))?; + 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 fcg = mcg .next_function( Arc::clone(&info), @@ -432,17 +455,15 @@ pub fn read_module< info.write().unwrap().globals.push(global_init); } ParserState::EndWasm => { - // TODO Consolidate with BeginFunction body if possible - if !mcg_info_fed { - info.write().unwrap().namespace_table = - namespace_builder.take().unwrap().finish(); - info.write().unwrap().name_table = name_builder.take().unwrap().finish(); - mcg.feed_signatures(info.read().unwrap().signatures.clone()) - .map_err(|x| LoadError::Codegen(format!("{:?}", x)))?; - mcg.feed_function_signatures(info.read().unwrap().func_assoc.clone()) - .map_err(|x| LoadError::Codegen(format!("{:?}", x)))?; - mcg.check_precondition(&info.read().unwrap()) - .map_err(|x| LoadError::Codegen(format!("{:?}", x)))?; + 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(), + )?; } break; } diff --git a/lib/runtime-core/src/state.rs b/lib/runtime-core/src/state.rs index 1dfcae813..55809e965 100644 --- a/lib/runtime-core/src/state.rs +++ b/lib/runtime-core/src/state.rs @@ -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)] pub mod x64_decl { use super::*; + use crate::types::Type; /// General-purpose registers. #[repr(u8)] @@ -610,9 +611,88 @@ pub mod x64_decl { _ => 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 { + 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)] pub mod x64 { //! The x64 state module contains functions to generate state and code for x64 targets. diff --git a/lib/runtime-core/src/trampoline_x64.rs b/lib/runtime-core/src/trampoline_x64.rs index 048098321..e85d2d910 100644 --- a/lib/runtime-core/src/trampoline_x64.rs +++ b/lib/runtime-core/src/trampoline_x64.rs @@ -7,6 +7,8 @@ //! Variadic functions are not supported because `rax` is used by the trampoline code. use crate::loader::CodeMemory; +use crate::state::x64_decl::ArgumentRegisterAllocator; +use crate::types::Type; use crate::vm::Ctx; use std::collections::BTreeMap; use std::fmt; @@ -246,44 +248,50 @@ impl TrampolineBufferBuilder { &mut self, target: unsafe extern "C" fn(*const CallContext, *const u64) -> u64, context: *const CallContext, - num_params: u32, + params: &[Type], + _returns: &[Type], ) -> usize { let idx = self.offsets.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 { stack_offset += 8; } self.code.extend_from_slice(&[0x48, 0x81, 0xec]); // sub ?, %rsp self.code.extend_from_slice(value_to_bytes(&stack_offset)); - for i in 0..num_params { - match i { - 0..=5 => { - // mov %?, ?(%rsp) - let prefix: &[u8] = match i { - 0 => &[0x48, 0x89, 0xbc, 0x24], // rdi - 1 => &[0x48, 0x89, 0xb4, 0x24], // rsi - 2 => &[0x48, 0x89, 0x94, 0x24], // rdx - 3 => &[0x48, 0x89, 0x8c, 0x24], // rcx - 4 => &[0x4c, 0x89, 0x84, 0x24], // r8 - 5 => &[0x4c, 0x89, 0x8c, 0x24], // r9 - _ => unreachable!(), - }; + + let mut allocator = ArgumentRegisterAllocator::default(); + + let mut source_stack_count: u32 = 0; // # of allocated slots in the source stack. + + for (i, ty) in params.iter().enumerate() { + match allocator.next(*ty) { + Some(reg) => { + // This argument is allocated to a register. + + let prefix = reg + .prefix_mov_to_stack() + .expect("cannot get instruction prefix for argument register"); 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(&[ 0x48, 0x8b, 0x84, 0x24, // mov ?(%rsp), %rax ]); 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) 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 ctx = TestContext { value: 100 }; - let idx = - builder.add_callinfo_trampoline(do_add, &ctx as *const TestContext as *const _, 8); + let param_types: Vec = vec![Type::I32; 8]; + let idx = builder.add_callinfo_trampoline( + do_add, + &ctx as *const TestContext as *const _, + ¶m_types, + &[Type::I32], + ); let buf = builder.build(); let t = buf.get_trampoline(idx); let ret = unsafe { @@ -407,9 +420,49 @@ mod tests { 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] fn test_many_global_trampolines() { 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 { @@ -427,7 +480,8 @@ mod tests { for i in 0..5000usize { let mut builder = TrampolineBufferBuilder::new(); 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 .insert(builder.code()) .expect("cannot insert new code into global buffer"); diff --git a/lib/runtime-core/src/typed_func.rs b/lib/runtime-core/src/typed_func.rs index 0b29d54ea..6578042a7 100644 --- a/lib/runtime-core/src/typed_func.rs +++ b/lib/runtime-core/src/typed_func.rs @@ -306,16 +306,15 @@ impl<'a> DynamicFunc<'a> { { use crate::trampoline_x64::{CallContext, TrampolineBufferBuilder}; use crate::types::Value; - use std::convert::TryFrom; struct PolymorphicContext { arg_types: Vec, func: Box Vec>, } - unsafe extern "C" fn enter_host_polymorphic( + unsafe fn do_enter_host_polymorphic( ctx: *const CallContext, args: *const u64, - ) -> u64 { + ) -> Vec { let ctx = &*(ctx as *const PolymorphicContext); let vmctx = &mut *(*args.offset(0) as *mut vm::Ctx); let args: Vec = ctx @@ -335,13 +334,40 @@ impl<'a> DynamicFunc<'a> { } }) .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 { 0 } else if rets.len() == 1 { - u64::try_from(rets[0].to_u128()).expect( - "128-bit return value from polymorphic host functions is not yet supported", - ) + match rets[0] { + 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 { panic!( "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 mem::size_of::() != 0 { - unimplemented!("DynamicFunc with captured environment is not yet supported"); + if cfg!(not(feature = "dynamicfunc-fat-closures")) && mem::size_of::() != 0 { + unimplemented!("DynamicFunc with captured environment is disabled"); } let mut builder = TrampolineBufferBuilder::new(); @@ -360,11 +385,29 @@ impl<'a> DynamicFunc<'a> { func: Box::new(func), }); let ctx = Box::into_raw(ctx); - builder.add_callinfo_trampoline( - enter_host_polymorphic, - ctx as *const _, - (signature.params().len() + 1) as u32, // +vmctx - ); + + 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( + unsafe { std::mem::transmute(enter_host_polymorphic_f as usize) }, + ctx as *const _, + &native_param_types, + signature.returns(), + ); + } + _ => { + builder.add_callinfo_trampoline( + enter_host_polymorphic_i, + ctx as *const _, + &native_param_types, + signature.returns(), + ); + } + } + let ptr = builder .insert_global() .expect("cannot bump-allocate global trampoline memory"); diff --git a/lib/runtime/Cargo.toml b/lib/runtime/Cargo.toml index f836c9693..cb3a1d700 100644 --- a/lib/runtime/Cargo.toml +++ b/lib/runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-runtime" -version = "0.15.0" +version = "0.16.2" description = "Wasmer runtime library" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -11,17 +11,17 @@ edition = "2018" readme = "README.md" [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" memmap = "0.7" [dependencies.wasmer-runtime-core] path = "../runtime-core" -version = "0.15.0" +version = "0.16.2" [dependencies.wasmer-clif-backend] path = "../clif-backend" -version = "0.15.0" +version = "0.16.2" optional = true # Dependencies for caching. diff --git a/lib/singlepass-backend/Cargo.toml b/lib/singlepass-backend/Cargo.toml index b1964dc3d..889492287 100644 --- a/lib/singlepass-backend/Cargo.toml +++ b/lib/singlepass-backend/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-singlepass-backend" -version = "0.15.0" +version = "0.16.2" repository = "https://github.com/wasmerio/wasmer" description = "Wasmer runtime single pass compiler backend" license = "MIT" @@ -11,7 +11,7 @@ edition = "2018" readme = "README.md" [dependencies] -wasmer-runtime-core = { path = "../runtime-core", version = "0.15.0" } +wasmer-runtime-core = { path = "../runtime-core", version = "0.16.2" } dynasm = "0.5" dynasmrt = "0.5" lazy_static = "1.4" diff --git a/lib/singlepass-backend/src/codegen_x64.rs b/lib/singlepass-backend/src/codegen_x64.rs index 78bc0af9a..5903508fc 100644 --- a/lib/singlepass-backend/src/codegen_x64.rs +++ b/lib/singlepass-backend/src/codegen_x64.rs @@ -32,8 +32,9 @@ use wasmer_runtime_core::{ memory::MemoryType, module::{ModuleInfo, ModuleInner}, state::{ - x64::new_machine_state, x64::X64Register, FunctionStateMap, MachineState, MachineValue, - ModuleStateMap, OffsetInfo, SuspendOffset, WasmAbstractValue, + x64::new_machine_state, x64::X64Register, x64_decl::ArgumentRegisterAllocator, + FunctionStateMap, MachineState, MachineValue, ModuleStateMap, OffsetInfo, SuspendOffset, + WasmAbstractValue, }, structures::{Map, TypedIndex}, typed_func::{Trampoline, Wasm}, @@ -204,6 +205,7 @@ pub struct X64FunctionCode { signatures: Arc>, function_signatures: Arc>, + signature: FuncSig, fsm: FunctionStateMap, offset: usize, @@ -712,11 +714,22 @@ impl ModuleCodeGenerator machine.track_state = self.config.as_ref().unwrap().track_state; 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 { local_function_id: self.functions.len(), - signatures: self.signatures.as_ref().unwrap().clone(), - function_signatures: self.function_signatures.as_ref().unwrap().clone(), + signatures: signatures.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` offset: begin_offset.0, @@ -869,7 +882,7 @@ impl ModuleCodeGenerator 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 id = labels.len(); @@ -880,6 +893,92 @@ impl ModuleCodeGenerator a.emit_label(label); 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 = 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 // from Ctx and jumps to it. @@ -6260,7 +6359,14 @@ impl FunctionCodeGenerator for X64FunctionCode { false, )[0]; self.value_stack.push(ret); - a.emit_mov(Size::S64, Location::GPR(GPR::RAX), 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); + } + } } } Operator::CallIndirect { index, table_index } => { @@ -6399,7 +6505,14 @@ impl FunctionCodeGenerator for X64FunctionCode { false, )[0]; self.value_stack.push(ret); - a.emit_mov(Size::S64, Location::GPR(GPR::RAX), 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); + } + } } } Operator::If { ty } => { @@ -7614,6 +7727,18 @@ impl FunctionCodeGenerator for X64FunctionCode { self.machine.finalize_locals(a, &self.locals); a.emit_mov(Size::S64, Location::GPR(GPR::RBP), Location::GPR(GPR::RSP)); 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(); } else { let released = &self.value_stack[frame.value_stack_depth..]; diff --git a/lib/spectests/Cargo.toml b/lib/spectests/Cargo.toml index c5497c476..a4b6576ce 100644 --- a/lib/spectests/Cargo.toml +++ b/lib/spectests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-spectests" -version = "0.15.0" +version = "0.16.2" description = "Wasmer spectests library" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -9,10 +9,10 @@ edition = "2018" [dependencies] glob = "0.3" -wasmer-runtime = { path = "../runtime", version = "0.15.0", default-features = false} -wasmer-clif-backend = { path = "../clif-backend", version = "0.15.0", optional = true} -wasmer-llvm-backend = { path = "../llvm-backend", version = "0.15.0", features = ["test"], optional = true } -wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.15.0", optional = true } +wasmer-runtime = { path = "../runtime", version = "0.16.2", default-features = false} +wasmer-clif-backend = { path = "../clif-backend", version = "0.16.2", optional = true} +wasmer-llvm-backend = { path = "../llvm-backend", version = "0.16.2", features = ["test"], optional = true } +wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.16.2", optional = true } [build-dependencies] wabt = "0.9.1" diff --git a/lib/spectests/tests/spectest.rs b/lib/spectests/tests/spectest.rs index 514403d70..409a9d908 100644 --- a/lib/spectests/tests/spectest.rs +++ b/lib/spectests/tests/spectest.rs @@ -256,6 +256,16 @@ mod tests { 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::() { + format!("{}", s) + } else { + "(unknown)".into() + } + } + fn parse_and_run( path: &PathBuf, file_excludes: &HashSet, @@ -342,7 +352,7 @@ mod tests { file: filename.to_string(), line: line, kind: format!("{}", "Module"), - message: format!("caught panic {:?}", e), + message: format!("caught panic {}", format_panic(&e)), }, &test_key, excludes, @@ -798,7 +808,7 @@ mod tests { file: filename.to_string(), line: line, kind: format!("{}", "AssertInvalid"), - message: format!("caught panic {:?}", p), + message: format!("caught panic {}", format_panic(&p)), }, &test_key, excludes, @@ -851,7 +861,7 @@ mod tests { file: filename.to_string(), line: line, kind: format!("{}", "AssertMalformed"), - message: format!("caught panic {:?}", p), + message: format!("caught panic {}", format_panic(&p)), }, &test_key, excludes, @@ -975,7 +985,7 @@ mod tests { file: filename.to_string(), line: line, kind: format!("{}", "AssertUnlinkable"), - message: format!("caught panic {:?}", e), + message: format!("caught panic {}", format_panic(&e)), }, &test_key, excludes, diff --git a/lib/wasi-experimental-io-devices/Cargo.toml b/lib/wasi-experimental-io-devices/Cargo.toml index 32c8e266b..06421d396 100644 --- a/lib/wasi-experimental-io-devices/Cargo.toml +++ b/lib/wasi-experimental-io-devices/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-wasi-experimental-io-devices" -version = "0.15.0" +version = "0.16.2" authors = ["The Wasmer Engineering Team "] edition = "2018" repository = "https://github.com/wasmerio/wasmer" @@ -14,8 +14,8 @@ maintenance = { status = "experimental" } [dependencies] log = "0.4" minifb = "0.13" -wasmer-wasi = { version = "0.15.0", path = "../wasi" } -wasmer-runtime-core = { version = "0.15.0", path = "../runtime-core" } +wasmer-wasi = { version = "0.16.2", path = "../wasi" } +wasmer-runtime-core = { version = "0.16.2", path = "../runtime-core" } ref_thread_local = "0.0" serde = "1" typetag = "0.1" diff --git a/lib/wasi-tests/Cargo.toml b/lib/wasi-tests/Cargo.toml index c7208be5d..3a542ab7a 100644 --- a/lib/wasi-tests/Cargo.toml +++ b/lib/wasi-tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-wasi-tests" -version = "0.15.0" +version = "0.16.2" description = "Tests for our WASI implementation" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -10,18 +10,18 @@ build = "build/mod.rs" [dependencies] # 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-wasi = { path = "../wasi", version = "0.15.0" } +wasmer-runtime = { path = "../runtime", version = "0.16.2", default-features = false } +wasmer-wasi = { path = "../wasi", version = "0.16.2" } # hack to get tests to work -wasmer-clif-backend = { path = "../clif-backend", version = "0.15.0", optional = true} -wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.15.0", optional = true } -wasmer-llvm-backend = { path = "../llvm-backend", version = "0.15.0", features = ["test"], optional = true } +wasmer-clif-backend = { path = "../clif-backend", version = "0.16.2", optional = true} +wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.16.2", optional = true } +wasmer-llvm-backend = { path = "../llvm-backend", version = "0.16.2", features = ["test"], optional = true } [build-dependencies] glob = "0.3" [dev-dependencies] -wasmer-dev-utils = { path = "../dev-utils", version = "0.15.0"} +wasmer-dev-utils = { path = "../dev-utils", version = "0.16.2"} [features] clif = ["wasmer-clif-backend", "wasmer-runtime/default-backend-cranelift"] diff --git a/lib/wasi/Cargo.toml b/lib/wasi/Cargo.toml index 35886c948..e26bf73e3 100644 --- a/lib/wasi/Cargo.toml +++ b/lib/wasi/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-wasi" -version = "0.15.0" +version = "0.16.2" description = "Wasmer runtime WASI implementation library" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -19,7 +19,7 @@ getrandom = "0.1" time = "0.1" typetag = "0.1" 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] winapi = "0.3" diff --git a/lib/win-exception-handler/Cargo.toml b/lib/win-exception-handler/Cargo.toml index 0a92ae94b..02d5c54b4 100644 --- a/lib/win-exception-handler/Cargo.toml +++ b/lib/win-exception-handler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-win-exception-handler" -version = "0.15.0" +version = "0.16.2" description = "Wasmer runtime exception handling for Windows" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -8,7 +8,7 @@ repository = "https://github.com/wasmerio/wasmer" edition = "2018" [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"] } libc = "0.2.60" diff --git a/scripts/update_version_numbers.sh b/scripts/update_version_numbers.sh index 77392a5a3..c436e38b7 100755 --- a/scripts/update_version_numbers.sh +++ b/scripts/update_version_numbers.sh @@ -1,5 +1,5 @@ -PREVIOUS_VERSION='0.14.1' -NEXT_VERSION='0.15.0' +PREVIOUS_VERSION='0.16.1' +NEXT_VERSION='0.16.2' # quick hack fd Cargo.toml --exec sed -i '' "s/version = \"$PREVIOUS_VERSION\"/version = \"$NEXT_VERSION\"/" diff --git a/src/installer/media/wizard_logo.ico b/src/installer/media/wizard_logo.ico index 664b0d7a1..80d69b055 100644 Binary files a/src/installer/media/wizard_logo.ico and b/src/installer/media/wizard_logo.ico differ diff --git a/src/installer/media/wizard_logo_2.bmp b/src/installer/media/wizard_logo_2.bmp index 959d76829..91c93bac3 100644 Binary files a/src/installer/media/wizard_logo_2.bmp and b/src/installer/media/wizard_logo_2.bmp differ diff --git a/src/installer/media/wizard_logo_small.bmp b/src/installer/media/wizard_logo_small.bmp index 9ca204fca..03d6e4dec 100644 Binary files a/src/installer/media/wizard_logo_small.bmp and b/src/installer/media/wizard_logo_small.bmp differ diff --git a/src/installer/wasmer.iss b/src/installer/wasmer.iss index 408a92e39..767409584 100644 --- a/src/installer/wasmer.iss +++ b/src/installer/wasmer.iss @@ -1,6 +1,6 @@ [Setup] AppName=Wasmer -AppVersion=0.15.0 +AppVersion=0.16.2 DefaultDirName={pf}\Wasmer DefaultGroupName=Wasmer Compression=lzma2 @@ -23,6 +23,7 @@ Root: HKCU; Subkey: "Environment"; ValueType:string; ValueName: "WASMER_CACHE_DI [Files] Source: "..\..\target\release\wasmer.exe"; DestDir: "{app}\bin" Source: "..\..\wapm-cli\target\release\wapm.exe"; DestDir: "{app}\bin" +Source: "wax.cmd"; DestDir: "{app}\bin" [Dirs] Name: "{%USERPROFILE}\.wasmer" diff --git a/src/installer/wax.cmd b/src/installer/wax.cmd new file mode 100644 index 000000000..efe9eaffb --- /dev/null +++ b/src/installer/wax.cmd @@ -0,0 +1,2 @@ +@echo off +wapm.exe execute %*