mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-22 21:21:33 +00:00
Redesign import namespaces
This commit is contained in:
@ -1,3 +1,4 @@
|
||||
use hashbrown::HashMap;
|
||||
use std::rc::Rc;
|
||||
use wabt::wat2wasm;
|
||||
use wasmer_clif_backend::CraneliftCompiler;
|
||||
@ -15,9 +16,8 @@ fn main() -> Result<(), String> {
|
||||
let wasm_binary = wat2wasm(IMPORT_MODULE.as_bytes()).expect("WAST not valid or malformed");
|
||||
let inner_module = runtime::compile(&wasm_binary, &CraneliftCompiler::new())?;
|
||||
|
||||
let mut imports = Imports::new();
|
||||
imports.register_export(
|
||||
"env",
|
||||
let mut env_namespace = HashMap::new();
|
||||
env_namespace.insert(
|
||||
"print_i32",
|
||||
Export::Function {
|
||||
func: unsafe { FuncRef::new(print_num as _) },
|
||||
@ -28,13 +28,15 @@ fn main() -> Result<(), String> {
|
||||
},
|
||||
},
|
||||
);
|
||||
let mut imports = Imports::new();
|
||||
imports.register("env", env_namespace);
|
||||
|
||||
let imports = Rc::new(imports);
|
||||
|
||||
let inner_instance = inner_module.instantiate(imports)?;
|
||||
|
||||
let mut outer_imports = Imports::new();
|
||||
outer_imports.register_instance("env", inner_instance);
|
||||
outer_imports.register("env", inner_instance);
|
||||
let outer_imports = Rc::new(outer_imports);
|
||||
let outer_module = runtime::compile(EXAMPLE_WASM, &CraneliftCompiler::new())?;
|
||||
let mut outer_instance = outer_module.instantiate(outer_imports)?;
|
||||
@ -57,15 +59,3 @@ static IMPORT_MODULE: &str = r#"
|
||||
get_local $p0
|
||||
call $print_i32))
|
||||
"#;
|
||||
|
||||
fn generate_imports() -> Rc<Imports> {
|
||||
let wasm_binary = wat2wasm(IMPORT_MODULE.as_bytes()).expect("WAST not valid or malformed");
|
||||
let module = wasmer_runtime::compile(&wasm_binary[..], &CraneliftCompiler::new())
|
||||
.expect("WASM can't be compiled");
|
||||
let instance = module
|
||||
.instantiate(Rc::new(Imports::new()))
|
||||
.expect("WASM can't be instantiated");
|
||||
let mut imports = Imports::new();
|
||||
imports.register_instance("env", instance);
|
||||
Rc::new(imports)
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ fn generate_imports() -> Rc<Imports> {
|
||||
// let module = wasmer_runtime::compile(&wasm_binary[..], &CraneliftCompiler::new()).expect("WASM can't be compiled");
|
||||
// let instance = module.instantiate(Rc::new(Imports::new())).expect("WASM can't be instantiated");
|
||||
let imports = Imports::new();
|
||||
// imports.register_instance("spectest", instance);
|
||||
// imports.register("spectest", instance);
|
||||
Rc::new(imports)
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ use crate::{
|
||||
vm,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Context {
|
||||
External(*mut vm::Ctx),
|
||||
Internal,
|
||||
|
@ -1,17 +1,27 @@
|
||||
use crate::{export::Export, Instance};
|
||||
use crate::export::Export;
|
||||
use hashbrown::{hash_map::Entry, HashMap};
|
||||
|
||||
pub trait ImportResolver {
|
||||
fn get(&self, namespace: &str, name: &str) -> Option<Export>;
|
||||
}
|
||||
|
||||
enum Namespace {
|
||||
Instance(Box<Instance>),
|
||||
UserSupplied(HashMap<String, Export>),
|
||||
pub trait Namespace {
|
||||
fn get_export(&self, name: &str) -> Option<Export>;
|
||||
}
|
||||
|
||||
impl Namespace for HashMap<String, Export> {
|
||||
fn get_export(&self, name: &str) -> Option<Export> {
|
||||
self.get(name).cloned()
|
||||
}
|
||||
}
|
||||
impl<'a> Namespace for HashMap<&'a str, Export> {
|
||||
fn get_export(&self, name: &str) -> Option<Export> {
|
||||
self.get(name).cloned()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Imports {
|
||||
map: HashMap<String, Namespace>,
|
||||
map: HashMap<String, Box<dyn Namespace>>,
|
||||
}
|
||||
|
||||
impl Imports {
|
||||
@ -21,38 +31,50 @@ impl Imports {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn register_instance(&mut self, namespace: impl Into<String>, instance: Box<Instance>) {
|
||||
match self.map.entry(namespace.into()) {
|
||||
Entry::Vacant(empty) => empty.insert(Namespace::Instance(instance)),
|
||||
Entry::Occupied(_) => {
|
||||
panic!("cannot register an instance in a namespace that already exists")
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn register_export(
|
||||
pub fn register(
|
||||
&mut self,
|
||||
namespace: impl Into<String>,
|
||||
name: impl Into<String>,
|
||||
export: Export,
|
||||
) {
|
||||
let namespace_item = self
|
||||
.map
|
||||
.entry(namespace.into())
|
||||
.or_insert_with(|| Namespace::UserSupplied(HashMap::new()));
|
||||
|
||||
match namespace_item {
|
||||
Namespace::UserSupplied(ref mut map) => map.insert(name.into(), export),
|
||||
Namespace::Instance(_) => panic!("cannot register an export in a namespace that has already been used to register an instance"),
|
||||
};
|
||||
namespace: impl Namespace + 'static,
|
||||
) -> Option<Box<dyn Namespace>> {
|
||||
match self.map.entry(name.into()) {
|
||||
Entry::Vacant(empty) => {
|
||||
empty.insert(Box::new(namespace));
|
||||
None
|
||||
}
|
||||
Entry::Occupied(mut occupied) => Some(occupied.insert(Box::new(namespace))),
|
||||
}
|
||||
}
|
||||
|
||||
// pub fn register_instance(&mut self, namespace: impl Into<String>, instance: Box<Instance>) {
|
||||
// match self.map.entry(namespace.into()) {
|
||||
// Entry::Vacant(empty) => empty.insert(Namespace::Instance(instance)),
|
||||
// Entry::Occupied(_) => {
|
||||
// panic!("cannot register an instance in a namespace that already exists")
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
|
||||
// pub fn register_export(
|
||||
// &mut self,
|
||||
// namespace: impl Into<String>,
|
||||
// name: impl Into<String>,
|
||||
// export: Export,
|
||||
// ) {
|
||||
// let namespace_item = self
|
||||
// .map
|
||||
// .entry(namespace.into())
|
||||
// .or_insert_with(|| Namespace::UserSupplied(HashMap::new()));
|
||||
|
||||
// match namespace_item {
|
||||
// Namespace::UserSupplied(ref mut map) => map.insert(name.into(), export),
|
||||
// Namespace::Instance(_) => panic!("cannot register an export in a namespace that has already been used to register an instance"),
|
||||
// };
|
||||
// }
|
||||
}
|
||||
|
||||
impl ImportResolver for Imports {
|
||||
fn get(&self, namespace: &str, name: &str) -> Option<Export> {
|
||||
match self.map.get(namespace)? {
|
||||
Namespace::UserSupplied(map) => map.get(name).cloned(),
|
||||
Namespace::Instance(instance) => instance.get_export(name).ok(),
|
||||
}
|
||||
fn get(&self, namespace_name: &str, name: &str) -> Option<Export> {
|
||||
let namespace = self.map.get(namespace_name)?;
|
||||
namespace.get_export(name)
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use crate::recovery::call_protected;
|
||||
use crate::{
|
||||
backing::{ImportBacking, LocalBacking},
|
||||
export::{Context, Export},
|
||||
import::ImportResolver,
|
||||
import::{ImportResolver, Namespace},
|
||||
module::{ExportIndex, Module},
|
||||
types::{FuncIndex, FuncSig, MapIndex, Memory, MemoryIndex, Type, Value},
|
||||
vm,
|
||||
@ -130,16 +130,6 @@ impl Instance {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_export(&self, name: &str) -> Result<Export, String> {
|
||||
let export_index = self
|
||||
.module
|
||||
.exports
|
||||
.get(name)
|
||||
.ok_or_else(|| format!("there is no export with that name: {}", name))?;
|
||||
|
||||
Ok(self.get_export_from_index(export_index))
|
||||
}
|
||||
|
||||
pub fn exports(&self) -> ExportIter {
|
||||
ExportIter::new(self)
|
||||
}
|
||||
@ -238,6 +228,14 @@ impl Instance {
|
||||
}
|
||||
}
|
||||
|
||||
impl Namespace for Box<Instance> {
|
||||
fn get_export(&self, name: &str) -> Option<Export> {
|
||||
let export_index = self.module.exports.get(name)?;
|
||||
|
||||
Some(self.get_export_from_index(export_index))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FuncRef(*const vm::Func);
|
||||
|
||||
|
@ -22,7 +22,7 @@ pub fn generate_imports() -> Rc<Imports> {
|
||||
.instantiate(Rc::new(Imports::new()))
|
||||
.expect("WASM can't be instantiated");
|
||||
let mut imports = Imports::new();
|
||||
imports.register_instance("spectest", instance);
|
||||
imports.register("spectest", instance);
|
||||
Rc::new(imports)
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user