From 170ffa276634045549bf6d329e3da1c3a57f0492 Mon Sep 17 00:00:00 2001 From: Yaron Wittenstein Date: Mon, 7 Oct 2019 13:01:54 +0300 Subject: [PATCH 01/11] adding tests for `state_creator` of `import_object` --- lib/runtime-core/src/import.rs | 50 ++++++++++++++++++++++++++++++++++ lib/runtime-core/src/lib.rs | 2 +- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/lib/runtime-core/src/import.rs b/lib/runtime-core/src/import.rs index 9d86205b156..aef51405549 100644 --- a/lib/runtime-core/src/import.rs +++ b/lib/runtime-core/src/import.rs @@ -254,6 +254,56 @@ mod test { use crate::export::Export; use crate::global::Global; use crate::types::Value; + use std::ffi::c_void; + use std::sync::Arc; + + struct Data { + inner: *const c_void, + } + + unsafe impl Send for Data {} + unsafe impl Sync for Data {} + + fn dummy_state_creator(data: Arc) -> (*mut c_void, fn(*mut c_void)) { + let data: *mut Data = Arc::into_raw(data) as _; + + (data as _, |_| {}) + } + + #[test] + fn state_creator_fn() { + let ptr = std::ptr::null(); + + let data = Arc::new(Data { inner: ptr }); + + let imports = imports! { + move || dummy_state_creator(Arc::clone(&data)), + }; + + let (state, _dtor) = imports.call_state_creator().unwrap(); + let data: &mut Data = unsafe { &mut *(state as *mut Data) }; + + assert_eq!(ptr, data.inner); + } + + #[test] + fn state_creator_closure() { + let ptr = std::ptr::null(); + + let data = Arc::new(Data { inner: ptr }); + + let imports = imports! { + move || { + let data: *mut Data = Arc::into_raw(Arc::clone(&data)) as _; + (data as _, |_| {}) + }, + }; + + let (state, _dtor) = imports.call_state_creator().unwrap(); + let data: &mut Data = unsafe { &mut *(state as *mut Data) }; + + assert_eq!(ptr, data.inner); + } #[test] fn extending_works() { diff --git a/lib/runtime-core/src/lib.rs b/lib/runtime-core/src/lib.rs index 26a76f7dbf6..d9c0d06f0b3 100644 --- a/lib/runtime-core/src/lib.rs +++ b/lib/runtime-core/src/lib.rs @@ -1,4 +1,4 @@ -#![deny( +#![allow( dead_code, nonstandard_style, unused_imports, From 6ca581279811aee9d26d77ed2b7372a6153fe3bf Mon Sep 17 00:00:00 2001 From: Yaron Wittenstein Date: Mon, 7 Oct 2019 16:58:58 +0300 Subject: [PATCH 02/11] When `deterministic` feature will be enabled (turned-off by default) it'll guarantee deterministic execution of wasm programs across different hardware/circumstances. This is very useful for Blockchain projects having wasm smart-contracts This is critical for Blockchain projects that require execution to be deterministic in order to reach a consensus of the state transition of each smart-contract transaction. --- Cargo.toml | 4 +++- lib/runtime-core/Cargo.toml | 1 + lib/runtime-core/src/codegen.rs | 3 +++ lib/runtime-core/src/lib.rs | 3 +++ lib/runtime/Cargo.toml | 1 + lib/runtime/src/lib.rs | 12 +++++++----- lib/singlepass-backend/Cargo.toml | 4 ++++ 7 files changed, 22 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4d619059e35..93479c41598 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ wabt = "0.9.1" wasmer-clif-backend = { path = "lib/clif-backend" } wasmer-singlepass-backend = { path = "lib/singlepass-backend", optional = true } wasmer-middleware-common = { path = "lib/middleware-common" } -wasmer-runtime = { path = "lib/runtime" } +wasmer-runtime = { path = "lib/runtime", default-features = false } wasmer-runtime-core = { path = "lib/runtime-core" } wasmer-emscripten = { path = "lib/emscripten" } wasmer-llvm-backend = { path = "lib/llvm-backend", optional = true } @@ -101,6 +101,8 @@ backend-singlepass = [ wasi = ["wasmer-wasi"] managed = ["backend-singlepass", "wasmer-runtime-core/managed"] +deterministic = ["wasmer-runtime/deterministic"] + [[example]] name = "plugin" crate-type = ["bin"] diff --git a/lib/runtime-core/Cargo.toml b/lib/runtime-core/Cargo.toml index 7fd9e32e835..ee1fd19ebff 100644 --- a/lib/runtime-core/Cargo.toml +++ b/lib/runtime-core/Cargo.toml @@ -58,3 +58,4 @@ trace = ["debug"] "backend-singlepass" = [] "backend-llvm" = [] managed = [] +deterministic = ["wasmparser/deterministic"] diff --git a/lib/runtime-core/src/codegen.rs b/lib/runtime-core/src/codegen.rs index 3db1b374368..7027d6266a3 100644 --- a/lib/runtime-core/src/codegen.rs +++ b/lib/runtime-core/src/codegen.rs @@ -145,6 +145,9 @@ pub fn validating_parser_config(features: &Features) -> wasmparser::ValidatingPa enable_simd: features.simd, enable_bulk_memory: false, enable_multi_value: false, + + #[cfg(feature = "deterministic")] + deterministic_only: true, }, } } diff --git a/lib/runtime-core/src/lib.rs b/lib/runtime-core/src/lib.rs index 26a76f7dbf6..d933b555f30 100644 --- a/lib/runtime-core/src/lib.rs +++ b/lib/runtime-core/src/lib.rs @@ -145,6 +145,9 @@ pub fn validate_and_report_errors_with_features( enable_multi_value: false, enable_reference_types: false, enable_threads: features.threads, + + #[cfg(feature = "deterministic")] + deterministic_only: true, }, }; let mut parser = wasmparser::ValidatingParser::new(wasm, Some(config)); diff --git a/lib/runtime/Cargo.toml b/lib/runtime/Cargo.toml index 2e42055c2e4..a3a59f7e50e 100644 --- a/lib/runtime/Cargo.toml +++ b/lib/runtime/Cargo.toml @@ -41,6 +41,7 @@ singlepass = ["wasmer-singlepass-backend"] default-backend-singlepass = ["singlepass"] default-backend-llvm = ["llvm"] default-backend-cranelift = ["cranelift"] +deterministic = ["wasmer-singlepass-backend/deterministic"] [[bench]] name = "nginx" diff --git a/lib/runtime/src/lib.rs b/lib/runtime/src/lib.rs index 2945ff3d534..3505de6492d 100644 --- a/lib/runtime/src/lib.rs +++ b/lib/runtime/src/lib.rs @@ -70,7 +70,7 @@ //! let value = add_one.call(42)?; //! //! assert_eq!(value, 43); -//! +//! //! Ok(()) //! } //! ``` @@ -199,13 +199,15 @@ pub fn default_compiler() -> impl Compiler { feature = "default-backend-llvm", any( feature = "default-backend-cranelift", - feature = "default-backend-singlepass" + feature = "default-backend-singlepass", + feature = "deterministic" ) ), all( feature = "default-backend-cranelift", - feature = "default-backend-singlepass" - ) + any(feature = "default-backend-singlepass", feature = "deterministic") + ), + all(feature = "default-backend-singlepass", feature = "deterministic") ))] compile_error!( "The `default-backend-X` features are mutually exclusive. Please choose just one" @@ -214,7 +216,7 @@ pub fn default_compiler() -> impl Compiler { #[cfg(feature = "default-backend-llvm")] use wasmer_llvm_backend::LLVMCompiler as DefaultCompiler; - #[cfg(feature = "default-backend-singlepass")] + #[cfg(any(feature = "default-backend-singlepass", feature = "deterministic"))] use wasmer_singlepass_backend::SinglePassCompiler as DefaultCompiler; #[cfg(feature = "default-backend-cranelift")] diff --git a/lib/singlepass-backend/Cargo.toml b/lib/singlepass-backend/Cargo.toml index 5243cc60150..d6dc63c7a2d 100644 --- a/lib/singlepass-backend/Cargo.toml +++ b/lib/singlepass-backend/Cargo.toml @@ -18,3 +18,7 @@ byteorder = "1.3" nix = "0.15" libc = "0.2.60" smallvec = "0.6" + +[features] +default = [] +deterministic = ["wasmparser/deterministic", "wasmer-runtime-core/deterministic"] From 4adfbc4f01f83c31d995f5f05480442c2ecdf4a6 Mon Sep 17 00:00:00 2001 From: Yaron Wittenstein Date: Mon, 7 Oct 2019 22:02:33 +0300 Subject: [PATCH 03/11] fixes to PR --- lib/runtime-core/src/import.rs | 8 +++----- lib/runtime-core/src/lib.rs | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/runtime-core/src/import.rs b/lib/runtime-core/src/import.rs index aef51405549..51bfda71a33 100644 --- a/lib/runtime-core/src/import.rs +++ b/lib/runtime-core/src/import.rs @@ -258,7 +258,7 @@ mod test { use std::sync::Arc; struct Data { - inner: *const c_void, + inner: *const u32, } unsafe impl Send for Data {} @@ -272,8 +272,7 @@ mod test { #[test] fn state_creator_fn() { - let ptr = std::ptr::null(); - + let ptr = &0xAABBCCDDu32 as *const u32; let data = Arc::new(Data { inner: ptr }); let imports = imports! { @@ -288,8 +287,7 @@ mod test { #[test] fn state_creator_closure() { - let ptr = std::ptr::null(); - + let ptr = &0xAABBCCDDu32 as *const u32; let data = Arc::new(Data { inner: ptr }); let imports = imports! { diff --git a/lib/runtime-core/src/lib.rs b/lib/runtime-core/src/lib.rs index d9c0d06f0b3..26a76f7dbf6 100644 --- a/lib/runtime-core/src/lib.rs +++ b/lib/runtime-core/src/lib.rs @@ -1,4 +1,4 @@ -#![allow( +#![deny( dead_code, nonstandard_style, unused_imports, From 7ce5ec4df9ad6056b77389321003229253cddaa8 Mon Sep 17 00:00:00 2001 From: Yaron Wittenstein Date: Mon, 7 Oct 2019 22:34:32 +0300 Subject: [PATCH 04/11] fixes to PR comments --- Cargo.toml | 3 +-- lib/runtime/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 93479c41598..467e65419e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ wabt = "0.9.1" wasmer-clif-backend = { path = "lib/clif-backend" } wasmer-singlepass-backend = { path = "lib/singlepass-backend", optional = true } wasmer-middleware-common = { path = "lib/middleware-common" } -wasmer-runtime = { path = "lib/runtime", default-features = false } +wasmer-runtime = { path = "lib/runtime" } wasmer-runtime-core = { path = "lib/runtime-core" } wasmer-emscripten = { path = "lib/emscripten" } wasmer-llvm-backend = { path = "lib/llvm-backend", optional = true } @@ -100,7 +100,6 @@ backend-singlepass = [ ] wasi = ["wasmer-wasi"] managed = ["backend-singlepass", "wasmer-runtime-core/managed"] - deterministic = ["wasmer-runtime/deterministic"] [[example]] diff --git a/lib/runtime/Cargo.toml b/lib/runtime/Cargo.toml index a3a59f7e50e..838eed3ce57 100644 --- a/lib/runtime/Cargo.toml +++ b/lib/runtime/Cargo.toml @@ -41,7 +41,7 @@ singlepass = ["wasmer-singlepass-backend"] default-backend-singlepass = ["singlepass"] default-backend-llvm = ["llvm"] default-backend-cranelift = ["cranelift"] -deterministic = ["wasmer-singlepass-backend/deterministic"] +deterministic = ["wasmer-singlepass-backend/deterministic", "wasmer-runtime-core/deterministic"] [[bench]] name = "nginx" From 899099f3256a1c9ced175d9864da6a7ca5166cd7 Mon Sep 17 00:00:00 2001 From: Yaron Wittenstein Date: Mon, 7 Oct 2019 22:58:46 +0300 Subject: [PATCH 05/11] Cargo.toml - removing `deterministic` feature flag --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 467e65419e5..4d619059e35 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -100,7 +100,6 @@ backend-singlepass = [ ] wasi = ["wasmer-wasi"] managed = ["backend-singlepass", "wasmer-runtime-core/managed"] -deterministic = ["wasmer-runtime/deterministic"] [[example]] name = "plugin" From 3489bfb9b9814f84424b63cff7dec297a6a4f1d6 Mon Sep 17 00:00:00 2001 From: Yaron Wittenstein Date: Mon, 7 Oct 2019 23:07:20 +0300 Subject: [PATCH 06/11] renamed feature flag `deterministic` to `deterministic-execution` --- lib/runtime-core/Cargo.toml | 2 +- lib/runtime-core/src/codegen.rs | 2 +- lib/runtime-core/src/lib.rs | 2 +- lib/runtime/Cargo.toml | 2 +- lib/runtime/src/lib.rs | 22 ++++++++++++++++------ lib/singlepass-backend/Cargo.toml | 2 +- 6 files changed, 21 insertions(+), 11 deletions(-) diff --git a/lib/runtime-core/Cargo.toml b/lib/runtime-core/Cargo.toml index ee1fd19ebff..f4f80d985c5 100644 --- a/lib/runtime-core/Cargo.toml +++ b/lib/runtime-core/Cargo.toml @@ -58,4 +58,4 @@ trace = ["debug"] "backend-singlepass" = [] "backend-llvm" = [] managed = [] -deterministic = ["wasmparser/deterministic"] +deterministic-execution = ["wasmparser/deterministic"] diff --git a/lib/runtime-core/src/codegen.rs b/lib/runtime-core/src/codegen.rs index 7027d6266a3..8d98bb0c0f9 100644 --- a/lib/runtime-core/src/codegen.rs +++ b/lib/runtime-core/src/codegen.rs @@ -146,7 +146,7 @@ pub fn validating_parser_config(features: &Features) -> wasmparser::ValidatingPa enable_bulk_memory: false, enable_multi_value: false, - #[cfg(feature = "deterministic")] + #[cfg(feature = "deterministic-execution")] deterministic_only: true, }, } diff --git a/lib/runtime-core/src/lib.rs b/lib/runtime-core/src/lib.rs index d933b555f30..accea76414d 100644 --- a/lib/runtime-core/src/lib.rs +++ b/lib/runtime-core/src/lib.rs @@ -146,7 +146,7 @@ pub fn validate_and_report_errors_with_features( enable_reference_types: false, enable_threads: features.threads, - #[cfg(feature = "deterministic")] + #[cfg(feature = "deterministic-execution")] deterministic_only: true, }, }; diff --git a/lib/runtime/Cargo.toml b/lib/runtime/Cargo.toml index 838eed3ce57..8ed986c5041 100644 --- a/lib/runtime/Cargo.toml +++ b/lib/runtime/Cargo.toml @@ -41,7 +41,7 @@ singlepass = ["wasmer-singlepass-backend"] default-backend-singlepass = ["singlepass"] default-backend-llvm = ["llvm"] default-backend-cranelift = ["cranelift"] -deterministic = ["wasmer-singlepass-backend/deterministic", "wasmer-runtime-core/deterministic"] +deterministic-execution = ["wasmer-singlepass-backend/deterministic-execution", "wasmer-runtime-core/deterministic-execution"] [[bench]] name = "nginx" diff --git a/lib/runtime/src/lib.rs b/lib/runtime/src/lib.rs index 3505de6492d..903dc47836e 100644 --- a/lib/runtime/src/lib.rs +++ b/lib/runtime/src/lib.rs @@ -200,14 +200,20 @@ pub fn default_compiler() -> impl Compiler { any( feature = "default-backend-cranelift", feature = "default-backend-singlepass", - feature = "deterministic" + feature = "deterministic-execution" ) ), all( feature = "default-backend-cranelift", - any(feature = "default-backend-singlepass", feature = "deterministic") + any( + feature = "default-backend-singlepass", + feature = "deterministic-execution" + ) ), - all(feature = "default-backend-singlepass", feature = "deterministic") + all( + feature = "default-backend-singlepass", + feature = "deterministic-execution" + ) ))] compile_error!( "The `default-backend-X` features are mutually exclusive. Please choose just one" @@ -216,7 +222,10 @@ pub fn default_compiler() -> impl Compiler { #[cfg(feature = "default-backend-llvm")] use wasmer_llvm_backend::LLVMCompiler as DefaultCompiler; - #[cfg(any(feature = "default-backend-singlepass", feature = "deterministic"))] + #[cfg(any( + feature = "default-backend-singlepass", + feature = "deterministic-execution" + ))] use wasmer_singlepass_backend::SinglePassCompiler as DefaultCompiler; #[cfg(feature = "default-backend-cranelift")] @@ -235,7 +244,7 @@ pub fn compiler_for_backend(backend: Backend) -> Option> { #[cfg(feature = "cranelift")] Backend::Cranelift => Some(Box::new(wasmer_clif_backend::CraneliftCompiler::new())), - #[cfg(feature = "singlepass")] + #[cfg(any(feature = "singlepass", feature = "deterministic-execution"))] Backend::Singlepass => Some(Box::new( wasmer_singlepass_backend::SinglePassCompiler::new(), )), @@ -246,7 +255,8 @@ pub fn compiler_for_backend(backend: Backend) -> Option> { #[cfg(any( not(feature = "llvm"), not(feature = "singlepass"), - not(feature = "cranelift") + not(feature = "cranelift"), + not(feature = "deterministic-execution"), ))] _ => None, } diff --git a/lib/singlepass-backend/Cargo.toml b/lib/singlepass-backend/Cargo.toml index d6dc63c7a2d..e3a40548ecd 100644 --- a/lib/singlepass-backend/Cargo.toml +++ b/lib/singlepass-backend/Cargo.toml @@ -21,4 +21,4 @@ smallvec = "0.6" [features] default = [] -deterministic = ["wasmparser/deterministic", "wasmer-runtime-core/deterministic"] +deterministic-execution = ["wasmparser/deterministic", "wasmer-runtime-core/deterministic-execution"] From 176b938cb617493faa4fff33727eeecda5baa82a Mon Sep 17 00:00:00 2001 From: Mark McCaskey <5770194+MarkMcCaskey@users.noreply.github.com> Date: Thu, 5 Dec 2019 11:59:26 -0800 Subject: [PATCH 07/11] Remove wasmparser dep from singlepass --- lib/singlepass-backend/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/singlepass-backend/Cargo.toml b/lib/singlepass-backend/Cargo.toml index eb292dbcbc7..7b9e424b501 100644 --- a/lib/singlepass-backend/Cargo.toml +++ b/lib/singlepass-backend/Cargo.toml @@ -25,4 +25,4 @@ bincode = "1.2" [features] default = [] -deterministic-execution = ["wasmparser/deterministic", "wasmer-runtime-core/deterministic-execution"] \ No newline at end of file +deterministic-execution = ["wasmer-runtime-core/deterministic-execution"] From d144976da045db011c697a22003948e4736e9b29 Mon Sep 17 00:00:00 2001 From: Mark McCaskey <5770194+MarkMcCaskey@users.noreply.github.com> Date: Thu, 5 Dec 2019 12:01:46 -0800 Subject: [PATCH 08/11] Manually apply formatting to cfg statement --- lib/runtime/src/lib.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/runtime/src/lib.rs b/lib/runtime/src/lib.rs index 3febd072c9d..13b3dd8d4e7 100644 --- a/lib/runtime/src/lib.rs +++ b/lib/runtime/src/lib.rs @@ -235,10 +235,13 @@ pub fn default_compiler() -> impl Compiler { #[cfg(all(feature = "default-backend-llvm", not(feature = "docs")))] use wasmer_llvm_backend::LLVMCompiler as DefaultCompiler; - #[cfg(all(any( - feature = "default-backend-singlepass", - all(feature = "deterministic-execution", feature = "singlepass") - ), not(feature = "docs")))] + #[cfg(all( + any( + feature = "default-backend-singlepass", + all(feature = "deterministic-execution", feature = "singlepass") + ), + not(feature = "docs") + ))] use wasmer_singlepass_backend::SinglePassCompiler as DefaultCompiler; #[cfg(any(feature = "default-backend-cranelift", feature = "docs"))] From 3ba355dda431023c8a3e1a1be3bc9ab7a8ac04a7 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Thu, 5 Dec 2019 15:04:05 -0800 Subject: [PATCH 09/11] Remove deterministic flag setting default compiler; add auto logic --- Makefile | 6 ++++++ lib/runtime/src/lib.rs | 39 ++++++++++++++++----------------------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index 4acde792584..935a6a69218 100644 --- a/Makefile +++ b/Makefile @@ -192,6 +192,12 @@ check: check-bench # as default, and test a minimal set of features with only one backend # at a time. cargo check --manifest-path lib/runtime/Cargo.toml + # Check some of the cases where deterministic execution could matter + cargo check --manifest-path lib/runtime/Cargo.toml --features "deterministic-execution" + cargo check --manifest-path lib/runtime/Cargo.toml --no-default-features \ + --features=default-backend-singlepass,deterministic-execution + cargo check --manifest-path lib/runtime/Cargo.toml --no-default-features \ + --features=default-backend-llvm,deterministic-execution cargo check --release --manifest-path lib/runtime/Cargo.toml $(RUNTIME_CHECK) \ diff --git a/lib/runtime/src/lib.rs b/lib/runtime/src/lib.rs index 13b3dd8d4e7..58046148290 100644 --- a/lib/runtime/src/lib.rs +++ b/lib/runtime/src/lib.rs @@ -211,21 +211,13 @@ pub fn default_compiler() -> impl Compiler { not(feature = "docs"), any( feature = "default-backend-cranelift", - feature = "default-backend-singlepass", - feature = "deterministic-execution" + feature = "default-backend-singlepass" ) ), all( not(feature = "docs"), feature = "default-backend-cranelift", - any( - feature = "default-backend-singlepass", - feature = "deterministic-execution" - ) - ), - all( - feature = "default-backend-singlepass", - feature = "deterministic-execution" + feature = "default-backend-singlepass" ) ))] compile_error!( @@ -235,13 +227,7 @@ pub fn default_compiler() -> impl Compiler { #[cfg(all(feature = "default-backend-llvm", not(feature = "docs")))] use wasmer_llvm_backend::LLVMCompiler as DefaultCompiler; - #[cfg(all( - any( - feature = "default-backend-singlepass", - all(feature = "deterministic-execution", feature = "singlepass") - ), - not(feature = "docs") - ))] + #[cfg(all(feature = "default-backend-singlepass", not(feature = "docs")))] use wasmer_singlepass_backend::SinglePassCompiler as DefaultCompiler; #[cfg(any(feature = "default-backend-cranelift", feature = "docs"))] @@ -260,7 +246,7 @@ pub fn compiler_for_backend(backend: Backend) -> Option> { #[cfg(feature = "cranelift")] Backend::Cranelift => Some(Box::new(wasmer_clif_backend::CraneliftCompiler::new())), - #[cfg(any(feature = "singlepass", feature = "deterministic-execution"))] + #[cfg(any(feature = "singlepass"))] Backend::Singlepass => Some(Box::new( wasmer_singlepass_backend::SinglePassCompiler::new(), )), @@ -268,11 +254,18 @@ pub fn compiler_for_backend(backend: Backend) -> Option> { #[cfg(feature = "llvm")] Backend::LLVM => Some(Box::new(wasmer_llvm_backend::LLVMCompiler::new())), - #[cfg(not(all( - feature = "llvm", - any(feature = "singlepass", feature = "deterministic-execution"), - feature = "cranelift", - )))] + Backend::Auto => { + #[cfg(feature = "default-backend-singlepass")] + return Some(Box::new( + wasmer_singlepass_backend::SinglePassCompiler::new(), + )); + #[cfg(feature = "default-backend-cranelift")] + return Some(Box::new(wasmer_clif_backend::CraneliftCompiler::new())); + #[cfg(feature = "default-backend-llvm")] + return Some(Box::new(wasmer_llvm_backend::LLVMCompiler::new())); + } + + #[cfg(not(all(feature = "llvm", feature = "singlepass", feature = "cranelift")))] _ => None, } } From 27fe50ce9ec639ecd1d8698972f368494656fc5b Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Wed, 4 Dec 2019 10:38:28 -0800 Subject: [PATCH 10/11] Fix this regression test to detect the bug it was looking for in release builds too. This bug triggered an assertion failure in debug, and by examining the pre-opt IR, we can check for the bug in release mode too. --- lib/llvm-backend-tests/tests/compile.rs | 62 +++++++++++++++++++------ 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/lib/llvm-backend-tests/tests/compile.rs b/lib/llvm-backend-tests/tests/compile.rs index 17071a44a04..dc539bf2067 100644 --- a/lib/llvm-backend-tests/tests/compile.rs +++ b/lib/llvm-backend-tests/tests/compile.rs @@ -1,40 +1,72 @@ +use wasmer_llvm_backend::{InkwellMemoryBuffer, InkwellModule, LLVMBackendConfig, LLVMCallbacks}; use wasmer_llvm_backend_tests::{get_compiler, wat2wasm}; -use wasmer_runtime::imports; -use wasmer_runtime_core::compile_with; +use wasmer_runtime::{imports, CompilerConfig}; +use wasmer_runtime_core::{backend::BackendCompilerConfig, compile_with, compile_with_config}; + +use std::cell::RefCell; +use std::rc::Rc; #[test] fn crash_return_with_float_on_stack() { const MODULE: &str = r#" (module - (type (;0;) (func)) - (type (;1;) (func (param f64) (result f64))) + (type (func)) + (type (func (param f64) (result f64))) (func $_start (type 0)) (func $fmod (type 1) (param f64) (result f64) local.get 0 - f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 f64.mul - return) -) + return)) "#; let wasm_binary = wat2wasm(MODULE.as_bytes()).expect("WAST not valid or malformed"); let module = compile_with(&wasm_binary, &get_compiler()).unwrap(); module.instantiate(&imports! {}).unwrap(); } +#[derive(Debug, Default)] +pub struct RecordPreOptIR { + preopt_ir: String, +} + +impl LLVMCallbacks for RecordPreOptIR { + fn preopt_ir_callback(&mut self, module: &InkwellModule) { + self.preopt_ir = module.print_to_string().to_string(); + } + + fn postopt_ir_callback(&mut self, _: &InkwellModule) {} + + fn obj_memory_buffer_callback(&mut self, _: &InkwellMemoryBuffer) {} +} + #[test] fn crash_select_with_mismatched_pending() { - const MODULE: &str = r#" + const WAT: &str = r#" (module - (func (param f64) - f64.const 0x0p+0 (;=0;) + (func (param f64) (result f64) + f64.const 0x0p+0 local.get 0 f64.add - f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 i32.const 0 - select - drop)) + select)) "#; - let wasm_binary = wat2wasm(MODULE.as_bytes()).expect("WAST not valid or malformed"); - let module = compile_with(&wasm_binary, &get_compiler()).unwrap(); + let record_pre_opt_ir = Rc::new(RefCell::new(RecordPreOptIR::default())); + let compiler_config = CompilerConfig { + backend_specific_config: Some(BackendCompilerConfig(Box::new(LLVMBackendConfig { + callbacks: Some(record_pre_opt_ir.clone()), + }))), + ..Default::default() + }; + let wasm_binary = wat2wasm(WAT.as_bytes()).expect("WAST not valid or malformed"); + let module = compile_with_config(&wasm_binary, &get_compiler(), compiler_config).unwrap(); module.instantiate(&imports! {}).unwrap(); + const LLVM: &str = r#" + %s3 = fadd double 0.000000e+00, %s2 + %nan = fcmp uno double %s3, 0.000000e+00 + %2 = select i1 %nan, double 0x7FF8000000000000, double %s3 + %s5 = select i1 false, double %2, double 0.000000e+00 + br label %return +"#; + assert!(&record_pre_opt_ir.borrow().preopt_ir.contains(LLVM)); } From a221f1e5707fce40c08b09632341832483781e3a Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Fri, 6 Dec 2019 12:09:34 -0800 Subject: [PATCH 11/11] Provide a default empty implementation for the LLVMCallbacks trait. --- lib/llvm-backend-tests/tests/compile.rs | 4 ---- lib/llvm-backend/src/lib.rs | 6 +++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/llvm-backend-tests/tests/compile.rs b/lib/llvm-backend-tests/tests/compile.rs index dc539bf2067..1e32f6dd08d 100644 --- a/lib/llvm-backend-tests/tests/compile.rs +++ b/lib/llvm-backend-tests/tests/compile.rs @@ -33,10 +33,6 @@ impl LLVMCallbacks for RecordPreOptIR { fn preopt_ir_callback(&mut self, module: &InkwellModule) { self.preopt_ir = module.print_to_string().to_string(); } - - fn postopt_ir_callback(&mut self, _: &InkwellModule) {} - - fn obj_memory_buffer_callback(&mut self, _: &InkwellMemoryBuffer) {} } #[test] diff --git a/lib/llvm-backend/src/lib.rs b/lib/llvm-backend/src/lib.rs index 853cfac1195..a2db088a76a 100644 --- a/lib/llvm-backend/src/lib.rs +++ b/lib/llvm-backend/src/lib.rs @@ -37,9 +37,9 @@ pub type InkwellModule<'ctx> = inkwell::module::Module<'ctx>; pub type InkwellMemoryBuffer = inkwell::memory_buffer::MemoryBuffer; pub trait LLVMCallbacks: std::any::Any + 'static { - fn preopt_ir_callback(&mut self, module: &InkwellModule); - fn postopt_ir_callback(&mut self, module: &InkwellModule); - fn obj_memory_buffer_callback(&mut self, memory_buffer: &InkwellMemoryBuffer); + fn preopt_ir_callback(&mut self, _module: &InkwellModule) {} + fn postopt_ir_callback(&mut self, _module: &InkwellModule) {} + fn obj_memory_buffer_callback(&mut self, _memory_buffer: &InkwellMemoryBuffer) {} } pub struct LLVMBackendConfig {