diff --git a/lib/clif-backend/src/func_env.rs b/lib/clif-backend/src/func_env.rs index 8670e0000..e222f2e07 100644 --- a/lib/clif-backend/src/func_env.rs +++ b/lib/clif-backend/src/func_env.rs @@ -75,7 +75,7 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> { let vmctx = func.create_global_value(ir::GlobalValueData::VMContext); let ptr_type = self.pointer_type(); - let local_global_addr = match global_index.local_or_import(self.env.module) { + let local_global_addr = match global_index.local_or_import(&self.env.module.info) { LocalOrImport::Local(local_global_index) => { let globals_base_addr = func.create_global_value(ir::GlobalValueData::Load { base: vmctx, @@ -145,7 +145,7 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> { let vmctx = func.create_global_value(ir::GlobalValueData::VMContext); let ptr_type = self.pointer_type(); - let (local_memory_ptr_ptr, description) = match mem_index.local_or_import(self.env.module) { + let (local_memory_ptr_ptr, description) = match mem_index.local_or_import(&self.env.module.info) { LocalOrImport::Local(local_mem_index) => { let memories_base_addr = func.create_global_value(ir::GlobalValueData::Load { base: vmctx, @@ -253,7 +253,7 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> { let vmctx = func.create_global_value(ir::GlobalValueData::VMContext); let ptr_type = self.pointer_type(); - let (table_struct_ptr_ptr, description) = match table_index.local_or_import(self.env.module) + let (table_struct_ptr_ptr, description) = match table_index.local_or_import(&self.env.module.info) { LocalOrImport::Local(local_table_index) => { let tables_base = func.create_global_value(ir::GlobalValueData::Load { @@ -476,7 +476,7 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> { ) -> cranelift_wasm::WasmResult { let callee_index: FuncIndex = Converter(clif_callee_index).into(); - match callee_index.local_or_import(self.env.module) { + match callee_index.local_or_import(&self.env.module.info) { LocalOrImport::Local(_) => { // this is an internal function let vmctx = pos @@ -568,7 +568,7 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> { let mem_index: MemoryIndex = Converter(clif_mem_index).into(); - let (namespace, mem_index, description) = match mem_index.local_or_import(self.env.module) { + let (namespace, mem_index, description) = match mem_index.local_or_import(&self.env.module.info) { LocalOrImport::Local(local_mem_index) => ( call_names::LOCAL_NAMESPACE, local_mem_index.index(), @@ -631,7 +631,7 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> { let mem_index: MemoryIndex = Converter(clif_mem_index).into(); - let (namespace, mem_index, description) = match mem_index.local_or_import(self.env.module) { + let (namespace, mem_index, description) = match mem_index.local_or_import(&self.env.module.info) { LocalOrImport::Local(local_mem_index) => ( call_names::LOCAL_NAMESPACE, local_mem_index.index(), diff --git a/lib/clif-backend/src/lib.rs b/lib/clif-backend/src/lib.rs index 07bae97c6..cbe455b93 100644 --- a/lib/clif-backend/src/lib.rs +++ b/lib/clif-backend/src/lib.rs @@ -48,7 +48,7 @@ impl Compiler for CraneliftCompiler { let isa = get_isa(); - let mut module = module::Module::empty(); + let mut module = module::Module::new(wasm); let module_env = module_env::ModuleEnv::new(&mut module, &*isa); let func_bodies = module_env.translate(wasm)?; @@ -72,7 +72,7 @@ impl Compiler for CraneliftCompiler { let isa = get_isa(); - let mut module = module::Module::empty(); + let mut module = module::Module::new(wasm); let module_env = module_env::ModuleEnv::new(&mut module, &*isa); let func_bodies = module_env.translate(wasm)?; diff --git a/lib/clif-backend/src/module.rs b/lib/clif-backend/src/module.rs index c48072ac8..e2ee8efe8 100644 --- a/lib/clif-backend/src/module.rs +++ b/lib/clif-backend/src/module.rs @@ -6,115 +6,83 @@ use cranelift_codegen::{ir, isa}; use cranelift_entity::EntityRef; use cranelift_wasm; use hashbrown::HashMap; -use std::{ - ops::{Deref, DerefMut}, - ptr::NonNull, -}; + #[cfg(feature = "cache")] use wasmer_runtime_core::{ backend::sys::Memory, cache::{Cache, Error as CacheError}, }; + use wasmer_runtime_core::{ - backend::{Backend, FuncResolver, ProtectedCaller, Token, UserTrapper}, - error::{CompileResult, RuntimeResult}, - module::{ModuleInfo, ModuleInner, StringTable}, + backend::Backend, + error::CompileResult, + module::{ModuleInfo, ModuleInner, StringTable, WasmHash}, structures::{Map, TypedIndex}, types::{ FuncIndex, FuncSig, GlobalIndex, LocalFuncIndex, MemoryIndex, SigIndex, TableIndex, Type, - Value, }, - vm::{self, ImportBacking}, }; -struct Placeholder; - -impl FuncResolver for Placeholder { - fn get( - &self, - _module: &ModuleInner, - _local_func_index: LocalFuncIndex, - ) -> Option> { - None - } -} - -impl ProtectedCaller for Placeholder { - fn call( - &self, - _module: &ModuleInner, - _func_index: FuncIndex, - _params: &[Value], - _import_backing: &ImportBacking, - _vmctx: *mut vm::Ctx, - _: Token, - ) -> RuntimeResult> { - Ok(vec![]) - } - - fn get_early_trapper(&self) -> Box { - unimplemented!() - } -} - /// This contains all of the items in a `ModuleInner` except the `func_resolver`. pub struct Module { - pub module: ModuleInner, + pub info: ModuleInfo, } impl Module { - pub fn empty() -> Self { + pub fn new(wasm: &[u8]) -> Self { Self { - module: ModuleInner { - // this is a placeholder - func_resolver: Box::new(Placeholder), - protected_caller: Box::new(Placeholder), + info: ModuleInfo { + memories: Map::new(), + globals: Map::new(), + tables: Map::new(), - info: ModuleInfo { - memories: Map::new(), - globals: Map::new(), - tables: Map::new(), + imported_functions: Map::new(), + imported_memories: Map::new(), + imported_tables: Map::new(), + imported_globals: Map::new(), - imported_functions: Map::new(), - imported_memories: Map::new(), - imported_tables: Map::new(), - imported_globals: Map::new(), + exports: HashMap::new(), - exports: HashMap::new(), + data_initializers: Vec::new(), + elem_initializers: Vec::new(), - data_initializers: Vec::new(), - elem_initializers: Vec::new(), + start_func: None, - start_func: None, + func_assoc: Map::new(), + signatures: Map::new(), + backend: Backend::Cranelift, - func_assoc: Map::new(), - signatures: Map::new(), - backend: Backend::Cranelift, + namespace_table: StringTable::new(), + name_table: StringTable::new(), - namespace_table: StringTable::new(), - name_table: StringTable::new(), - }, + wasm_hash: WasmHash::generate(wasm), }, } } pub fn compile( - mut self, + self, isa: &isa::TargetIsa, functions: Map, ) -> CompileResult { let (func_resolver_builder, handler_data) = - FuncResolverBuilder::new(isa, functions, &self.module.info)?; + FuncResolverBuilder::new(isa, functions, &self.info)?; + - self.module.func_resolver = - Box::new(func_resolver_builder.finalize(&self.module.info.signatures)?); + let func_resolver = + Box::new(func_resolver_builder.finalize(&self.info.signatures)?); - let trampolines = Trampolines::new(isa, &self.module.info); + let trampolines = Trampolines::new(isa, &self.info); - self.module.protected_caller = - Box::new(Caller::new(&self.module.info, handler_data, trampolines)); + let protected_caller = + Box::new(Caller::new(&self.info, handler_data, trampolines)); - Ok(self.module) + Ok(ModuleInner { + func_resolver, + protected_caller, + + info: self.info, + }) } #[cfg(feature = "cache")] @@ -124,16 +92,16 @@ impl Module { functions: Map, ) -> CompileResult<(ModuleInfo, BackendCache, Memory)> { let (func_resolver_builder, handler_data) = - FuncResolverBuilder::new(isa, functions, &self.module.info)?; + FuncResolverBuilder::new(isa, functions, &self.info)?; - let trampolines = Trampolines::new(isa, &self.module.info); + let trampolines = Trampolines::new(isa, &self.info); let trampoline_cache = trampolines.to_trampoline_cache(); let (backend_cache, compiled_code) = func_resolver_builder.to_backend_cache(trampoline_cache, handler_data); - Ok((self.module.info, backend_cache, compiled_code)) + Ok((self.info, backend_cache, compiled_code)) } #[cfg(feature = "cache")] @@ -159,20 +127,6 @@ impl Module { } } -impl Deref for Module { - type Target = ModuleInner; - - fn deref(&self) -> &ModuleInner { - &self.module - } -} - -impl DerefMut for Module { - fn deref_mut(&mut self) -> &mut ModuleInner { - &mut self.module - } -} - pub struct Converter(pub T); macro_rules! convert_clif_to_runtime_index { diff --git a/lib/clif-backend/src/module_env.rs b/lib/clif-backend/src/module_env.rs index 65bd5f839..b80e8826d 100644 --- a/lib/clif-backend/src/module_env.rs +++ b/lib/clif-backend/src/module_env.rs @@ -139,7 +139,7 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa> // assert!(!desc.mutable); let global_index: GlobalIndex = Converter(global_index).into(); let imported_global_index = global_index - .local_or_import(self.module) + .local_or_import(&self.module.info) .import() .expect("invalid global initializer when declaring an imported global"); Initializer::GetGlobal(imported_global_index) @@ -249,7 +249,7 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa> let base = match base { Some(global_index) => { let global_index: GlobalIndex = Converter(global_index).into(); - Initializer::GetGlobal(match global_index.local_or_import(self.module) { + Initializer::GetGlobal(match global_index.local_or_import(&self.module.info) { LocalOrImport::Import(imported_global_index) => imported_global_index, LocalOrImport::Local(_) => { panic!("invalid global initializer when declaring an imported global") @@ -319,7 +319,7 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa> let base = match base { Some(global_index) => { let global_index: GlobalIndex = Converter(global_index).into(); - Initializer::GetGlobal(match global_index.local_or_import(self.module) { + Initializer::GetGlobal(match global_index.local_or_import(&self.module.info) { LocalOrImport::Import(imported_global_index) => imported_global_index, LocalOrImport::Local(_) => { panic!("invalid global initializer when declaring an imported global") @@ -389,7 +389,7 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa> let name = ir::ExternalName::user(0, func_index.index() as u32); let sig = func_env.generate_signature( - self.get_func_type(Converter(func_index.convert_up(self.module)).into()), + self.get_func_type(Converter(func_index.convert_up(&self.module.info)).into()), ); let mut func = ir::Function::with_name_signature(name, sig); diff --git a/lib/clif-backend/src/signal/mod.rs b/lib/clif-backend/src/signal/mod.rs index 31dbb44dd..1468d99eb 100644 --- a/lib/clif-backend/src/signal/mod.rs +++ b/lib/clif-backend/src/signal/mod.rs @@ -160,7 +160,7 @@ fn get_func_from_index( .get(func_index) .expect("broken invariant, incorrect func index"); - let (func_ptr, ctx) = match func_index.local_or_import(module) { + let (func_ptr, ctx) = match func_index.local_or_import(&module.info) { LocalOrImport::Local(local_func_index) => ( module .func_resolver diff --git a/lib/runtime-core/src/backend.rs b/lib/runtime-core/src/backend.rs index 9b5ec049e..328e3c826 100644 --- a/lib/runtime-core/src/backend.rs +++ b/lib/runtime-core/src/backend.rs @@ -99,3 +99,7 @@ pub trait FuncResolver: Send + Sync { local_func_index: LocalFuncIndex, ) -> Option>; } + +pub trait CacheGen: Send + Sync { + fn generate_cache(&self, module: &ModuleInner) -> Result<(Box, Box<[u8]>, Memory), CacheError>; +} \ No newline at end of file diff --git a/lib/runtime-core/src/backing.rs b/lib/runtime-core/src/backing.rs index d81e33065..ef2556895 100644 --- a/lib/runtime-core/src/backing.rs +++ b/lib/runtime-core/src/backing.rs @@ -91,7 +91,7 @@ impl LocalBacking { } } as usize; - match init.memory_index.local_or_import(module) { + match init.memory_index.local_or_import(&module.info) { LocalOrImport::Local(local_memory_index) => { let memory_desc = module.info.memories[local_memory_index]; let data_top = init_base + init.data.len(); @@ -159,7 +159,7 @@ impl LocalBacking { } } as usize; - match init.table_index.local_or_import(module) { + match init.table_index.local_or_import(&module.info) { LocalOrImport::Local(local_table_index) => { let table = &tables[local_table_index]; @@ -177,7 +177,7 @@ impl LocalBacking { SigRegistry.lookup_sig_index(Arc::clone(&signature)).index() as u32, ); - let (func, ctx) = match func_index.local_or_import(module) { + let (func, ctx) = match func_index.local_or_import(&module.info) { LocalOrImport::Local(local_func_index) => ( module .func_resolver @@ -215,7 +215,7 @@ impl LocalBacking { SigRegistry.lookup_sig_index(Arc::clone(&signature)).index() as u32, ); - let (func, ctx) = match func_index.local_or_import(module) { + let (func, ctx) = match func_index.local_or_import(&module.info) { LocalOrImport::Local(local_func_index) => ( module .func_resolver @@ -364,7 +364,7 @@ fn import_functions( }, ) in &module.info.imported_functions { - let sig_index = module.info.func_assoc[index.convert_up(module)]; + let sig_index = module.info.func_assoc[index.convert_up(&module.info)]; let expected_sig = &module.info.signatures[sig_index]; let namespace = module.info.namespace_table.get(*namespace_index); diff --git a/lib/runtime-core/src/instance.rs b/lib/runtime-core/src/instance.rs index a8f36325a..a634b21e5 100644 --- a/lib/runtime-core/src/instance.rs +++ b/lib/runtime-core/src/instance.rs @@ -121,14 +121,14 @@ impl Instance { })?; } - let ctx = match func_index.local_or_import(&*self.module) { + let ctx = match func_index.local_or_import(&self.module.info) { LocalOrImport::Local(_) => self.inner.vmctx, LocalOrImport::Import(imported_func_index) => { self.inner.import_backing.vm_functions[imported_func_index].vmctx } }; - let func_ptr = match func_index.local_or_import(&self.module) { + let func_ptr = match func_index.local_or_import(&self.module.info) { LocalOrImport::Local(local_func_index) => self .module .func_resolver @@ -288,7 +288,7 @@ impl Instance { })? } - let vmctx = match func_index.local_or_import(&self.module) { + let vmctx = match func_index.local_or_import(&self.module.info) { LocalOrImport::Local(_) => self.inner.vmctx, LocalOrImport::Import(imported_func_index) => { self.inner.import_backing.vm_functions[imported_func_index].vmctx @@ -355,7 +355,7 @@ impl InstanceInner { .get(func_index) .expect("broken invariant, incorrect func index"); - let (func_ptr, ctx) = match func_index.local_or_import(module) { + let (func_ptr, ctx) = match func_index.local_or_import(&module.info) { LocalOrImport::Local(local_func_index) => ( module .func_resolver @@ -384,7 +384,7 @@ impl InstanceInner { } fn get_memory_from_index(&self, module: &ModuleInner, mem_index: MemoryIndex) -> Memory { - match mem_index.local_or_import(module) { + match mem_index.local_or_import(&module.info) { LocalOrImport::Local(local_mem_index) => self.backing.memories[local_mem_index].clone(), LocalOrImport::Import(imported_mem_index) => { self.import_backing.memories[imported_mem_index].clone() @@ -393,7 +393,7 @@ impl InstanceInner { } fn get_global_from_index(&self, module: &ModuleInner, global_index: GlobalIndex) -> Global { - match global_index.local_or_import(module) { + match global_index.local_or_import(&module.info) { LocalOrImport::Local(local_global_index) => { self.backing.globals[local_global_index].clone() } @@ -404,7 +404,7 @@ impl InstanceInner { } fn get_table_from_index(&self, module: &ModuleInner, table_index: TableIndex) -> Table { - match table_index.local_or_import(module) { + match table_index.local_or_import(&module.info) { LocalOrImport::Local(local_table_index) => { self.backing.tables[local_table_index].clone() } @@ -462,7 +462,7 @@ impl<'a> DynFunc<'a> { })? } - let vmctx = match self.func_index.local_or_import(self.module) { + let vmctx = match self.func_index.local_or_import(&self.module.info) { LocalOrImport::Local(_) => self.instance_inner.vmctx, LocalOrImport::Import(imported_func_index) => { self.instance_inner.import_backing.vm_functions[imported_func_index].vmctx @@ -488,7 +488,7 @@ impl<'a> DynFunc<'a> { } pub fn raw(&self) -> *const vm::Func { - match self.func_index.local_or_import(self.module) { + match self.func_index.local_or_import(&self.module.info) { LocalOrImport::Local(local_func_index) => self .module .func_resolver diff --git a/lib/runtime-core/src/module.rs b/lib/runtime-core/src/module.rs index 0fdb24018..aca3fc221 100644 --- a/lib/runtime-core/src/module.rs +++ b/lib/runtime-core/src/module.rs @@ -51,6 +51,18 @@ pub struct ModuleInfo { pub namespace_table: StringTable, pub name_table: StringTable, + + pub wasm_hash: WasmHash, +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))] +pub struct WasmHash([u8; 32]); + +impl WasmHash { + pub fn generate(wasm: &[u8]) -> Self { + WasmHash(super::cache::hash_data(wasm)) + } } /// A compiled WebAssembly module. @@ -60,7 +72,9 @@ pub struct ModuleInfo { /// /// [`compile`]: fn.compile.html /// [`compile_with`]: fn.compile_with.html -pub struct Module(#[doc(hidden)] pub Arc); +pub struct Module { + inner: Arc, +} impl Module { pub(crate) fn new(inner: Arc) -> Self { @@ -68,7 +82,7 @@ impl Module { EARLY_TRAPPER .with(|ucell| *ucell.get() = Some(inner.protected_caller.get_early_trapper())); } - Module(inner) + Module { inner } } /// Instantiate a WebAssembly module with the provided [`ImportObject`]. @@ -94,7 +108,7 @@ impl Module { /// # } /// ``` pub fn instantiate(&self, import_object: &ImportObject) -> Result { - Instance::new(Arc::clone(&self.0), import_object) + Instance::new(Arc::clone(&self.inner), import_object) } } diff --git a/lib/runtime-core/src/types.rs b/lib/runtime-core/src/types.rs index fd57bf12c..271b336ba 100644 --- a/lib/runtime-core/src/types.rs +++ b/lib/runtime-core/src/types.rs @@ -1,4 +1,4 @@ -use crate::{memory::MemoryType, module::ModuleInner, structures::TypedIndex, units::Pages}; +use crate::{memory::MemoryType, module::ModuleInfo, structures::TypedIndex, units::Pages}; use std::{borrow::Cow, mem}; /// Represents a WebAssembly type. @@ -364,23 +364,23 @@ define_map_index![ macro_rules! define_local_or_import { ($ty:ident, $local_ty:ident, $imported_ty:ident, $imports:ident) => { impl $ty { - pub fn local_or_import(self, module: &ModuleInner) -> LocalOrImport<$ty> { - if self.index() < module.info.$imports.len() { + pub fn local_or_import(self, info: &ModuleInfo) -> LocalOrImport<$ty> { + if self.index() < info.$imports.len() { LocalOrImport::Import(::Import::new(self.index())) } else { - LocalOrImport::Local(::Local::new(self.index() - module.info.$imports.len())) + LocalOrImport::Local(::Local::new(self.index() - info.$imports.len())) } } } impl $local_ty { - pub fn convert_up(self, module: &ModuleInner) -> $ty { - $ty ((self.index() + module.info.$imports.len()) as u32) + pub fn convert_up(self, info: &ModuleInfo) -> $ty { + $ty ((self.index() + info.$imports.len()) as u32) } } impl $imported_ty { - pub fn convert_up(self, _module: &ModuleInner) -> $ty { + pub fn convert_up(self, _info: &ModuleInfo) -> $ty { $ty (self.index() as u32) } } diff --git a/lib/runtime-core/src/vm.rs b/lib/runtime-core/src/vm.rs index faee819be..abea76db8 100644 --- a/lib/runtime-core/src/vm.rs +++ b/lib/runtime-core/src/vm.rs @@ -116,7 +116,7 @@ impl Ctx { pub fn memory(&self, mem_index: u32) -> &Memory { let module = unsafe { &*self.module }; let mem_index = MemoryIndex::new(mem_index as usize); - match mem_index.local_or_import(module) { + match mem_index.local_or_import(&module.info) { LocalOrImport::Local(local_mem_index) => unsafe { let local_backing = &*self.local_backing; &local_backing.memories[local_mem_index] @@ -497,6 +497,7 @@ mod vm_ctx_tests { use crate::backend::{Backend, FuncResolver, ProtectedCaller, Token, UserTrapper}; use crate::error::RuntimeResult; use crate::types::{FuncIndex, LocalFuncIndex, Value}; + use crate::module::WasmHash; use hashbrown::HashMap; use std::ptr::NonNull; struct Placeholder; @@ -553,6 +554,8 @@ mod vm_ctx_tests { namespace_table: StringTable::new(), name_table: StringTable::new(), + + wasm_hash: WasmHash::generate(&[]), }, } } diff --git a/lib/runtime/Cargo.toml b/lib/runtime/Cargo.toml index 2a2478193..fe6cc80d2 100644 --- a/lib/runtime/Cargo.toml +++ b/lib/runtime/Cargo.toml @@ -10,11 +10,9 @@ readme = "README.md" [dependencies] wasmer-runtime-core = { path = "../runtime-core", version = "0.1.2" } -wasmer-clif-backend = { path = "../clif-backend", version = "0.1.2", optional = true } +wasmer-clif-backend = { path = "../clif-backend", version = "0.1.2" } lazy_static = "1.2.0" [features] -default = ["default-compiler", "cache"] -default-compiler = ["wasmer-clif-backend/cache", "wasmer-runtime-core/cache"] -cache = ["default-compiler"] +default = ["wasmer-clif-backend/cache", "wasmer-runtime-core/cache"] debug = ["wasmer-clif-backend/debug", "wasmer-runtime-core/debug"] diff --git a/lib/runtime/src/cache.rs b/lib/runtime/src/cache.rs index ceb6d171e..b0db19fe8 100644 --- a/lib/runtime/src/cache.rs +++ b/lib/runtime/src/cache.rs @@ -1,128 +1,139 @@ use crate::Module; use std::path::Path; use wasmer_runtime_core::cache::{hash_data, Cache as CoreCache}; +use wasmer_runtime_core::module::{WasmHash}; pub use wasmer_runtime_core::cache::Error; -/// On-disk storage of compiled WebAssembly. -/// -/// A `Cache` can be used to quickly reload already -/// compiled WebAssembly from a previous execution -/// during which the wasm was explicitly compiled -/// as a `Cache`. -/// -/// # Usage: -/// -/// ``` -/// use wasmer_runtime::{compile_cache, Cache}; -/// -/// # use wasmer_runtime::error::{CompileResult, CacheError}; -/// # fn make_cache(wasm: &[u8]) -> CompileResult<()> { -/// // Make a cache. -/// let cache = compile_cache(wasm)?; -/// -/// # Ok(()) -/// # } -/// # fn usage_cache(cache: Cache) -> Result<(), CacheError> { -/// // Store the cache in a file. -/// cache.store("some_cache_file")?; -/// -/// // Load the cache. -/// let cache = Cache::load("some_cache_file")?; -/// let module = unsafe { cache.into_module()? }; -/// # Ok(()) -/// # } -/// ``` -/// -/// # Performance Characteristics: -/// -/// Loading caches from files has been optimized for latency. -/// There is still more work to do that will reduce -/// loading time, especially for very large modules, -/// but it will require signifigant internal work. -/// -/// # Drawbacks: -/// -/// Due to internal shortcomings, you cannot convert -/// a module into a `Cache`. This means that compiling -/// into a `Cache` and then converting into a module -/// has more overhead than directly compiling -/// into a [`Module`]. -/// -/// [`Module`]: struct.Module.html -pub struct Cache(pub(crate) CoreCache); +// /// On-disk storage of compiled WebAssembly. +// /// +// /// A `Cache` can be used to quickly reload already +// /// compiled WebAssembly from a previous execution +// /// during which the wasm was explicitly compiled +// /// as a `Cache`. +// /// +// /// # Usage: +// /// +// /// ``` +// /// use wasmer_runtime::{compile_cache, Cache}; +// /// +// /// # use wasmer_runtime::error::{CompileResult, CacheError}; +// /// # fn make_cache(wasm: &[u8]) -> CompileResult<()> { +// /// // Make a cache. +// /// let cache = compile_cache(wasm)?; +// /// +// /// # Ok(()) +// /// # } +// /// # fn usage_cache(cache: Cache) -> Result<(), CacheError> { +// /// // Store the cache in a file. +// /// cache.store("some_cache_file")?; +// /// +// /// // Load the cache. +// /// let cache = Cache::load("some_cache_file")?; +// /// let module = unsafe { cache.into_module()? }; +// /// # Ok(()) +// /// # } +// /// ``` +// /// +// /// # Performance Characteristics: +// /// +// /// Loading caches from files has been optimized for latency. +// /// There is still more work to do that will reduce +// /// loading time, especially for very large modules, +// /// but it will require signifigant internal work. +// /// +// /// # Drawbacks: +// /// +// /// Due to internal shortcomings, you cannot convert +// /// a module into a `Cache`. This means that compiling +// /// into a `Cache` and then converting into a module +// /// has more overhead than directly compiling +// /// into a [`Module`]. +// /// +// /// [`Module`]: struct.Module.html +// pub struct Cache(pub(crate) CoreCache); -impl Cache { - /// Load a `Cache` from the file specified by `path`. - /// - /// # Usage: - /// - /// ``` - /// use wasmer_runtime::Cache; - /// # use wasmer_runtime::error::CacheError; - /// - /// # fn load_cache() -> Result<(), CacheError> { - /// let cache = Cache::load("some_file.cache")?; - /// # Ok(()) - /// # } - /// ``` - pub fn load>(path: P) -> Result { - CoreCache::open(path).map(|core_cache| Cache(core_cache)) - } +// impl Cache { +// /// Load a `Cache` from the file specified by `path`. +// /// +// /// # Usage: +// /// +// /// ``` +// /// use wasmer_runtime::Cache; +// /// # use wasmer_runtime::error::CacheError; +// /// +// /// # fn load_cache() -> Result<(), CacheError> { +// /// let cache = Cache::load("some_file.cache")?; +// /// # Ok(()) +// /// # } +// /// ``` +// pub fn load>(path: P) -> Result { +// CoreCache::open(path).map(|core_cache| Cache(core_cache)) +// } - /// Convert a `Cache` into a [`Module`]. - /// - /// [`Module`]: struct.Module.html - /// - /// # Usage: - /// - /// ``` - /// use wasmer_runtime::Cache; - /// - /// # use wasmer_runtime::error::CacheError; - /// # fn cache2module(cache: Cache) -> Result<(), CacheError> { - /// let module = unsafe { cache.into_module()? }; - /// # Ok(()) - /// # } - /// ``` - /// - /// # Notes: - /// - /// This method is unsafe because the runtime cannot confirm - /// that this cache was not tampered with or corrupted. - pub unsafe fn into_module(self) -> Result { - let default_compiler = super::default_compiler(); +// /// Convert a `Cache` into a [`Module`]. +// /// +// /// [`Module`]: struct.Module.html +// /// +// /// # Usage: +// /// +// /// ``` +// /// use wasmer_runtime::Cache; +// /// +// /// # use wasmer_runtime::error::CacheError; +// /// # fn cache2module(cache: Cache) -> Result<(), CacheError> { +// /// let module = unsafe { cache.into_module()? }; +// /// # Ok(()) +// /// # } +// /// ``` +// /// +// /// # Notes: +// /// +// /// This method is unsafe because the runtime cannot confirm +// /// that this cache was not tampered with or corrupted. +// pub unsafe fn into_module(self) -> Result { +// let default_compiler = super::default_compiler(); - wasmer_runtime_core::load_cache_with(self.0, default_compiler) - } +// wasmer_runtime_core::load_cache_with(self.0, default_compiler) +// } - /// Compare the Sha256 hash of the wasm this cache was build - /// from with some other WebAssembly. - /// - /// The main use-case for this is invalidating old caches. - pub fn compare_wasm(&self, wasm: &[u8]) -> bool { - let param_wasm_hash = hash_data(wasm); - self.0.wasm_hash() as &[u8] == ¶m_wasm_hash as &[u8] - } +// /// Compare the Sha256 hash of the wasm this cache was build +// /// from with some other WebAssembly. +// /// +// /// The main use-case for this is invalidating old caches. +// pub fn compare_wasm(&self, wasm: &[u8]) -> bool { +// let param_wasm_hash = hash_data(wasm); +// self.0.wasm_hash() as &[u8] == ¶m_wasm_hash as &[u8] +// } - /// Store this cache in a file. - /// - /// # Notes: - /// - /// If a file exists at the specified path, it will be overwritten. - /// - /// # Usage: - /// - /// ``` - /// use wasmer_runtime::Cache; - /// - /// # use wasmer_runtime::error::CacheError; - /// # fn store_cache(cache: Cache) -> Result<(), CacheError> { - /// cache.store("some_file.cache")?; - /// # Ok(()) - /// # } - /// ``` - pub fn store>(&self, path: P) -> Result<(), Error> { - self.0.store(path) - } +// /// Store this cache in a file. +// /// +// /// # Notes: +// /// +// /// If a file exists at the specified path, it will be overwritten. +// /// +// /// # Usage: +// /// +// /// ``` +// /// use wasmer_runtime::Cache; +// /// +// /// # use wasmer_runtime::error::CacheError; +// /// # fn store_cache(cache: Cache) -> Result<(), CacheError> { +// /// cache.store("some_file.cache")?; +// /// # Ok(()) +// /// # } +// /// ``` +// pub fn store>(&self, path: P) -> Result<(), Error> { +// self.0.store(path) +// } +// } + +pub trait Cache { + type Key; + type LoadError; + type StoreError; + + unsafe fn load(&self, key: Self::Key) -> Result; + fn store(&mut self, module: Module) -> Result; } + diff --git a/lib/runtime/src/lib.rs b/lib/runtime/src/lib.rs index f100a5bad..48a4c27f5 100644 --- a/lib/runtime/src/lib.rs +++ b/lib/runtime/src/lib.rs @@ -99,7 +99,6 @@ pub mod wasm { } pub mod error { - #[cfg(feature = "cache")] pub use super::cache::Error as CacheError; pub use wasmer_runtime_core::error::*; } @@ -109,13 +108,10 @@ pub mod units { pub use wasmer_runtime_core::units::{Bytes, Pages}; } -#[cfg(feature = "cache")] mod cache; -#[cfg(feature = "default-compiler")] use wasmer_runtime_core::backend::Compiler; -#[cfg(feature = "cache")] pub use self::cache::Cache; /// Compile WebAssembly binary code into a [`Module`]. @@ -131,7 +127,6 @@ pub use self::cache::Cache; /// binary code of the wasm module you want to compile. /// # Errors: /// If the operation fails, the function returns `Err(error::CompileError::...)`. -#[cfg(feature = "default-compiler")] pub fn compile(wasm: &[u8]) -> error::CompileResult { wasmer_runtime_core::compile_with(&wasm[..], default_compiler()) } @@ -154,38 +149,35 @@ pub fn compile(wasm: &[u8]) -> error::CompileResult { /// `error::CompileError`, `error::LinkError`, or /// `error::RuntimeError` (all combined into an `error::Error`), /// depending on the cause of the failure. -#[cfg(feature = "default-compiler")] pub fn instantiate(wasm: &[u8], import_object: &ImportObject) -> error::Result { let module = compile(wasm)?; module.instantiate(import_object) } -/// Compile wasm into a [`Cache`] that can be stored to a file or -/// converted into [`Module`]. -/// -/// [`Cache`]: struct.Cache.html -/// [`Module`]: struct.Module.html -/// -/// # Usage: -/// -/// ``` -/// # use wasmer_runtime::error::CompileResult; -/// use wasmer_runtime::compile_cache; -/// -/// # fn make_cache(wasm: &[u8]) -> CompileResult<()> { -/// let cache = compile_cache(wasm)?; -/// # Ok(()) -/// # } -/// ``` -#[cfg(feature = "cache")] -pub fn compile_cache(wasm: &[u8]) -> error::CompileResult { - let default_compiler = default_compiler(); +// /// Compile wasm into a [`Cache`] that can be stored to a file or +// /// converted into [`Module`]. +// /// +// /// [`Cache`]: struct.Cache.html +// /// [`Module`]: struct.Module.html +// /// +// /// # Usage: +// /// +// /// ``` +// /// # use wasmer_runtime::error::CompileResult; +// /// use wasmer_runtime::compile_cache; +// /// +// /// # fn make_cache(wasm: &[u8]) -> CompileResult<()> { +// /// let cache = compile_cache(wasm)?; +// /// # Ok(()) +// /// # } +// /// ``` +// pub fn compile_cache(wasm: &[u8]) -> error::CompileResult { +// let default_compiler = default_compiler(); - wasmer_runtime_core::compile_to_cache_with(wasm, default_compiler) - .map(|core_cache| Cache(core_cache)) -} +// wasmer_runtime_core::compile_to_cache_with(wasm, default_compiler) +// .map(|core_cache| Cache(core_cache)) +// } -#[cfg(feature = "default-compiler")] fn default_compiler() -> &'static dyn Compiler { use lazy_static::lazy_static; use wasmer_clif_backend::CraneliftCompiler;