use std::sync::Arc; use wasmer::{CompilerConfig, Engine as WasmerEngine, Features, ModuleMiddleware, Store}; #[derive(Clone, Debug, PartialEq)] pub enum Compiler { LLVM, Cranelift, Singlepass, } #[derive(Clone, Debug, PartialEq)] pub enum Engine { Native, JIT, } #[derive(Clone)] pub struct Config { pub compiler: Compiler, pub engine: Engine, pub features: Features, pub middlewares: Vec>, pub canonicalize_nans: bool, } impl Config { pub fn new(engine: Engine, compiler: Compiler) -> Self { Self { compiler, engine, features: Default::default(), canonicalize_nans: false, middlewares: vec![], } } pub fn set_middlewares(&mut self, middlewares: Vec>) { self.middlewares = middlewares; } pub fn set_features(&mut self, features: Features) { self.features = features; } pub fn set_nan_canonicalization(&mut self, canonicalize_nans: bool) { self.canonicalize_nans = canonicalize_nans; } pub fn store(&self) -> Store { let compiler_config = self.compiler_config(self.canonicalize_nans); let engine = self.engine(compiler_config); Store::new(&*engine) } pub fn headless_store(&self) -> Store { let engine = self.engine_headless(); Store::new(&*engine) } pub fn engine(&self, compiler_config: Box) -> Box { #[cfg(not(feature = "engine"))] compile_error!("Plese enable at least one engine via the features"); match &self.engine { #[cfg(feature = "native")] Engine::Native => Box::new( wasmer_engine_native::Native::new(compiler_config) .features(self.features.clone()) .engine(), ), #[cfg(feature = "jit")] Engine::JIT => Box::new( wasmer_engine_jit::JIT::new(compiler_config) .features(self.features.clone()) .engine(), ), engine => panic!( "The {:?} Engine is not enabled. Please enable it using the features", engine ), } } pub fn engine_headless(&self) -> Box { match &self.engine { #[cfg(feature = "native")] Engine::Native => Box::new(wasmer_engine_native::Native::headless().engine()), #[cfg(feature = "jit")] Engine::JIT => Box::new(wasmer_engine_jit::JIT::headless().engine()), engine => panic!( "The {:?} Engine is not enabled. Please enable it using the features", engine ), } } pub fn compiler_config(&self, canonicalize_nans: bool) -> Box { #[cfg(not(feature = "compiler"))] compile_error!("Plese enable at least one compiler via the features"); match &self.compiler { #[cfg(feature = "cranelift")] Compiler::Cranelift => { let mut compiler = wasmer_compiler_cranelift::Cranelift::new(); compiler.canonicalize_nans(canonicalize_nans); compiler.enable_verifier(); self.add_middlewares(&mut compiler); Box::new(compiler) } #[cfg(feature = "llvm")] Compiler::LLVM => { let mut compiler = wasmer_compiler_llvm::LLVM::new(); compiler.canonicalize_nans(canonicalize_nans); compiler.enable_verifier(); self.add_middlewares(&mut compiler); Box::new(compiler) } #[cfg(feature = "singlepass")] Compiler::Singlepass => { let mut compiler = wasmer_compiler_singlepass::Singlepass::new(); compiler.canonicalize_nans(canonicalize_nans); compiler.enable_verifier(); self.add_middlewares(&mut compiler); Box::new(compiler) } #[allow(dead_code)] compiler => { panic!( "The {:?} Compiler is not enabled. Enable it via the features", compiler ) } } } fn add_middlewares(&self, config: &mut dyn CompilerConfig) { for middleware in self.middlewares.iter() { config.push_middleware(middleware.clone()); } } }