Get table imports working

This commit is contained in:
Lachlan Sneff
2019-01-29 10:16:39 -08:00
parent 98305c8731
commit 19242a413f
21 changed files with 859 additions and 595 deletions

View File

@ -2,14 +2,13 @@ use crate::{
backend::Token,
backing::{ImportBacking, LocalBacking},
error::{CallError, CallResult, ResolveError, ResolveResult, Result},
export::{Context, Export, ExportIter, FuncPointer, TablePointer},
export::{Context, Export, ExportIter, FuncPointer},
global::Global,
import::{ImportObject, LikeNamespace},
memory::Memory,
module::{ExportIndex, Module, ModuleInner},
types::{
FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, TableDesc, TableIndex, Value,
},
table::Table,
types::{FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, TableIndex, Value},
vm,
};
use std::{mem, sync::Arc};
@ -18,7 +17,14 @@ 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.
@ -52,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,
@ -87,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
@ -102,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 {
@ -140,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
@ -166,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
@ -174,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
@ -190,15 +197,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(),
@ -206,7 +213,7 @@ 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.vm_functions[imported_func_index].vmctx
}
@ -229,7 +236,7 @@ impl Instance {
impl InstanceInner {
pub(crate) fn get_export_from_index(
&mut self,
&self,
module: &ModuleInner,
export_index: &ExportIndex,
) -> Export {
@ -240,7 +247,7 @@ 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,
@ -255,24 +262,17 @@ impl InstanceInner {
Export::Global(global)
}
ExportIndex::Table(table_index) => {
let (local, ctx, desc) = 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,
},
desc,
}
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)
@ -297,12 +297,12 @@ 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) -> 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) => self.backing.memories[local_mem_index].clone(),
LocalOrImport::Import(imported_mem_index) => {
@ -311,7 +311,7 @@ impl InstanceInner {
}
}
fn get_global_from_index(&mut self, module: &ModuleInner, global_index: GlobalIndex) -> Global {
fn get_global_from_index(&self, module: &ModuleInner, global_index: GlobalIndex) -> Global {
match global_index.local_or_import(module) {
LocalOrImport::Local(local_global_index) => {
self.backing.globals[local_global_index].clone()
@ -322,35 +322,13 @@ impl InstanceInner {
}
}
fn get_table_from_index(
&mut self,
module: &ModuleInner,
table_index: TableIndex,
) -> (TablePointer, Context, TableDesc) {
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 &(_, desc) = &module
.imported_tables
.get(imported_table_index)
.expect("missing imported table index");
let vm::ImportedTable { table, vmctx } =
&self.import_backing.vm_tables[imported_table_index];
(
unsafe { TablePointer::new(*table) },
Context::External(*vmctx),
*desc,
)
self.import_backing.tables[imported_table_index].clone()
}
}
}
@ -366,9 +344,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,
}
@ -396,7 +374,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(),
@ -404,7 +382,7 @@ 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.vm_functions[imported_func_index].vmctx
}
@ -425,7 +403,7 @@ impl<'a> Function<'a> {
}
pub fn signature(&self) -> &FuncSig {
self.signature
&*self.signature
}
pub fn raw(&self) -> *const vm::Func {