Reduce number of crates needed for Config usage

This commit is an attempt to reduce the number of crates necessary to
link to when using `wasmtime::Config` in "default mode" or with only one
or two tweaks. The change moves to a builder-style pattern for `Config`
to only require importing crates as necessary if you configure a
particular setting. This then also propagates that change to `Context`
as well by taking a `Config` instead of requiring that all arguments are
passed alone.
This commit is contained in:
Alex Crichton
2019-11-13 08:00:30 -08:00
parent 98266498af
commit fb60a21930
8 changed files with 88 additions and 96 deletions

View File

@@ -1,8 +1,8 @@
use crate::Config;
use alloc::rc::Rc;
use core::cell::{RefCell, RefMut};
use core::hash::{Hash, Hasher};
use cranelift_codegen::settings;
use wasmtime_jit::{CompilationStrategy, Compiler, Features};
use wasmtime_jit::{Compiler, Features};
#[derive(Clone)]
pub struct Context {
@@ -12,21 +12,19 @@ pub struct Context {
}
impl Context {
pub fn new(compiler: Compiler, features: Features, debug_info: bool) -> Context {
Context {
compiler: Rc::new(RefCell::new(compiler)),
features,
debug_info,
}
pub fn new(config: &Config) -> Context {
let isa_builder =
cranelift_native::builder().expect("host machine is not a supported target");
let isa = isa_builder.finish(config.flags.clone());
Context::new_with_compiler(config, Compiler::new(isa, config.strategy))
}
pub fn create(
flags: settings::Flags,
features: Features,
debug_info: bool,
strategy: CompilationStrategy,
) -> Context {
Context::new(create_compiler(flags, strategy), features, debug_info)
pub fn new_with_compiler(config: &Config, compiler: Compiler) -> Context {
Context {
compiler: Rc::new(RefCell::new(compiler)),
features: config.features.clone(),
debug_info: config.debug_info,
}
}
pub(crate) fn debug_info(&self) -> bool {
@@ -54,13 +52,3 @@ impl PartialEq for Context {
Rc::ptr_eq(&self.compiler, &other.compiler)
}
}
pub(crate) fn create_compiler(flags: settings::Flags, strategy: CompilationStrategy) -> Compiler {
let isa = {
let isa_builder =
cranelift_native::builder().expect("host machine is not a supported target");
isa_builder.finish(flags)
};
Compiler::new(isa, strategy)
}

View File

@@ -15,15 +15,23 @@ fn default_flags() -> settings::Flags {
settings::Flags::new(flag_builder)
}
/// Global configuration options used to create an [`Engine`] and customize its
/// behavior.
///
/// This structure exposed a builder-like interface and is primarily consumed by
/// [`Engine::new()`]
#[derive(Clone)]
pub struct Config {
flags: settings::Flags,
features: Features,
debug_info: bool,
strategy: CompilationStrategy,
pub(crate) flags: settings::Flags,
pub(crate) features: Features,
pub(crate) debug_info: bool,
pub(crate) strategy: CompilationStrategy,
}
impl Config {
pub fn default() -> Config {
/// Creates a new configuration object with the default configuration
/// specified.
pub fn new() -> Config {
Config {
debug_info: false,
features: Default::default(),
@@ -32,54 +40,68 @@ impl Config {
}
}
pub fn new(
flags: settings::Flags,
features: Features,
debug_info: bool,
strategy: CompilationStrategy,
) -> Config {
Config {
flags,
features,
debug_info,
strategy,
}
/// Configures whether DWARF debug information will be emitted during
/// compilation.
///
/// By default this option is `false`.
pub fn debug_info(&mut self, enable: bool) -> &mut Self {
self.debug_info = enable;
self
}
pub(crate) fn debug_info(&self) -> bool {
self.debug_info
/// 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
}
pub(crate) fn flags(&self) -> &settings::Flags {
&self.flags
/// Indicates which WebAssembly features are enabled for this compilation
/// session.
///
/// By default only stable features are enabled by default (and none are
/// fully stabilized yet at this time). If you're loading wasm modules
/// which may use non-MVP features you'll want to be sure to call this
/// method and enable the appropriate feature in the [`Features`]
/// structure.
pub fn features(&mut self, features: Features) -> &mut Self {
self.features = features;
self
}
pub(crate) fn features(&self) -> &Features {
&self.features
/// Configures the compilation `strategy` provided, indicating which
/// backend will be used for compiling WebAssembly to native code.
///
/// 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
}
}
pub(crate) fn strategy(&self) -> CompilationStrategy {
self.strategy
impl Default for Config {
fn default() -> Config {
Config::new()
}
}
// Engine
#[derive(Default)]
pub struct Engine {
config: Config,
}
impl Engine {
pub fn new(config: Config) -> Engine {
Engine { config }
}
pub fn default() -> Engine {
Engine::new(Config::default())
}
pub(crate) fn config(&self) -> &Config {
&self.config
pub fn new(config: &Config) -> Engine {
Engine {
config: config.clone(),
}
}
}
@@ -94,13 +116,9 @@ pub struct Store {
impl Store {
pub fn new(engine: &HostRef<Engine>) -> Store {
let flags = engine.borrow().config().flags().clone();
let features = engine.borrow().config().features().clone();
let debug_info = engine.borrow().config().debug_info();
let strategy = engine.borrow().config().strategy();
Store {
engine: engine.clone(),
context: Context::create(flags, features, debug_info, strategy),
context: Context::new(&engine.borrow().config),
global_exports: Rc::new(RefCell::new(HashMap::new())),
signature_cache: HashMap::new(),
}

View File

@@ -24,7 +24,7 @@ fn test_import_calling_export() {
}
}
let engine = HostRef::new(Engine::new(Config::default()));
let engine = HostRef::new(Engine::default());
let store = HostRef::new(Store::new(&engine));
let module = HostRef::new(
Module::new(