mirror of
https://github.com/fluencelabs/wasmer
synced 2025-04-23 17:32:14 +00:00
Saved
This commit is contained in:
parent
3c7dc200fa
commit
82eea00a02
lib
@ -23,24 +23,16 @@ libc = "0.2.48"
|
|||||||
# Dependencies for caching.
|
# Dependencies for caching.
|
||||||
[dependencies.serde]
|
[dependencies.serde]
|
||||||
version = "1.0"
|
version = "1.0"
|
||||||
optional = true
|
|
||||||
[dependencies.serde_derive]
|
[dependencies.serde_derive]
|
||||||
version = "1.0"
|
version = "1.0"
|
||||||
optional = true
|
|
||||||
[dependencies.serde_bytes]
|
[dependencies.serde_bytes]
|
||||||
version = "0.10"
|
version = "0.10"
|
||||||
optional = true
|
|
||||||
# [dependencies.bincode]
|
|
||||||
# version = "1.0.1"
|
|
||||||
# optional = true
|
|
||||||
[dependencies.serde-bench]
|
[dependencies.serde-bench]
|
||||||
version = "0.0.7"
|
version = "0.0.7"
|
||||||
optional = true
|
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = { version = "0.3", features = ["errhandlingapi", "minwindef", "minwinbase", "winnt"] }
|
winapi = { version = "0.3", features = ["errhandlingapi", "minwindef", "minwinbase", "winnt"] }
|
||||||
wasmer-win-exception-handler = { path = "../win-exception-handler", version = "0.0.1" }
|
wasmer-win-exception-handler = { path = "../win-exception-handler", version = "0.0.1" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
cache = ["serde", "serde_derive", "serde_bytes", "serde-bench", "wasmer-runtime-core/cache"]
|
|
||||||
debug = ["wasmer-runtime-core/debug"]
|
debug = ["wasmer-runtime-core/debug"]
|
||||||
|
@ -32,8 +32,7 @@ impl CacheGenerator {
|
|||||||
impl CacheGen for CacheGenerator {
|
impl CacheGen for CacheGenerator {
|
||||||
fn generate_cache(&self, module: &ModuleInner) -> Result<(Box<ModuleInfo>, Box<[u8]>, Arc<Memory>), Error> {
|
fn generate_cache(&self, module: &ModuleInner) -> Result<(Box<ModuleInfo>, Box<[u8]>, Arc<Memory>), Error> {
|
||||||
let info = Box::new(module.info.clone());
|
let info = Box::new(module.info.clone());
|
||||||
|
Ok((info, self.backend_cache.into_backend_data()?.into_boxed_slice(), Arc::clone(&self.memory)))
|
||||||
Err(Error::Unknown("".to_string()))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,18 +53,26 @@ pub struct BackendCache {
|
|||||||
|
|
||||||
impl BackendCache {
|
impl BackendCache {
|
||||||
pub fn from_cache(cache: Cache) -> Result<(ModuleInfo, Memory, Self), Error> {
|
pub fn from_cache(cache: Cache) -> Result<(ModuleInfo, Memory, Self), Error> {
|
||||||
let (info, backend_data, compiled_code) = cache.consume();
|
let (info, backend_data, compiled_code_arc) = cache.consume();
|
||||||
|
|
||||||
let backend_cache = deserialize(backend_data.as_slice())
|
// If this is the only references to this arc, move the memory out.
|
||||||
|
// else, clone the memory to a new location. This could take a long time,
|
||||||
|
// depending on the throughput of your memcpy implementation.
|
||||||
|
let compiled_code = match Arc::try_unwrap(compiled_code_arc) {
|
||||||
|
Ok(code) => code,
|
||||||
|
Err(arc) => (*arc).clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let backend_cache = deserialize(&backend_data)
|
||||||
.map_err(|e| Error::DeserializeError(e.to_string()))?;
|
.map_err(|e| Error::DeserializeError(e.to_string()))?;
|
||||||
|
|
||||||
Ok((info, compiled_code, backend_cache))
|
Ok((info, compiled_code, backend_cache))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_backend_data(self) -> Result<Vec<u8>, Error> {
|
pub fn into_backend_data(&self) -> Result<Vec<u8>, Error> {
|
||||||
let mut buffer = Vec::new();
|
let mut buffer = Vec::new();
|
||||||
|
|
||||||
serialize(&mut buffer, &self).map_err(|e| Error::SerializeError(e.to_string()))?;
|
serialize(&mut buffer, self).map_err(|e| Error::SerializeError(e.to_string()))?;
|
||||||
|
|
||||||
Ok(buffer)
|
Ok(buffer)
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#[cfg(feature = "cache")]
|
|
||||||
mod cache;
|
mod cache;
|
||||||
mod func_env;
|
mod func_env;
|
||||||
mod libcalls;
|
mod libcalls;
|
||||||
@ -14,7 +14,7 @@ use cranelift_codegen::{
|
|||||||
settings::{self, Configurable},
|
settings::{self, Configurable},
|
||||||
};
|
};
|
||||||
use target_lexicon::Triple;
|
use target_lexicon::Triple;
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
backend::sys::Memory,
|
backend::sys::Memory,
|
||||||
cache::{Cache, Error as CacheError},
|
cache::{Cache, Error as CacheError},
|
||||||
@ -25,10 +25,10 @@ use wasmer_runtime_core::{
|
|||||||
error::{CompileError, CompileResult},
|
error::{CompileError, CompileResult},
|
||||||
module::ModuleInner,
|
module::ModuleInner,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
|
|
||||||
use wasmparser::{self, WasmDecoder};
|
use wasmparser::{self, WasmDecoder};
|
||||||
@ -57,12 +57,12 @@ impl Compiler for CraneliftCompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a wasmer Module from an already-compiled cache.
|
/// Create a wasmer Module from an already-compiled cache.
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
unsafe fn from_cache(&self, cache: Cache, _: Token) -> Result<ModuleInner, CacheError> {
|
unsafe fn from_cache(&self, cache: Cache, _: Token) -> Result<ModuleInner, CacheError> {
|
||||||
module::Module::from_cache(cache)
|
module::Module::from_cache(cache)
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[cfg(feature = "cache")]
|
//
|
||||||
// fn compile_to_backend_cache_data(
|
// fn compile_to_backend_cache_data(
|
||||||
// &self,
|
// &self,
|
||||||
// wasm: &[u8],
|
// wasm: &[u8],
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#[cfg(feature = "cache")]
|
|
||||||
use crate::cache::{BackendCache, CacheGenerator};
|
use crate::cache::{BackendCache, CacheGenerator};
|
||||||
use crate::{resolver::FuncResolverBuilder, signal::Caller, trampoline::Trampolines};
|
use crate::{resolver::FuncResolverBuilder, signal::Caller, trampoline::Trampolines};
|
||||||
|
|
||||||
@ -8,7 +8,7 @@ use cranelift_wasm;
|
|||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
backend::sys::Memory,
|
backend::sys::Memory,
|
||||||
cache::{Cache, Error as CacheError},
|
cache::{Cache, Error as CacheError},
|
||||||
@ -17,13 +17,15 @@ use wasmer_runtime_core::{
|
|||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
backend::Backend,
|
backend::Backend,
|
||||||
error::CompileResult,
|
error::CompileResult,
|
||||||
module::{ModuleInfo, ModuleInner, StringTable, WasmHash},
|
module::{ModuleInfo, ModuleInner, StringTable},
|
||||||
structures::{Map, TypedIndex},
|
structures::{Map, TypedIndex},
|
||||||
types::{
|
types::{
|
||||||
FuncIndex, FuncSig, GlobalIndex, LocalFuncIndex, MemoryIndex, SigIndex, TableIndex, Type,
|
FuncIndex, FuncSig, GlobalIndex, LocalFuncIndex, MemoryIndex, SigIndex, TableIndex, Type,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use wasmer_runtime_core::module::WasmHash;
|
||||||
|
|
||||||
/// This contains all of the items in a `ModuleInner` except the `func_resolver`.
|
/// This contains all of the items in a `ModuleInner` except the `func_resolver`.
|
||||||
pub struct Module {
|
pub struct Module {
|
||||||
pub info: ModuleInfo,
|
pub info: ModuleInfo,
|
||||||
@ -56,6 +58,7 @@ impl Module {
|
|||||||
namespace_table: StringTable::new(),
|
namespace_table: StringTable::new(),
|
||||||
name_table: StringTable::new(),
|
name_table: StringTable::new(),
|
||||||
|
|
||||||
|
|
||||||
wasm_hash: WasmHash::generate(wasm),
|
wasm_hash: WasmHash::generate(wasm),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -77,6 +80,7 @@ impl Module {
|
|||||||
let protected_caller =
|
let protected_caller =
|
||||||
Caller::new(&self.info, handler_data, trampolines);
|
Caller::new(&self.info, handler_data, trampolines);
|
||||||
|
|
||||||
|
|
||||||
let cache_gen = Box::new(CacheGenerator::new(backend_cache, Arc::clone(&func_resolver.memory)));
|
let cache_gen = Box::new(CacheGenerator::new(backend_cache, Arc::clone(&func_resolver.memory)));
|
||||||
|
|
||||||
Ok(ModuleInner {
|
Ok(ModuleInner {
|
||||||
@ -88,26 +92,7 @@ impl Module {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[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.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.info, backend_cache, compiled_code))
|
|
||||||
// }
|
|
||||||
|
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
pub fn from_cache(cache: Cache) -> Result<ModuleInner, CacheError> {
|
pub fn from_cache(cache: Cache) -> Result<ModuleInner, CacheError> {
|
||||||
let (info, compiled_code, backend_cache) = BackendCache::from_cache(cache)?;
|
let (info, compiled_code, backend_cache) = BackendCache::from_cache(cache)?;
|
||||||
|
|
||||||
@ -120,6 +105,8 @@ impl Module {
|
|||||||
.map_err(|e| CacheError::Unknown(format!("{:?}", e)))?;
|
.map_err(|e| CacheError::Unknown(format!("{:?}", e)))?;
|
||||||
|
|
||||||
let protected_caller = Caller::new(&info, handler_data, trampolines);
|
let protected_caller = Caller::new(&info, handler_data, trampolines);
|
||||||
|
|
||||||
|
|
||||||
let cache_gen = Box::new(CacheGenerator::new(backend_cache, Arc::clone(&func_resolver.memory)));
|
let cache_gen = Box::new(CacheGenerator::new(backend_cache, Arc::clone(&func_resolver.memory)));
|
||||||
|
|
||||||
Ok(ModuleInner {
|
Ok(ModuleInner {
|
||||||
|
@ -22,7 +22,7 @@ pub mod call_names {
|
|||||||
pub const DYNAMIC_MEM_SIZE: u32 = 5;
|
pub const DYNAMIC_MEM_SIZE: u32 = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum Reloc {
|
pub enum Reloc {
|
||||||
Abs8,
|
Abs8,
|
||||||
@ -30,7 +30,7 @@ pub enum Reloc {
|
|||||||
X86CallPCRel4,
|
X86CallPCRel4,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub enum LibCall {
|
pub enum LibCall {
|
||||||
Probestack,
|
Probestack,
|
||||||
@ -44,7 +44,7 @@ pub enum LibCall {
|
|||||||
NearestF64,
|
NearestF64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ExternalRelocation {
|
pub struct ExternalRelocation {
|
||||||
/// The relocation code.
|
/// The relocation code.
|
||||||
@ -66,7 +66,7 @@ pub struct LocalRelocation {
|
|||||||
pub target: FuncIndex,
|
pub target: FuncIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum VmCallKind {
|
pub enum VmCallKind {
|
||||||
StaticMemoryGrow,
|
StaticMemoryGrow,
|
||||||
@ -79,7 +79,7 @@ pub enum VmCallKind {
|
|||||||
DynamicMemorySize,
|
DynamicMemorySize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum VmCall {
|
pub enum VmCall {
|
||||||
Local(VmCallKind),
|
Local(VmCallKind),
|
||||||
@ -87,7 +87,7 @@ pub enum VmCall {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Specify the type of relocation
|
/// Specify the type of relocation
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum RelocationType {
|
pub enum RelocationType {
|
||||||
Intrinsic(String),
|
Intrinsic(String),
|
||||||
@ -218,7 +218,7 @@ impl binemit::RelocSink for RelocSink {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum TrapCode {
|
pub enum TrapCode {
|
||||||
StackOverflow,
|
StackOverflow,
|
||||||
@ -244,7 +244,7 @@ impl RelocSink {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct TrapData {
|
pub struct TrapData {
|
||||||
pub trapcode: TrapCode,
|
pub trapcode: TrapCode,
|
||||||
@ -253,7 +253,7 @@ pub struct TrapData {
|
|||||||
|
|
||||||
/// Simple implementation of a TrapSink
|
/// Simple implementation of a TrapSink
|
||||||
/// that saves the info for later.
|
/// that saves the info for later.
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct TrapSink {
|
pub struct TrapSink {
|
||||||
trap_datas: Vec<(usize, TrapData)>,
|
trap_datas: Vec<(usize, TrapData)>,
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#[cfg(feature = "cache")]
|
|
||||||
use crate::{
|
use crate::{
|
||||||
cache::{BackendCache, TrampolineCache},
|
cache::{BackendCache, TrampolineCache},
|
||||||
trampoline::Trampolines,
|
trampoline::Trampolines,
|
||||||
@ -20,7 +20,7 @@ use std::{
|
|||||||
cell::UnsafeCell,
|
cell::UnsafeCell,
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
use wasmer_runtime_core::cache::Error as CacheError;
|
use wasmer_runtime_core::cache::Error as CacheError;
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
self,
|
self,
|
||||||
@ -43,16 +43,24 @@ extern "C" {
|
|||||||
pub fn __chkstk();
|
pub fn __chkstk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn lookup_func(map: &SliceMap<LocalFuncIndex, usize>, memory: &Memory, local_func_index: LocalFuncIndex) -> Option<NonNull<vm::Func>> {
|
||||||
|
let offset = *map.get(local_func_index)?;
|
||||||
|
let ptr = unsafe { memory.as_ptr().add(offset) };
|
||||||
|
|
||||||
|
NonNull::new(ptr).map(|nonnull| nonnull.cast())
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub struct FuncResolverBuilder {
|
pub struct FuncResolverBuilder {
|
||||||
resolver: FuncResolver,
|
map: Map<LocalFuncIndex, usize>,
|
||||||
|
memory: Memory,
|
||||||
local_relocs: Map<LocalFuncIndex, Box<[LocalRelocation]>>,
|
local_relocs: Map<LocalFuncIndex, Box<[LocalRelocation]>>,
|
||||||
external_relocs: Map<LocalFuncIndex, Box<[ExternalRelocation]>>,
|
external_relocs: Map<LocalFuncIndex, Box<[ExternalRelocation]>>,
|
||||||
import_len: usize,
|
import_len: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FuncResolverBuilder {
|
impl FuncResolverBuilder {
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
pub fn new_from_backend_cache(
|
pub fn new_from_backend_cache(
|
||||||
backend_cache: BackendCache,
|
backend_cache: BackendCache,
|
||||||
mut code: Memory,
|
mut code: Memory,
|
||||||
@ -68,10 +76,8 @@ impl FuncResolverBuilder {
|
|||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
Self {
|
Self {
|
||||||
resolver: FuncResolver {
|
|
||||||
map: backend_cache.offsets,
|
map: backend_cache.offsets,
|
||||||
memory: Arc::new(UnsafeCell::new(code)),
|
memory: code,
|
||||||
},
|
|
||||||
local_relocs: Map::new(),
|
local_relocs: Map::new(),
|
||||||
external_relocs: backend_cache.external_relocs,
|
external_relocs: backend_cache.external_relocs,
|
||||||
import_len: info.imported_functions.len(),
|
import_len: info.imported_functions.len(),
|
||||||
@ -155,7 +161,8 @@ impl FuncResolverBuilder {
|
|||||||
let handler_data = HandlerData::new(Arc::new(trap_sink), memory.as_ptr() as _, memory.size());
|
let handler_data = HandlerData::new(Arc::new(trap_sink), memory.as_ptr() as _, memory.size());
|
||||||
|
|
||||||
let mut func_resolver_builder = Self {
|
let mut func_resolver_builder = Self {
|
||||||
resolver: FuncResolver { map, memory: Arc::new(UnsafeCell::new(memory)) },
|
map,
|
||||||
|
memory,
|
||||||
local_relocs,
|
local_relocs,
|
||||||
external_relocs,
|
external_relocs,
|
||||||
import_len: info.imported_functions.len(),
|
import_len: info.imported_functions.len(),
|
||||||
@ -171,11 +178,11 @@ impl FuncResolverBuilder {
|
|||||||
for ref reloc in relocs.iter() {
|
for ref reloc in relocs.iter() {
|
||||||
let local_func_index = LocalFuncIndex::new(reloc.target.index() - self.import_len);
|
let local_func_index = LocalFuncIndex::new(reloc.target.index() - self.import_len);
|
||||||
let target_func_address =
|
let target_func_address =
|
||||||
self.resolver.lookup(local_func_index).unwrap().as_ptr() as usize;
|
lookup_func(&self.map, &self.memory, local_func_index).unwrap().as_ptr() as usize;
|
||||||
|
|
||||||
// We need the address of the current function
|
// We need the address of the current function
|
||||||
// because these calls are relative.
|
// because these calls are relative.
|
||||||
let func_addr = self.resolver.lookup(index).unwrap().as_ptr() as usize;
|
let func_addr = lookup_func(&self.map, &self.memory, index).unwrap().as_ptr() as usize;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let reloc_address = func_addr + reloc.offset as usize;
|
let reloc_address = func_addr + reloc.offset as usize;
|
||||||
@ -190,14 +197,11 @@ impl FuncResolverBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn finalize(
|
pub fn finalize(
|
||||||
self,
|
mut self,
|
||||||
signatures: &SliceMap<SigIndex, Arc<FuncSig>>,
|
signatures: &SliceMap<SigIndex, Arc<FuncSig>>,
|
||||||
trampolines: Arc<Trampolines>,
|
trampolines: Arc<Trampolines>,
|
||||||
handler_data: HandlerData,
|
handler_data: HandlerData,
|
||||||
) -> CompileResult<(FuncResolver, BackendCache)> {
|
) -> CompileResult<(FuncResolver, BackendCache)> {
|
||||||
{
|
|
||||||
let mut memory = unsafe { (*self.resolver.memory.get()) };
|
|
||||||
|
|
||||||
for (index, relocs) in self.external_relocs.iter() {
|
for (index, relocs) in self.external_relocs.iter() {
|
||||||
for ref reloc in relocs.iter() {
|
for ref reloc in relocs.iter() {
|
||||||
let target_func_address: isize = match reloc.target {
|
let target_func_address: isize = match reloc.target {
|
||||||
@ -269,7 +273,7 @@ impl FuncResolverBuilder {
|
|||||||
|
|
||||||
// We need the address of the current function
|
// We need the address of the current function
|
||||||
// because some of these calls are relative.
|
// because some of these calls are relative.
|
||||||
let func_addr = self.resolver.lookup(index).unwrap().as_ptr();
|
let func_addr = lookup_func(&self.map, &self.memory, index).unwrap().as_ptr() as usize;
|
||||||
|
|
||||||
// Determine relocation type and apply relocation.
|
// Determine relocation type and apply relocation.
|
||||||
match reloc.reloc {
|
match reloc.reloc {
|
||||||
@ -277,9 +281,9 @@ impl FuncResolverBuilder {
|
|||||||
let ptr_to_write = (target_func_address as u64)
|
let ptr_to_write = (target_func_address as u64)
|
||||||
.checked_add(reloc.addend as u64)
|
.checked_add(reloc.addend as u64)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let empty_space_offset = self.resolver.map[index] + reloc.offset as usize;
|
let empty_space_offset = self.map[index] + reloc.offset as usize;
|
||||||
let ptr_slice = unsafe {
|
let ptr_slice = unsafe {
|
||||||
&mut memory.as_slice_mut()
|
&mut self.memory.as_slice_mut()
|
||||||
[empty_space_offset..empty_space_offset + 8]
|
[empty_space_offset..empty_space_offset + 8]
|
||||||
};
|
};
|
||||||
LittleEndian::write_u64(ptr_slice, ptr_to_write);
|
LittleEndian::write_u64(ptr_slice, ptr_to_write);
|
||||||
@ -297,20 +301,22 @@ impl FuncResolverBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
memory
|
self.memory
|
||||||
.protect(.., Protect::ReadExec)
|
.protect(.., Protect::ReadExec)
|
||||||
.map_err(|e| CompileError::InternalError { msg: e.to_string() })?;
|
.map_err(|e| CompileError::InternalError { msg: e.to_string() })?;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let backend_cache = BackendCache {
|
let backend_cache = BackendCache {
|
||||||
external_relocs: self.external_relocs.clone(),
|
external_relocs: self.external_relocs.clone(),
|
||||||
offsets: self.resolver.map.clone(),
|
offsets: self.map.clone(),
|
||||||
trap_sink: handler_data.trap_data,
|
trap_sink: handler_data.trap_data,
|
||||||
trampolines: trampolines.to_trampoline_cache(),
|
trampolines: trampolines.to_trampoline_cache(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((self.resolver, backend_cache))
|
Ok((FuncResolver {
|
||||||
|
map: self.map,
|
||||||
|
memory: Arc::new(self.memory),
|
||||||
|
}, backend_cache))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,16 +326,7 @@ unsafe impl Send for FuncResolver {}
|
|||||||
/// Resolves a function index to a function address.
|
/// Resolves a function index to a function address.
|
||||||
pub struct FuncResolver {
|
pub struct FuncResolver {
|
||||||
map: Map<LocalFuncIndex, usize>,
|
map: Map<LocalFuncIndex, usize>,
|
||||||
pub(crate) memory: Arc<UnsafeCell<Memory>>,
|
pub(crate) memory: Arc<Memory>,
|
||||||
}
|
|
||||||
|
|
||||||
impl FuncResolver {
|
|
||||||
fn lookup(&self, local_func_index: LocalFuncIndex) -> Option<NonNull<vm::Func>> {
|
|
||||||
let offset = *self.map.get(local_func_index)?;
|
|
||||||
let ptr = unsafe { (*self.memory.get()).as_ptr().add(offset) };
|
|
||||||
|
|
||||||
NonNull::new(ptr).map(|nonnull| nonnull.cast())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements FuncResolver trait.
|
// Implements FuncResolver trait.
|
||||||
@ -339,7 +336,7 @@ impl backend::FuncResolver for FuncResolver {
|
|||||||
_module: &wasmer_runtime_core::module::ModuleInner,
|
_module: &wasmer_runtime_core::module::ModuleInner,
|
||||||
index: LocalFuncIndex,
|
index: LocalFuncIndex,
|
||||||
) -> Option<NonNull<vm::Func>> {
|
) -> Option<NonNull<vm::Func>> {
|
||||||
self.lookup(index)
|
lookup_func(&self.map, &self.memory, index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#[cfg(feature = "cache")]
|
|
||||||
use crate::cache::TrampolineCache;
|
use crate::cache::TrampolineCache;
|
||||||
use cranelift_codegen::{
|
use cranelift_codegen::{
|
||||||
binemit::{NullTrapSink, Reloc, RelocSink},
|
binemit::{NullTrapSink, Reloc, RelocSink},
|
||||||
@ -33,7 +33,7 @@ pub struct Trampolines {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Trampolines {
|
impl Trampolines {
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
pub fn from_trampoline_cache(cache: TrampolineCache) -> Self {
|
pub fn from_trampoline_cache(cache: TrampolineCache) -> Self {
|
||||||
// pub struct TrampolineCache {
|
// pub struct TrampolineCache {
|
||||||
// #[serde(with = "serde_bytes")]
|
// #[serde(with = "serde_bytes")]
|
||||||
@ -57,7 +57,7 @@ impl Trampolines {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
pub fn to_trampoline_cache(&self) -> TrampolineCache {
|
pub fn to_trampoline_cache(&self) -> TrampolineCache {
|
||||||
let mut code = vec![0; self.memory.size()];
|
let mut code = vec![0; self.memory.size()];
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ repository = "https://github.com/wasmerio/wasmer"
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
hashbrown = "0.1"
|
|
||||||
nix = "0.12.0"
|
nix = "0.12.0"
|
||||||
page_size = "0.4.1"
|
page_size = "0.4.1"
|
||||||
wasmparser = "0.23.0"
|
wasmparser = "0.23.0"
|
||||||
@ -21,22 +20,20 @@ libc = "0.2.48"
|
|||||||
# Dependencies for caching.
|
# Dependencies for caching.
|
||||||
[dependencies.serde]
|
[dependencies.serde]
|
||||||
version = "1.0"
|
version = "1.0"
|
||||||
optional = true
|
features = ["rc"]
|
||||||
[dependencies.serde_derive]
|
[dependencies.serde_derive]
|
||||||
version = "1.0"
|
version = "1.0"
|
||||||
optional = true
|
|
||||||
[dependencies.serde_bytes]
|
[dependencies.serde_bytes]
|
||||||
version = "0.10"
|
version = "0.10"
|
||||||
optional = true
|
|
||||||
[dependencies.serde-bench]
|
[dependencies.serde-bench]
|
||||||
version = "0.0.7"
|
version = "0.0.7"
|
||||||
optional = true
|
|
||||||
[dependencies.memmap]
|
[dependencies.memmap]
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
optional = true
|
|
||||||
[dependencies.sha2]
|
[dependencies.sha2]
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
optional = true
|
[dependencies.hashbrown]
|
||||||
|
version = "0.1"
|
||||||
|
features = ["serde"]
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = { version = "0.3", features = ["memoryapi"] }
|
winapi = { version = "0.3", features = ["memoryapi"] }
|
||||||
@ -47,5 +44,4 @@ field-offset = "0.1.1"
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
debug = []
|
debug = []
|
||||||
cache = ["serde/rc", "serde_derive", "serde_bytes", "hashbrown/serde", "serde-bench", "memmap", "sha2"]
|
|
||||||
|
|
||||||
|
@ -2,11 +2,11 @@ use crate::{
|
|||||||
backing::ImportBacking,
|
backing::ImportBacking,
|
||||||
error::CompileResult,
|
error::CompileResult,
|
||||||
error::RuntimeResult,
|
error::RuntimeResult,
|
||||||
module::ModuleInner,
|
module::{ModuleInner},
|
||||||
types::{FuncIndex, LocalFuncIndex, Value},
|
types::{FuncIndex, LocalFuncIndex, Value},
|
||||||
vm,
|
vm,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
use crate::{
|
use crate::{
|
||||||
cache::{Cache, Error as CacheError},
|
cache::{Cache, Error as CacheError},
|
||||||
module::ModuleInfo,
|
module::ModuleInfo,
|
||||||
@ -14,12 +14,14 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub mod sys {
|
pub mod sys {
|
||||||
pub use crate::sys::*;
|
pub use crate::sys::*;
|
||||||
}
|
}
|
||||||
pub use crate::sig_registry::SigRegistry;
|
pub use crate::sig_registry::SigRegistry;
|
||||||
|
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum Backend {
|
pub enum Backend {
|
||||||
Cranelift,
|
Cranelift,
|
||||||
@ -43,7 +45,7 @@ pub trait Compiler {
|
|||||||
/// be called from inside the runtime.
|
/// be called from inside the runtime.
|
||||||
fn compile(&self, wasm: &[u8], _: Token) -> CompileResult<ModuleInner>;
|
fn compile(&self, wasm: &[u8], _: Token) -> CompileResult<ModuleInner>;
|
||||||
|
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
unsafe fn from_cache(&self, cache: Cache, _: Token) -> Result<ModuleInner, CacheError>;
|
unsafe fn from_cache(&self, cache: Cache, _: Token) -> Result<ModuleInner, CacheError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +95,7 @@ pub trait FuncResolver: Send + Sync {
|
|||||||
) -> Option<NonNull<vm::Func>>;
|
) -> Option<NonNull<vm::Func>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub trait CacheGen: Send + Sync {
|
pub trait CacheGen: Send + Sync {
|
||||||
fn generate_cache(&self, module: &ModuleInner) -> Result<(Box<ModuleInfo>, Box<[u8]>, Arc<Memory>), CacheError>;
|
fn generate_cache(&self, module: &ModuleInner) -> Result<(Box<ModuleInfo>, Box<[u8]>, Arc<Memory>), CacheError>;
|
||||||
}
|
}
|
@ -6,6 +6,7 @@ use std::{
|
|||||||
fs::File,
|
fs::File,
|
||||||
io::{self, Seek, SeekFrom, Write},
|
io::{self, Seek, SeekFrom, Write},
|
||||||
mem,
|
mem,
|
||||||
|
sync::Arc,
|
||||||
path::Path,
|
path::Path,
|
||||||
slice,
|
slice,
|
||||||
};
|
};
|
||||||
@ -67,31 +68,26 @@ impl CacheHeader {
|
|||||||
struct CacheInner {
|
struct CacheInner {
|
||||||
info: Box<ModuleInfo>,
|
info: Box<ModuleInfo>,
|
||||||
#[serde(with = "serde_bytes")]
|
#[serde(with = "serde_bytes")]
|
||||||
backend_metadata: Vec<u8>,
|
backend_metadata: Box<[u8]>,
|
||||||
compiled_code: Memory,
|
compiled_code: Arc<Memory>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Cache {
|
pub struct Cache {
|
||||||
inner: CacheInner,
|
inner: CacheInner,
|
||||||
wasm_hash: Box<[u8; 32]>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cache {
|
impl Cache {
|
||||||
pub(crate) fn new(
|
pub(crate) fn from_parts(
|
||||||
wasm: &[u8],
|
|
||||||
info: Box<ModuleInfo>,
|
info: Box<ModuleInfo>,
|
||||||
backend_metadata: Vec<u8>,
|
backend_metadata: Box<[u8]>,
|
||||||
compiled_code: Memory,
|
compiled_code: Arc<Memory>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let wasm_hash = hash_data(wasm);
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
inner: CacheInner {
|
inner: CacheInner {
|
||||||
info,
|
info,
|
||||||
backend_metadata,
|
backend_metadata,
|
||||||
compiled_code,
|
compiled_code,
|
||||||
},
|
},
|
||||||
wasm_hash: Box::new(wasm_hash),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +106,6 @@ impl Cache {
|
|||||||
|
|
||||||
Ok(Cache {
|
Ok(Cache {
|
||||||
inner,
|
inner,
|
||||||
wasm_hash: Box::new(header.wasm_hash),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,12 +113,8 @@ impl Cache {
|
|||||||
&self.inner.info
|
&self.inner.info
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wasm_hash(&self) -> &[u8; 32] {
|
|
||||||
&self.wasm_hash
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn consume(self) -> (ModuleInfo, Vec<u8>, Memory) {
|
pub fn consume(self) -> (ModuleInfo, Box<[u8]>, Arc<Memory>) {
|
||||||
(
|
(
|
||||||
*self.inner.info,
|
*self.inner.info,
|
||||||
self.inner.backend_metadata,
|
self.inner.backend_metadata,
|
||||||
@ -152,11 +143,7 @@ impl Cache {
|
|||||||
file.seek(SeekFrom::Start(0))
|
file.seek(SeekFrom::Start(0))
|
||||||
.map_err(|e| Error::Unknown(e.to_string()))?;
|
.map_err(|e| Error::Unknown(e.to_string()))?;
|
||||||
|
|
||||||
let wasm_hash = {
|
let wasm_hash = self.inner.info.wasm_hash.into_array();
|
||||||
let mut array = [0u8; 32];
|
|
||||||
array.copy_from_slice(&*self.wasm_hash);
|
|
||||||
array
|
|
||||||
};
|
|
||||||
|
|
||||||
let cache_header = CacheHeader {
|
let cache_header = CacheHeader {
|
||||||
magic: [
|
magic: [
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate field_offset;
|
extern crate field_offset;
|
||||||
|
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ mod macros;
|
|||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub mod backend;
|
pub mod backend;
|
||||||
mod backing;
|
mod backing;
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
pub mod cache;
|
pub mod cache;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod export;
|
pub mod export;
|
||||||
@ -44,7 +44,7 @@ pub use self::module::Module;
|
|||||||
pub use self::typed_func::Func;
|
pub use self::typed_func::Func;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
use self::cache::{Cache, Error as CacheError};
|
use self::cache::{Cache, Error as CacheError};
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
@ -90,7 +90,7 @@ pub fn validate(wasm: &[u8]) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[cfg(feature = "cache")]
|
//
|
||||||
// pub fn compile_to_cache_with(
|
// pub fn compile_to_cache_with(
|
||||||
// wasm: &[u8],
|
// wasm: &[u8],
|
||||||
// compiler: &dyn backend::Compiler,
|
// compiler: &dyn backend::Compiler,
|
||||||
@ -102,7 +102,7 @@ pub fn validate(wasm: &[u8]) -> bool {
|
|||||||
// Ok(Cache::new(wasm, info, backend_metadata, compiled_code))
|
// Ok(Cache::new(wasm, info, backend_metadata, compiled_code))
|
||||||
// }
|
// }
|
||||||
|
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
pub unsafe fn load_cache_with(
|
pub unsafe fn load_cache_with(
|
||||||
cache: Cache,
|
cache: Cache,
|
||||||
compiler: &dyn backend::Compiler,
|
compiler: &dyn backend::Compiler,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
backend::{Backend, FuncResolver, ProtectedCaller, CacheGen},
|
backend::{Backend, FuncResolver, ProtectedCaller},
|
||||||
error::Result,
|
error,
|
||||||
import::ImportObject,
|
import::ImportObject,
|
||||||
structures::{Map, TypedIndex},
|
structures::{Map, TypedIndex},
|
||||||
typed_func::EARLY_TRAPPER,
|
typed_func::EARLY_TRAPPER,
|
||||||
@ -10,8 +10,11 @@ use crate::{
|
|||||||
LocalGlobalIndex, LocalMemoryIndex, LocalTableIndex, MemoryDescriptor, MemoryIndex,
|
LocalGlobalIndex, LocalMemoryIndex, LocalTableIndex, MemoryDescriptor, MemoryIndex,
|
||||||
SigIndex, TableDescriptor, TableIndex,
|
SigIndex, TableDescriptor, TableIndex,
|
||||||
},
|
},
|
||||||
|
cache::{Cache, Error as CacheError},
|
||||||
Instance,
|
Instance,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::backend::CacheGen;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@ -21,13 +24,15 @@ use std::sync::Arc;
|
|||||||
pub struct ModuleInner {
|
pub struct ModuleInner {
|
||||||
pub func_resolver: Box<dyn FuncResolver>,
|
pub func_resolver: Box<dyn FuncResolver>,
|
||||||
pub protected_caller: Box<dyn ProtectedCaller>,
|
pub protected_caller: Box<dyn ProtectedCaller>,
|
||||||
|
|
||||||
|
|
||||||
pub cache_gen: Box<dyn CacheGen>,
|
pub cache_gen: Box<dyn CacheGen>,
|
||||||
|
|
||||||
pub info: ModuleInfo,
|
pub info: ModuleInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct ModuleInfo {
|
pub struct ModuleInfo {
|
||||||
// This are strictly local and the typsystem ensures that.
|
// This are strictly local and the typsystem ensures that.
|
||||||
pub memories: Map<LocalMemoryIndex, MemoryDescriptor>,
|
pub memories: Map<LocalMemoryIndex, MemoryDescriptor>,
|
||||||
@ -57,13 +62,19 @@ pub struct ModuleInfo {
|
|||||||
pub wasm_hash: WasmHash,
|
pub wasm_hash: WasmHash,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct WasmHash([u8; 32]);
|
pub struct WasmHash([u8; 32]);
|
||||||
|
|
||||||
|
|
||||||
impl WasmHash {
|
impl WasmHash {
|
||||||
pub fn generate(wasm: &[u8]) -> Self {
|
pub fn generate(wasm: &[u8]) -> Self {
|
||||||
WasmHash(super::cache::hash_data(wasm))
|
WasmHash(crate::cache::hash_data(wasm))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn into_array(self) -> [u8; 32] {
|
||||||
|
self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,22 +120,27 @@ impl Module {
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn instantiate(&self, import_object: &ImportObject) -> Result<Instance> {
|
pub fn instantiate(&self, import_object: &ImportObject) -> error::Result<Instance> {
|
||||||
Instance::new(Arc::clone(&self.inner), import_object)
|
Instance::new(Arc::clone(&self.inner), import_object)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cache(&self) -> Result<Cache, CacheError> {
|
||||||
|
let (info, backend_cache, code) = self.inner.cache_gen.generate_cache(&self.inner)?;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleInner {}
|
impl ModuleInner {}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ImportName {
|
pub struct ImportName {
|
||||||
pub namespace_index: NamespaceIndex,
|
pub namespace_index: NamespaceIndex,
|
||||||
pub name_index: NameIndex,
|
pub name_index: NameIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum ExportIndex {
|
pub enum ExportIndex {
|
||||||
Func(FuncIndex),
|
Func(FuncIndex),
|
||||||
@ -134,7 +150,7 @@ pub enum ExportIndex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A data initializer for linear memory.
|
/// A data initializer for linear memory.
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct DataInitializer {
|
pub struct DataInitializer {
|
||||||
/// The index of the memory to initialize.
|
/// The index of the memory to initialize.
|
||||||
@ -147,7 +163,7 @@ pub struct DataInitializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A WebAssembly table initializer.
|
/// A WebAssembly table initializer.
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TableInitializer {
|
pub struct TableInitializer {
|
||||||
/// The index of a table to initialize.
|
/// The index of a table to initialize.
|
||||||
@ -209,7 +225,7 @@ impl<K: TypedIndex> StringTableBuilder<K> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct StringTable<K: TypedIndex> {
|
pub struct StringTable<K: TypedIndex> {
|
||||||
table: Map<K, (u32, u32)>,
|
table: Map<K, (u32, u32)>,
|
||||||
@ -233,7 +249,7 @@ impl<K: TypedIndex> StringTable<K> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct NamespaceIndex(u32);
|
pub struct NamespaceIndex(u32);
|
||||||
|
|
||||||
@ -249,7 +265,7 @@ impl TypedIndex for NamespaceIndex {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct NameIndex(u32);
|
pub struct NameIndex(u32);
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Dense item map
|
/// Dense item map
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Map<K, V>
|
pub struct Map<K, V>
|
||||||
where
|
where
|
||||||
|
@ -10,18 +10,18 @@ pub use self::unix::*;
|
|||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
pub use self::windows::*;
|
pub use self::windows::*;
|
||||||
|
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
use serde::{
|
use serde::{
|
||||||
de::{self, SeqAccess, Visitor},
|
de::{self, SeqAccess, Visitor},
|
||||||
ser::SerializeStruct,
|
ser::SerializeStruct,
|
||||||
Deserialize, Deserializer, Serialize, Serializer,
|
Deserialize, Deserializer, Serialize, Serializer,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
use serde_bytes::Bytes;
|
use serde_bytes::Bytes;
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
impl Serialize for Memory {
|
impl Serialize for Memory {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
@ -36,7 +36,7 @@ impl Serialize for Memory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
impl<'de> Deserialize<'de> for Memory {
|
impl<'de> Deserialize<'de> for Memory {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
|
@ -205,7 +205,17 @@ impl Drop for Memory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
impl Clone for Memory {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
let mut new = Memory::with_size_protect(self.size, self.protection).unwrap();
|
||||||
|
unsafe {
|
||||||
|
new.as_slice_mut().copy_from_slice(self.as_slice());
|
||||||
|
}
|
||||||
|
new
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub enum Protect {
|
pub enum Protect {
|
||||||
|
@ -156,7 +156,17 @@ impl Drop for Memory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
impl Clone for Memory {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
let mut new = Memory::with_size_protect(self.size, self.protection).unwrap();
|
||||||
|
unsafe {
|
||||||
|
new.as_slice_mut().copy_from_slice(self.as_slice());
|
||||||
|
}
|
||||||
|
new
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub enum Protect {
|
pub enum Protect {
|
||||||
|
@ -2,7 +2,7 @@ use crate::{memory::MemoryType, module::ModuleInfo, structures::TypedIndex, unit
|
|||||||
use std::{borrow::Cow, mem};
|
use std::{borrow::Cow, mem};
|
||||||
|
|
||||||
/// Represents a WebAssembly type.
|
/// Represents a WebAssembly type.
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub enum Type {
|
pub enum Type {
|
||||||
/// The `i32` type.
|
/// The `i32` type.
|
||||||
@ -25,7 +25,7 @@ impl std::fmt::Display for Type {
|
|||||||
///
|
///
|
||||||
/// As the number of types in WebAssembly expand,
|
/// As the number of types in WebAssembly expand,
|
||||||
/// this structure will expand as well.
|
/// this structure will expand as well.
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Value {
|
pub enum Value {
|
||||||
/// The `i32` type.
|
/// The `i32` type.
|
||||||
@ -171,14 +171,14 @@ impl ValueType for f64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum ElementType {
|
pub enum ElementType {
|
||||||
/// Any wasm function.
|
/// Any wasm function.
|
||||||
Anyfunc,
|
Anyfunc,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct TableDescriptor {
|
pub struct TableDescriptor {
|
||||||
/// Type of data stored in this table.
|
/// Type of data stored in this table.
|
||||||
@ -203,7 +203,7 @@ impl TableDescriptor {
|
|||||||
/// A const value initializer.
|
/// A const value initializer.
|
||||||
/// Over time, this will be able to represent more and more
|
/// Over time, this will be able to represent more and more
|
||||||
/// complex expressions.
|
/// complex expressions.
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Initializer {
|
pub enum Initializer {
|
||||||
/// Corresponds to a `const.*` instruction.
|
/// Corresponds to a `const.*` instruction.
|
||||||
@ -212,7 +212,7 @@ pub enum Initializer {
|
|||||||
GetGlobal(ImportedGlobalIndex),
|
GetGlobal(ImportedGlobalIndex),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct GlobalDescriptor {
|
pub struct GlobalDescriptor {
|
||||||
pub mutable: bool,
|
pub mutable: bool,
|
||||||
@ -220,7 +220,7 @@ pub struct GlobalDescriptor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A wasm global.
|
/// A wasm global.
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct GlobalInit {
|
pub struct GlobalInit {
|
||||||
pub desc: GlobalDescriptor,
|
pub desc: GlobalDescriptor,
|
||||||
@ -228,7 +228,7 @@ pub struct GlobalInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A wasm memory.
|
/// A wasm memory.
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct MemoryDescriptor {
|
pub struct MemoryDescriptor {
|
||||||
/// The minimum number of allowed pages.
|
/// The minimum number of allowed pages.
|
||||||
@ -261,7 +261,7 @@ impl MemoryDescriptor {
|
|||||||
|
|
||||||
/// The signature of a function that is either implemented
|
/// The signature of a function that is either implemented
|
||||||
/// in a wasm module or exposed to wasm by the host.
|
/// in a wasm module or exposed to wasm by the host.
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct FuncSig {
|
pub struct FuncSig {
|
||||||
params: Cow<'static, [Type]>,
|
params: Cow<'static, [Type]>,
|
||||||
@ -324,7 +324,7 @@ pub trait LocalImport {
|
|||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
macro_rules! define_map_index {
|
macro_rules! define_map_index {
|
||||||
($ty:ident) => {
|
($ty:ident) => {
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct $ty (u32);
|
pub struct $ty (u32);
|
||||||
impl TypedIndex for $ty {
|
impl TypedIndex for $ty {
|
||||||
@ -400,7 +400,7 @@ define_local_or_import![
|
|||||||
(GlobalIndex | (LocalGlobalIndex, ImportedGlobalIndex): imported_globals),
|
(GlobalIndex | (LocalGlobalIndex, ImportedGlobalIndex): imported_globals),
|
||||||
];
|
];
|
||||||
|
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct SigIndex(u32);
|
pub struct SigIndex(u32);
|
||||||
impl TypedIndex for SigIndex {
|
impl TypedIndex for SigIndex {
|
||||||
|
@ -7,7 +7,7 @@ const WASM_PAGE_SIZE: usize = 65_536;
|
|||||||
const WASM_MAX_PAGES: usize = 65_536;
|
const WASM_MAX_PAGES: usize = 65_536;
|
||||||
|
|
||||||
/// Units of WebAssembly pages (as specified to be 65,536 bytes).
|
/// Units of WebAssembly pages (as specified to be 65,536 bytes).
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct Pages(pub u32);
|
pub struct Pages(pub u32);
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ impl fmt::Debug for Pages {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Units of WebAssembly memory in terms of 8-bit bytes.
|
/// Units of WebAssembly memory in terms of 8-bit bytes.
|
||||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct Bytes(pub usize);
|
pub struct Bytes(pub usize);
|
||||||
|
|
||||||
|
@ -9,10 +9,15 @@ edition = "2018"
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.1.2" }
|
|
||||||
wasmer-clif-backend = { path = "../clif-backend", version = "0.1.2" }
|
|
||||||
lazy_static = "1.2.0"
|
lazy_static = "1.2.0"
|
||||||
|
|
||||||
|
[dependencies.wasmer-runtime-core]
|
||||||
|
path = "../runtime-core"
|
||||||
|
version = "0.1.2"
|
||||||
|
|
||||||
|
[dependencies.wasmer-clif-backend]
|
||||||
|
path = "../clif-backend"
|
||||||
|
version = "0.1.2"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["wasmer-clif-backend/cache", "wasmer-runtime-core/cache"]
|
|
||||||
debug = ["wasmer-clif-backend/debug", "wasmer-runtime-core/debug"]
|
debug = ["wasmer-clif-backend/debug", "wasmer-runtime-core/debug"]
|
||||||
|
@ -19,5 +19,5 @@ wasmer-clif-backend = { path = "../clif-backend", version = "0.1.2" }
|
|||||||
wabt = "0.7.2"
|
wabt = "0.7.2"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["fast-tests", "wasmer-runtime-core/cache", "wasmer-clif-backend/cache"]
|
default = ["fast-tests"]
|
||||||
fast-tests = []
|
fast-tests = []
|
Loading…
x
Reference in New Issue
Block a user