Merge branch 'master' into fix/emscripten-translate

This commit is contained in:
Brandon Fish
2019-01-29 23:07:32 -06:00
46 changed files with 2510 additions and 1514 deletions

View File

@ -2,24 +2,29 @@ use crate::{
backend::Token,
backing::{ImportBacking, LocalBacking},
error::{CallError, CallResult, ResolveError, ResolveResult, Result},
export::{
Context, Export, ExportIter, FuncPointer, GlobalPointer, MemoryPointer, TablePointer,
},
export::{Context, Export, ExportIter, FuncPointer},
global::Global,
import::{ImportObject, LikeNamespace},
memory::Memory,
module::{ExportIndex, Module, ModuleInner},
types::{
FuncIndex, FuncSig, GlobalDesc, GlobalIndex, LocalOrImport, Memory, MemoryIndex, Table,
TableIndex, Value,
},
table::Table,
types::{FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, TableIndex, Value},
vm,
};
use std::{mem, rc::Rc};
use std::{mem, sync::Arc};
pub(crate) struct InstanceInner {
#[allow(dead_code)]
pub(crate) backing: LocalBacking,
import_backing: ImportBacking,
vmctx: Box<vm::Ctx>,
pub(crate) vmctx: *mut vm::Ctx,
}
impl Drop for InstanceInner {
fn drop(&mut self) {
// Drop the vmctx.
unsafe { Box::from_raw(self.vmctx) };
}
}
/// An instantiated WebAssembly module.
@ -30,14 +35,17 @@ pub(crate) struct InstanceInner {
///
/// [`ImportObject`]: struct.ImportObject.html
pub struct Instance {
module: Rc<ModuleInner>,
module: Arc<ModuleInner>,
inner: Box<InstanceInner>,
#[allow(dead_code)]
imports: Box<ImportObject>,
}
impl Instance {
pub(crate) fn new(module: Rc<ModuleInner>, mut imports: Box<ImportObject>) -> Result<Instance> {
pub(crate) fn new(
module: Arc<ModuleInner>,
mut imports: Box<ImportObject>,
) -> Result<Instance> {
// 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.
@ -50,15 +58,16 @@ impl Instance {
let mut inner = Box::new(InstanceInner {
backing,
import_backing,
vmctx,
vmctx: Box::leak(vmctx),
});
// Initialize the vm::Ctx in-place after the backing
// has been boxed.
*inner.vmctx =
unsafe { vm::Ctx::new(&mut inner.backing, &mut inner.import_backing, &module) };
unsafe {
*inner.vmctx = vm::Ctx::new(&mut inner.backing, &mut inner.import_backing, &module)
};
let mut instance = Instance {
let instance = Instance {
module,
inner,
imports,
@ -85,7 +94,7 @@ impl Instance {
/// # Ok(())
/// # }
/// ```
pub fn func(&mut self, name: &str) -> ResolveResult<Function> {
pub fn func(&self, name: &str) -> ResolveResult<Function> {
let export_index =
self.module
.exports
@ -100,12 +109,12 @@ impl Instance {
.func_assoc
.get(*func_index)
.expect("broken invariant, incorrect func index");
let signature = self.module.sig_registry.lookup_func_sig(sig_index);
let signature = self.module.sig_registry.lookup_signature(sig_index);
Ok(Function {
signature,
module: &self.module,
instance_inner: &mut self.inner,
instance_inner: &self.inner,
func_index: *func_index,
})
} else {
@ -138,7 +147,7 @@ impl Instance {
/// # Ok(())
/// # }
/// ```
pub fn call(&mut self, name: &str, args: &[Value]) -> CallResult<Vec<Value>> {
pub fn call(&self, name: &str, args: &[Value]) -> CallResult<Vec<Value>> {
let export_index =
self.module
.exports
@ -164,7 +173,7 @@ impl Instance {
///
/// [`Ctx`]: struct.Ctx.html
pub fn context(&self) -> &vm::Ctx {
&self.inner.vmctx
unsafe { &*self.inner.vmctx }
}
/// Returns a mutable reference to the
@ -172,7 +181,7 @@ impl Instance {
///
/// [`Ctx`]: struct.Ctx.html
pub fn context_mut(&mut self) -> &mut vm::Ctx {
&mut self.inner.vmctx
unsafe { &mut *self.inner.vmctx }
}
/// Returns a iterator over all of the items
@ -183,7 +192,7 @@ impl Instance {
/// The module used to instantiate this Instance.
pub fn module(&self) -> Module {
Module::new(Rc::clone(&self.module))
Module::new(Arc::clone(&self.module))
}
pub fn ctx(&mut self) -> &mut vm::Ctx {
@ -192,15 +201,15 @@ impl Instance {
}
impl Instance {
fn call_with_index(&mut self, func_index: FuncIndex, args: &[Value]) -> CallResult<Vec<Value>> {
fn call_with_index(&self, func_index: FuncIndex, args: &[Value]) -> CallResult<Vec<Value>> {
let sig_index = *self
.module
.func_assoc
.get(func_index)
.expect("broken invariant, incorrect func index");
let signature = self.module.sig_registry.lookup_func_sig(sig_index);
let signature = self.module.sig_registry.lookup_signature(sig_index);
if !signature.check_sig(args) {
if !signature.check_param_value_types(args) {
Err(ResolveError::Signature {
expected: signature.clone(),
found: args.iter().map(|val| val.ty()).collect(),
@ -208,9 +217,9 @@ impl Instance {
}
let vmctx = match func_index.local_or_import(&self.module) {
LocalOrImport::Local(_) => &mut *self.inner.vmctx,
LocalOrImport::Local(_) => self.inner.vmctx,
LocalOrImport::Import(imported_func_index) => {
self.inner.import_backing.functions[imported_func_index].vmctx
self.inner.import_backing.vm_functions[imported_func_index].vmctx
}
};
@ -231,7 +240,7 @@ impl Instance {
impl InstanceInner {
pub(crate) fn get_export_from_index(
&mut self,
&self,
module: &ModuleInner,
export_index: &ExportIndex,
) -> Export {
@ -242,46 +251,32 @@ impl InstanceInner {
Export::Function {
func,
ctx: match ctx {
Context::Internal => Context::External(&mut *self.vmctx),
Context::Internal => Context::External(self.vmctx),
ctx @ Context::External(_) => ctx,
},
signature,
}
}
ExportIndex::Memory(memory_index) => {
let (local, ctx, memory) = self.get_memory_from_index(module, *memory_index);
Export::Memory {
local,
ctx: match ctx {
Context::Internal => Context::External(&mut *self.vmctx),
ctx @ Context::External(_) => ctx,
},
memory,
}
let memory = self.get_memory_from_index(module, *memory_index);
Export::Memory(memory)
}
ExportIndex::Global(global_index) => {
let (local, global) = self.get_global_from_index(module, *global_index);
Export::Global { local, global }
let global = self.get_global_from_index(module, *global_index);
Export::Global(global)
}
ExportIndex::Table(table_index) => {
let (local, ctx, table) = self.get_table_from_index(module, *table_index);
Export::Table {
local,
ctx: match ctx {
Context::Internal => Context::External(&mut *self.vmctx),
ctx @ Context::External(_) => ctx,
},
table,
}
let table = self.get_table_from_index(module, *table_index);
Export::Table(table)
}
}
}
fn get_func_from_index(
&mut self,
&self,
module: &ModuleInner,
func_index: FuncIndex,
) -> (FuncPointer, Context, FuncSig) {
) -> (FuncPointer, Context, Arc<FuncSig>) {
let sig_index = *module
.func_assoc
.get(func_index)
@ -298,7 +293,7 @@ impl InstanceInner {
Context::Internal,
),
LocalOrImport::Import(imported_func_index) => {
let imported_func = &self.import_backing.functions[imported_func_index];
let imported_func = &self.import_backing.vm_functions[imported_func_index];
(
imported_func.func as *const _,
Context::External(imported_func.vmctx),
@ -306,105 +301,38 @@ impl InstanceInner {
}
};
let signature = module.sig_registry.lookup_func_sig(sig_index).clone();
let signature = module.sig_registry.lookup_signature(sig_index);
(unsafe { FuncPointer::new(func_ptr) }, ctx, signature)
}
fn get_memory_from_index(
&mut self,
module: &ModuleInner,
mem_index: MemoryIndex,
) -> (MemoryPointer, Context, Memory) {
fn get_memory_from_index(&self, module: &ModuleInner, mem_index: MemoryIndex) -> Memory {
match mem_index.local_or_import(module) {
LocalOrImport::Local(local_mem_index) => {
let vm_mem = &mut self.backing.vm_memories[local_mem_index];
(
unsafe { MemoryPointer::new(vm_mem) },
Context::Internal,
*module
.memories
.get(local_mem_index)
.expect("broken invariant, memories"),
)
}
LocalOrImport::Local(local_mem_index) => self.backing.memories[local_mem_index].clone(),
LocalOrImport::Import(imported_mem_index) => {
let &(_, mem) = &module
.imported_memories
.get(imported_mem_index)
.expect("missing imported memory index");
let vm::ImportedMemory { memory, vmctx } =
&self.import_backing.memories[imported_mem_index];
(
unsafe { MemoryPointer::new(*memory) },
Context::External(*vmctx),
*mem,
)
self.import_backing.memories[imported_mem_index].clone()
}
}
}
fn get_global_from_index(
&mut self,
module: &ModuleInner,
global_index: GlobalIndex,
) -> (GlobalPointer, GlobalDesc) {
fn get_global_from_index(&self, module: &ModuleInner, global_index: GlobalIndex) -> Global {
match global_index.local_or_import(module) {
LocalOrImport::Local(local_global_index) => {
let vm_global = &mut self.backing.vm_globals[local_global_index];
(
unsafe { GlobalPointer::new(vm_global) },
module
.globals
.get(local_global_index)
.expect("broken invariant, globals")
.desc,
)
self.backing.globals[local_global_index].clone()
}
LocalOrImport::Import(imported_global_index) => {
let &(_, imported_global_desc) = &module
.imported_globals
.get(imported_global_index)
.expect("missing imported global index");
let vm::ImportedGlobal { global } =
&self.import_backing.globals[imported_global_index];
(
unsafe { GlobalPointer::new(*global) },
*imported_global_desc,
)
LocalOrImport::Import(import_global_index) => {
self.import_backing.globals[import_global_index].clone()
}
}
}
fn get_table_from_index(
&mut self,
module: &ModuleInner,
table_index: TableIndex,
) -> (TablePointer, Context, Table) {
fn get_table_from_index(&self, module: &ModuleInner, table_index: TableIndex) -> Table {
match table_index.local_or_import(module) {
LocalOrImport::Local(local_table_index) => {
let vm_table = &mut self.backing.vm_tables[local_table_index];
(
unsafe { TablePointer::new(vm_table) },
Context::Internal,
*module
.tables
.get(local_table_index)
.expect("broken invariant, tables"),
)
self.backing.tables[local_table_index].clone()
}
LocalOrImport::Import(imported_table_index) => {
let &(_, tab) = &module
.imported_tables
.get(imported_table_index)
.expect("missing imported table index");
let vm::ImportedTable { table, vmctx } =
&self.import_backing.tables[imported_table_index];
(
unsafe { TablePointer::new(*table) },
Context::External(*vmctx),
*tab,
)
self.import_backing.tables[imported_table_index].clone()
}
}
}
@ -420,9 +348,9 @@ impl LikeNamespace for Instance {
/// A representation of an exported WebAssembly function.
pub struct Function<'a> {
signature: &'a FuncSig,
pub(crate) signature: Arc<FuncSig>,
module: &'a ModuleInner,
instance_inner: &'a mut InstanceInner,
pub(crate) instance_inner: &'a InstanceInner,
func_index: FuncIndex,
}
@ -450,7 +378,7 @@ impl<'a> Function<'a> {
/// # }
/// ```
pub fn call(&mut self, params: &[Value]) -> CallResult<Vec<Value>> {
if !self.signature.check_sig(params) {
if !self.signature.check_param_value_types(params) {
Err(ResolveError::Signature {
expected: self.signature.clone(),
found: params.iter().map(|val| val.ty()).collect(),
@ -458,9 +386,9 @@ impl<'a> Function<'a> {
}
let vmctx = match self.func_index.local_or_import(self.module) {
LocalOrImport::Local(_) => &mut *self.instance_inner.vmctx,
LocalOrImport::Local(_) => self.instance_inner.vmctx,
LocalOrImport::Import(imported_func_index) => {
self.instance_inner.import_backing.functions[imported_func_index].vmctx
self.instance_inner.import_backing.vm_functions[imported_func_index].vmctx
}
};
@ -479,7 +407,7 @@ impl<'a> Function<'a> {
}
pub fn signature(&self) -> &FuncSig {
self.signature
&*self.signature
}
pub fn raw(&self) -> *const vm::Func {
@ -491,7 +419,7 @@ impl<'a> Function<'a> {
.unwrap()
.as_ptr(),
LocalOrImport::Import(import_func_index) => {
self.instance_inner.import_backing.functions[import_func_index].func
self.instance_inner.import_backing.vm_functions[import_func_index].func
}
}
}