Use ModuleInfo instead of ModuleInner when possible

This commit is contained in:
Lachlan Sneff
2019-02-18 11:56:20 -08:00
parent 7602071e1a
commit e381bbd07b
14 changed files with 252 additions and 276 deletions

View File

@ -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<ir::Inst> {
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(),

View File

@ -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)?;

View File

@ -6,70 +6,31 @@ 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<NonNull<vm::Func>> {
None
}
}
impl ProtectedCaller for Placeholder {
fn call(
&self,
_module: &ModuleInner,
_func_index: FuncIndex,
_params: &[Value],
_import_backing: &ImportBacking,
_vmctx: *mut vm::Ctx,
_: Token,
) -> RuntimeResult<Vec<Value>> {
Ok(vec![])
}
fn get_early_trapper(&self) -> Box<dyn UserTrapper> {
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(),
@ -93,28 +54,35 @@ impl Module {
namespace_table: StringTable::new(),
name_table: StringTable::new(),
},
wasm_hash: WasmHash::generate(wasm),
},
}
}
pub fn compile(
mut self,
self,
isa: &isa::TargetIsa,
functions: Map<LocalFuncIndex, ir::Function>,
) -> CompileResult<ModuleInner> {
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 trampolines = Trampolines::new(isa, &self.module.info);
let func_resolver =
Box::new(func_resolver_builder.finalize(&self.info.signatures)?);
self.module.protected_caller =
Box::new(Caller::new(&self.module.info, handler_data, trampolines));
let trampolines = Trampolines::new(isa, &self.info);
Ok(self.module)
let protected_caller =
Box::new(Caller::new(&self.info, handler_data, trampolines));
Ok(ModuleInner {
func_resolver,
protected_caller,
info: self.info,
})
}
#[cfg(feature = "cache")]
@ -124,16 +92,16 @@ impl Module {
functions: Map<LocalFuncIndex, ir::Function>,
) -> 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<T>(pub T);
macro_rules! convert_clif_to_runtime_index {

View File

@ -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);

View File

@ -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

View File

@ -99,3 +99,7 @@ pub trait FuncResolver: Send + Sync {
local_func_index: LocalFuncIndex,
) -> Option<NonNull<vm::Func>>;
}
pub trait CacheGen: Send + Sync {
fn generate_cache(&self, module: &ModuleInner) -> Result<(Box<ModuleInfo>, Box<[u8]>, Memory), CacheError>;
}

View File

@ -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);

View File

@ -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

View File

@ -51,6 +51,18 @@ pub struct ModuleInfo {
pub namespace_table: StringTable<NamespaceIndex>,
pub name_table: StringTable<NameIndex>,
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<ModuleInner>);
pub struct Module {
inner: Arc<ModuleInner>,
}
impl Module {
pub(crate) fn new(inner: Arc<ModuleInner>) -> 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> {
Instance::new(Arc::clone(&self.0), import_object)
Instance::new(Arc::clone(&self.inner), import_object)
}
}

View File

@ -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(<Self as LocalImport>::Import::new(self.index()))
} else {
LocalOrImport::Local(<Self as LocalImport>::Local::new(self.index() - module.info.$imports.len()))
LocalOrImport::Local(<Self as LocalImport>::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)
}
}

View File

@ -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(&[]),
},
}
}

View File

@ -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"]

View File

@ -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<P: AsRef<Path>>(path: P) -> Result<Self, Error> {
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<P: AsRef<Path>>(path: P) -> Result<Self, Error> {
// 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<Module, Error> {
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<Module, Error> {
// 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] == &param_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] == &param_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<P: AsRef<Path>>(&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<P: AsRef<Path>>(&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<Module, Self::LoadError>;
fn store(&mut self, module: Module) -> Result<Self::Key, Self::StoreError>;
}

View File

@ -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<Module> {
wasmer_runtime_core::compile_with(&wasm[..], default_compiler())
}
@ -154,38 +149,35 @@ pub fn compile(wasm: &[u8]) -> error::CompileResult<Module> {
/// `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<Instance> {
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<Cache> {
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<Cache> {
// 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;