diff --git a/Cargo.lock b/Cargo.lock index 5a94f65114..e0a39439b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1991,7 +1991,6 @@ dependencies = [ "wasmtime-interface-types", "wasmtime-jit", "wasmtime-obj", - "wasmtime-runtime", "wasmtime-wasi", "wasmtime-wasi-c", "wasmtime-wast", diff --git a/Cargo.toml b/Cargo.toml index 09fa3ca5ae..323ad14482 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,6 @@ wasmtime = { path = "crates/api" } wasmtime-debug = { path = "crates/debug" } wasmtime-environ = { path = "crates/environ" } wasmtime-interface-types = { path = "crates/interface-types" } -wasmtime-runtime = { path = "crates/runtime" } wasmtime-jit = { path = "crates/jit" } wasmtime-obj = { path = "crates/obj" } wasmtime-wast = { path = "crates/wast" } diff --git a/crates/api/src/context.rs b/crates/api/src/context.rs index 29cea2e98d..b369a43b6b 100644 --- a/crates/api/src/context.rs +++ b/crates/api/src/context.rs @@ -2,6 +2,7 @@ use crate::Config; use std::cell::{RefCell, RefMut}; use std::hash::{Hash, Hasher}; use std::rc::Rc; +use wasmtime_environ::settings; use wasmtime_jit::{native, Compiler, Features}; #[derive(Clone)] @@ -13,7 +14,7 @@ pub struct Context { impl Context { pub fn new(config: &Config) -> Context { - let isa = native::builder().finish(config.flags.clone()); + let isa = native::builder().finish(settings::Flags::new(config.flags.clone())); Context::new_with_compiler(config, Compiler::new(isa, config.strategy)) } diff --git a/crates/api/src/lib.rs b/crates/api/src/lib.rs index e3a3fd8d1a..18c3d0bf5c 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, Strategy}; +pub use crate::runtime::{Config, Engine, OptLevel, 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 49c69e6d77..c7b5d87de2 100644 --- a/crates/api/src/runtime.rs +++ b/crates/api/src/runtime.rs @@ -4,18 +4,16 @@ use std::cell::RefCell; use std::collections::HashMap; use std::rc::Rc; use std::sync::Arc; -use wasmtime_environ::{ir, settings}; +use wasmtime_environ::{ + ir, + settings::{self, Configurable}, +}; use wasmtime_jit::{CompilationStrategy, Features}; // Runtime Environment // Configuration -fn default_flags() -> settings::Flags { - let flag_builder = settings::builder(); - settings::Flags::new(flag_builder) -} - /// Global configuration options used to create an [`Engine`] and customize its /// behavior. /// @@ -23,7 +21,7 @@ fn default_flags() -> settings::Flags { /// [`Engine::new()`] #[derive(Clone)] pub struct Config { - pub(crate) flags: settings::Flags, + pub(crate) flags: settings::Builder, pub(crate) features: Features, pub(crate) debug_info: bool, pub(crate) strategy: CompilationStrategy, @@ -33,10 +31,18 @@ impl Config { /// Creates a new configuration object with the default configuration /// specified. pub fn new() -> Config { + let mut flags = settings::builder(); + + // There are two possible traps for division, and this way + // we get the proper one if code traps. + flags + .enable("avoid_div_traps") + .expect("should be valid flag"); + Config { debug_info: false, features: Default::default(), - flags: default_flags(), + flags, strategy: CompilationStrategy::Auto, } } @@ -50,16 +56,6 @@ impl Config { self } - /// Configures various flags for compilation such as optimization level and - /// such. - /// - /// For more information on defaults and configuration options, see the - /// documentation for [`Flags`](settings::Flags) - pub fn flags(&mut self, flags: settings::Flags) -> &mut Self { - self.flags = flags; - self - } - /// Configures whether the WebAssembly threads proposal will be enabled for /// compilation. /// @@ -116,6 +112,10 @@ impl Config { /// [proposal]: https://github.com/webassembly/simd pub fn wasm_simd(&mut self, enable: bool) -> &mut Self { self.features.simd = enable; + let val = if enable { "true" } else { "false" }; + self.flags + .set("enable_simd", val) + .expect("should be valid flag"); self } @@ -165,6 +165,8 @@ impl Config { /// modules, and for more documentation consult the [`Strategy`] enumeration /// and its documentation. /// + /// The default value for this is `Strategy::Auto`. + /// /// # Errors /// /// Some compilation strategies require compile-time options of `wasmtime` @@ -183,6 +185,41 @@ impl Config { }; Ok(self) } + + /// Configures whether the debug verifier of Cranelift is enabled or not. + /// + /// When Cranelift is used as a code generation backend this will configure + /// it to have the `enable_verifier` flag which will enable a number of debug + /// checks inside of Cranelift. This is largely only useful for the + /// developers of wasmtime itself. + /// + /// The default value for this is `false` + pub fn cranelift_debug_verifier(&mut self, enable: bool) -> &mut Self { + let val = if enable { "true" } else { "false" }; + self.flags + .set("enable_verifier", val) + .expect("should be valid flag"); + self + } + + /// Configures the Cranelift code generator optimization level. + /// + /// When the Cranelift code generator is used you can configure the + /// optimization level used for generated code in a few various ways. For + /// more information see the documentation of [`OptLevel`]. + /// + /// The default value for this is `OptLevel::None`. + pub fn cranelift_opt_level(&mut self, level: OptLevel) -> &mut Self { + let val = match level { + OptLevel::None => "none", + OptLevel::Speed => "speed", + OptLevel::SpeedAndSize => "speed_and_size", + }; + self.flags + .set("opt_level", val) + .expect("should be valid flag"); + self + } } impl Default for Config { @@ -215,6 +252,20 @@ pub enum Strategy { Lightbeam, } +/// Possible optimization levels for the Cranelift codegen backend. +#[non_exhaustive] +#[derive(Clone, Debug)] +pub enum OptLevel { + /// No optimizations performed, minimizes compilation time by disabling most + /// optimizations. + None, + /// Generates the fastest possible code, but may take longer. + Speed, + /// Similar to `speed`, but also performs transformations aimed at reducing + /// code size. + SpeedAndSize, +} + // Engine /// An `Engine` which is a global context for compilation and management of wasm @@ -313,4 +364,5 @@ impl Store { fn _assert_send_sync() { fn _assert() {} _assert::(); + _assert::(); } diff --git a/crates/environ/src/data_structures.rs b/crates/environ/src/data_structures.rs index eeef93b8bf..6be6c33dab 100644 --- a/crates/environ/src/data_structures.rs +++ b/crates/environ/src/data_structures.rs @@ -9,7 +9,7 @@ pub mod ir { } pub mod settings { - pub use cranelift_codegen::settings::{builder, Configurable, Flags}; + pub use cranelift_codegen::settings::{builder, Builder, Configurable, Flags}; } pub mod isa { diff --git a/crates/test-programs/tests/wasm_tests/runtime.rs b/crates/test-programs/tests/wasm_tests/runtime.rs index 6688b022e6..a0c7e420d9 100644 --- a/crates/test-programs/tests/wasm_tests/runtime.rs +++ b/crates/test-programs/tests/wasm_tests/runtime.rs @@ -1,21 +1,10 @@ use anyhow::{bail, Context}; use std::fs::File; use std::path::Path; -use wasmtime::{Config, Engine, HostRef, Instance, Module, Store}; -use wasmtime_environ::settings::{self, Configurable}; +use wasmtime::{Engine, HostRef, Instance, Module, Store}; pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> anyhow::Result<()> { - // Prepare runtime - let mut flag_builder = settings::builder(); - - // Enable proper trap for division - flag_builder - .enable("avoid_div_traps") - .context("error while enabling proper division trap")?; - - let mut config = Config::new(); - config.flags(settings::Flags::new(flag_builder)); - let engine = Engine::new(&config); + let engine = Engine::default(); let store = HostRef::new(Store::new(&engine)); let global_exports = store.borrow().global_exports().clone(); diff --git a/src/bin/wasmtime.rs b/src/bin/wasmtime.rs index 46f828927a..aa04be0c90 100644 --- a/src/bin/wasmtime.rs +++ b/src/bin/wasmtime.rs @@ -36,7 +36,6 @@ use wasi_common::preopen_dir; use wasmtime::{Config, Engine, HostRef, Instance, Module, Store}; use wasmtime_cli::pick_compilation_strategy; use wasmtime_environ::{cache_create_new_config, cache_init}; -use wasmtime_environ::{settings, settings::Configurable}; use wasmtime_interface_types::ModuleData; use wasmtime_wasi::create_wasi_instance; use wasmtime_wasi::old::snapshot_0::create_wasi_instance as create_wasi_instance_snapshot_0; @@ -231,29 +230,21 @@ fn main() -> Result<()> { } let mut config = Config::new(); - let mut flag_builder = settings::builder(); - - // There are two possible traps for division, and this way - // we get the proper one if code traps. - flag_builder.enable("avoid_div_traps")?; // Enable/disable producing of debug info. config.debug_info(args.flag_g); // Enable verifier passes in debug mode. - if cfg!(debug_assertions) { - flag_builder.enable("enable_verifier")?; - } + config.cranelift_debug_verifier(cfg!(debug_assertions)); // Enable SIMD if requested if args.flag_enable_simd { - flag_builder.enable("enable_simd")?; config.wasm_simd(true); } // Enable optimization if requested. if args.flag_optimize { - flag_builder.set("opt_level", "speed")?; + config.cranelift_opt_level(wasmtime::OptLevel::Speed); } // Decide how to compile. @@ -261,7 +252,6 @@ fn main() -> Result<()> { 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 ca23b41c29..bd0ab19cc1 100644 --- a/src/bin/wast.rs +++ b/src/bin/wast.rs @@ -29,8 +29,6 @@ use std::path::Path; use std::process; use wasmtime::{Config, Engine, HostRef, Store}; use wasmtime_cli::pick_compilation_strategy; -use wasmtime_environ::settings; -use wasmtime_environ::settings::Configurable; use wasmtime_environ::{cache_create_new_config, cache_init}; use wasmtime_wast::WastContext; @@ -118,25 +116,16 @@ fn main() -> Result<()> { } let mut cfg = Config::new(); - let mut flag_builder = settings::builder(); - - // There are two possible traps for division, and this way - // we get the proper one if code traps. - flag_builder.enable("avoid_div_traps").unwrap(); - // Enable verifier passes in debug mode. - if cfg!(debug_assertions) { - flag_builder.enable("enable_verifier").unwrap(); - } + cfg.cranelift_debug_verifier(cfg!(debug_assertions)); // Enable optimization if requested. if args.flag_optimize { - flag_builder.set("opt_level", "speed").unwrap(); + cfg.cranelift_opt_level(wasmtime::OptLevel::Speed); } // Enable SIMD if requested if args.flag_enable_simd { - flag_builder.enable("enable_simd").unwrap(); cfg.wasm_simd(true); } @@ -144,8 +133,7 @@ fn main() -> Result<()> { 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); diff --git a/tests/wast_testsuites.rs b/tests/wast_testsuites.rs index 0edf30c1f6..e56310e1b6 100644 --- a/tests/wast_testsuites.rs +++ b/tests/wast_testsuites.rs @@ -1,7 +1,5 @@ use std::path::Path; use wasmtime::{Config, Engine, HostRef, Store, Strategy}; -use wasmtime_environ::settings; -use wasmtime_environ::settings::Configurable; use wasmtime_wast::WastContext; include!(concat!(env!("OUT_DIR"), "/wast_testsuite_tests.rs")); @@ -12,16 +10,11 @@ include!(concat!(env!("OUT_DIR"), "/wast_testsuite_tests.rs")); fn run_wast(wast: &str, strategy: Strategy) -> anyhow::Result<()> { let wast = Path::new(wast); - let mut flag_builder = settings::builder(); - flag_builder.enable("enable_verifier").unwrap(); - flag_builder.enable("avoid_div_traps").unwrap(); - flag_builder.enable("enable_simd").unwrap(); - 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)? - .flags(settings::Flags::new(flag_builder)); + .cranelift_debug_verifier(true); let store = HostRef::new(Store::new(&Engine::new(&cfg))); let mut wast_context = WastContext::new(store); wast_context.register_spectest()?;