2019-02-06 16:26:45 -08:00
|
|
|
#[cfg(feature = "cache")]
|
|
|
|
use crate::cache::BackendCache;
|
2019-02-07 17:08:42 -08:00
|
|
|
use crate::{resolver::FuncResolverBuilder, signal::Caller, trampoline::Trampolines};
|
2019-02-06 16:26:45 -08:00
|
|
|
|
2019-01-16 17:59:12 -08:00
|
|
|
use cranelift_codegen::{ir, isa};
|
|
|
|
use cranelift_entity::EntityRef;
|
|
|
|
use cranelift_wasm;
|
|
|
|
use hashbrown::HashMap;
|
|
|
|
use std::{
|
|
|
|
ops::{Deref, DerefMut},
|
|
|
|
ptr::NonNull,
|
|
|
|
};
|
2019-02-06 16:26:45 -08:00
|
|
|
#[cfg(feature = "cache")]
|
|
|
|
use wasmer_runtime_core::{
|
|
|
|
backend::sys::Memory,
|
|
|
|
cache::{Cache, Error as CacheError},
|
|
|
|
};
|
2019-01-22 13:02:06 -06:00
|
|
|
use wasmer_runtime_core::{
|
2019-02-08 13:08:03 -08:00
|
|
|
backend::{Backend, FuncResolver, ProtectedCaller, Token, UserTrapper},
|
2019-01-18 14:30:15 -08:00
|
|
|
error::{CompileResult, RuntimeResult},
|
2019-02-06 16:26:45 -08:00
|
|
|
module::{ModuleInfo, ModuleInner, StringTable},
|
2019-01-16 17:59:12 -08:00
|
|
|
structures::{Map, TypedIndex},
|
2019-01-16 10:26:10 -08:00
|
|
|
types::{
|
2019-01-16 17:59:12 -08:00
|
|
|
FuncIndex, FuncSig, GlobalIndex, LocalFuncIndex, MemoryIndex, SigIndex, TableIndex, Type,
|
2019-01-18 14:30:15 -08:00
|
|
|
Value,
|
2019-01-16 10:26:10 -08:00
|
|
|
},
|
2019-01-18 14:30:15 -08:00
|
|
|
vm::{self, ImportBacking},
|
2019-01-16 10:26:10 -08:00
|
|
|
};
|
|
|
|
|
2019-01-18 14:30:15 -08:00
|
|
|
struct Placeholder;
|
2019-01-16 17:59:12 -08:00
|
|
|
|
2019-01-18 14:30:15 -08:00
|
|
|
impl FuncResolver for Placeholder {
|
2019-01-16 17:59:12 -08:00
|
|
|
fn get(
|
|
|
|
&self,
|
|
|
|
_module: &ModuleInner,
|
|
|
|
_local_func_index: LocalFuncIndex,
|
|
|
|
) -> Option<NonNull<vm::Func>> {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-18 14:30:15 -08:00
|
|
|
impl ProtectedCaller for Placeholder {
|
|
|
|
fn call(
|
|
|
|
&self,
|
|
|
|
_module: &ModuleInner,
|
|
|
|
_func_index: FuncIndex,
|
|
|
|
_params: &[Value],
|
|
|
|
_import_backing: &ImportBacking,
|
|
|
|
_vmctx: *mut vm::Ctx,
|
|
|
|
_: Token,
|
2019-01-22 15:00:27 -08:00
|
|
|
) -> RuntimeResult<Vec<Value>> {
|
|
|
|
Ok(vec![])
|
2019-01-18 14:30:15 -08:00
|
|
|
}
|
2019-02-08 13:08:03 -08:00
|
|
|
|
|
|
|
fn get_early_trapper(&self) -> Box<dyn UserTrapper> {
|
|
|
|
unimplemented!()
|
|
|
|
}
|
2019-01-18 14:30:15 -08:00
|
|
|
}
|
|
|
|
|
2019-01-16 17:59:12 -08:00
|
|
|
/// This contains all of the items in a `ModuleInner` except the `func_resolver`.
|
2019-01-16 10:26:10 -08:00
|
|
|
pub struct Module {
|
2019-01-17 19:55:25 +01:00
|
|
|
pub module: ModuleInner,
|
2019-01-16 17:59:12 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Module {
|
|
|
|
pub fn empty() -> Self {
|
|
|
|
Self {
|
|
|
|
module: ModuleInner {
|
|
|
|
// this is a placeholder
|
2019-01-18 14:30:15 -08:00
|
|
|
func_resolver: Box::new(Placeholder),
|
|
|
|
protected_caller: Box::new(Placeholder),
|
|
|
|
|
2019-02-06 16:26:45 -08:00
|
|
|
info: ModuleInfo {
|
|
|
|
memories: Map::new(),
|
|
|
|
globals: Map::new(),
|
|
|
|
tables: Map::new(),
|
2019-01-16 17:59:12 -08:00
|
|
|
|
2019-02-06 16:26:45 -08:00
|
|
|
imported_functions: Map::new(),
|
|
|
|
imported_memories: Map::new(),
|
|
|
|
imported_tables: Map::new(),
|
|
|
|
imported_globals: Map::new(),
|
2019-01-16 17:59:12 -08:00
|
|
|
|
2019-02-06 16:26:45 -08:00
|
|
|
exports: HashMap::new(),
|
2019-01-16 17:59:12 -08:00
|
|
|
|
2019-02-06 16:26:45 -08:00
|
|
|
data_initializers: Vec::new(),
|
|
|
|
elem_initializers: Vec::new(),
|
2019-01-16 17:59:12 -08:00
|
|
|
|
2019-02-06 16:26:45 -08:00
|
|
|
start_func: None,
|
2019-01-16 17:59:12 -08:00
|
|
|
|
2019-02-06 16:26:45 -08:00
|
|
|
func_assoc: Map::new(),
|
|
|
|
signatures: Map::new(),
|
|
|
|
backend: Backend::Cranelift,
|
|
|
|
|
|
|
|
namespace_table: StringTable::new(),
|
|
|
|
name_table: StringTable::new(),
|
|
|
|
},
|
2019-01-16 17:59:12 -08:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn compile(
|
|
|
|
mut self,
|
|
|
|
isa: &isa::TargetIsa,
|
|
|
|
functions: Map<LocalFuncIndex, ir::Function>,
|
2019-01-18 09:17:44 -08:00
|
|
|
) -> CompileResult<ModuleInner> {
|
2019-01-23 00:31:58 -06:00
|
|
|
let (func_resolver_builder, handler_data) =
|
2019-02-06 16:26:45 -08:00
|
|
|
FuncResolverBuilder::new(isa, functions, &self.module.info)?;
|
2019-01-29 10:28:18 -08:00
|
|
|
|
2019-02-06 16:26:45 -08:00
|
|
|
self.module.func_resolver =
|
|
|
|
Box::new(func_resolver_builder.finalize(&self.module.info.signatures)?);
|
2019-01-18 14:30:15 -08:00
|
|
|
|
2019-02-06 16:26:45 -08:00
|
|
|
let trampolines = Trampolines::new(isa, &self.module.info);
|
2019-01-22 15:00:27 -08:00
|
|
|
|
|
|
|
self.module.protected_caller =
|
2019-02-06 16:26:45 -08:00
|
|
|
Box::new(Caller::new(&self.module.info, handler_data, trampolines));
|
2019-01-18 14:30:15 -08:00
|
|
|
|
2019-01-16 17:59:12 -08:00
|
|
|
Ok(self.module)
|
|
|
|
}
|
2019-02-06 16:26:45 -08:00
|
|
|
|
|
|
|
#[cfg(feature = "cache")]
|
|
|
|
pub fn compile_to_backend_cache(
|
|
|
|
self,
|
|
|
|
isa: &isa::TargetIsa,
|
|
|
|
functions: Map<LocalFuncIndex, ir::Function>,
|
|
|
|
) -> CompileResult<(ModuleInfo, BackendCache, Memory)> {
|
|
|
|
let (func_resolver_builder, handler_data) =
|
|
|
|
FuncResolverBuilder::new(isa, functions, &self.module.info)?;
|
|
|
|
|
|
|
|
let trampolines = Trampolines::new(isa, &self.module.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))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "cache")]
|
|
|
|
pub fn from_cache(cache: Cache) -> Result<ModuleInner, CacheError> {
|
|
|
|
let (info, compiled_code, backend_cache) = BackendCache::from_cache(cache)?;
|
|
|
|
|
|
|
|
let (func_resolver_builder, trampolines, handler_data) =
|
|
|
|
FuncResolverBuilder::new_from_backend_cache(backend_cache, compiled_code, &info)?;
|
|
|
|
|
|
|
|
let func_resolver = Box::new(
|
|
|
|
func_resolver_builder
|
|
|
|
.finalize(&info.signatures)
|
|
|
|
.map_err(|e| CacheError::Unknown(format!("{:?}", e)))?,
|
|
|
|
);
|
|
|
|
|
|
|
|
let protected_caller = Box::new(Caller::new(&info, handler_data, trampolines));
|
|
|
|
|
|
|
|
Ok(ModuleInner {
|
|
|
|
func_resolver,
|
|
|
|
protected_caller,
|
|
|
|
info,
|
|
|
|
})
|
|
|
|
}
|
2019-01-16 17:59:12 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
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 {
|
|
|
|
($clif_index:ident, $runtime_index:ident) => {
|
|
|
|
impl From<Converter<cranelift_wasm::$clif_index>> for $runtime_index {
|
|
|
|
fn from(clif_index: Converter<cranelift_wasm::$clif_index>) -> Self {
|
|
|
|
$runtime_index::new(clif_index.0.index())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<Converter<$runtime_index>> for cranelift_wasm::$clif_index {
|
|
|
|
fn from(runtime_index: Converter<$runtime_index>) -> Self {
|
|
|
|
cranelift_wasm::$clif_index::new(runtime_index.0.index())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
($(($clif_index:ident: $runtime_index:ident),)*) => {
|
|
|
|
$(
|
|
|
|
convert_clif_to_runtime_index!($clif_index, $runtime_index);
|
|
|
|
)*
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
convert_clif_to_runtime_index![
|
|
|
|
(FuncIndex: FuncIndex),
|
|
|
|
(MemoryIndex: MemoryIndex),
|
|
|
|
(TableIndex: TableIndex),
|
|
|
|
(GlobalIndex: GlobalIndex),
|
|
|
|
(SignatureIndex: SigIndex),
|
|
|
|
];
|
|
|
|
|
|
|
|
impl<'a> From<Converter<&'a ir::Signature>> for FuncSig {
|
|
|
|
fn from(signature: Converter<&'a ir::Signature>) -> Self {
|
2019-01-29 10:16:39 -08:00
|
|
|
FuncSig::new(
|
|
|
|
signature
|
2019-01-16 17:59:12 -08:00
|
|
|
.0
|
|
|
|
.params
|
|
|
|
.iter()
|
|
|
|
.map(|param| Converter(param.value_type).into())
|
2019-01-29 10:16:39 -08:00
|
|
|
.collect::<Vec<_>>(),
|
|
|
|
signature
|
2019-01-16 17:59:12 -08:00
|
|
|
.0
|
|
|
|
.returns
|
|
|
|
.iter()
|
|
|
|
.map(|ret| Converter(ret.value_type).into())
|
2019-01-29 10:16:39 -08:00
|
|
|
.collect::<Vec<_>>(),
|
|
|
|
)
|
2019-01-16 17:59:12 -08:00
|
|
|
}
|
|
|
|
}
|
2019-01-16 10:26:10 -08:00
|
|
|
|
2019-01-16 17:59:12 -08:00
|
|
|
impl From<Converter<ir::Type>> for Type {
|
|
|
|
fn from(ty: Converter<ir::Type>) -> Self {
|
|
|
|
match ty.0 {
|
|
|
|
ir::types::I32 => Type::I32,
|
|
|
|
ir::types::I64 => Type::I64,
|
|
|
|
ir::types::F32 => Type::F32,
|
|
|
|
ir::types::F64 => Type::F64,
|
|
|
|
_ => panic!("unsupported wasm type"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|