Add FuncResolver and ImportResolver traits

This commit is contained in:
Lachlan Sneff 2018-12-29 15:23:47 -05:00
parent 8a19b042f8
commit faf41e295c
5 changed files with 31 additions and 43 deletions

View File

@ -1,7 +1,16 @@
use crate::runtime::module::Module;
use crate::runtime::{
module::Module,
types::FuncIndex,
vm,
};
use std::ptr::NonNull;
use std::sync::Arc;
pub trait Compiler {
/// Compiles a `Module` from WebAssembly binary format
fn compile(&self, wasm: &[u8]) -> Result<Arc<Module>, String>;
}
pub trait FuncResolver {
fn get(&self, module: &Module, index: FuncIndex) -> Option<NonNull<vm::Func>>;
}

View File

@ -1,5 +1,5 @@
use crate::runtime::{
instance::{Import, Imports},
instance::{ImportResolver, Import},
memory::LinearMemory,
module::{ImportName, Module},
sig_registry::SigRegistry,
@ -114,7 +114,7 @@ impl LocalBacking {
imports.functions[func_index.index()].clone()
} else {
vm::ImportedFunc {
func: (module.function_resolver)(module, func_index)
func: module.func_resolver.get(module, func_index)
.unwrap()
.as_ptr(),
}
@ -237,7 +237,7 @@ pub struct ImportBacking {
}
impl ImportBacking {
pub fn new(module: &Module, imports: &Imports) -> Result<Self, String> {
pub fn new(module: &Module, imports: &dyn ImportResolver) -> Result<Self, String> {
assert!(
module.imported_memories.len() == 0,
"imported memories not yet supported"
@ -260,9 +260,9 @@ impl ImportBacking {
let expected_sig = &module.signatures[expected_sig_index];
let import = imports.get(mod_name, item_name);
if let Some(Import::Func(func, signature)) = import {
if expected_sig == signature {
if expected_sig == &signature {
functions.push(vm::ImportedFunc {
func: *func,
func: func,
// vmctx: ptr::null_mut(),
});
} else {
@ -294,10 +294,10 @@ impl ImportBacking {
globals.push(vm::ImportedGlobal {
global: vm::LocalGlobal {
data: match val {
Val::I32(n) => *n as u64,
Val::I64(n) => *n as u64,
Val::F32(n) => *n as u64,
Val::F64(n) => *n,
Val::I32(n) => n as u64,
Val::I64(n) => n as u64,
Val::F32(n) => n as u64,
Val::F64(n) => n,
},
},
});

View File

@ -8,7 +8,6 @@ use crate::runtime::{
types::{FuncIndex, FuncSig, Memory, Table, Type, Val},
vm,
};
use hashbrown::HashMap;
use libffi::high::{arg as libffi_arg, call as libffi_call, CodePtr};
use std::iter;
use std::sync::Arc;
@ -21,7 +20,7 @@ pub struct Instance {
}
impl Instance {
pub fn new(module: Arc<Module>, imports: &Imports) -> Result<Box<Instance>, String> {
pub(in crate::runtime) fn new(module: Arc<Module>, imports: &dyn ImportResolver) -> Result<Box<Instance>, String> {
let sig_registry = SigRegistry::new(&*module);
let import_backing = ImportBacking::new(&*module, imports)?;
@ -109,7 +108,7 @@ impl Instance {
.collect();
let func_ptr = CodePtr::from_ptr(
(self.module.function_resolver)(&*self.module, func_index)
self.module.func_resolver.get(&*self.module, func_index)
.expect("broken invariant, func resolver not synced with module.exports")
.cast()
.as_ptr(),
@ -144,25 +143,6 @@ pub enum Import {
Global(Val),
}
pub struct Imports {
map: HashMap<String, HashMap<String, Import>>,
}
impl Imports {
pub fn new() -> Self {
Self {
map: HashMap::new(),
}
}
pub fn add(&mut self, module: String, name: String, import: Import) {
self.map
.entry(module)
.or_insert(HashMap::new())
.insert(name, import);
}
pub fn get(&self, module: &str, name: &str) -> Option<&Import> {
self.map.get(module).and_then(|m| m.get(name))
}
pub trait ImportResolver {
fn get(&self, module: &str, name: &str) -> Option<Import>;
}

View File

@ -9,15 +9,15 @@ pub mod types;
pub mod vm;
pub mod vmcalls;
pub use self::backend::Compiler;
pub use self::instance::{Import, Imports, Instance};
pub use self::backend::{Compiler, FuncResolver};
pub use self::instance::{Import, ImportResolver, Instance};
pub use self::module::Module;
/// Compile a webassembly module using the provided compiler and linked with the provided imports.
pub fn compile(
compiler: &dyn Compiler,
pub fn instantiate(
wasm: &[u8],
imports: &Imports,
compiler: &dyn Compiler,
imports: &dyn ImportResolver,
) -> Result<Box<Instance>, String> {
let module = compiler.compile(wasm)?;
Instance::new(module, imports)

View File

@ -3,14 +3,13 @@ use crate::runtime::{
FuncIndex, FuncSig, Global, GlobalDesc, GlobalIndex, Map, MapIndex, Memory, MemoryIndex,
SigIndex, Table, TableIndex,
},
vm,
backend::FuncResolver,
};
use hashbrown::HashMap;
use std::ptr::NonNull;
/// This is used to instantiate a new webassembly module.
pub struct Module {
pub function_resolver: Box<dyn Fn(&Module, FuncIndex) -> Option<NonNull<vm::Func>>>,
pub func_resolver: Box<dyn FuncResolver>,
pub memories: Map<MemoryIndex, Memory>,
pub globals: Map<GlobalIndex, Global>,
pub tables: Map<TableIndex, Table>,