diff --git a/lib/runtime-core/src/backend.rs b/lib/runtime-core/src/backend.rs index 1eb8ba108..572fe7fb9 100644 --- a/lib/runtime-core/src/backend.rs +++ b/lib/runtime-core/src/backend.rs @@ -110,6 +110,11 @@ impl Default for MemoryBoundCheckMode { } } +#[derive(Default)] +pub struct Features { + pub simd: bool, +} + /// Configuration data for the compiler #[derive(Default)] pub struct CompilerConfig { @@ -118,6 +123,7 @@ pub struct CompilerConfig { pub memory_bound_check_mode: MemoryBoundCheckMode, pub enforce_stack_check: bool, pub track_state: bool, + pub features: Features, } pub trait Compiler { diff --git a/lib/runtime-core/src/lib.rs b/lib/runtime-core/src/lib.rs index 52b7cf82a..2eb26cb89 100644 --- a/lib/runtime-core/src/lib.rs +++ b/lib/runtime-core/src/lib.rs @@ -117,8 +117,26 @@ pub fn validate(wasm: &[u8]) -> bool { /// The same as `validate` but with an Error message on failure pub fn validate_and_report_errors(wasm: &[u8]) -> ::std::result::Result<(), String> { + validate_and_report_errors_with_features(wasm, Default::default()) +} + +/// The same as `validate_and_report_errors` but with a Features. +pub fn validate_and_report_errors_with_features( + wasm: &[u8], + features: backend::Features, +) -> ::std::result::Result<(), String> { use wasmparser::WasmDecoder; - let mut parser = wasmparser::ValidatingParser::new(wasm, None); + let config = wasmparser::ValidatingParserConfig { + operator_config: wasmparser::OperatorValidatorConfig { + enable_simd: features.simd, + enable_bulk_memory: false, + enable_multi_value: false, + enable_reference_types: false, + enable_threads: false, + }, + mutable_global_imports: false, + }; + let mut parser = wasmparser::ValidatingParser::new(wasm, Some(config)); loop { let state = parser.read(); match *state { diff --git a/src/bin/kwasmd.rs b/src/bin/kwasmd.rs index bee998471..d0e0723cd 100644 --- a/src/bin/kwasmd.rs +++ b/src/bin/kwasmd.rs @@ -55,6 +55,7 @@ fn handle_client(mut stream: UnixStream) { memory_bound_check_mode: MemoryBoundCheckMode::Disable, enforce_stack_check: true, track_state: false, + features: Default::default(), }, &SinglePassCompiler::new(), ) diff --git a/src/bin/wasmer.rs b/src/bin/wasmer.rs index 2f24548e3..0ac460dfc 100644 --- a/src/bin/wasmer.rs +++ b/src/bin/wasmer.rs @@ -23,7 +23,7 @@ use wasmer_runtime::{ }; use wasmer_runtime_core::{ self, - backend::{Backend, Compiler, CompilerConfig, MemoryBoundCheckMode}, + backend::{Backend, Compiler, CompilerConfig, Features, MemoryBoundCheckMode}, debug, loader::{Instance as LoadedInstance, LocalLoader}, }; @@ -67,6 +67,17 @@ enum CLIOptions { SelfUpdate, } +#[derive(Debug, StructOpt)] +struct PrestandardFeatures { + /// Enable support for the SIMD proposal. + #[structopt(long = "enable-simd")] + simd: bool, + + /// Enable support for all pre-standard proposals. + #[structopt(long = "enable-all")] + all: bool, +} + #[derive(Debug, StructOpt)] struct Run { // Disable the cache @@ -134,6 +145,9 @@ struct Run { #[structopt(long = "cache-key", hidden = true)] cache_key: Option, + #[structopt(flatten)] + features: PrestandardFeatures, + /// Application arguments #[structopt(name = "--", raw(multiple = "true"))] args: Vec, @@ -185,6 +199,9 @@ struct Validate { /// Input file #[structopt(parse(from_os_str))] path: PathBuf, + + #[structopt(flatten)] + features: PrestandardFeatures, } /// Read the contents of a file @@ -315,10 +332,14 @@ fn execute_wasm(options: &Run) -> Result<(), String> { None }; + // Don't error on --enable-all for other backends. + if options.features.simd && options.backend != Backend::LLVM { + return Err("SIMD is only supported in the LLVM backend for now".to_string()); + } + if !utils::is_wasm_binary(&wasm_binary) { let mut features = wabt::Features::new(); - if options.backend == Backend::LLVM { - // SIMD is only supported in the LLVM backend for now + if options.features.simd || options.features.all { features.enable_simd(); } wasm_binary = wabt::wat2wasm_with_features(wasm_binary, features) @@ -357,6 +378,9 @@ fn execute_wasm(options: &Run) -> Result<(), String> { memory_bound_check_mode: MemoryBoundCheckMode::Disable, enforce_stack_check: true, track_state, + features: Features { + simd: options.features.simd || options.features.all, + }, }, &*compiler, ) @@ -367,6 +391,9 @@ fn execute_wasm(options: &Run) -> Result<(), String> { CompilerConfig { symbol_map: em_symbol_map, track_state, + features: Features { + simd: options.features.simd || options.features.all, + }, ..Default::default() }, &*compiler, @@ -737,8 +764,13 @@ fn validate_wasm(validate: Validate) -> Result<(), String> { )); } - wasmer_runtime_core::validate_and_report_errors(&wasm_binary) - .map_err(|err| format!("Validation failed: {}", err))?; + wasmer_runtime_core::validate_and_report_errors_with_features( + &wasm_binary, + Features { + simd: validate.features.simd || validate.features.all, + }, + ) + .map_err(|err| format!("Validation failed: {}", err))?; Ok(()) }