mirror of
https://github.com/fluencelabs/wasmer
synced 2025-04-02 07:51:03 +00:00
Fix most compile-time errors
This commit is contained in:
parent
fb04ba0bce
commit
5ce75fc0ad
@ -1,7 +1,5 @@
|
|||||||
use std::ops::{Index, IndexMut};
|
use std::ops::{Index, IndexMut};
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use std::marker::PhantomData;
|
|
||||||
use crate::runtime::types::MapIndex;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
@ -105,41 +103,4 @@ impl<'a, T> From<&'a [T]> for BoundedSlice<T> {
|
|||||||
len: slice.len(),
|
len: slice.len(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
#[repr(transparent)]
|
|
||||||
pub struct IndexedSlice<'a, T, I> {
|
|
||||||
ptr: NonNull<T>,
|
|
||||||
_phantom: PhantomData<I>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T: 'a, I> IndexedSlice<T, I>
|
|
||||||
where
|
|
||||||
I: MapIndex,
|
|
||||||
{
|
|
||||||
pub(crate) fn new(ptr: *mut T) -> Self {
|
|
||||||
Self {
|
|
||||||
ptr: NonNull::new(ptr).unwrap(),
|
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn get(&self, index: I) -> &T {
|
|
||||||
let ptr = self.as_ptr();
|
|
||||||
&*ptr.add(index.index())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn get_mut(&mut self, index: I) -> &mut T {
|
|
||||||
let ptr = self.as_mut_ptr();
|
|
||||||
&mut *ptr.add(index.index())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_ptr(&self) -> *const T {
|
|
||||||
self.ptr.as_ptr()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_mut_ptr(&mut self) -> *mut T {
|
|
||||||
self.ptr.as_ptr()
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,5 +1,4 @@
|
|||||||
use crate::runtime::module::Module;
|
|
||||||
use crate::runtime::types::FuncIndex;
|
|
||||||
use crate::runtime::{
|
use crate::runtime::{
|
||||||
vm,
|
vm,
|
||||||
module::Module,
|
module::Module,
|
||||||
@ -12,5 +11,5 @@ pub trait Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait FuncResolver {
|
pub trait FuncResolver {
|
||||||
pub fn resolve(&self, index: FuncIndex) -> Option<*const vm::Func>;
|
fn resolve(&self, index: FuncIndex) -> Option<*const vm::Func>;
|
||||||
}
|
}
|
@ -2,11 +2,10 @@ use crate::runtime::{
|
|||||||
vm,
|
vm,
|
||||||
module::Module,
|
module::Module,
|
||||||
table::TableBacking,
|
table::TableBacking,
|
||||||
types::{Val, GlobalInit},
|
types::{Val, GlobalInit, MapIndex},
|
||||||
memory::LinearMemory,
|
memory::LinearMemory,
|
||||||
instance::{Imports, Import},
|
instance::{Imports, Import},
|
||||||
};
|
};
|
||||||
use std::{ptr, mem};
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -14,9 +13,9 @@ pub struct LocalBacking {
|
|||||||
memories: Box<[LinearMemory]>,
|
memories: Box<[LinearMemory]>,
|
||||||
tables: Box<[TableBacking]>,
|
tables: Box<[TableBacking]>,
|
||||||
|
|
||||||
vm_memories: Box<[vm::LocalMemory]>,
|
pub vm_memories: Box<[vm::LocalMemory]>,
|
||||||
vm_tables: Box<[vm::LocalTable]>,
|
pub vm_tables: Box<[vm::LocalTable]>,
|
||||||
vm_globals: Box<[vm::LocalGlobal]>,
|
pub vm_globals: Box<[vm::LocalGlobal]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LocalBacking {
|
impl LocalBacking {
|
||||||
@ -29,8 +28,8 @@ impl LocalBacking {
|
|||||||
memories,
|
memories,
|
||||||
tables,
|
tables,
|
||||||
|
|
||||||
vm_memories: Self::finalize_memories(module, &mut memories[..], options),
|
vm_memories: Self::finalize_memories(module, &mut memories[..]),
|
||||||
vm_tables: Self::finalize_tables(module, &mut tables[..], options),
|
vm_tables: Self::finalize_tables(module, &mut tables[..]),
|
||||||
vm_globals: Self::finalize_globals(module, imports, globals),
|
vm_globals: Self::finalize_globals(module, imports, globals),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,7 +41,7 @@ impl LocalBacking {
|
|||||||
// If we use emscripten, we set a fixed initial and maximum
|
// If we use emscripten, we set a fixed initial and maximum
|
||||||
debug!(
|
debug!(
|
||||||
"Instance - init memory ({}, {:?})",
|
"Instance - init memory ({}, {:?})",
|
||||||
memory.min, memory.max
|
mem.min, mem.max
|
||||||
);
|
);
|
||||||
// let memory = if options.abi == InstanceABI::Emscripten {
|
// let memory = if options.abi == InstanceABI::Emscripten {
|
||||||
// // We use MAX_PAGES, so at the end the result is:
|
// // We use MAX_PAGES, so at the end the result is:
|
||||||
@ -80,7 +79,7 @@ impl LocalBacking {
|
|||||||
fn generate_tables(module: &Module) -> Box<[TableBacking]> {
|
fn generate_tables(module: &Module) -> Box<[TableBacking]> {
|
||||||
let mut tables = Vec::with_capacity(module.tables.len());
|
let mut tables = Vec::with_capacity(module.tables.len());
|
||||||
|
|
||||||
for table in &module.tables {
|
for (_, table) in &module.tables {
|
||||||
let table_backing = TableBacking::new(table);
|
let table_backing = TableBacking::new(table);
|
||||||
tables.push(table_backing);
|
tables.push(table_backing);
|
||||||
}
|
}
|
||||||
@ -99,13 +98,13 @@ impl LocalBacking {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn finalize_globals(module: &Module, imports: &ImportBacking, globals: Box<[vm::LocalGlobal]>) -> Box<[vm::LocalGlobal]> {
|
fn finalize_globals(module: &Module, imports: &ImportBacking, globals: Box<[vm::LocalGlobal]>) -> Box<[vm::LocalGlobal]> {
|
||||||
for (to, from) in globals.iter_mut().zip(module.globals.iter()) {
|
for (to, (_, from)) in globals.iter_mut().zip(module.globals.into_iter()) {
|
||||||
*to = match from.init {
|
to.data = match from.init {
|
||||||
GlobalInit::Val(Val::I32(x)) => x as u64,
|
GlobalInit::Val(Val::I32(x)) => x as u64,
|
||||||
GlobalInit::Val(Val::I64(x)) => x as u64,
|
GlobalInit::Val(Val::I64(x)) => x as u64,
|
||||||
GlobalInit::Val(Val::F32(x)) => x as u64,
|
GlobalInit::Val(Val::F32(x)) => x as u64,
|
||||||
GlobalInit::Val(Val::F64(x)) => x,
|
GlobalInit::Val(Val::F64(x)) => x,
|
||||||
GlobalInit::GetGlobal(index) => unsafe { (*imports.globals[index.index()].global).data },
|
GlobalInit::GetGlobal(index) => unsafe { (imports.globals[index.index()].global).data },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,10 +181,10 @@ impl LocalBacking {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ImportBacking {
|
pub struct ImportBacking {
|
||||||
functions: Box<[vm::ImportedFunc]>,
|
pub functions: Box<[vm::ImportedFunc]>,
|
||||||
memories: Box<[vm::ImportedMemory]>,
|
pub memories: Box<[vm::ImportedMemory]>,
|
||||||
tables: Box<[vm::ImportedTable]>,
|
pub tables: Box<[vm::ImportedTable]>,
|
||||||
globals: Box<[vm::ImportedGlobal]>,
|
pub globals: Box<[vm::ImportedGlobal]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImportBacking {
|
impl ImportBacking {
|
||||||
@ -195,42 +194,43 @@ impl ImportBacking {
|
|||||||
|
|
||||||
let mut functions = Vec::with_capacity(module.imported_functions.len());
|
let mut functions = Vec::with_capacity(module.imported_functions.len());
|
||||||
for (index, (mod_name, item_name)) in &module.imported_functions {
|
for (index, (mod_name, item_name)) in &module.imported_functions {
|
||||||
let expected_sig = module.signatures[index];
|
let expected_sig_index = module.signature_assoc[index];
|
||||||
|
let expected_sig = module.signatures[expected_sig_index];
|
||||||
let import = imports.get(mod_name, item_name);
|
let import = imports.get(mod_name, item_name);
|
||||||
if let Import::Func(func, signature) = import {
|
if let Some(Import::Func(func, signature)) = import {
|
||||||
if expected_sig == signature {
|
if &expected_sig == signature {
|
||||||
functions.push(vm::ImportedFunc {
|
functions.push(vm::ImportedFunc {
|
||||||
func,
|
func: *func,
|
||||||
vmctx: ptr::null_mut(),
|
// vmctx: ptr::null_mut(),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return Err(format!("unexpected signature for {}:{}", mod_name, item_name));
|
return Err(format!("unexpected signature for {:?}:{:?}", mod_name, item_name));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(format!("incorrect type for {}:{}", mod_name, item_name));
|
return Err(format!("incorrect type for {:?}:{:?}", mod_name, item_name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut globals = Vec::with_capacity(module.imported_globals.len());
|
let mut globals = Vec::with_capacity(module.imported_globals.len());
|
||||||
for (_, ((mod_name, item_name), global_desc)) in &module.imported_globals {
|
for (_, ((mod_name, item_name), global_desc)) in &module.imported_globals {
|
||||||
let import = imports.get(mod_name, item_name);
|
let import = imports.get(mod_name, item_name);
|
||||||
if let Import::Global(val) = import {
|
if let Some(Import::Global(val)) = import {
|
||||||
if val.ty() == global_desc.ty {
|
if val.ty() == global_desc.ty {
|
||||||
globals.push(vm::ImportedGlobal {
|
globals.push(vm::ImportedGlobal {
|
||||||
global: vm::LocalGlobal {
|
global: vm::LocalGlobal {
|
||||||
data: match val {
|
data: match val {
|
||||||
Val::I32(n) => n as u64,
|
Val::I32(n) => *n as u64,
|
||||||
Val::I64(n) => n as u64,
|
Val::I64(n) => *n as u64,
|
||||||
Val::F32(n) => n as u64,
|
Val::F32(n) => *n as u64,
|
||||||
Val::F64(n) => n,
|
Val::F64(n) => *n,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return Err(format!("unexpected global type for {}:{}", mod_name, item_name));
|
return Err(format!("unexpected global type for {:?}:{:?}", mod_name, item_name));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(format!("incorrect type for {}:{}", mod_name, item_name));
|
return Err(format!("incorrect type for {:?}:{:?}", mod_name, item_name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,21 +1,24 @@
|
|||||||
use crate::runtime::{
|
use crate::runtime::{
|
||||||
vm,
|
vm,
|
||||||
backing::{LocalBacking, ImportBacking},
|
backing::{LocalBacking, ImportBacking},
|
||||||
module::{ModuleName, ItemName},
|
module::{Module, ModuleName, ItemName},
|
||||||
types::{Val, Memory, Table, Global, FuncSig},
|
types::{Val, Memory, Table, FuncSig},
|
||||||
table::TableBacking,
|
table::TableBacking,
|
||||||
memory::LinearMemory,
|
memory::LinearMemory,
|
||||||
|
sig_registry::SigRegistry,
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use hashbrown::{HashMap, Entry};
|
use hashbrown::HashMap;
|
||||||
|
|
||||||
pub struct Instance {
|
pub struct Instance {
|
||||||
pub vmctx: vm::Ctx,
|
pub vmctx: vm::Ctx,
|
||||||
|
|
||||||
backing: LocalBacking,
|
backing: LocalBacking,
|
||||||
imports: ImportBacking,
|
import_backing: ImportBacking,
|
||||||
|
|
||||||
pub module: Arc<Module>,
|
pub module: Arc<Module>,
|
||||||
|
|
||||||
|
pub sig_registry: SigRegistry,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Instance {
|
impl Instance {
|
||||||
@ -23,18 +26,21 @@ impl Instance {
|
|||||||
let mut import_backing = ImportBacking::new(&*module, imports)?;
|
let mut import_backing = ImportBacking::new(&*module, imports)?;
|
||||||
let mut backing = LocalBacking::new(&*module, &import_backing);
|
let mut backing = LocalBacking::new(&*module, &import_backing);
|
||||||
|
|
||||||
let vmctx = vm::Ctx::new(&mut backing, &mut imports);
|
let sig_registry = SigRegistry::new();
|
||||||
|
|
||||||
|
let vmctx = vm::Ctx::new(&mut backing, &mut import_backing, &sig_registry);
|
||||||
|
|
||||||
Ok(Box::new(Instance {
|
Ok(Box::new(Instance {
|
||||||
vmctx,
|
vmctx,
|
||||||
backing,
|
backing,
|
||||||
import_backing,
|
import_backing,
|
||||||
module,
|
module,
|
||||||
|
sig_registry,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug)]
|
||||||
pub enum Import {
|
pub enum Import {
|
||||||
Func(*const vm::Func, FuncSig),
|
Func(*const vm::Func, FuncSig),
|
||||||
Table(Arc<TableBacking>, Table),
|
Table(Arc<TableBacking>, Table),
|
||||||
@ -54,10 +60,10 @@ impl Imports {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(&mut self, module: ModuleName, name: ItemName, import: Import) {
|
pub fn add(&mut self, module: ModuleName, name: ItemName, import: Import) {
|
||||||
self.map.entry(module).or_insert(HashMap::new()).insert(name, import)
|
self.map.entry(module).or_insert(HashMap::new()).insert(name, import);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, module: ModuleName, name: ItemName) -> Option<&Import> {
|
pub fn get(&self, module: &[u8], name: &[u8]) -> Option<&Import> {
|
||||||
self.map.get().and_then(|m| m.get(name))
|
self.map.get(module).and_then(|m| m.get(name))
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,7 +10,7 @@ use std::slice;
|
|||||||
use crate::common::mmap::Mmap;
|
use crate::common::mmap::Mmap;
|
||||||
use crate::runtime::{
|
use crate::runtime::{
|
||||||
vm::LocalMemory,
|
vm::LocalMemory,
|
||||||
types::{Memory, Map, FuncIndex},
|
types::Memory,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A linear memory instance.
|
/// A linear memory instance.
|
||||||
@ -62,7 +62,7 @@ impl LinearMemory {
|
|||||||
assert!(!mem.shared, "shared memories must have a maximum size.");
|
assert!(!mem.shared, "shared memories must have a maximum size.");
|
||||||
|
|
||||||
(mem.min as usize * Self::PAGE_SIZE as usize, mem.min, 0, false)
|
(mem.min as usize * Self::PAGE_SIZE as usize, mem.min, 0, false)
|
||||||
}
|
};
|
||||||
|
|
||||||
let mut mmap = Mmap::with_size(mmap_size).unwrap();
|
let mut mmap = Mmap::with_size(mmap_size).unwrap();
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ impl LinearMemory {
|
|||||||
|
|
||||||
/// Returns the maximum number of wasm pages allowed.
|
/// Returns the maximum number of wasm pages allowed.
|
||||||
pub fn maximum_size(&self) -> u32 {
|
pub fn maximum_size(&self) -> u32 {
|
||||||
self.maximum.unwrap_or(Self::MAX_PAGES)
|
self.max.unwrap_or(Self::MAX_PAGES)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_vm_memory(&mut self) -> LocalMemory {
|
pub fn into_vm_memory(&mut self) -> LocalMemory {
|
||||||
@ -131,7 +131,7 @@ impl LinearMemory {
|
|||||||
None => return None,
|
None => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(val) = self.maximum {
|
if let Some(val) = self.max {
|
||||||
if new_pages > val {
|
if new_pages > val {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -147,7 +147,7 @@ impl LinearMemory {
|
|||||||
|
|
||||||
if new_bytes > self.mmap.len() - self.offset_guard_size {
|
if new_bytes > self.mmap.len() - self.offset_guard_size {
|
||||||
let mmap_size = new_bytes.checked_add(self.offset_guard_size)?;
|
let mmap_size = new_bytes.checked_add(self.offset_guard_size)?;
|
||||||
let mut new_mmap = Mmap::with_size(request_bytes).ok()?;
|
let mut new_mmap = Mmap::with_size(mmap_size).ok()?;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
region::protect(
|
region::protect(
|
||||||
@ -158,7 +158,7 @@ impl LinearMemory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let copy_size = self.mmap.len() - self.offset_guard_size;
|
let copy_size = self.mmap.len() - self.offset_guard_size;
|
||||||
new_mmap.as_mut_slice()[..copy_size].copy_from_slice(self.mmap.as_slice()[..copy_size]);
|
new_mmap.as_mut_slice()[..copy_size].copy_from_slice(&self.mmap.as_slice()[..copy_size]);
|
||||||
|
|
||||||
self.mmap = new_mmap;
|
self.mmap = new_mmap;
|
||||||
}
|
}
|
||||||
@ -182,7 +182,7 @@ impl LinearMemory {
|
|||||||
None => return None,
|
None => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(val) = self.maximum {
|
if let Some(val) = self.max {
|
||||||
if new_pages > val {
|
if new_pages > val {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -213,7 +213,7 @@ impl LinearMemory {
|
|||||||
// Not comparing based on memory content. That would be inefficient.
|
// Not comparing based on memory content. That would be inefficient.
|
||||||
impl PartialEq for LinearMemory {
|
impl PartialEq for LinearMemory {
|
||||||
fn eq(&self, other: &LinearMemory) -> bool {
|
fn eq(&self, other: &LinearMemory) -> bool {
|
||||||
self.current == other.current && self.maximum == other.maximum
|
self.current == other.current && self.max == other.max
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,9 +9,9 @@ mod instance;
|
|||||||
mod table;
|
mod table;
|
||||||
mod sig_registry;
|
mod sig_registry;
|
||||||
|
|
||||||
pub use backend::Compiler;
|
pub use self::backend::Compiler;
|
||||||
pub use instance::{Instance, Imports, Import};
|
pub use self::instance::{Instance, Imports, Import};
|
||||||
pub use module::{ModuleName, ItemName, Module};
|
pub use self::module::{ModuleName, ItemName, Module};
|
||||||
|
|
||||||
/// Compile a webassembly module using the provided compiler and linked with the provided imports.
|
/// Compile a webassembly module using the provided compiler and linked with the provided imports.
|
||||||
pub fn compile(compiler: &dyn Compiler, wasm: &[u8], imports: &Imports) -> Result<Box<Instance>, String> {
|
pub fn compile(compiler: &dyn Compiler, wasm: &[u8], imports: &Imports) -> Result<Box<Instance>, String> {
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
use crate::runtime::types::{
|
use crate::runtime::types::{
|
||||||
Map,
|
Map,
|
||||||
FuncIndex, MemoryIndex, TableIndex, GlobalIndex,
|
FuncIndex, MemoryIndex, TableIndex, GlobalIndex, SigIndex,
|
||||||
Memory, Globals, GlobalDesc, FuncSig, Table,
|
Memory, Global, GlobalDesc, FuncSig, Table,
|
||||||
};
|
};
|
||||||
use crate::runtime::backend::FuncResolver;
|
use crate::runtime::backend::FuncResolver;
|
||||||
|
|
||||||
/// This is used to instantiate a new webassembly module.
|
/// This is used to instantiate a new webassembly module.
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Module {
|
pub struct Module {
|
||||||
pub functions: Box<dyn FuncResolver>,
|
pub functions: Box<dyn FuncResolver>,
|
||||||
pub memories: Map<Memory, MemoryIndex>,
|
pub memories: Map<Memory, MemoryIndex>,
|
||||||
@ -23,7 +22,8 @@ pub struct Module {
|
|||||||
pub data_initializers: Vec<DataInitializer>,
|
pub data_initializers: Vec<DataInitializer>,
|
||||||
pub start_func: FuncIndex,
|
pub start_func: FuncIndex,
|
||||||
|
|
||||||
pub signatures: Map<FuncSig, FuncIndex>,
|
pub signature_assoc: Map<SigIndex, FuncIndex>,
|
||||||
|
pub signatures: Map<FuncSig, SigIndex>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type ModuleName = Vec<u8>;
|
pub type ModuleName = Vec<u8>;
|
||||||
|
@ -1,5 +1,32 @@
|
|||||||
|
|
||||||
|
use hashbrown::HashMap;
|
||||||
|
use crate::runtime::{
|
||||||
|
types::{Map, SigIndex, FuncSig},
|
||||||
|
vm,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct SignatureRegistry {
|
pub struct SigRegistry {
|
||||||
|
sig_set: HashMap<FuncSig, vm::SigId>,
|
||||||
|
signatures: Map<vm::SigId, SigIndex>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SigRegistry {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
sig_set: HashMap::new(),
|
||||||
|
signatures: Map::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_vm_signatures(&self) -> *const vm::SigId {
|
||||||
|
self.signatures.as_ptr()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn register(&mut self, signature: FuncSig, sig_index: SigIndex) {
|
||||||
|
let index = self.sig_set.len();
|
||||||
|
let vm_sig_id = *self.sig_set.entry(signature).or_insert_with(|| {
|
||||||
|
vm::SigId(index as u32)
|
||||||
|
});
|
||||||
|
self.signatures.push(vm_sig_id);
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
use super::vm;
|
use super::vm;
|
||||||
use crate::runtime::types::{ElementType, Table};
|
use crate::runtime::types::{ElementType, Table};
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone)]
|
||||||
enum TableElements {
|
enum TableElements {
|
||||||
/// This is intended to be a caller-checked Anyfunc.
|
/// This is intended to be a caller-checked Anyfunc.
|
||||||
Anyfunc(Box<[vm::Anyfunc]>),
|
Anyfunc(Box<[vm::Anyfunc]>),
|
||||||
@ -18,7 +18,7 @@ impl TableBacking {
|
|||||||
match table.ty {
|
match table.ty {
|
||||||
ElementType::Anyfunc => {
|
ElementType::Anyfunc => {
|
||||||
Self {
|
Self {
|
||||||
elements: TableElements::Anyfunc(vec![vm::Anyfunc::null(); table.min].into_boxed_slice()),
|
elements: TableElements::Anyfunc(vec![vm::Anyfunc::null(); table.min as usize].into_boxed_slice()),
|
||||||
max: table.max,
|
max: table.max,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::{slice, iter};
|
use std::{
|
||||||
|
slice, iter,
|
||||||
|
ops::{Index, IndexMut},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub enum Type {
|
pub enum Type {
|
||||||
/// The `i32` type.
|
/// The `i32` type.
|
||||||
I32,
|
I32,
|
||||||
@ -38,25 +41,25 @@ impl Val {
|
|||||||
|
|
||||||
impl From<i32> for Val {
|
impl From<i32> for Val {
|
||||||
fn from(n: i32) -> Self {
|
fn from(n: i32) -> Self {
|
||||||
Self::I32(n)
|
Val::I32(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<i64> for Val {
|
impl From<i64> for Val {
|
||||||
fn from(n: i64) -> Self {
|
fn from(n: i64) -> Self {
|
||||||
Self::I64(n)
|
Val::I64(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<f32> for Val {
|
impl From<f32> for Val {
|
||||||
fn from(n: f32) -> Self {
|
fn from(n: f32) -> Self {
|
||||||
Self::F32(n.to_bits())
|
Val::F32(n.to_bits())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<f64> for Val {
|
impl From<f64> for Val {
|
||||||
fn from(n: f64) -> Self {
|
fn from(n: f64) -> Self {
|
||||||
Self::I64(n.to_bits())
|
Val::F64(n.to_bits())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +119,7 @@ impl Memory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A wasm func.
|
/// A wasm func.
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct FuncSig {
|
pub struct FuncSig {
|
||||||
pub params: Vec<Type>,
|
pub params: Vec<Type>,
|
||||||
pub returns: Vec<Type>,
|
pub returns: Vec<Type>,
|
||||||
@ -137,7 +140,10 @@ where
|
|||||||
_marker: PhantomData<I>,
|
_marker: PhantomData<I>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Map {
|
impl<T, I> Map<T, I>
|
||||||
|
where
|
||||||
|
I: MapIndex,
|
||||||
|
{
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
elems: Vec::new(),
|
elems: Vec::new(),
|
||||||
@ -165,6 +171,10 @@ impl Map {
|
|||||||
self.elems.push(value);
|
self.elems.push(value);
|
||||||
I::new(len)
|
I::new(len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn as_ptr(&self) -> *const T {
|
||||||
|
self.elems.as_ptr()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, I> Index<I> for Map<T, I>
|
impl<T, I> Index<I> for Map<T, I>
|
||||||
@ -206,13 +216,13 @@ where
|
|||||||
type IntoIter = IterMut<'a, T, I>;
|
type IntoIter = IterMut<'a, T, I>;
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
Iter::new(self.elems.iter_mut())
|
IterMut::new(self.elems.iter_mut())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Iter<'a, T: 'a, I: MapIndex> {
|
pub struct Iter<'a, T: 'a, I: MapIndex> {
|
||||||
enumerated: iter::Enumerate<slice::Iter<'A, T>>,
|
enumerated: iter::Enumerate<slice::Iter<'a, T>>,
|
||||||
_marker: PhantomData,
|
_marker: PhantomData<I>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: 'a, I: MapIndex> Iter<'a, T, I> {
|
impl<'a, T: 'a, I: MapIndex> Iter<'a, T, I> {
|
||||||
@ -227,18 +237,18 @@ impl<'a, T: 'a, I: MapIndex> Iter<'a, T, I> {
|
|||||||
impl<'a, T: 'a, I: MapIndex> Iterator for Iter<'a, T, I> {
|
impl<'a, T: 'a, I: MapIndex> Iterator for Iter<'a, T, I> {
|
||||||
type Item = (I, &'a T);
|
type Item = (I, &'a T);
|
||||||
|
|
||||||
fn next(&mut self) -> Self::Item {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
self.enumerated.next().map(|i, v| (I::new(i), v))
|
self.enumerated.next().map(|(i, v)| (I::new(i), v))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct IterMut<'a, T: 'a, I: MapIndex> {
|
pub struct IterMut<'a, T: 'a, I: MapIndex> {
|
||||||
enumerated: iter::Enumerate<slice::Iter<'A, T>>,
|
enumerated: iter::Enumerate<slice::IterMut<'a, T>>,
|
||||||
_marker: PhantomData,
|
_marker: PhantomData<I>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: 'a, I: MapIndex> IterMut<'a, T, I> {
|
impl<'a, T: 'a, I: MapIndex> IterMut<'a, T, I> {
|
||||||
fn new(iter: slice::Iter<'a, T>) -> Self {
|
fn new(iter: slice::IterMut<'a, T>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
enumerated: iter.enumerate(),
|
enumerated: iter.enumerate(),
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
@ -249,8 +259,8 @@ impl<'a, T: 'a, I: MapIndex> IterMut<'a, T, I> {
|
|||||||
impl<'a, T: 'a, I: MapIndex> Iterator for IterMut<'a, T, I> {
|
impl<'a, T: 'a, I: MapIndex> Iterator for IterMut<'a, T, I> {
|
||||||
type Item = (I, &'a mut T);
|
type Item = (I, &'a mut T);
|
||||||
|
|
||||||
fn next(&mut self) -> Self::Item {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
self.enumerated.next().map(|i, v| (I::new(i), v))
|
self.enumerated.next().map(|(i, v)| (I::new(i), v))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +278,7 @@ macro_rules! define_map_index {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
($($ty:ident),*) => {
|
($($ty:ident,)*) => {
|
||||||
$(
|
$(
|
||||||
define_map_index!($ty);
|
define_map_index!($ty);
|
||||||
)*
|
)*
|
||||||
@ -277,5 +287,5 @@ macro_rules! define_map_index {
|
|||||||
|
|
||||||
define_map_index![
|
define_map_index![
|
||||||
FuncIndex, MemoryIndex, GlobalIndex, TableIndex,
|
FuncIndex, MemoryIndex, GlobalIndex, TableIndex,
|
||||||
SignatureIndex,
|
SigIndex,
|
||||||
];
|
];
|
@ -1,15 +1,16 @@
|
|||||||
use std::{ptr, mem};
|
use std::{ptr, mem};
|
||||||
use crate::runtime::{
|
use crate::runtime::{
|
||||||
types::{
|
// types::{
|
||||||
MemoryIndex, TableIndex, GlobalIndex, FuncIndex,
|
// MemoryIndex, TableIndex, GlobalIndex, FuncIndex,
|
||||||
SignatureIndex,
|
// SigIndex,
|
||||||
},
|
// },
|
||||||
backing::{LocalBacking, ImportBacking},
|
backing::{LocalBacking, ImportBacking},
|
||||||
|
sig_registry::SigRegistry,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Ctx<'a> {
|
pub struct Ctx {
|
||||||
/// A pointer to an array of locally-defined memories, indexed by `MemoryIndex`.
|
/// A pointer to an array of locally-defined memories, indexed by `MemoryIndex`.
|
||||||
pub memories: *mut LocalMemory,
|
pub memories: *mut LocalMemory,
|
||||||
|
|
||||||
@ -32,14 +33,14 @@ pub struct Ctx<'a> {
|
|||||||
pub imported_funcs: *mut ImportedFunc,
|
pub imported_funcs: *mut ImportedFunc,
|
||||||
|
|
||||||
/// Signature identifiers for signature-checked indirect calls.
|
/// Signature identifiers for signature-checked indirect calls.
|
||||||
pub sig_ids: *mut SigId,
|
pub signatures: *const SigId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ctx {
|
impl Ctx {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
local_backing: &mut LocalBacking,
|
local_backing: &mut LocalBacking,
|
||||||
import_backing: &mut ImportBacking,
|
import_backing: &mut ImportBacking,
|
||||||
sig_ids: *mut SigId,
|
sig_registry: &SigRegistry,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
memories: local_backing.vm_memories.as_mut_ptr(),
|
memories: local_backing.vm_memories.as_mut_ptr(),
|
||||||
@ -48,9 +49,10 @@ impl Ctx {
|
|||||||
|
|
||||||
imported_memories: import_backing.memories.as_mut_ptr(),
|
imported_memories: import_backing.memories.as_mut_ptr(),
|
||||||
imported_tables: import_backing.tables.as_mut_ptr(),
|
imported_tables: import_backing.tables.as_mut_ptr(),
|
||||||
|
imported_globals: import_backing.globals.as_mut_ptr(),
|
||||||
imported_funcs: import_backing.functions.as_mut_ptr(),
|
imported_funcs: import_backing.functions.as_mut_ptr(),
|
||||||
|
|
||||||
sig_ids,
|
signatures: sig_registry.into_vm_signatures(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +84,7 @@ impl Ctx {
|
|||||||
6 * (mem::size_of::<usize>() as u8)
|
6 * (mem::size_of::<usize>() as u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn offset_sig_ids() -> u8 {
|
pub fn offset_signatures() -> u8 {
|
||||||
7 * (mem::size_of::<usize>() as u8)
|
7 * (mem::size_of::<usize>() as u8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,7 +212,7 @@ impl ImportedGlobal {
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct SigId(u32);
|
pub struct SigId(pub u32);
|
||||||
|
|
||||||
/// Caller-checked anyfunc
|
/// Caller-checked anyfunc
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -225,7 +227,6 @@ impl Anyfunc {
|
|||||||
Self {
|
Self {
|
||||||
func_data: ImportedFunc {
|
func_data: ImportedFunc {
|
||||||
func: ptr::null(),
|
func: ptr::null(),
|
||||||
vmctx: ptr::null_mut(),
|
|
||||||
},
|
},
|
||||||
sig_id: SigId(u32::max_value()),
|
sig_id: SigId(u32::max_value()),
|
||||||
}
|
}
|
||||||
@ -235,9 +236,9 @@ impl Anyfunc {
|
|||||||
0 * (mem::size_of::<usize>() as u8)
|
0 * (mem::size_of::<usize>() as u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn offset_vmctx() -> u8 {
|
// pub fn offset_vmctx() -> u8 {
|
||||||
1 * (mem::size_of::<usize>() as u8)
|
// 1 * (mem::size_of::<usize>() as u8)
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn offset_sig_id() -> u8 {
|
pub fn offset_sig_id() -> u8 {
|
||||||
2 * (mem::size_of::<usize>() as u8)
|
2 * (mem::size_of::<usize>() as u8)
|
||||||
@ -296,8 +297,8 @@ mod vm_offset_tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Ctx::offset_sig_ids() as usize,
|
Ctx::offset_signatures() as usize,
|
||||||
offset_of!(Ctx => sig_ids).get_byte_offset(),
|
offset_of!(Ctx => signatures).get_byte_offset(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,10 +385,10 @@ mod vm_offset_tests {
|
|||||||
offset_of!(Anyfunc => func_data: ImportedFunc => func).get_byte_offset(),
|
offset_of!(Anyfunc => func_data: ImportedFunc => func).get_byte_offset(),
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
// assert_eq!(
|
||||||
Anyfunc::offset_vmctx() as usize,
|
// Anyfunc::offset_vmctx() as usize,
|
||||||
offset_of!(Anyfunc => func_data: ImportedFunc => vmctx).get_byte_offset(),
|
// offset_of!(Anyfunc => func_data: ImportedFunc => vmctx).get_byte_offset(),
|
||||||
);
|
// );
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Anyfunc::offset_sig_id() as usize,
|
Anyfunc::offset_sig_id() as usize,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user