diff --git a/crates/api/src/runtime.rs b/crates/api/src/runtime.rs index 8908483996..4f724875e2 100644 --- a/crates/api/src/runtime.rs +++ b/crates/api/src/runtime.rs @@ -267,6 +267,22 @@ impl Config { self } + /// Configures whether Cranelift should perform a NaN-canonicalization pass. + /// + /// When Cranelift is used as a code generation backend this will configure + /// it to replace NaNs with a single canonical value. This is useful for users + /// requiring entirely deterministic WebAssembly computation. + /// This is not required by the WebAssembly spec, so it is not enabled by default. + /// + /// The default value for this is `false` + pub fn cranelift_nan_canonicalization(&mut self, enable: bool) -> &mut Self { + let val = if enable { "true" } else { "false" }; + self.flags + .set("enable_nan_canonicalization", val) + .expect("should be valid flag"); + self + } + /// Loads cache configuration specified at `path`. /// /// This method will read the file specified by `path` on the filesystem and diff --git a/crates/fuzzing/src/generators.rs b/crates/fuzzing/src/generators.rs index 15715b3a44..d8ab981588 100644 --- a/crates/fuzzing/src/generators.rs +++ b/crates/fuzzing/src/generators.rs @@ -66,9 +66,7 @@ pub struct DifferentialConfig { impl DifferentialConfig { /// Convert this differential fuzzing config into a `wasmtime::Config`. pub fn to_wasmtime_config(&self) -> anyhow::Result { - let mut config = wasmtime::Config::new(); - config.cranelift_debug_verifier(true); - config.strategy(match self.strategy { + let mut config = crate::fuzz_default_config(match self.strategy { DifferentialStrategy::Cranelift => wasmtime::Strategy::Cranelift, DifferentialStrategy::Lightbeam => wasmtime::Strategy::Lightbeam, })?; diff --git a/crates/fuzzing/src/lib.rs b/crates/fuzzing/src/lib.rs index d56295883a..d9f884e616 100644 --- a/crates/fuzzing/src/lib.rs +++ b/crates/fuzzing/src/lib.rs @@ -30,3 +30,18 @@ pub(crate) fn init_fuzzing() { .expect("should only initialize the rayon thread pool once!"); }) } + +/// Create default fuzzing config with given strategy +pub(crate) fn fuzz_default_config( + strategy: wasmtime::Strategy, +) -> anyhow::Result { + init_fuzzing(); + let mut config = wasmtime::Config::new(); + config + .cranelift_debug_verifier(true) + .cranelift_nan_canonicalization(true) + .wasm_multi_value(true) + .wasm_bulk_memory(true) + .strategy(strategy)?; + Ok(config) +} diff --git a/crates/fuzzing/src/oracles.rs b/crates/fuzzing/src/oracles.rs index ebee9cc436..f57f13c0eb 100644 --- a/crates/fuzzing/src/oracles.rs +++ b/crates/fuzzing/src/oracles.rs @@ -16,18 +16,6 @@ use dummy::dummy_imports; use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; use wasmtime::*; -fn fuzz_default_config(strategy: Strategy) -> Config { - crate::init_fuzzing(); - let mut config = Config::new(); - config - .cranelift_debug_verifier(true) - .wasm_multi_value(true) - .wasm_bulk_memory(true) - .strategy(strategy) - .expect("failed to enable lightbeam"); - return config; -} - fn log_wasm(wasm: &[u8]) { static CNT: AtomicUsize = AtomicUsize::new(0); if !log::log_enabled!(log::Level::Debug) { @@ -51,7 +39,7 @@ fn log_wasm(wasm: &[u8]) { /// /// You can control which compiler is used via passing a `Strategy`. pub fn instantiate(wasm: &[u8], strategy: Strategy) { - instantiate_with_config(wasm, fuzz_default_config(strategy)); + instantiate_with_config(wasm, crate::fuzz_default_config(strategy).unwrap()); } /// Instantiate the Wasm buffer, and implicitly fail if we have an unexpected @@ -98,7 +86,7 @@ pub fn instantiate_with_config(wasm: &[u8], config: Config) { pub fn compile(wasm: &[u8], strategy: Strategy) { crate::init_fuzzing(); - let engine = Engine::new(&fuzz_default_config(strategy)); + let engine = Engine::new(&crate::fuzz_default_config(strategy).unwrap()); let store = Store::new(&engine); log_wasm(wasm); let _ = Module::new(&store, wasm);