Add export_func macro, prelude, and rename imports stuff

This commit is contained in:
Lachlan Sneff
2019-01-21 14:43:04 -08:00
parent c25fce1721
commit 10c5aa02a2
13 changed files with 81 additions and 63 deletions

View File

@ -6,7 +6,7 @@ use hashbrown::HashMap;
use std::mem; use std::mem;
use wasmer_runtime::{ use wasmer_runtime::{
export::{Context, Export, FuncPointer, GlobalPointer}, export::{Context, Export, FuncPointer, GlobalPointer},
import::{Imports, NamespaceMap}, import::{ImportObject, NamespaceMap},
memory::LinearMemory, memory::LinearMemory,
types::{ types::{
FuncSig, GlobalDesc, FuncSig, GlobalDesc,
@ -153,8 +153,8 @@ impl<'a> EmscriptenGlobals<'a> {
} }
} }
pub fn generate_emscripten_env(globals: &EmscriptenGlobals) -> Imports { pub fn generate_emscripten_env(globals: &EmscriptenGlobals) -> ImportObject {
let mut imports = Imports::new(); let mut imports = ImportObject::new();
let mut env_namespace = NamespaceMap::new(); let mut env_namespace = NamespaceMap::new();
let mut asm_namespace = NamespaceMap::new(); let mut asm_namespace = NamespaceMap::new();
let mut global_namespace = NamespaceMap::new(); let mut global_namespace = NamespaceMap::new();

View File

@ -78,7 +78,7 @@ static COMMON: &'static str = r##"
use std::{{f32, f64}}; use std::{{f32, f64}};
use wabt::wat2wasm; use wabt::wat2wasm;
use wasmer_clif_backend::CraneliftCompiler; use wasmer_clif_backend::CraneliftCompiler;
use wasmer_runtime::import::Imports; use wasmer_runtime::import::ImportObject;
use wasmer_runtime::types::Value; use wasmer_runtime::types::Value;
use wasmer_runtime::{{Instance, module::Module}}; use wasmer_runtime::{{Instance, module::Module}};
use wasmer_runtime::error::Result; use wasmer_runtime::error::Result;
@ -94,14 +94,14 @@ static IMPORT_MODULE: &str = r#"
(global $global_i32 (export "global_i32") i32 (i32.const 666))) (global $global_i32 (export "global_i32") i32 (i32.const 666)))
"#; "#;
pub fn generate_imports() -> Imports { pub fn generate_imports() -> ImportObject {
let wasm_binary = wat2wasm(IMPORT_MODULE.as_bytes()).expect("WAST not valid or malformed"); let wasm_binary = wat2wasm(IMPORT_MODULE.as_bytes()).expect("WAST not valid or malformed");
let module = wasmer_runtime::compile(&wasm_binary[..], &CraneliftCompiler::new()) let module = wasmer_runtime::compile(&wasm_binary[..], &CraneliftCompiler::new())
.expect("WASM can't be compiled"); .expect("WASM can't be compiled");
let instance = module let instance = module
.instantiate(Imports::new()) .instantiate(ImportObject::new())
.expect("WASM can't be instantiated"); .expect("WASM can't be instantiated");
let mut imports = Imports::new(); let mut imports = ImportObject::new();
imports.register("spectest", instance); imports.register("spectest", instance);
imports imports
} }

View File

@ -1,13 +1,6 @@
use wabt::wat2wasm; use wabt::wat2wasm;
use wasmer_clif_backend::CraneliftCompiler; use wasmer_clif_backend::CraneliftCompiler;
use wasmer_runtime::{ use wasmer_runtime::{self as runtime, error::Result, prelude::*};
self as runtime,
error::Result,
export::{Context, Export, FuncPointer},
import::{Imports, NamespaceMap},
types::{FuncSig, Type, Value},
vm,
};
static EXAMPLE_WASM: &'static [u8] = include_bytes!("simple.wasm"); static EXAMPLE_WASM: &'static [u8] = include_bytes!("simple.wasm");
@ -15,24 +8,20 @@ fn main() -> Result<()> {
let wasm_binary = wat2wasm(IMPORT_MODULE.as_bytes()).expect("WAST not valid or malformed"); let wasm_binary = wat2wasm(IMPORT_MODULE.as_bytes()).expect("WAST not valid or malformed");
let inner_module = runtime::compile(&wasm_binary, &CraneliftCompiler::new())?; let inner_module = runtime::compile(&wasm_binary, &CraneliftCompiler::new())?;
let mut env_namespace = NamespaceMap::new(); let mut env_namespace = Namespace::new();
env_namespace.insert( env_namespace.insert("print_i32", unsafe {
"print_i32", export_func!(
Export::Function { print_num,
func: unsafe { FuncPointer::new(print_num as _) }, [I32] -> [I32]
ctx: Context::Internal, )
signature: FuncSig { });
params: vec![Type::I32],
returns: vec![Type::I32], let mut imports = ImportObject::new();
},
},
);
let mut imports = Imports::new();
imports.register("env", env_namespace); imports.register("env", env_namespace);
let inner_instance = inner_module.instantiate(imports)?; let inner_instance = inner_module.instantiate(imports)?;
let mut outer_imports = Imports::new(); let mut outer_imports = ImportObject::new();
outer_imports.register("env", inner_instance); outer_imports.register("env", inner_instance);
let outer_module = runtime::compile(EXAMPLE_WASM, &CraneliftCompiler::new())?; let outer_module = runtime::compile(EXAMPLE_WASM, &CraneliftCompiler::new())?;

View File

@ -1,6 +1,6 @@
use wabt::wat2wasm; use wabt::wat2wasm;
use wasmer_clif_backend::CraneliftCompiler; use wasmer_clif_backend::CraneliftCompiler;
use wasmer_runtime::{import::Imports, Instance}; use wasmer_runtime::{import::ImportObject, Instance};
fn main() { fn main() {
let mut instance = create_module_1(); let mut instance = create_module_1();
@ -42,14 +42,14 @@ static IMPORT_MODULE: &str = r#"
(global $global_i32 (export "global_i32") i32 (i32.const 666))) (global $global_i32 (export "global_i32") i32 (i32.const 666)))
"#; "#;
pub fn generate_imports() -> Imports { pub fn generate_imports() -> ImportObject {
let wasm_binary = wat2wasm(IMPORT_MODULE.as_bytes()).expect("WAST not valid or malformed"); let wasm_binary = wat2wasm(IMPORT_MODULE.as_bytes()).expect("WAST not valid or malformed");
let module = wasmer_runtime::compile(&wasm_binary[..], &CraneliftCompiler::new()) let module = wasmer_runtime::compile(&wasm_binary[..], &CraneliftCompiler::new())
.expect("WASM can't be compiled"); .expect("WASM can't be compiled");
let instance = module let instance = module
.instantiate(Imports::new()) .instantiate(ImportObject::new())
.expect("WASM can't be instantiated"); .expect("WASM can't be instantiated");
let mut imports = Imports::new(); let mut imports = ImportObject::new();
imports.register("spectest", instance); imports.register("spectest", instance);
imports imports
} }

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
error::{LinkError, LinkResult}, error::{LinkError, LinkResult},
export::{Context, Export}, export::{Context, Export},
import::Imports, import::ImportObject,
memory::LinearMemory, memory::LinearMemory,
module::{ImportName, ModuleInner}, module::{ImportName, ModuleInner},
structures::{BoxedMap, Map, SliceMap, TypedIndex}, structures::{BoxedMap, Map, SliceMap, TypedIndex},
@ -304,7 +304,7 @@ pub struct ImportBacking {
impl ImportBacking { impl ImportBacking {
pub fn new( pub fn new(
module: &ModuleInner, module: &ModuleInner,
imports: &mut Imports, imports: &mut ImportObject,
vmctx: *mut vm::Ctx, vmctx: *mut vm::Ctx,
) -> LinkResult<Self> { ) -> LinkResult<Self> {
let mut failed = false; let mut failed = false;
@ -357,7 +357,7 @@ impl ImportBacking {
fn import_functions( fn import_functions(
module: &ModuleInner, module: &ModuleInner,
imports: &mut Imports, imports: &mut ImportObject,
vmctx: *mut vm::Ctx, vmctx: *mut vm::Ctx,
) -> LinkResult<BoxedMap<ImportedFuncIndex, vm::ImportedFunc>> { ) -> LinkResult<BoxedMap<ImportedFuncIndex, vm::ImportedFunc>> {
let mut link_errors = vec![]; let mut link_errors = vec![];
@ -424,7 +424,7 @@ fn import_functions(
fn import_memories( fn import_memories(
module: &ModuleInner, module: &ModuleInner,
imports: &mut Imports, imports: &mut ImportObject,
vmctx: *mut vm::Ctx, vmctx: *mut vm::Ctx,
) -> LinkResult<BoxedMap<ImportedMemoryIndex, vm::ImportedMemory>> { ) -> LinkResult<BoxedMap<ImportedMemoryIndex, vm::ImportedMemory>> {
let mut link_errors = vec![]; let mut link_errors = vec![];
@ -491,7 +491,7 @@ fn import_memories(
fn import_tables( fn import_tables(
module: &ModuleInner, module: &ModuleInner,
imports: &mut Imports, imports: &mut ImportObject,
vmctx: *mut vm::Ctx, vmctx: *mut vm::Ctx,
) -> LinkResult<BoxedMap<ImportedTableIndex, vm::ImportedTable>> { ) -> LinkResult<BoxedMap<ImportedTableIndex, vm::ImportedTable>> {
let mut link_errors = vec![]; let mut link_errors = vec![];
@ -556,7 +556,7 @@ fn import_tables(
fn import_globals( fn import_globals(
module: &ModuleInner, module: &ModuleInner,
imports: &mut Imports, imports: &mut ImportObject,
) -> LinkResult<BoxedMap<ImportedGlobalIndex, vm::ImportedGlobal>> { ) -> LinkResult<BoxedMap<ImportedGlobalIndex, vm::ImportedGlobal>> {
let mut link_errors = vec![]; let mut link_errors = vec![];
let mut globals = Map::with_capacity(module.imported_globals.len()); let mut globals = Map::with_capacity(module.imported_globals.len());

View File

@ -1,25 +1,25 @@
use crate::export::Export; use crate::export::Export;
use hashbrown::{hash_map::Entry, HashMap}; use hashbrown::{hash_map::Entry, HashMap};
pub trait Namespace { pub trait LikeNamespace {
fn get_export(&mut self, name: &str) -> Option<Export>; fn get_export(&mut self, name: &str) -> Option<Export>;
} }
pub struct Imports { pub struct ImportObject {
map: HashMap<String, Box<dyn Namespace>>, map: HashMap<String, Box<dyn LikeNamespace>>,
} }
impl Imports { impl ImportObject {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
map: HashMap::new(), map: HashMap::new(),
} }
} }
pub fn register<S, N>(&mut self, name: S, namespace: N) -> Option<Box<dyn Namespace>> pub fn register<S, N>(&mut self, name: S, namespace: N) -> Option<Box<dyn LikeNamespace>>
where where
S: Into<String>, S: Into<String>,
N: Namespace + 'static, N: LikeNamespace + 'static,
{ {
match self.map.entry(name.into()) { match self.map.entry(name.into()) {
Entry::Vacant(empty) => { Entry::Vacant(empty) => {
@ -30,18 +30,18 @@ impl Imports {
} }
} }
pub fn get_namespace(&mut self, namespace: &str) -> Option<&mut (dyn Namespace + 'static)> { pub fn get_namespace(&mut self, namespace: &str) -> Option<&mut (dyn LikeNamespace + 'static)> {
self.map self.map
.get_mut(namespace) .get_mut(namespace)
.map(|namespace| &mut **namespace) .map(|namespace| &mut **namespace)
} }
} }
pub struct NamespaceMap { pub struct Namespace {
map: HashMap<String, Export>, map: HashMap<String, Export>,
} }
impl NamespaceMap { impl Namespace {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
map: HashMap::new(), map: HashMap::new(),
@ -53,7 +53,7 @@ impl NamespaceMap {
} }
} }
impl Namespace for NamespaceMap { impl LikeNamespace for Namespace {
fn get_export(&mut self, name: &str) -> Option<Export> { fn get_export(&mut self, name: &str) -> Option<Export> {
self.map.get(name).cloned() self.map.get(name).cloned()
} }

View File

@ -5,7 +5,7 @@ use crate::{
export::{ export::{
Context, Export, ExportIter, FuncPointer, GlobalPointer, MemoryPointer, TablePointer, Context, Export, ExportIter, FuncPointer, GlobalPointer, MemoryPointer, TablePointer,
}, },
import::{Imports, Namespace}, import::{ImportObject, LikeNamespace},
module::{ExportIndex, Module, ModuleInner}, module::{ExportIndex, Module, ModuleInner},
types::{ types::{
FuncIndex, FuncSig, GlobalDesc, GlobalIndex, LocalOrImport, Memory, MemoryIndex, Table, FuncIndex, FuncSig, GlobalDesc, GlobalIndex, LocalOrImport, Memory, MemoryIndex, Table,
@ -28,11 +28,11 @@ pub struct Instance {
pub module: Rc<ModuleInner>, pub module: Rc<ModuleInner>,
inner: Box<InstanceInner>, inner: Box<InstanceInner>,
#[allow(dead_code)] #[allow(dead_code)]
imports: Box<Imports>, imports: Box<ImportObject>,
} }
impl Instance { impl Instance {
pub(crate) fn new(module: Rc<ModuleInner>, mut imports: Box<Imports>) -> Result<Instance> { pub(crate) fn new(module: Rc<ModuleInner>, mut imports: Box<ImportObject>) -> Result<Instance> {
// We need the backing and import_backing to create a vm::Ctx, but we need // 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 // 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. // uninitialized vm::Ctx and then initialize it in-place.
@ -325,7 +325,7 @@ impl InstanceInner {
} }
} }
impl Namespace for Instance { impl LikeNamespace for Instance {
fn get_export(&mut self, name: &str) -> Option<Export> { fn get_export(&mut self, name: &str) -> Option<Export> {
let export_index = self.module.exports.get(name)?; let export_index = self.module.exports.get(name)?;

View File

@ -3,7 +3,7 @@
extern crate field_offset; extern crate field_offset;
#[macro_use] #[macro_use]
pub mod macros; mod macros;
#[doc(hidden)] #[doc(hidden)]
pub mod backend; pub mod backend;
mod backing; mod backing;
@ -29,6 +29,17 @@ pub use self::instance::Instance;
pub use self::module::Module; pub use self::module::Module;
use std::rc::Rc; use std::rc::Rc;
pub mod prelude {
pub use crate::export_func;
pub use crate::import::{ImportObject, Namespace};
pub use crate::types::{
FuncIndex, GlobalIndex, ImportedFuncIndex, ImportedGlobalIndex, ImportedMemoryIndex,
ImportedTableIndex, LocalFuncIndex, LocalGlobalIndex, LocalMemoryIndex, LocalTableIndex,
MemoryIndex, TableIndex, Type, Value,
};
pub use crate::vm;
}
/// Compile a webassembly module using the provided compiler. /// Compile a webassembly module using the provided compiler.
pub fn compile(wasm: &[u8], compiler: &dyn backend::Compiler) -> CompileResult<module::Module> { pub fn compile(wasm: &[u8], compiler: &dyn backend::Compiler) -> CompileResult<module::Module> {
let token = backend::Token::generate(); let token = backend::Token::generate();

View File

@ -1,5 +1,23 @@
#[macro_export]
macro_rules! debug { macro_rules! debug {
($fmt:expr) => (if cfg!(any(debug_assertions, feature="debug")) { println!(concat!("wasmer-runtime(:{})::", $fmt), line!()) }); ($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)*) }); ($fmt:expr, $($arg:tt)*) => (if cfg!(any(debug_assertions, feature="debug")) { println!(concat!("wasmer-runtime(:{})::", $fmt, "\n"), line!(), $($arg)*) });
} }
#[macro_export]
macro_rules! export_func {
($func:ident, [ $( $params:ident ),* ] -> [ $( $returns:ident ),* ]) => {{
use wasmer_runtime::{
export::{Context, Export, FuncPointer},
types::{FuncSig, Type},
};
Export::Function {
func: FuncPointer::new($func as _),
ctx: Context::Internal,
signature: FuncSig {
params: vec![$(Type::$params,)*],
returns: vec![$(Type::$params,)*],
},
}
}};
}

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
backend::{FuncResolver, ProtectedCaller}, backend::{FuncResolver, ProtectedCaller},
error::Result, error::Result,
import::Imports, import::ImportObject,
sig_registry::SigRegistry, sig_registry::SigRegistry,
structures::Map, structures::Map,
types::{ types::{
@ -50,7 +50,7 @@ impl Module {
} }
/// Instantiate a WebAssembly module with the provided imports. /// Instantiate a WebAssembly module with the provided imports.
pub fn instantiate(&self, imports: Imports) -> Result<Instance> { pub fn instantiate(&self, imports: ImportObject) -> Result<Instance> {
Instance::new(Rc::clone(&self.0), Box::new(imports)) Instance::new(Rc::clone(&self.0), Box::new(imports))
} }
} }

View File

@ -4,7 +4,7 @@ mod tests {
use wasmer_clif_backend::CraneliftCompiler; use wasmer_clif_backend::CraneliftCompiler;
use wasmer_runtime::{ use wasmer_runtime::{
error::{CallError, RuntimeError}, error::{CallError, RuntimeError},
import::Imports, import::ImportObject,
}; };
// The semantics of stack overflow are documented at: // The semantics of stack overflow are documented at:
@ -25,7 +25,7 @@ mod tests {
let module = wasmer_runtime::compile(&wasm_binary[..], &CraneliftCompiler::new()) let module = wasmer_runtime::compile(&wasm_binary[..], &CraneliftCompiler::new())
.expect("WASM can't be compiled"); .expect("WASM can't be compiled");
let mut instance = module let mut instance = module
.instantiate(Imports::new()) .instantiate(ImportObject::new())
.expect("WASM can't be instantiated"); .expect("WASM can't be instantiated");
let result = instance.call("stack-overflow", &[]); let result = instance.call("stack-overflow", &[]);

View File

@ -76,7 +76,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
wasmer_emscripten::generate_emscripten_env(&emscripten_globals), wasmer_emscripten::generate_emscripten_env(&emscripten_globals),
) )
} else { } else {
(InstanceABI::None, wasmer_runtime::import::Imports::new()) (InstanceABI::None, wasmer_runtime::import::ImportObject::new())
}; };
let mut instance = module let mut instance = module

View File

@ -4,7 +4,7 @@ use wasmer_clif_backend::CraneliftCompiler;
use wasmer_runtime::{ use wasmer_runtime::{
self as runtime, self as runtime,
error::{CallResult, Result}, error::{CallResult, Result},
import::Imports, import::ImportObject,
instance::Instance, instance::Instance,
module::Module, module::Module,
}; };
@ -41,7 +41,7 @@ pub enum InstanceABI {
/// If the operation fails, the Result rejects with a /// If the operation fails, the Result rejects with a
/// webassembly::CompileError, webassembly::LinkError, or /// webassembly::CompileError, webassembly::LinkError, or
/// webassembly::RuntimeError, depending on the cause of the failure. /// webassembly::RuntimeError, depending on the cause of the failure.
pub fn instantiate(buffer_source: &[u8], import_object: Imports) -> Result<ResultObject> { pub fn instantiate(buffer_source: &[u8], import_object: ImportObject) -> Result<ResultObject> {
debug!("webassembly - compiling module"); debug!("webassembly - compiling module");
let module = compile(&buffer_source[..])?; let module = compile(&buffer_source[..])?;
@ -60,7 +60,7 @@ pub fn instantiate(buffer_source: &[u8], import_object: Imports) -> Result<Resul
/// This is the most efficient, optimized way to load wasm code. /// This is the most efficient, optimized way to load wasm code.
pub fn instantiate_streaming( pub fn instantiate_streaming(
_buffer_source: Vec<u8>, _buffer_source: Vec<u8>,
_import_object: Imports, _import_object: ImportObject,
) -> Result<ResultObject> { ) -> Result<ResultObject> {
unimplemented!(); unimplemented!();
} }