mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-12 00:21:20 +00:00
Saved
This commit is contained in:
@ -8,7 +8,6 @@ repository = "https://github.com/wasmerio/wasmer"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
hashbrown = "0.1"
|
||||
nix = "0.12.0"
|
||||
page_size = "0.4.1"
|
||||
wasmparser = "0.23.0"
|
||||
@ -21,22 +20,20 @@ libc = "0.2.48"
|
||||
# Dependencies for caching.
|
||||
[dependencies.serde]
|
||||
version = "1.0"
|
||||
optional = true
|
||||
features = ["rc"]
|
||||
[dependencies.serde_derive]
|
||||
version = "1.0"
|
||||
optional = true
|
||||
[dependencies.serde_bytes]
|
||||
version = "0.10"
|
||||
optional = true
|
||||
[dependencies.serde-bench]
|
||||
version = "0.0.7"
|
||||
optional = true
|
||||
[dependencies.memmap]
|
||||
version = "0.7.0"
|
||||
optional = true
|
||||
[dependencies.sha2]
|
||||
version = "0.8.0"
|
||||
optional = true
|
||||
[dependencies.hashbrown]
|
||||
version = "0.1"
|
||||
features = ["serde"]
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winapi = { version = "0.3", features = ["memoryapi"] }
|
||||
@ -47,5 +44,4 @@ field-offset = "0.1.1"
|
||||
|
||||
[features]
|
||||
debug = []
|
||||
cache = ["serde/rc", "serde_derive", "serde_bytes", "hashbrown/serde", "serde-bench", "memmap", "sha2"]
|
||||
|
||||
|
@ -2,11 +2,11 @@ use crate::{
|
||||
backing::ImportBacking,
|
||||
error::CompileResult,
|
||||
error::RuntimeResult,
|
||||
module::ModuleInner,
|
||||
module::{ModuleInner},
|
||||
types::{FuncIndex, LocalFuncIndex, Value},
|
||||
vm,
|
||||
};
|
||||
#[cfg(feature = "cache")]
|
||||
|
||||
use crate::{
|
||||
cache::{Cache, Error as CacheError},
|
||||
module::ModuleInfo,
|
||||
@ -14,12 +14,14 @@ use crate::{
|
||||
};
|
||||
use std::ptr::NonNull;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
pub mod sys {
|
||||
pub use crate::sys::*;
|
||||
}
|
||||
pub use crate::sig_registry::SigRegistry;
|
||||
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum Backend {
|
||||
Cranelift,
|
||||
@ -43,7 +45,7 @@ pub trait Compiler {
|
||||
/// be called from inside the runtime.
|
||||
fn compile(&self, wasm: &[u8], _: Token) -> CompileResult<ModuleInner>;
|
||||
|
||||
#[cfg(feature = "cache")]
|
||||
|
||||
unsafe fn from_cache(&self, cache: Cache, _: Token) -> Result<ModuleInner, CacheError>;
|
||||
}
|
||||
|
||||
@ -93,6 +95,7 @@ pub trait FuncResolver: Send + Sync {
|
||||
) -> Option<NonNull<vm::Func>>;
|
||||
}
|
||||
|
||||
|
||||
pub trait CacheGen: Send + Sync {
|
||||
fn generate_cache(&self, module: &ModuleInner) -> Result<(Box<ModuleInfo>, Box<[u8]>, Arc<Memory>), CacheError>;
|
||||
}
|
@ -6,6 +6,7 @@ use std::{
|
||||
fs::File,
|
||||
io::{self, Seek, SeekFrom, Write},
|
||||
mem,
|
||||
sync::Arc,
|
||||
path::Path,
|
||||
slice,
|
||||
};
|
||||
@ -67,31 +68,26 @@ impl CacheHeader {
|
||||
struct CacheInner {
|
||||
info: Box<ModuleInfo>,
|
||||
#[serde(with = "serde_bytes")]
|
||||
backend_metadata: Vec<u8>,
|
||||
compiled_code: Memory,
|
||||
backend_metadata: Box<[u8]>,
|
||||
compiled_code: Arc<Memory>,
|
||||
}
|
||||
|
||||
pub struct Cache {
|
||||
inner: CacheInner,
|
||||
wasm_hash: Box<[u8; 32]>,
|
||||
}
|
||||
|
||||
impl Cache {
|
||||
pub(crate) fn new(
|
||||
wasm: &[u8],
|
||||
pub(crate) fn from_parts(
|
||||
info: Box<ModuleInfo>,
|
||||
backend_metadata: Vec<u8>,
|
||||
compiled_code: Memory,
|
||||
backend_metadata: Box<[u8]>,
|
||||
compiled_code: Arc<Memory>,
|
||||
) -> Self {
|
||||
let wasm_hash = hash_data(wasm);
|
||||
|
||||
Self {
|
||||
inner: CacheInner {
|
||||
info,
|
||||
backend_metadata,
|
||||
compiled_code,
|
||||
},
|
||||
wasm_hash: Box::new(wasm_hash),
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,7 +106,6 @@ impl Cache {
|
||||
|
||||
Ok(Cache {
|
||||
inner,
|
||||
wasm_hash: Box::new(header.wasm_hash),
|
||||
})
|
||||
}
|
||||
|
||||
@ -118,12 +113,8 @@ impl Cache {
|
||||
&self.inner.info
|
||||
}
|
||||
|
||||
pub fn wasm_hash(&self) -> &[u8; 32] {
|
||||
&self.wasm_hash
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn consume(self) -> (ModuleInfo, Vec<u8>, Memory) {
|
||||
pub fn consume(self) -> (ModuleInfo, Box<[u8]>, Arc<Memory>) {
|
||||
(
|
||||
*self.inner.info,
|
||||
self.inner.backend_metadata,
|
||||
@ -152,11 +143,7 @@ impl Cache {
|
||||
file.seek(SeekFrom::Start(0))
|
||||
.map_err(|e| Error::Unknown(e.to_string()))?;
|
||||
|
||||
let wasm_hash = {
|
||||
let mut array = [0u8; 32];
|
||||
array.copy_from_slice(&*self.wasm_hash);
|
||||
array
|
||||
};
|
||||
let wasm_hash = self.inner.info.wasm_hash.into_array();
|
||||
|
||||
let cache_header = CacheHeader {
|
||||
magic: [
|
||||
|
@ -2,7 +2,7 @@
|
||||
#[macro_use]
|
||||
extern crate field_offset;
|
||||
|
||||
#[cfg(feature = "cache")]
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
@ -11,7 +11,7 @@ mod macros;
|
||||
#[doc(hidden)]
|
||||
pub mod backend;
|
||||
mod backing;
|
||||
#[cfg(feature = "cache")]
|
||||
|
||||
pub mod cache;
|
||||
pub mod error;
|
||||
pub mod export;
|
||||
@ -44,7 +44,7 @@ pub use self::module::Module;
|
||||
pub use self::typed_func::Func;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[cfg(feature = "cache")]
|
||||
|
||||
use self::cache::{Cache, Error as CacheError};
|
||||
|
||||
pub mod prelude {
|
||||
@ -90,7 +90,7 @@ pub fn validate(wasm: &[u8]) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
// #[cfg(feature = "cache")]
|
||||
//
|
||||
// pub fn compile_to_cache_with(
|
||||
// wasm: &[u8],
|
||||
// compiler: &dyn backend::Compiler,
|
||||
@ -102,7 +102,7 @@ pub fn validate(wasm: &[u8]) -> bool {
|
||||
// Ok(Cache::new(wasm, info, backend_metadata, compiled_code))
|
||||
// }
|
||||
|
||||
#[cfg(feature = "cache")]
|
||||
|
||||
pub unsafe fn load_cache_with(
|
||||
cache: Cache,
|
||||
compiler: &dyn backend::Compiler,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
backend::{Backend, FuncResolver, ProtectedCaller, CacheGen},
|
||||
error::Result,
|
||||
backend::{Backend, FuncResolver, ProtectedCaller},
|
||||
error,
|
||||
import::ImportObject,
|
||||
structures::{Map, TypedIndex},
|
||||
typed_func::EARLY_TRAPPER,
|
||||
@ -10,8 +10,11 @@ use crate::{
|
||||
LocalGlobalIndex, LocalMemoryIndex, LocalTableIndex, MemoryDescriptor, MemoryIndex,
|
||||
SigIndex, TableDescriptor, TableIndex,
|
||||
},
|
||||
cache::{Cache, Error as CacheError},
|
||||
Instance,
|
||||
};
|
||||
|
||||
use crate::backend::CacheGen;
|
||||
use hashbrown::HashMap;
|
||||
use indexmap::IndexMap;
|
||||
use std::sync::Arc;
|
||||
@ -21,13 +24,15 @@ use std::sync::Arc;
|
||||
pub struct ModuleInner {
|
||||
pub func_resolver: Box<dyn FuncResolver>,
|
||||
pub protected_caller: Box<dyn ProtectedCaller>,
|
||||
|
||||
|
||||
pub cache_gen: Box<dyn CacheGen>,
|
||||
|
||||
pub info: ModuleInfo,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct ModuleInfo {
|
||||
// This are strictly local and the typsystem ensures that.
|
||||
pub memories: Map<LocalMemoryIndex, MemoryDescriptor>,
|
||||
@ -57,13 +62,19 @@ pub struct ModuleInfo {
|
||||
pub wasm_hash: WasmHash,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct WasmHash([u8; 32]);
|
||||
|
||||
|
||||
impl WasmHash {
|
||||
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(())
|
||||
/// # }
|
||||
/// ```
|
||||
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)
|
||||
}
|
||||
|
||||
pub fn cache(&self) -> Result<Cache, CacheError> {
|
||||
let (info, backend_cache, code) = self.inner.cache_gen.generate_cache(&self.inner)?;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
impl ModuleInner {}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ImportName {
|
||||
pub namespace_index: NamespaceIndex,
|
||||
pub name_index: NameIndex,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ExportIndex {
|
||||
Func(FuncIndex),
|
||||
@ -134,7 +150,7 @@ pub enum ExportIndex {
|
||||
}
|
||||
|
||||
/// A data initializer for linear memory.
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DataInitializer {
|
||||
/// The index of the memory to initialize.
|
||||
@ -147,7 +163,7 @@ pub struct DataInitializer {
|
||||
}
|
||||
|
||||
/// A WebAssembly table initializer.
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TableInitializer {
|
||||
/// 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)]
|
||||
pub struct StringTable<K: TypedIndex> {
|
||||
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)]
|
||||
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)]
|
||||
pub struct NameIndex(u32);
|
||||
|
||||
|
@ -8,7 +8,7 @@ use std::{
|
||||
};
|
||||
|
||||
/// Dense item map
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Map<K, V>
|
||||
where
|
||||
|
@ -10,18 +10,18 @@ pub use self::unix::*;
|
||||
#[cfg(windows)]
|
||||
pub use self::windows::*;
|
||||
|
||||
#[cfg(feature = "cache")]
|
||||
|
||||
use serde::{
|
||||
de::{self, SeqAccess, Visitor},
|
||||
ser::SerializeStruct,
|
||||
Deserialize, Deserializer, Serialize, Serializer,
|
||||
};
|
||||
#[cfg(feature = "cache")]
|
||||
|
||||
use serde_bytes::Bytes;
|
||||
#[cfg(feature = "cache")]
|
||||
|
||||
use std::fmt;
|
||||
|
||||
#[cfg(feature = "cache")]
|
||||
|
||||
impl Serialize for Memory {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
@ -36,7 +36,7 @@ impl Serialize for Memory {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "cache")]
|
||||
|
||||
impl<'de> Deserialize<'de> for Memory {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
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)]
|
||||
#[allow(dead_code)]
|
||||
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)]
|
||||
#[allow(dead_code)]
|
||||
pub enum Protect {
|
||||
|
@ -2,7 +2,7 @@ use crate::{memory::MemoryType, module::ModuleInfo, structures::TypedIndex, unit
|
||||
use std::{borrow::Cow, mem};
|
||||
|
||||
/// Represents a WebAssembly type.
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum Type {
|
||||
/// The `i32` type.
|
||||
@ -25,7 +25,7 @@ impl std::fmt::Display for Type {
|
||||
///
|
||||
/// As the number of types in WebAssembly expand,
|
||||
/// this structure will expand as well.
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Value {
|
||||
/// 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)]
|
||||
pub enum ElementType {
|
||||
/// Any wasm function.
|
||||
Anyfunc,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct TableDescriptor {
|
||||
/// Type of data stored in this table.
|
||||
@ -203,7 +203,7 @@ impl TableDescriptor {
|
||||
/// A const value initializer.
|
||||
/// Over time, this will be able to represent more and more
|
||||
/// complex expressions.
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Initializer {
|
||||
/// Corresponds to a `const.*` instruction.
|
||||
@ -212,7 +212,7 @@ pub enum Initializer {
|
||||
GetGlobal(ImportedGlobalIndex),
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct GlobalDescriptor {
|
||||
pub mutable: bool,
|
||||
@ -220,7 +220,7 @@ pub struct GlobalDescriptor {
|
||||
}
|
||||
|
||||
/// A wasm global.
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GlobalInit {
|
||||
pub desc: GlobalDescriptor,
|
||||
@ -228,7 +228,7 @@ pub struct GlobalInit {
|
||||
}
|
||||
|
||||
/// A wasm memory.
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct MemoryDescriptor {
|
||||
/// The minimum number of allowed pages.
|
||||
@ -261,7 +261,7 @@ impl MemoryDescriptor {
|
||||
|
||||
/// The signature of a function that is either implemented
|
||||
/// 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)]
|
||||
pub struct FuncSig {
|
||||
params: Cow<'static, [Type]>,
|
||||
@ -324,7 +324,7 @@ pub trait LocalImport {
|
||||
#[rustfmt::skip]
|
||||
macro_rules! define_map_index {
|
||||
($ty:ident) => {
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct $ty (u32);
|
||||
impl TypedIndex for $ty {
|
||||
@ -400,7 +400,7 @@ define_local_or_import![
|
||||
(GlobalIndex | (LocalGlobalIndex, ImportedGlobalIndex): imported_globals),
|
||||
];
|
||||
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct SigIndex(u32);
|
||||
impl TypedIndex for SigIndex {
|
||||
|
@ -7,7 +7,7 @@ const WASM_PAGE_SIZE: usize = 65_536;
|
||||
const WASM_MAX_PAGES: usize = 65_536;
|
||||
|
||||
/// 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)]
|
||||
pub struct Pages(pub u32);
|
||||
|
||||
@ -33,7 +33,7 @@ impl fmt::Debug for Pages {
|
||||
}
|
||||
|
||||
/// 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)]
|
||||
pub struct Bytes(pub usize);
|
||||
|
||||
|
Reference in New Issue
Block a user