diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 93522c43e1..f746db693a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -207,7 +207,7 @@ jobs: submodules: true - uses: ./.github/actions/install-rust with: - toolchain: nightly-2019-08-15 + toolchain: nightly-2020-01-06 - uses: ./.github/actions/binary-compatible-builds - run: mkdir crates/misc/py/wheelhouse shell: bash diff --git a/Cargo.lock b/Cargo.lock index ca5cb311f9..ea00c661a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2016,6 +2016,7 @@ dependencies = [ name = "wasmtime-environ" version = "0.7.0" dependencies = [ + "anyhow", "base64 0.11.0", "bincode", "cranelift-codegen", @@ -2054,6 +2055,7 @@ dependencies = [ "env_logger 0.7.1", "libfuzzer-sys", "log", + "wasmtime", "wasmtime-fuzzing", "wasmtime-jit", ] @@ -2115,6 +2117,7 @@ dependencies = [ name = "wasmtime-obj" version = "0.7.0" dependencies = [ + "anyhow", "faerie", "more-asserts", "wasmtime-environ", diff --git a/Cargo.toml b/Cargo.toml index c7d6d111f2..09fa3ca5ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,7 +60,8 @@ members = [ lightbeam = [ "wasmtime-environ/lightbeam", "wasmtime-jit/lightbeam", - "wasmtime-wast/lightbeam" + "wasmtime-wast/lightbeam", + "wasmtime/lightbeam", ] wasi-c = ["wasmtime-wasi-c"] test_programs = ["test-programs/test_programs"] diff --git a/build.rs b/build.rs index 085ac3eea3..4eed5d4154 100644 --- a/build.rs +++ b/build.rs @@ -149,7 +149,7 @@ fn write_testsuite_tests( writeln!(out, "fn r#{}() -> anyhow::Result<()> {{", &testname)?; writeln!( out, - "crate::run_wast(r#\"{}\"#, crate::CompilationStrategy::{})", + "crate::run_wast(r#\"{}\"#, crate::Strategy::{})", path.display(), strategy )?; diff --git a/crates/api/Cargo.toml b/crates/api/Cargo.toml index 7f0ea581aa..3a71adc41e 100644 --- a/crates/api/Cargo.toml +++ b/crates/api/Cargo.toml @@ -36,3 +36,9 @@ wat = "1.0" [badges] maintenance = { status = "actively-developed" } + +[features] +# Enables experimental support for the lightbeam codegen backend, an alternative +# to cranelift. Requires Nightly Rust currently, and this is not enabled by +# default. +lightbeam = ["wasmtime-jit/lightbeam"] diff --git a/crates/api/src/lib.rs b/crates/api/src/lib.rs index 22cd1f8f84..e3a3fd8d1a 100644 --- a/crates/api/src/lib.rs +++ b/crates/api/src/lib.rs @@ -27,7 +27,7 @@ pub use crate::externals::*; pub use crate::instance::Instance; pub use crate::module::Module; pub use crate::r#ref::{AnyRef, HostInfo, HostRef}; -pub use crate::runtime::{Config, Engine, Store}; +pub use crate::runtime::{Config, Engine, Store, Strategy}; pub use crate::trap::{FrameInfo, Trap, TrapInfo}; pub use crate::types::*; pub use crate::values::*; diff --git a/crates/api/src/runtime.rs b/crates/api/src/runtime.rs index bef4313664..49c69e6d77 100644 --- a/crates/api/src/runtime.rs +++ b/crates/api/src/runtime.rs @@ -1,4 +1,5 @@ use crate::context::Context; +use anyhow::Result; use std::cell::RefCell; use std::collections::HashMap; use std::rc::Rc; @@ -158,15 +159,29 @@ impl Config { self } - /// Configures the compilation `strategy` provided, indicating which - /// backend will be used for compiling WebAssembly to native code. + /// Configures which compilation strategy will be used for wasm modules. /// - /// Currently the primary strategies are with cranelift (an optimizing - /// compiler) or lightbeam (a fast single-pass JIT which produces code - /// quickly). - pub fn strategy(&mut self, strategy: CompilationStrategy) -> &mut Self { - self.strategy = strategy; - self + /// This method can be used to configure which compiler is used for wasm + /// modules, and for more documentation consult the [`Strategy`] enumeration + /// and its documentation. + /// + /// # Errors + /// + /// Some compilation strategies require compile-time options of `wasmtime` + /// itself to be set, but if they're not set and the strategy is specified + /// here then an error will be returned. + pub fn strategy(&mut self, strategy: Strategy) -> Result<&mut Self> { + self.strategy = match strategy { + Strategy::Auto => CompilationStrategy::Auto, + Strategy::Cranelift => CompilationStrategy::Cranelift, + #[cfg(feature = "lightbeam")] + Strategy::Lightbeam => CompilationStrategy::Lightbeam, + #[cfg(not(feature = "lightbeam"))] + Strategy::Lightbeam => { + anyhow::bail!("lightbeam compilation strategy wasn't enabled at compile time"); + } + }; + Ok(self) } } @@ -176,6 +191,30 @@ impl Default for Config { } } +/// Possible Compilation strategies for a wasm module. +#[non_exhaustive] +#[derive(Clone, Debug)] +pub enum Strategy { + /// An indicator that the compilation strategy should be automatically + /// selected. + /// + /// This is generally what you want for most projects and indicates that the + /// `wasmtime` crate itself should make the decision about what the best + /// code generator for a wasm module is. + /// + /// Currently this always defaults to Cranelift, but the default value will + /// change over time. + Auto, + + /// Currently the default backend, Cranelift aims to be a reasonably fast + /// code generator which generates high quality machine code. + Cranelift, + + /// A single-pass code generator that is faster than Cranelift but doesn't + /// produce as high-quality code. + Lightbeam, +} + // Engine /// An `Engine` which is a global context for compilation and management of wasm diff --git a/crates/environ/Cargo.toml b/crates/environ/Cargo.toml index 396d88eb0e..78a6154f3f 100644 --- a/crates/environ/Cargo.toml +++ b/crates/environ/Cargo.toml @@ -12,6 +12,7 @@ readme = "README.md" edition = "2018" [dependencies] +anyhow = "1.0" cranelift-codegen = { version = "0.52.0", features = ["enable-serde"] } cranelift-entity = { version = "0.52.0", features = ["enable-serde"] } cranelift-wasm = { version = "0.52.0", features = ["enable-serde"] } diff --git a/crates/environ/src/cache/config.rs b/crates/environ/src/cache/config.rs index d6a29ee4d4..73831aa7bf 100644 --- a/crates/environ/src/cache/config.rs +++ b/crates/environ/src/cache/config.rs @@ -1,6 +1,7 @@ //! Module for configuring the cache system. use super::worker; +use anyhow::{anyhow, bail, Context, Result}; use directories::ProjectDirs; use lazy_static::lazy_static; use log::{debug, error, trace, warn}; @@ -137,32 +138,32 @@ pub fn init + Debug>( /// Creates a new configuration file at specified path, or default path if None is passed. /// Fails if file already exists. -pub fn create_new_config + Debug>( - config_file: Option

, -) -> Result { +pub fn create_new_config + Debug>(config_file: Option

) -> Result { trace!("Creating new config file, path: {:?}", config_file); - let config_file = config_file.as_ref().map_or_else( - || DEFAULT_CONFIG_PATH.as_ref().map(|p| p.as_ref()), - |p| Ok(p.as_ref()), - )?; + let config_file = config_file + .as_ref() + .map_or_else( + || DEFAULT_CONFIG_PATH.as_ref().map(|p| p.as_ref()), + |p| Ok(p.as_ref()), + ) + .map_err(|s| anyhow!("{}", s))?; if config_file.exists() { - return Err(format!( + bail!( "Specified config file already exists! Path: {}", config_file.display() - )); + ); } let parent_dir = config_file .parent() - .ok_or_else(|| format!("Invalid cache config path: {}", config_file.display()))?; + .ok_or_else(|| anyhow!("Invalid cache config path: {}", config_file.display()))?; - fs::create_dir_all(parent_dir).map_err(|err| { + fs::create_dir_all(parent_dir).with_context(|| { format!( - "Failed to create config directory, config path: {}, error: {}", + "Failed to create config directory, config path: {}", config_file.display(), - err ) })?; @@ -175,11 +176,10 @@ pub fn create_new_config + Debug>( enabled = true "; - fs::write(&config_file, &content).map_err(|err| { + fs::write(&config_file, &content).with_context(|| { format!( - "Failed to flush config to the disk, path: {}, msg: {}", + "Failed to flush config to the disk, path: {}", config_file.display(), - err ) })?; diff --git a/crates/fuzzing/src/oracles.rs b/crates/fuzzing/src/oracles.rs index 004f1ad906..45c6290332 100644 --- a/crates/fuzzing/src/oracles.rs +++ b/crates/fuzzing/src/oracles.rs @@ -32,14 +32,15 @@ fn host_isa() -> Box { /// Performs initial validation, and returns early if the Wasm is invalid. /// /// You can control which compiler is used via passing a `CompilationStrategy`. -pub fn instantiate(wasm: &[u8], compilation_strategy: CompilationStrategy) { +pub fn instantiate(wasm: &[u8], strategy: Strategy) { if wasmparser::validate(wasm, None).is_err() { return; } let mut config = Config::new(); - config.strategy(compilation_strategy); - + config + .strategy(strategy) + .expect("failed to enable lightbeam"); let engine = Engine::new(&config); let store = HostRef::new(Store::new(&engine)); diff --git a/crates/fuzzing/tests/regressions.rs b/crates/fuzzing/tests/regressions.rs index 069cd8ae0b..925720c0da 100644 --- a/crates/fuzzing/tests/regressions.rs +++ b/crates/fuzzing/tests/regressions.rs @@ -5,10 +5,11 @@ //! use the Wasm binary by including it via //! `include_bytes!("./regressions/some-descriptive-name.wasm")`. +use wasmtime::Strategy; use wasmtime_fuzzing::oracles; #[test] fn instantiate_empty_module() { let data = wat::parse_str(include_str!("./regressions/empty.wat")).unwrap(); - oracles::instantiate(&data, wasmtime_jit::CompilationStrategy::Auto); + oracles::instantiate(&data, Strategy::Auto); } diff --git a/crates/obj/Cargo.toml b/crates/obj/Cargo.toml index c8ed4b1672..fabe65a65f 100644 --- a/crates/obj/Cargo.toml +++ b/crates/obj/Cargo.toml @@ -11,6 +11,7 @@ readme = "README.md" edition = "2018" [dependencies] +anyhow = "1.0" wasmtime-environ = { path = "../environ" } faerie = "0.13.0" more-asserts = "0.2.1" diff --git a/crates/obj/src/data_segment.rs b/crates/obj/src/data_segment.rs index c4ce8862cd..4662544753 100644 --- a/crates/obj/src/data_segment.rs +++ b/crates/obj/src/data_segment.rs @@ -1,3 +1,4 @@ +use anyhow::Result; use faerie::{Artifact, Decl}; use wasmtime_environ::DataInitializer; @@ -6,10 +7,9 @@ pub fn declare_data_segment( obj: &mut Artifact, _data_initaliazer: &DataInitializer, index: usize, -) -> Result<(), String> { +) -> Result<()> { let name = format!("_memory_{}", index); - obj.declare(name, Decl::data()) - .map_err(|err| format!("{}", err))?; + obj.declare(name, Decl::data())?; Ok(()) } @@ -18,9 +18,8 @@ pub fn emit_data_segment( obj: &mut Artifact, data_initaliazer: &DataInitializer, index: usize, -) -> Result<(), String> { +) -> Result<()> { let name = format!("_memory_{}", index); - obj.define(name, Vec::from(data_initaliazer.data)) - .map_err(|err| format!("{}", err))?; + obj.define(name, Vec::from(data_initaliazer.data))?; Ok(()) } diff --git a/crates/obj/src/function.rs b/crates/obj/src/function.rs index dc1832d75d..da0bfc3f26 100644 --- a/crates/obj/src/function.rs +++ b/crates/obj/src/function.rs @@ -1,3 +1,4 @@ +use anyhow::Result; use faerie::{Artifact, Decl, Link}; use wasmtime_environ::entity::EntityRef; use wasmtime_environ::settings; @@ -19,26 +20,23 @@ pub fn declare_functions( obj: &mut Artifact, module: &Module, relocations: &Relocations, -) -> Result<(), String> { +) -> Result<()> { for i in 0..module.imported_funcs.len() { let string_name = format!("_wasm_function_{}", i); - obj.declare(string_name, Decl::function_import()) - .map_err(|err| format!("{}", err))?; + obj.declare(string_name, Decl::function_import())?; } for (_, function_relocs) in relocations.iter() { for r in function_relocs { let special_import_name = get_reloc_target_special_import_name(r.reloc_target); if let Some(special_import_name) = special_import_name { - obj.declare(special_import_name, Decl::function_import()) - .map_err(|err| format!("{}", err))?; + obj.declare(special_import_name, Decl::function_import())?; } } } for (i, _function_relocs) in relocations.iter().rev() { let func_index = module.func_index(i); let string_name = format!("_wasm_function_{}", func_index.index()); - obj.declare(string_name, Decl::function().global()) - .map_err(|err| format!("{}", err))?; + obj.declare(string_name, Decl::function().global())?; } Ok(()) } @@ -49,7 +47,7 @@ pub fn emit_functions( module: &Module, compilation: &Compilation, relocations: &Relocations, -) -> Result<(), String> { +) -> Result<()> { debug_assert!( module.start_func.is_none() || module.start_func.unwrap().index() >= module.imported_funcs.len(), @@ -66,8 +64,7 @@ pub fn emit_functions( let func_index = module.func_index(i); let string_name = format!("_wasm_function_{}", func_index.index()); - obj.define(string_name, body.clone()) - .map_err(|err| format!("{}", err))?; + obj.define(string_name, body.clone())?; } for (i, function_relocs) in relocations.iter() { @@ -82,8 +79,7 @@ pub fn emit_functions( from: &string_name, to: &target_name, at: r.offset as u64, - }) - .map_err(|err| format!("{}", err))?; + })?; } RelocationTarget::Memory32Grow | RelocationTarget::ImportedMemory32Grow @@ -93,8 +89,7 @@ pub fn emit_functions( from: &string_name, to: get_reloc_target_special_import_name(r.reloc_target).expect("name"), at: r.offset as u64, - }) - .map_err(|err| format!("{}", err))?; + })?; } RelocationTarget::JumpTable(_, _) => { // ignore relocations for jump tables diff --git a/crates/obj/src/module.rs b/crates/obj/src/module.rs index aa32ab0d8d..0117681e61 100644 --- a/crates/obj/src/module.rs +++ b/crates/obj/src/module.rs @@ -2,6 +2,7 @@ use crate::context::layout_vmcontext; use crate::data_segment::{declare_data_segment, emit_data_segment}; use crate::function::{declare_functions, emit_functions}; use crate::table::{declare_table, emit_table}; +use anyhow::Result; use faerie::{Artifact, Decl, Link}; use wasmtime_environ::isa::TargetFrontendConfig; use wasmtime_environ::{Compilation, DataInitializer, Module, Relocations}; @@ -10,18 +11,16 @@ fn emit_vmcontext_init( obj: &mut Artifact, module: &Module, target_config: &TargetFrontendConfig, -) -> Result<(), String> { +) -> Result<()> { let (data, table_relocs) = layout_vmcontext(module, target_config); - obj.declare_with("_vmcontext_init", Decl::data().global(), data.to_vec()) - .map_err(|err| format!("{}", err))?; + obj.declare_with("_vmcontext_init", Decl::data().global(), data.to_vec())?; for reloc in table_relocs.iter() { let target_name = format!("_table_{}", reloc.index); obj.link(Link { from: "_vmcontext_init", to: &target_name, at: reloc.offset as u64, - }) - .map_err(|err| format!("{}", err))?; + })?; } Ok(()) } @@ -35,7 +34,7 @@ pub fn emit_module( relocations: &Relocations, data_initializers: &[DataInitializer], target_config: &TargetFrontendConfig, -) -> Result<(), String> { +) -> Result<()> { declare_functions(obj, module, relocations)?; for (i, initializer) in data_initializers.iter().enumerate() { diff --git a/crates/obj/src/table.rs b/crates/obj/src/table.rs index 269e50927c..fe4b52c6a0 100644 --- a/crates/obj/src/table.rs +++ b/crates/obj/src/table.rs @@ -1,18 +1,17 @@ +use anyhow::Result; use faerie::{Artifact, Decl}; /// Declares data segment symbol -pub fn declare_table(obj: &mut Artifact, index: usize) -> Result<(), String> { +pub fn declare_table(obj: &mut Artifact, index: usize) -> Result<()> { let name = format!("_table_{}", index); - obj.declare(name, Decl::data()) - .map_err(|err| format!("{}", err))?; + obj.declare(name, Decl::data())?; Ok(()) } /// Emit segment data and initialization location -pub fn emit_table(obj: &mut Artifact, index: usize) -> Result<(), String> { +pub fn emit_table(obj: &mut Artifact, index: usize) -> Result<()> { let name = format!("_table_{}", index); // FIXME: We need to initialize table using function symbols - obj.define(name, Vec::new()) - .map_err(|err| format!("{}", err))?; + obj.define(name, Vec::new())?; Ok(()) } diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 7c0613627a..768cb84eca 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -14,6 +14,7 @@ env_logger = "0.7.1" log = "0.4.8" wasmtime-fuzzing = { path = "../crates/fuzzing", features = ["env_logger"] } wasmtime-jit = { path = "../crates/jit" } +wasmtime = { path = "../crates/api" } libfuzzer-sys = { git = "https://github.com/rust-fuzz/libfuzzer-sys.git" } [[bin]] diff --git a/fuzz/fuzz_targets/instantiate.rs b/fuzz/fuzz_targets/instantiate.rs index 36fb104b87..0db62f1d3e 100644 --- a/fuzz/fuzz_targets/instantiate.rs +++ b/fuzz/fuzz_targets/instantiate.rs @@ -1,12 +1,9 @@ #![no_main] use libfuzzer_sys::fuzz_target; +use wasmtime::Strategy; use wasmtime_fuzzing::{oracles, with_log_wasm_test_case}; -use wasmtime_jit::CompilationStrategy; fuzz_target!(|data: &[u8]| { - with_log_wasm_test_case!(data, |data| oracles::instantiate( - data, - CompilationStrategy::Auto - )); + with_log_wasm_test_case!(data, |data| oracles::instantiate(data, Strategy::Auto,)); }); diff --git a/fuzz/fuzz_targets/instantiate_translated.rs b/fuzz/fuzz_targets/instantiate_translated.rs index 19e313adea..0a575e5b58 100644 --- a/fuzz/fuzz_targets/instantiate_translated.rs +++ b/fuzz/fuzz_targets/instantiate_translated.rs @@ -1,12 +1,12 @@ #![no_main] use libfuzzer_sys::fuzz_target; +use wasmtime::Strategy; use wasmtime_fuzzing::{generators, oracles, with_log_wasm_test_case}; -use wasmtime_jit::CompilationStrategy; fuzz_target!(|data: generators::WasmOptTtf| { with_log_wasm_test_case!(&data.wasm, |wasm| oracles::instantiate( wasm, - CompilationStrategy::Auto + Strategy::Auto, )); }); diff --git a/src/bin/wasm2obj.rs b/src/bin/wasm2obj.rs index 5e297b13d1..5be8084c0b 100644 --- a/src/bin/wasm2obj.rs +++ b/src/bin/wasm2obj.rs @@ -26,15 +26,15 @@ ) )] +use anyhow::{anyhow, bail, Result}; use docopt::Docopt; use faerie::Artifact; use serde::Deserialize; -use std::error::Error; -use std::fmt::format; use std::path::{Path, PathBuf}; use std::str::FromStr; use std::{process, str}; use target_lexicon::Triple; +use wasmtime::Strategy; use wasmtime_cli::pick_compilation_strategy; use wasmtime_debug::{emit_debugsections, read_debuginfo}; use wasmtime_environ::entity::EntityRef; @@ -47,7 +47,7 @@ use wasmtime_environ::{ cache_create_new_config, cache_init, Compiler, Cranelift, ModuleEnvironment, ModuleVmctxInfo, Tunables, VMOffsets, }; -use wasmtime_jit::{native, CompilationStrategy}; +use wasmtime_jit::native; use wasmtime_obj::emit_module; const USAGE: &str = " @@ -176,18 +176,14 @@ fn handle_module( enable_optimize: bool, cranelift: bool, lightbeam: bool, -) -> Result<(), String> { - let data = match wat::parse_file(path) { - Ok(data) => data, - Err(err) => { - return Err(String::from(err.description())); - } - }; +) -> Result<()> { + let data = wat::parse_file(path)?; let isa_builder = match *target { Some(ref target) => { - let target = Triple::from_str(&target).map_err(|_| "could not parse --target")?; - native::lookup(target).map_err(|err| format!("{:?}", err))? + let target = + Triple::from_str(&target).map_err(|_| anyhow!("could not parse --target"))?; + native::lookup(target)? } None => native::builder(), }; @@ -213,7 +209,7 @@ fn handle_module( let tunables = Tunables::default(); // Decide how to compile. - let strategy = pick_compilation_strategy(cranelift, lightbeam); + let strategy = pick_compilation_strategy(cranelift, lightbeam)?; let ( module, @@ -224,10 +220,7 @@ fn handle_module( ) = { let environ = ModuleEnvironment::new(isa.frontend_config(), tunables); - let translation = environ - .translate(&data) - .map_err(|error| error.to_string())?; - + let translation = environ.translate(&data)?; ( translation.module, translation.module_translation.unwrap(), @@ -240,25 +233,24 @@ fn handle_module( // TODO: use the traps information let (compilation, relocations, address_transform, value_ranges, stack_slots, _traps) = match strategy { - CompilationStrategy::Auto | CompilationStrategy::Cranelift => { - Cranelift::compile_module( - &module, - &module_translation, - lazy_function_body_inputs, - &*isa, - generate_debug_info, - ) - .map_err(|e| e.to_string())? - } - #[cfg(feature = "lightbeam")] - CompilationStrategy::Lightbeam => Lightbeam::compile_module( + Strategy::Auto | Strategy::Cranelift => Cranelift::compile_module( &module, &module_translation, lazy_function_body_inputs, &*isa, generate_debug_info, - ) - .map_err(|e| e.to_string())?, + )?, + #[cfg(feature = "lightbeam")] + Strategy::Lightbeam => Lightbeam::compile_module( + &module, + &module_translation, + lazy_function_body_inputs, + &*isa, + generate_debug_info, + )?, + #[cfg(not(feature = "lightbeam"))] + Strategy::Lightbeam => bail!("lightbeam support not enabled"), + other => bail!("unsupported compilation strategy {:?}", other), }; let module_vmctx_info = { @@ -288,14 +280,12 @@ fn handle_module( &debug_data, &address_transform, &value_ranges, - ) - .map_err(|e| e.to_string())?; + )? } // FIXME: Make the format a parameter. - let file = - ::std::fs::File::create(Path::new(output)).map_err(|x| format(format_args!("{}", x)))?; - obj.write(file).map_err(|e| e.to_string())?; + let file = ::std::fs::File::create(Path::new(output))?; + obj.write(file)?; Ok(()) } diff --git a/src/bin/wasmtime.rs b/src/bin/wasmtime.rs index a02fa0d803..46f828927a 100644 --- a/src/bin/wasmtime.rs +++ b/src/bin/wasmtime.rs @@ -257,11 +257,11 @@ fn main() -> Result<()> { } // Decide how to compile. - let strategy = pick_compilation_strategy(args.flag_cranelift, args.flag_lightbeam); - - config - .flags(settings::Flags::new(flag_builder)) - .strategy(strategy); + config.strategy(pick_compilation_strategy( + args.flag_cranelift, + args.flag_lightbeam, + )?)?; + config.flags(settings::Flags::new(flag_builder)); let engine = Engine::new(&config); let store = HostRef::new(Store::new(&engine)); diff --git a/src/bin/wast.rs b/src/bin/wast.rs index 3edbf6194b..ca23b41c29 100644 --- a/src/bin/wast.rs +++ b/src/bin/wast.rs @@ -22,8 +22,8 @@ ) )] +use anyhow::{Context, Result}; use docopt::Docopt; -use pretty_env_logger; use serde::Deserialize; use std::path::Path; use std::process; @@ -75,7 +75,7 @@ struct Args { flag_cranelift: bool, } -fn main() { +fn main() -> Result<()> { let version = env!("CARGO_PKG_VERSION"); let args: Args = Docopt::new(USAGE) .and_then(|d| { @@ -95,19 +95,12 @@ fn main() { }; if args.flag_create_cache_config { - match cache_create_new_config(args.flag_cache_config) { - Ok(path) => { - println!( - "Successfully created new configuation file at {}", - path.display() - ); - return; - } - Err(err) => { - eprintln!("Error: {}", err); - process::exit(1); - } - } + let path = cache_create_new_config(args.flag_cache_config)?; + println!( + "Successfully created new configuation file at {}", + path.display() + ); + return Ok(()); } let errors = cache_init( @@ -148,22 +141,20 @@ fn main() { } // Decide how to compile. - let strategy = pick_compilation_strategy(args.flag_cranelift, args.flag_lightbeam); - cfg.strategy(strategy) - .flags(settings::Flags::new(flag_builder)); + cfg.strategy(pick_compilation_strategy( + args.flag_cranelift, + args.flag_lightbeam, + )?)? + .flags(settings::Flags::new(flag_builder)); let store = HostRef::new(Store::new(&Engine::new(&cfg))); let mut wast_context = WastContext::new(store); wast_context .register_spectest() - .expect("error instantiating \"spectest\""); + .context("error instantiating \"spectest\"")?; for filename in &args.arg_file { - wast_context - .run_file(Path::new(&filename)) - .unwrap_or_else(|e| { - eprintln!("{:?}", e); - process::exit(1) - }); + wast_context.run_file(Path::new(&filename))?; } + Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index 4680b12c92..aa64ce353e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,16 +1,13 @@ -use wasmtime_jit::CompilationStrategy; +use anyhow::{bail, Result}; +use wasmtime::Strategy; -pub fn pick_compilation_strategy(cranelift: bool, lightbeam: bool) -> CompilationStrategy { - // Decide how to compile. - match (lightbeam, cranelift) { - #[cfg(feature = "lightbeam")] - (true, false) => CompilationStrategy::Lightbeam, - #[cfg(not(feature = "lightbeam"))] - (true, false) => panic!("--lightbeam given, but Lightbeam support is not enabled"), - (false, true) => CompilationStrategy::Cranelift, - (false, false) => CompilationStrategy::Auto, - (true, true) => panic!("Can't enable --cranelift and --lightbeam at the same time"), - } +pub fn pick_compilation_strategy(cranelift: bool, lightbeam: bool) -> Result { + Ok(match (lightbeam, cranelift) { + (true, false) => Strategy::Lightbeam, + (false, true) => Strategy::Cranelift, + (false, false) => Strategy::Auto, + (true, true) => bail!("Can't enable --cranelift and --lightbeam at the same time"), + }) } pub fn init_file_per_thread_logger(prefix: &'static str) { diff --git a/tests/wast_testsuites.rs b/tests/wast_testsuites.rs index a2e1d420c8..0edf30c1f6 100644 --- a/tests/wast_testsuites.rs +++ b/tests/wast_testsuites.rs @@ -1,8 +1,7 @@ use std::path::Path; -use wasmtime::{Config, Engine, HostRef, Store}; +use wasmtime::{Config, Engine, HostRef, Store, Strategy}; use wasmtime_environ::settings; use wasmtime_environ::settings::Configurable; -use wasmtime_jit::CompilationStrategy; use wasmtime_wast::WastContext; include!(concat!(env!("OUT_DIR"), "/wast_testsuite_tests.rs")); @@ -10,7 +9,7 @@ include!(concat!(env!("OUT_DIR"), "/wast_testsuite_tests.rs")); // Each of the tests included from `wast_testsuite_tests` will call this // function which actually executes the `wast` test suite given the `strategy` // to compile it. -fn run_wast(wast: &str, strategy: CompilationStrategy) -> anyhow::Result<()> { +fn run_wast(wast: &str, strategy: Strategy) -> anyhow::Result<()> { let wast = Path::new(wast); let mut flag_builder = settings::builder(); @@ -21,7 +20,7 @@ fn run_wast(wast: &str, strategy: CompilationStrategy) -> anyhow::Result<()> { let mut cfg = Config::new(); cfg.wasm_simd(wast.iter().any(|s| s == "simd")) .wasm_multi_value(wast.iter().any(|s| s == "multi-value")) - .strategy(strategy) + .strategy(strategy)? .flags(settings::Flags::new(flag_builder)); let store = HostRef::new(Store::new(&Engine::new(&cfg))); let mut wast_context = WastContext::new(store);