mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-16 02:11:20 +00:00
Add caching. (#134)
* Allow a module to have a different signature registry than the process-specific * Add core ability to build compiled code caches * Remove timing printouts * Serialize/Deserialize memories to reduce copies * Work more on api * Relocate local functions relatively before external functions * Fix incorrect definition in test * merge errors caused by merge * Fix emscripten compile * Fix review comments
This commit is contained in:
@ -1,11 +1,10 @@
|
||||
use crate::{
|
||||
backend::{FuncResolver, ProtectedCaller},
|
||||
backend::{Backend, FuncResolver, ProtectedCaller},
|
||||
error::Result,
|
||||
import::ImportObject,
|
||||
sig_registry::SigRegistry,
|
||||
structures::Map,
|
||||
structures::{Map, TypedIndex},
|
||||
types::{
|
||||
FuncIndex, GlobalDescriptor, GlobalIndex, GlobalInit, ImportedFuncIndex,
|
||||
FuncIndex, FuncSig, GlobalDescriptor, GlobalIndex, GlobalInit, ImportedFuncIndex,
|
||||
ImportedGlobalIndex, ImportedMemoryIndex, ImportedTableIndex, Initializer,
|
||||
LocalGlobalIndex, LocalMemoryIndex, LocalTableIndex, MemoryDescriptor, MemoryIndex,
|
||||
SigIndex, TableDescriptor, TableIndex,
|
||||
@ -13,6 +12,7 @@ use crate::{
|
||||
Instance,
|
||||
};
|
||||
use hashbrown::HashMap;
|
||||
use indexmap::IndexMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// This is used to instantiate a new WebAssembly module.
|
||||
@ -21,6 +21,11 @@ pub struct ModuleInner {
|
||||
pub func_resolver: Box<dyn FuncResolver>,
|
||||
pub protected_caller: Box<dyn ProtectedCaller>,
|
||||
|
||||
pub info: ModuleInfo,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
pub struct ModuleInfo {
|
||||
// This are strictly local and the typsystem ensures that.
|
||||
pub memories: Map<LocalMemoryIndex, MemoryDescriptor>,
|
||||
pub globals: Map<LocalGlobalIndex, GlobalInit>,
|
||||
@ -40,7 +45,11 @@ pub struct ModuleInner {
|
||||
pub start_func: Option<FuncIndex>,
|
||||
|
||||
pub func_assoc: Map<FuncIndex, SigIndex>,
|
||||
pub sig_registry: SigRegistry,
|
||||
pub signatures: Map<SigIndex, Arc<FuncSig>>,
|
||||
pub backend: Backend,
|
||||
|
||||
pub namespace_table: StringTable<NamespaceIndex>,
|
||||
pub name_table: StringTable<NameIndex>,
|
||||
}
|
||||
|
||||
/// A compiled WebAssembly module.
|
||||
@ -87,21 +96,14 @@ impl Module {
|
||||
impl ModuleInner {}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ImportName {
|
||||
pub namespace: String,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl From<(String, String)> for ImportName {
|
||||
fn from(n: (String, String)) -> Self {
|
||||
ImportName {
|
||||
namespace: n.0,
|
||||
name: n.1,
|
||||
}
|
||||
}
|
||||
pub namespace_index: NamespaceIndex,
|
||||
pub name_index: NameIndex,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ExportIndex {
|
||||
Func(FuncIndex),
|
||||
@ -111,6 +113,7 @@ pub enum ExportIndex {
|
||||
}
|
||||
|
||||
/// A data initializer for linear memory.
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DataInitializer {
|
||||
/// The index of the memory to initialize.
|
||||
@ -118,10 +121,12 @@ pub struct DataInitializer {
|
||||
/// Either a constant offset or a `get_global`
|
||||
pub base: Initializer,
|
||||
/// The initialization data.
|
||||
#[cfg_attr(feature = "cache", serde(with = "serde_bytes"))]
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
/// A WebAssembly table initializer.
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TableInitializer {
|
||||
/// The index of a table to initialize.
|
||||
@ -131,3 +136,110 @@ pub struct TableInitializer {
|
||||
/// The values to write into the table elements.
|
||||
pub elements: Vec<FuncIndex>,
|
||||
}
|
||||
|
||||
pub struct StringTableBuilder<K: TypedIndex> {
|
||||
map: IndexMap<String, (K, u32, u32)>,
|
||||
buffer: String,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
impl<K: TypedIndex> StringTableBuilder<K> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
map: IndexMap::new(),
|
||||
buffer: String::new(),
|
||||
count: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn register<S>(&mut self, s: S) -> K
|
||||
where
|
||||
S: Into<String> + AsRef<str>,
|
||||
{
|
||||
let s_str = s.as_ref();
|
||||
|
||||
if self.map.contains_key(s_str) {
|
||||
self.map[s_str].0
|
||||
} else {
|
||||
let offset = self.buffer.len();
|
||||
let length = s_str.len();
|
||||
let index = TypedIndex::new(self.count as _);
|
||||
|
||||
self.buffer.push_str(s_str);
|
||||
self.map
|
||||
.insert(s.into(), (index, offset as u32, length as u32));
|
||||
self.count += 1;
|
||||
|
||||
index
|
||||
}
|
||||
}
|
||||
|
||||
pub fn finish(self) -> StringTable<K> {
|
||||
let table = self
|
||||
.map
|
||||
.values()
|
||||
.map(|(_, offset, length)| (*offset, *length))
|
||||
.collect();
|
||||
|
||||
StringTable {
|
||||
table,
|
||||
buffer: self.buffer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct StringTable<K: TypedIndex> {
|
||||
table: Map<K, (u32, u32)>,
|
||||
buffer: String,
|
||||
}
|
||||
|
||||
impl<K: TypedIndex> StringTable<K> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
table: Map::new(),
|
||||
buffer: String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self, index: K) -> &str {
|
||||
let (offset, length) = self.table[index];
|
||||
let offset = offset as usize;
|
||||
let length = length as usize;
|
||||
|
||||
&self.buffer[offset..offset + length]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct NamespaceIndex(u32);
|
||||
|
||||
impl TypedIndex for NamespaceIndex {
|
||||
#[doc(hidden)]
|
||||
fn new(index: usize) -> Self {
|
||||
NamespaceIndex(index as _)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
fn index(&self) -> usize {
|
||||
self.0 as usize
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "cache", derive(Serialize, Deserialize))]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct NameIndex(u32);
|
||||
|
||||
impl TypedIndex for NameIndex {
|
||||
#[doc(hidden)]
|
||||
fn new(index: usize) -> Self {
|
||||
NameIndex(index as _)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
fn index(&self) -> usize {
|
||||
self.0 as usize
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user