mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-16 18:31:23 +00:00
Rearrange some apis
This commit is contained in:
@ -205,7 +205,7 @@ fn import_memories(
|
||||
}) => {
|
||||
if expected_memory_desc.fits_in_imported(&memory_desc) {
|
||||
memories.push(vm::ImportedMemory {
|
||||
memory: local,
|
||||
memory: local.inner(),
|
||||
vmctx: match ctx {
|
||||
Context::External(ctx) => ctx,
|
||||
Context::Internal => vmctx,
|
||||
@ -284,7 +284,7 @@ fn import_globals(
|
||||
match import {
|
||||
Some(Export::Global { local, global }) => {
|
||||
if &global == global_desc {
|
||||
globals.push(vm::ImportedGlobal { global: local });
|
||||
globals.push(vm::ImportedGlobal { global: local.inner() });
|
||||
} else {
|
||||
return Err(format!(
|
||||
"unexpected global description for {:?}:{:?}",
|
||||
|
@ -1,8 +1,10 @@
|
||||
use crate::{
|
||||
instance::FuncRef,
|
||||
types::{FuncSig, GlobalDesc, Memory, Table},
|
||||
module::ExportIndex,
|
||||
vm,
|
||||
Instance,
|
||||
};
|
||||
use hashbrown::hash_map;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Context {
|
||||
@ -13,22 +15,111 @@ pub enum Context {
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Export {
|
||||
Function {
|
||||
func: FuncRef,
|
||||
func: FuncPointer,
|
||||
ctx: Context,
|
||||
signature: FuncSig,
|
||||
},
|
||||
Memory {
|
||||
local: *mut vm::LocalMemory,
|
||||
local: MemoryPointer,
|
||||
ctx: Context,
|
||||
memory: Memory,
|
||||
},
|
||||
Table {
|
||||
local: *mut vm::LocalTable,
|
||||
local: TablePointer,
|
||||
ctx: Context,
|
||||
table: Table,
|
||||
},
|
||||
Global {
|
||||
local: *mut vm::LocalGlobal,
|
||||
local: GlobalPointer,
|
||||
global: GlobalDesc,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FuncPointer(*const vm::Func);
|
||||
|
||||
impl FuncPointer {
|
||||
/// This needs to be unsafe because there is
|
||||
/// no way to check whether the passed function
|
||||
/// is valid and has the right signature.
|
||||
pub unsafe fn new(f: *const vm::Func) -> Self {
|
||||
FuncPointer(f)
|
||||
}
|
||||
|
||||
pub(crate) fn inner(&self) -> *const vm::Func {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MemoryPointer(*mut vm::LocalMemory);
|
||||
|
||||
impl MemoryPointer {
|
||||
/// This needs to be unsafe because there is
|
||||
/// no way to check whether the passed function
|
||||
/// is valid and has the right signature.
|
||||
pub unsafe fn new(f: *mut vm::LocalMemory) -> Self {
|
||||
MemoryPointer(f)
|
||||
}
|
||||
|
||||
pub(crate) fn inner(&self) -> *mut vm::LocalMemory {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TablePointer(*mut vm::LocalTable);
|
||||
|
||||
impl TablePointer {
|
||||
/// This needs to be unsafe because there is
|
||||
/// no way to check whether the passed function
|
||||
/// is valid and has the right signature.
|
||||
pub unsafe fn new(f: *mut vm::LocalTable) -> Self {
|
||||
TablePointer(f)
|
||||
}
|
||||
|
||||
pub(crate) fn inner(&self) -> *mut vm::LocalTable {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GlobalPointer(*mut vm::LocalGlobal);
|
||||
|
||||
impl GlobalPointer {
|
||||
/// This needs to be unsafe because there is
|
||||
/// no way to check whether the passed function
|
||||
/// is valid and has the right signature.
|
||||
pub unsafe fn new(f: *mut vm::LocalGlobal) -> Self {
|
||||
GlobalPointer(f)
|
||||
}
|
||||
|
||||
pub(crate) fn inner(&self) -> *mut vm::LocalGlobal {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ExportIter<'a> {
|
||||
instance: &'a Instance,
|
||||
iter: hash_map::Iter<'a, String, ExportIndex>,
|
||||
}
|
||||
|
||||
impl<'a> ExportIter<'a> {
|
||||
pub(crate) fn new(instance: &'a Instance) -> Self {
|
||||
Self {
|
||||
instance,
|
||||
iter: instance.module.exports.iter(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for ExportIter<'a> {
|
||||
type Item = (String, Export);
|
||||
fn next(&mut self) -> Option<(String, Export)> {
|
||||
let (name, export_index) = self.iter.next()?;
|
||||
Some((
|
||||
name.clone(),
|
||||
self.instance.get_export_from_index(export_index),
|
||||
))
|
||||
}
|
||||
}
|
@ -1,19 +1,17 @@
|
||||
use crate::recovery::call_protected;
|
||||
use crate::{
|
||||
backing::{ImportBacking, LocalBacking},
|
||||
export::{Context, Export},
|
||||
export::{Context, Export, ExportIter, FuncPointer, MemoryPointer},
|
||||
import::{ImportResolver, Namespace},
|
||||
module::{ExportIndex, Module},
|
||||
types::{FuncIndex, FuncSig, MapIndex, Memory, MemoryIndex, Type, Value},
|
||||
vm,
|
||||
};
|
||||
use hashbrown::hash_map;
|
||||
use libffi::high::{arg as libffi_arg, call as libffi_call, CodePtr};
|
||||
use std::rc::Rc;
|
||||
use std::{iter, mem};
|
||||
|
||||
pub struct Instance {
|
||||
pub module: Module,
|
||||
struct InstanceInner {
|
||||
#[allow(dead_code)]
|
||||
pub(crate) backing: LocalBacking,
|
||||
#[allow(dead_code)]
|
||||
@ -22,11 +20,16 @@ pub struct Instance {
|
||||
vmctx: Box<vm::Ctx>,
|
||||
}
|
||||
|
||||
pub struct Instance {
|
||||
pub module: Module,
|
||||
inner: Box<InstanceInner>,
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
pub(crate) fn new(
|
||||
module: Module,
|
||||
imports: Rc<dyn ImportResolver>,
|
||||
) -> Result<Box<Instance>, String> {
|
||||
) -> Result<Instance, String> {
|
||||
// We need the backing and import_backing to create a vm::Ctx, but we need
|
||||
// a vm::Ctx to create a backing and an import_backing. The solution is to create an
|
||||
// uninitialized vm::Ctx and then initialize it in-place.
|
||||
@ -36,8 +39,7 @@ impl Instance {
|
||||
let backing = LocalBacking::new(&module, &import_backing, &mut *vmctx);
|
||||
|
||||
// When Pin is stablized, this will use `Box::pinned` instead of `Box::new`.
|
||||
let mut instance = Box::new(Instance {
|
||||
module,
|
||||
let mut inner = Box::new(InstanceInner {
|
||||
backing,
|
||||
imports,
|
||||
import_backing,
|
||||
@ -46,7 +48,12 @@ impl Instance {
|
||||
|
||||
// Initialize the vm::Ctx in-place after the import_backing
|
||||
// has been boxed.
|
||||
*instance.vmctx = vm::Ctx::new(&mut instance.backing, &mut instance.import_backing);
|
||||
*inner.vmctx = vm::Ctx::new(&mut inner.backing, &mut inner.import_backing);
|
||||
|
||||
let mut instance = Instance {
|
||||
module,
|
||||
inner,
|
||||
};
|
||||
|
||||
if let Some(start_index) = instance.module.start_func {
|
||||
instance.call_with_index(start_index, &[])?;
|
||||
@ -77,6 +84,12 @@ impl Instance {
|
||||
self.call_with_index(func_index, args)
|
||||
}
|
||||
|
||||
pub fn exports(&self) -> ExportIter {
|
||||
ExportIter::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
fn call_with_index(
|
||||
&mut self,
|
||||
func_index: FuncIndex,
|
||||
@ -87,7 +100,7 @@ impl Instance {
|
||||
let func_ptr = CodePtr::from_ptr(func_ref.inner() as _);
|
||||
let vmctx_ptr = match ctx {
|
||||
Context::External(vmctx) => vmctx,
|
||||
Context::Internal => &mut *self.vmctx,
|
||||
Context::Internal => &mut *self.inner.vmctx,
|
||||
};
|
||||
|
||||
assert!(
|
||||
@ -130,11 +143,7 @@ impl Instance {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn exports(&self) -> ExportIter {
|
||||
ExportIter::new(self)
|
||||
}
|
||||
|
||||
fn get_export_from_index(&self, export_index: &ExportIndex) -> Export {
|
||||
pub(crate) fn get_export_from_index(&self, export_index: &ExportIndex) -> Export {
|
||||
match export_index {
|
||||
ExportIndex::Func(func_index) => {
|
||||
let (func, ctx, signature) = self.get_func_from_index(*func_index);
|
||||
@ -143,7 +152,7 @@ impl Instance {
|
||||
func,
|
||||
ctx: match ctx {
|
||||
Context::Internal => {
|
||||
Context::External(&*self.vmctx as *const vm::Ctx as *mut vm::Ctx)
|
||||
Context::External(&*self.inner.vmctx as *const vm::Ctx as *mut vm::Ctx)
|
||||
}
|
||||
ctx @ Context::External(_) => ctx,
|
||||
},
|
||||
@ -156,7 +165,7 @@ impl Instance {
|
||||
local,
|
||||
ctx: match ctx {
|
||||
Context::Internal => {
|
||||
Context::External(&*self.vmctx as *const vm::Ctx as *mut vm::Ctx)
|
||||
Context::External(&*self.inner.vmctx as *const vm::Ctx as *mut vm::Ctx)
|
||||
}
|
||||
ctx @ Context::External(_) => ctx,
|
||||
},
|
||||
@ -168,7 +177,7 @@ impl Instance {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_func_from_index(&self, func_index: FuncIndex) -> (FuncRef, Context, FuncSig) {
|
||||
fn get_func_from_index(&self, func_index: FuncIndex) -> (FuncPointer, Context, FuncSig) {
|
||||
let sig_index = *self
|
||||
.module
|
||||
.func_assoc
|
||||
@ -176,7 +185,7 @@ impl Instance {
|
||||
.expect("broken invariant, incorrect func index");
|
||||
|
||||
let (func_ptr, ctx) = if self.module.is_imported_function(func_index) {
|
||||
let imported_func = &self.import_backing.functions[func_index.index()];
|
||||
let imported_func = &self.inner.import_backing.functions[func_index.index()];
|
||||
(
|
||||
imported_func.func as *const _,
|
||||
Context::External(imported_func.vmctx),
|
||||
@ -195,13 +204,13 @@ impl Instance {
|
||||
|
||||
let signature = self.module.sig_registry.lookup_func_sig(sig_index).clone();
|
||||
|
||||
(FuncRef(func_ptr), ctx, signature)
|
||||
(unsafe { FuncPointer::new(func_ptr) }, ctx, signature)
|
||||
}
|
||||
|
||||
fn get_memory_from_index(
|
||||
&self,
|
||||
mem_index: MemoryIndex,
|
||||
) -> (*mut vm::LocalMemory, Context, Memory) {
|
||||
) -> (MemoryPointer, Context, Memory) {
|
||||
if self.module.is_imported_memory(mem_index) {
|
||||
let &(_, mem) = &self
|
||||
.module
|
||||
@ -209,14 +218,12 @@ impl Instance {
|
||||
.get(mem_index)
|
||||
.expect("missing imported memory index");
|
||||
let vm::ImportedMemory { memory, vmctx } =
|
||||
&self.import_backing.memories[mem_index.index()];
|
||||
(*memory, Context::External(*vmctx), *mem)
|
||||
&self.inner.import_backing.memories[mem_index.index()];
|
||||
(unsafe { MemoryPointer::new(*memory) }, Context::External(*vmctx), *mem)
|
||||
} else {
|
||||
// let vm_mem = .memories[mem_index.index() as usize];
|
||||
let vm_mem =
|
||||
unsafe { &mut (*self.vmctx.local_backing).memories[mem_index.index() as usize] };
|
||||
let vm_mem = &self.inner.backing.memories[mem_index.index() as usize];
|
||||
(
|
||||
&mut vm_mem.into_vm_memory(),
|
||||
unsafe { MemoryPointer::new(&mut vm_mem.into_vm_memory()) },
|
||||
Context::Internal,
|
||||
*self
|
||||
.module
|
||||
@ -228,7 +235,7 @@ impl Instance {
|
||||
}
|
||||
}
|
||||
|
||||
impl Namespace for Box<Instance> {
|
||||
impl Namespace for Instance {
|
||||
fn get_export(&self, name: &str) -> Option<Export> {
|
||||
let export_index = self.module.exports.get(name)?;
|
||||
|
||||
@ -236,47 +243,6 @@ impl Namespace for Box<Instance> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FuncRef(*const vm::Func);
|
||||
|
||||
impl FuncRef {
|
||||
/// This needs to be unsafe because there is
|
||||
/// no way to check whether the passed function
|
||||
/// is valid and has the right signature.
|
||||
pub unsafe fn new(f: *const vm::Func) -> Self {
|
||||
FuncRef(f)
|
||||
}
|
||||
|
||||
pub(crate) fn inner(&self) -> *const vm::Func {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ExportIter<'a> {
|
||||
instance: &'a Instance,
|
||||
iter: hash_map::Iter<'a, String, ExportIndex>,
|
||||
}
|
||||
|
||||
impl<'a> ExportIter<'a> {
|
||||
fn new(instance: &'a Instance) -> Self {
|
||||
Self {
|
||||
instance,
|
||||
iter: instance.module.exports.iter(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for ExportIter<'a> {
|
||||
type Item = (String, Export);
|
||||
fn next(&mut self) -> Option<(String, Export)> {
|
||||
let (name, export_index) = self.iter.next()?;
|
||||
Some((
|
||||
name.clone(),
|
||||
self.instance.get_export_from_index(export_index),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Remove this later, only needed for compilation till emscripten is updated
|
||||
impl Instance {
|
||||
pub fn memory_offset_addr(&self, _index: usize, _offset: usize) -> *const usize {
|
||||
|
@ -4,24 +4,23 @@ extern crate field_offset;
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
pub mod backend;
|
||||
mod backing;
|
||||
pub mod export;
|
||||
pub mod import;
|
||||
mod instance;
|
||||
mod memory;
|
||||
mod mmap;
|
||||
pub mod module;
|
||||
mod recovery;
|
||||
mod sig_registry;
|
||||
mod sighandler;
|
||||
pub mod backend;
|
||||
pub mod export;
|
||||
pub mod import;
|
||||
pub mod module;
|
||||
pub mod memory;
|
||||
pub mod table;
|
||||
pub mod types;
|
||||
pub mod vm;
|
||||
pub mod vmcalls;
|
||||
|
||||
pub use self::instance::{FuncRef, Instance};
|
||||
pub use self::memory::LinearMemory;
|
||||
pub use self::instance::Instance;
|
||||
|
||||
/// Compile a webassembly module using the provided compiler.
|
||||
pub fn compile(wasm: &[u8], compiler: &dyn backend::Compiler) -> Result<module::Module, String> {
|
||||
|
@ -1,4 +1,3 @@
|
||||
#[macro_export]
|
||||
macro_rules! debug {
|
||||
($fmt:expr) => (if cfg!(any(debug_assertions, feature="debug")) { println!(concat!("wasmer-runtime(:{})::", $fmt), line!()) });
|
||||
($fmt:expr, $($arg:tt)*) => (if cfg!(any(debug_assertions, feature="debug")) { println!(concat!("wasmer-runtime(:{})::", $fmt, "\n"), line!(), $($arg)*) });
|
||||
|
@ -8,7 +8,7 @@ use std::ops::{Deref, DerefMut};
|
||||
use crate::{
|
||||
mmap::{Mmap, Protect},
|
||||
types::Memory,
|
||||
vm::LocalMemory,
|
||||
vm,
|
||||
};
|
||||
|
||||
/// A linear memory instance.
|
||||
@ -38,16 +38,16 @@ pub struct LinearMemory {
|
||||
|
||||
/// It holds the raw bytes of memory accessed by a WebAssembly Instance
|
||||
impl LinearMemory {
|
||||
pub const PAGE_SIZE: u32 = 65_536;
|
||||
pub const MAX_PAGES: u32 = 65_536;
|
||||
pub(crate) const PAGE_SIZE: u32 = 65_536;
|
||||
pub(crate) const MAX_PAGES: u32 = 65_536;
|
||||
pub const DEFAULT_HEAP_SIZE: usize = 1 << 32; // 4 GiB
|
||||
pub const DEFAULT_GUARD_SIZE: usize = 1 << 31; // 2 GiB
|
||||
pub const DEFAULT_SIZE: usize = Self::DEFAULT_HEAP_SIZE + Self::DEFAULT_GUARD_SIZE; // 6 GiB
|
||||
pub(crate) const DEFAULT_SIZE: usize = Self::DEFAULT_HEAP_SIZE + Self::DEFAULT_GUARD_SIZE; // 6 GiB
|
||||
|
||||
/// Create a new linear memory instance with specified initial and maximum number of pages.
|
||||
///
|
||||
/// `maximum` cannot be set to more than `65536` pages.
|
||||
pub fn new(mem: &Memory) -> Self {
|
||||
pub(crate) fn new(mem: &Memory) -> Self {
|
||||
assert!(mem.min <= Self::MAX_PAGES);
|
||||
assert!(mem.max.is_none() || mem.max.unwrap() <= Self::MAX_PAGES);
|
||||
debug!("Instantiate LinearMemory(mem: {:?})", mem);
|
||||
@ -92,7 +92,7 @@ impl LinearMemory {
|
||||
}
|
||||
|
||||
/// Returns an base address of this linear memory.
|
||||
fn base(&mut self) -> *mut u8 {
|
||||
fn base(&self) -> *mut u8 {
|
||||
self.mmap.as_ptr()
|
||||
}
|
||||
|
||||
@ -110,8 +110,8 @@ impl LinearMemory {
|
||||
self.max.unwrap_or(Self::MAX_PAGES)
|
||||
}
|
||||
|
||||
pub(crate) fn into_vm_memory(&mut self) -> LocalMemory {
|
||||
LocalMemory {
|
||||
pub(crate) fn into_vm_memory(&self) -> vm::LocalMemory {
|
||||
vm::LocalMemory {
|
||||
base: self.base(),
|
||||
size: self.size(),
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ impl Module {
|
||||
}
|
||||
|
||||
/// Instantiate a webassembly module with the provided imports.
|
||||
pub fn instantiate(&self, imports: Rc<dyn ImportResolver>) -> Result<Box<Instance>, String> {
|
||||
pub fn instantiate(&self, imports: Rc<dyn ImportResolver>) -> Result<Instance, String> {
|
||||
Instance::new(Module(Rc::clone(&self.0)), imports)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user