allow several host imports

This commit is contained in:
vms 2020-06-07 12:33:26 +03:00
parent 7d5ae2f9b0
commit fe716cd078
13 changed files with 182 additions and 78 deletions

View File

@ -35,13 +35,15 @@ pub struct FCEWITInterfaces<'a> {
types: Vec<WITAstType>, types: Vec<WITAstType>,
/// All the imported functions. /// All the imported functions.
imports: MultiMap<CoreFunctionType, (ImportName<'a>, ImportNamespace<'a>)>, imports: Vec<Import<'a>>,
core_type_to_imports: MultiMap<CoreFunctionType, (ImportName<'a>, ImportNamespace<'a>)>,
/// All the adapters. /// All the adapters.
adapters: HashMap<AdapterFunctionType, Vec<Instruction>>, adapters: HashMap<AdapterFunctionType, Vec<Instruction>>,
/// All the exported functions. /// All the exported functions.
exports: MultiMap<CoreFunctionType, ExportName<'a>>, exports: Vec<Export<'a>>,
core_type_to_exports: MultiMap<CoreFunctionType, ExportName<'a>>,
/// All the implementations. /// All the implementations.
adapter_type_to_core: MultiMap<AdapterFunctionType, CoreFunctionType>, adapter_type_to_core: MultiMap<AdapterFunctionType, CoreFunctionType>,
@ -50,9 +52,9 @@ pub struct FCEWITInterfaces<'a> {
impl<'a> FCEWITInterfaces<'a> { impl<'a> FCEWITInterfaces<'a> {
pub fn new(interfaces: Interfaces<'a>) -> Self { pub fn new(interfaces: Interfaces<'a>) -> Self {
let imports = interfaces let core_type_to_imports = interfaces
.imports .imports
.into_iter() .iter()
.map(|import| (import.function_type, (import.namespace, import.name))) .map(|import| (import.function_type, (import.namespace, import.name)))
.collect::<MultiMap<_, _>>(); .collect::<MultiMap<_, _>>();
@ -62,9 +64,9 @@ impl<'a> FCEWITInterfaces<'a> {
.map(|adapter| (adapter.function_type, adapter.instructions)) .map(|adapter| (adapter.function_type, adapter.instructions))
.collect::<HashMap<_, _>>(); .collect::<HashMap<_, _>>();
let exports = interfaces let core_type_to_exports = interfaces
.exports .exports
.into_iter() .iter()
.map(|export| (export.function_type, export.name)) .map(|export| (export.function_type, export.name))
.collect::<MultiMap<_, _>>(); .collect::<MultiMap<_, _>>();
@ -92,9 +94,11 @@ impl<'a> FCEWITInterfaces<'a> {
Self { Self {
types: interfaces.types, types: interfaces.types,
imports, imports: interfaces.imports,
core_type_to_imports,
adapters, adapters,
exports, exports: interfaces.exports,
core_type_to_exports,
adapter_type_to_core, adapter_type_to_core,
core_type_to_adapter, core_type_to_adapter,
} }
@ -114,9 +118,7 @@ impl<'a> FCEWITInterfaces<'a> {
.ok_or_else(|| FCEWITInterfacesError::NoSuchType(idx)) .ok_or_else(|| FCEWITInterfacesError::NoSuchType(idx))
} }
pub fn imports( pub fn imports(&self) -> impl Iterator<Item = &Import<'_>> {
&self,
) -> impl Iterator<Item = (&CoreFunctionType, &(ImportName<'a>, ImportNamespace<'a>))> {
self.imports.iter() self.imports.iter()
} }
@ -124,14 +126,14 @@ impl<'a> FCEWITInterfaces<'a> {
&self, &self,
import_type: CoreFunctionType, import_type: CoreFunctionType,
) -> Option<&Vec<(ImportName<'a>, ImportNamespace<'a>)>> { ) -> Option<&Vec<(ImportName<'a>, ImportNamespace<'a>)>> {
self.imports.get_vec(&import_type) self.core_type_to_imports.get_vec(&import_type)
} }
pub fn imports_by_type_r( pub fn imports_by_type_r(
&self, &self,
import_type: CoreFunctionType, import_type: CoreFunctionType,
) -> Result<&Vec<(ImportName<'a>, ImportNamespace<'a>)>, FCEWITInterfacesError> { ) -> Result<&Vec<(ImportName<'a>, ImportNamespace<'a>)>, FCEWITInterfacesError> {
self.imports self.core_type_to_imports
.get_vec(&import_type) .get_vec(&import_type)
.ok_or_else(|| FCEWITInterfacesError::NoSuchImport(import_type)) .ok_or_else(|| FCEWITInterfacesError::NoSuchImport(import_type))
} }
@ -153,19 +155,19 @@ impl<'a> FCEWITInterfaces<'a> {
.ok_or_else(|| FCEWITInterfacesError::NoSuchAdapter(adapter_type)) .ok_or_else(|| FCEWITInterfacesError::NoSuchAdapter(adapter_type))
} }
pub fn exports(&self) -> impl Iterator<Item = (&CoreFunctionType, &ExportName<'a>)> { pub fn exports(&self) -> impl Iterator<Item = &Export<'_>> {
self.exports.iter() self.exports.iter()
} }
pub fn exports_by_type(&self, export_type: u32) -> Option<&Vec<ExportName<'a>>> { pub fn exports_by_type(&self, export_type: u32) -> Option<&Vec<ExportName<'a>>> {
self.exports.get_vec(&export_type) self.core_type_to_exports.get_vec(&export_type)
} }
pub fn exports_by_type_r( pub fn exports_by_type_r(
&self, &self,
export_type: CoreFunctionType, export_type: CoreFunctionType,
) -> Result<&Vec<ExportName<'a>>, FCEWITInterfacesError> { ) -> Result<&Vec<ExportName<'a>>, FCEWITInterfacesError> {
self.exports self.core_type_to_exports
.get_vec(&export_type) .get_vec(&export_type)
.ok_or_else(|| FCEWITInterfacesError::NoSuchImport(export_type)) .ok_or_else(|| FCEWITInterfacesError::NoSuchImport(export_type))
} }

View File

@ -7,7 +7,7 @@ edition = "2018"
[dependencies] [dependencies]
fce = { path = "../../fce" } fce = { path = "../../fce" }
wasmer-core = { package = "wasmer-runtime-core", version = "0.17.0" } wasmer-core = { package = "wasmer-runtime-core", version = "0.17.0", features = ["dynamicfunc-fat-closures"] }
wasmer-runtime = "0.17.0" wasmer-runtime = "0.17.0"
toml = "0.5.6" toml = "0.5.6"

View File

@ -163,10 +163,12 @@ pub(crate) fn parse_config_from_file(
} }
}); });
/*
println!( println!(
"parsed modules config:\n{:?}\nparsed rpc config:\n{:?}", "parsed modules config:\n{:?}\nparsed rpc config:\n{:?}",
modules_config, rpc_module_config modules_config, rpc_module_config
); );
*/
Ok(NodeConfig { Ok(NodeConfig {
modules_config, modules_config,

View File

@ -23,7 +23,7 @@ pub(super) fn log_utf8_string(ctx: &mut Ctx, offset: i32, size: i32) {
let wasm_ptr = WasmPtr::<u8, Array>::new(offset as _); let wasm_ptr = WasmPtr::<u8, Array>::new(offset as _);
match wasm_ptr.get_utf8_string(ctx.memory(0), size as _) { match wasm_ptr.get_utf8_string(ctx.memory(0), size as _) {
Some(msg) => print!("{}", msg), Some(msg) => print!("{}", msg),
None => print!("ipfs node logger: incorrect UTF8 string's been supplied to logger"), None => print!("ipfs node logger: incorrect UTF8 string's been supplied to logger\n"),
} }
} }
@ -32,12 +32,14 @@ pub(super) fn create_host_import_func(host_cmd: String) -> DynamicFunc<'static>
use wasmer_core::types::Type; use wasmer_core::types::Type;
use wasmer_core::types::FuncSig; use wasmer_core::types::FuncSig;
let func = Box::new(move |ctx: &mut Ctx, inputs: &[Value]| -> Vec<Value> { let func = move |ctx: &mut Ctx, inputs: &[Value]| -> Vec<Value> {
use wasmer_core::memory::ptr::{Array, WasmPtr}; use wasmer_core::memory::ptr::{Array, WasmPtr};
println!("inputs size is {}", inputs.len());
// TODO: refactor this // TODO: refactor this
let array_ptr = inputs[0].to_u128() as i32; let array_ptr = inputs[1].to_u128() as i32;
let array_size = inputs[1].to_u128() as i32; let array_size = inputs[0].to_u128() as i32;
println!("ptr is {}, size is {}", array_ptr, array_size);
let wasm_ptr = WasmPtr::<u8, Array>::new(array_ptr as _); let wasm_ptr = WasmPtr::<u8, Array>::new(array_ptr as _);
match wasm_ptr.get_utf8_string(ctx.memory(0), array_size as _) { match wasm_ptr.get_utf8_string(ctx.memory(0), array_size as _) {
@ -45,10 +47,10 @@ pub(super) fn create_host_import_func(host_cmd: String) -> DynamicFunc<'static>
None => print!("ipfs node logger: incorrect UTF8 string's been supplied to logger"), None => print!("ipfs node logger: incorrect UTF8 string's been supplied to logger"),
} }
vec![] vec![]
}); };
DynamicFunc::new( DynamicFunc::new(
std::sync::Arc::new(FuncSig::new(vec![Type::I32, Type::I32], vec![])), std::sync::Arc::new(FuncSig::new(vec![Type::I32, Type::I32], vec![Type::I32])),
func, func,
) )
} }

View File

@ -17,7 +17,7 @@
use super::errors::NodeError; use super::errors::NodeError;
use wasmer_core::import::ImportObject; use wasmer_core::import::ImportObject;
use wasmer_runtime::{imports, func}; use wasmer_runtime::func;
use fce::FCE; use fce::FCE;
use fce::WasmProcess; use fce::WasmProcess;
use fce::NodeFunction; use fce::NodeFunction;
@ -131,6 +131,7 @@ impl IpfsNode {
if let Some(imports) = module_config.imports { if let Some(imports) = module_config.imports {
for (import_name, host_cmd) in imports { for (import_name, host_cmd) in imports {
println!("{} - {}", import_name, host_cmd);
let host_import = create_host_import_func(host_cmd); let host_import = create_host_import_func(host_cmd);
namespace.insert(import_name, host_import); namespace.insert(import_name, host_import);
} }
@ -147,7 +148,7 @@ impl IpfsNode {
if let Some(preopened_files) = wasi.preopened_files { if let Some(preopened_files) = wasi.preopened_files {
wasm_module_config.wasi_preopened_files = preopened_files wasm_module_config.wasi_preopened_files = preopened_files
.iter() .iter()
.map(|file| PathBuf::from(file)) .map(PathBuf::from)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
} }

View File

@ -26,13 +26,19 @@ pub unsafe fn put(file_content_ptr: *mut u8, file_content_size: usize) {
let file_content = let file_content =
String::from_raw_parts(file_content_ptr, file_content_size, file_content_size); String::from_raw_parts(file_content_ptr, file_content_size, file_content_size);
let msg = format!("from Wasm node: file content is {}\n", file_content); let msg = format!(
"from Wasm ipfs_node.get: file content is {}\n",
file_content
);
log_utf8_string(msg.as_ptr() as _, msg.len() as _); log_utf8_string(msg.as_ptr() as _, msg.len() as _);
let cmd = format!("put {}", file_content); let cmd = format!("put {}", file_content);
ipfs(cmd.as_ptr() as _, cmd.len() as _); ipfs(cmd.as_ptr() as _, cmd.len() as _);
let result = "Hello from IPFS node, take your hash".to_string(); let after_ipfs = format!("after ipfs call");
log_utf8_string(after_ipfs.as_ptr() as _, after_ipfs.len() as _);
let result = "IPFS node: hash is asdasdsad".to_string();
*RESULT_PTR.get_mut() = result.as_ptr() as _; *RESULT_PTR.get_mut() = result.as_ptr() as _;
*RESULT_SIZE.get_mut() = result.len(); *RESULT_SIZE.get_mut() = result.len();
@ -43,13 +49,13 @@ pub unsafe fn put(file_content_ptr: *mut u8, file_content_size: usize) {
pub unsafe fn get(hash_ptr: *mut u8, hash_size: usize) { pub unsafe fn get(hash_ptr: *mut u8, hash_size: usize) {
let hash = String::from_raw_parts(hash_ptr, hash_size, hash_size); let hash = String::from_raw_parts(hash_ptr, hash_size, hash_size);
let msg = format!("from Wasm node: file content is {}\n", hash); let msg = format!("from Wasm ipfs_node.get: file hash is {}\n", hash);
log_utf8_string(msg.as_ptr() as _, msg.len() as _); log_utf8_string(msg.as_ptr() as _, msg.len() as _);
let cmd = format!("get {}", hash); let cmd = format!("get {}", hash);
ipfs(cmd.as_ptr() as _, cmd.len() as _); ipfs(cmd.as_ptr() as _, cmd.len() as _);
let result = "Hello from IPFS node, take your file".to_string(); let result = "IPFS node: file is hhhhaaa".to_string();
*RESULT_PTR.get_mut() = result.as_ptr() as _; *RESULT_PTR.get_mut() = result.as_ptr() as _;
*RESULT_SIZE.get_mut() = result.len(); *RESULT_SIZE.get_mut() = result.len();
@ -62,5 +68,5 @@ extern "C" {
fn log_utf8_string(ptr: i32, size: i32); fn log_utf8_string(ptr: i32, size: i32);
/// Put a file to ipfs, returns ipfs hash of the file. /// Put a file to ipfs, returns ipfs hash of the file.
fn ipfs(ptr: i32, size: i32); fn ipfs(ptr: i32, size: i32) -> i32;
} }

View File

@ -22,6 +22,9 @@
;; import ipfs put/get function ;; import ipfs put/get function
(@interface type (func (param string) (result string))) ;; 7 (@interface type (func (param string) (result string))) ;; 7
;; import ipfs put/get function
(@interface type (func (param string) (result string))) ;; 8
(@interface export "allocate" (func 0)) ;; 0 (@interface export "allocate" (func 0)) ;; 0
(@interface export "deallocate" (func 1)) ;; 1 (@interface export "deallocate" (func 1)) ;; 1
(@interface export "get_result_size" (func 3)) ;; 2 (@interface export "get_result_size" (func 3)) ;; 2
@ -30,9 +33,24 @@
(@interface export "set_result_ptr" (func 4)) ;; 5 (@interface export "set_result_ptr" (func 4)) ;; 5
(@interface export "put" (func 5)) ;; 6 (@interface export "put" (func 5)) ;; 6
(@interface export "get" (func 5)) ;; 7 (@interface export "get" (func 6)) ;; 7
(@interface func (type 6) (@interface func (type 7)
arg.get 0
string.size
call-core 0 ;; call allocate
arg.get 0
string.lower_memory
call-core 6 ;; call self.put
call-core 3 ;; call get_result_ptr
call-core 2 ;; call get_result_size
string.lift_memory
call-core 3 ;; call get_result_ptr
call-core 2 ;; call get_result_size
call-core 1 ;; call deallocate
)
(@interface func (type 8)
arg.get 0 arg.get 0
string.size string.size
call-core 0 ;; call allocate call-core 0 ;; call allocate
@ -48,4 +66,5 @@
) )
;; Implementations ;; Implementations
(@interface implement (func 5) (func 6)) (@interface implement (func 5) (func 7))
(@interface implement (func 6) (func 8))

View File

@ -18,7 +18,7 @@
mod mem; mod mem;
mod result; mod result;
// use crate::result::{RESULT_PTR, RESULT_SIZE}; use crate::result::{RESULT_PTR, RESULT_SIZE};
#[no_mangle] #[no_mangle]
pub unsafe fn invoke(file_content_ptr: *mut u8, file_content_size: usize) { pub unsafe fn invoke(file_content_ptr: *mut u8, file_content_size: usize) {
@ -26,19 +26,18 @@ pub unsafe fn invoke(file_content_ptr: *mut u8, file_content_size: usize) {
String::from_raw_parts(file_content_ptr, file_content_size, file_content_size); String::from_raw_parts(file_content_ptr, file_content_size, file_content_size);
let msg = format!("from Wasm rpc: file_content is {}\n", file_content); let msg = format!("from Wasm rpc: file_content is {}\n", file_content);
log_utf8_string(msg.as_ptr() as _, msg.len() as _); log_utf8_string(msg.as_ptr() as _, msg.len() as _);
log_utf8_string(msg.as_ptr() as _, msg.len() as _);
put(file_content_ptr as _, file_content_size as _); put(file_content.as_ptr() as _, file_content.len() as _);
/*
let hash = String::from_raw_parts( let hash = String::from_raw_parts(
*RESULT_PTR.get_mut(), *RESULT_PTR.get_mut() as _,
*RESULT_SIZE.get_mut(), *RESULT_SIZE.get_mut(),
*RESULT_SIZE.get_mut(), *RESULT_SIZE.get_mut(),
); );
let msg = format!("from Wasm rpc: hash is {}\n", hash); let msg = format!("from Wasm rpc: hash is {}\n", hash);
log_utf8_string(msg.as_ptr() as _, msg.len() as _); log_utf8_string(msg.as_ptr() as _, msg.len() as _);
*/
} }
#[link(wasm_import_module = "host")] #[link(wasm_import_module = "host")]

View File

@ -17,13 +17,19 @@
(@interface type (func (param i32 i32))) ;; 5 (@interface type (func (param i32 i32))) ;; 5
;; import ipfs put/get function ;; import ipfs put/get function
(@interface type (func (param string) (result string))) ;; 6 (@interface type (func (param i32 i32))) ;; 6
;; import ipfs put/get function ;; import ipfs put/get function
(@interface type (func (param string) (result string))) ;; 7 (@interface type (func (param string) (result string))) ;; 7
;; import ipfs put/get function ;; import ipfs put/get function
(@interface type (func (param i64 i32) (result i64 i32))) ;; 8 (@interface type (func (param string) (result string))) ;; 8
;; import ipfs put/get function
(@interface type (func (param i32 i32))) ;; 9
;; import ipfs put/get function
(@interface type (func (param i32 i32))) ;; 10
(@interface export "allocate" (func 0)) ;; 0 (@interface export "allocate" (func 0)) ;; 0
(@interface export "deallocate" (func 1)) ;; 1 (@interface export "deallocate" (func 1)) ;; 1
@ -34,7 +40,7 @@
(@interface export "set_result_ptr" (func 4)) ;; 6 (@interface export "set_result_ptr" (func 4)) ;; 6
(@interface import "ipfs_node.wasm" "get" (func (type 5))) (@interface import "ipfs_node.wasm" "get" (func (type 5)))
(@interface import "ipfs_node.wasm" "put" (func (type 5))) (@interface import "ipfs_node.wasm" "put" (func (type 6)))
(@interface import "ipfs_node.wasm" "get" (func (type 7))) ;; 7 (@interface import "ipfs_node.wasm" "get" (func (type 7))) ;; 7
(@interface import "ipfs_node.wasm" "put" (func (type 8))) ;; 8 (@interface import "ipfs_node.wasm" "put" (func (type 8))) ;; 8
@ -54,7 +60,7 @@
call-core 1 ;; call deallocate call-core 1 ;; call deallocate
) )
(@interface func (type 5) (@interface func (type 9)
arg.get 0 arg.get 0
arg.get 1 arg.get 1
string.lift_memory string.lift_memory
@ -68,6 +74,21 @@
call-core 5 ;; call set_result_ptr call-core 5 ;; call set_result_ptr
) )
(@interface func (type 10)
arg.get 0
arg.get 1
string.lift_memory
call-core 8 ;; call ipfs_node.put that returns string
dup
string.size
call-core 0 ;; call allocate
swap2
string.lower_memory
call-core 6 ;; call set_result_size
call-core 5 ;; call set_result_ptr
)
;; Implementations ;; Implementations
(@interface implement (func 2) (func 2)) (@interface implement (func 2) (func 2))
(@interface implement (func 5) (func 5)) (@interface implement (func 5) (func 9))
(@interface implement (func 6) (func 10))

View File

@ -28,6 +28,12 @@ pub struct FCE {
modules: HashMap<String, Arc<FCEModule>>, modules: HashMap<String, Arc<FCEModule>>,
} }
impl Drop for FCE {
fn drop(&mut self) {
// println!("FCE dropped");
}
}
impl FCE { impl FCE {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {

View File

@ -47,6 +47,12 @@ pub struct FCEModule {
exports_funcs: HashMap<String, WITModuleFunc>, exports_funcs: HashMap<String, WITModuleFunc>,
} }
impl Drop for FCEModule {
fn drop(&mut self) {
// println!("FCEModule dropped: {:?}", self.exports_funcs.keys());
}
}
impl FCEModule { impl FCEModule {
pub fn new( pub fn new(
wasm_bytes: &[u8], wasm_bytes: &[u8],
@ -183,16 +189,48 @@ impl FCEModule {
use wasmer_core::typed_func::DynamicFunc; use wasmer_core::typed_func::DynamicFunc;
use wasmer_core::vm::Ctx; use wasmer_core::vm::Ctx;
#[derive(Clone)]
struct T {}
impl Drop for T {
fn drop(&mut self) {
// println!("drop T");
}
}
// returns function that will be called from imports of Wasmer module // returns function that will be called from imports of Wasmer module
fn dyn_func_from_raw_import( fn dyn_func_from_raw_import(
inputs: Vec<IType>, inputs: Vec<IType>,
func: Box<dyn Fn(&mut Ctx, &[WValue]) -> Vec<WValue> + 'static>, wit_instance: Arc<MaybeUninit<WITInstance>>,
interpreter: WITInterpreter,
) -> DynamicFunc<'static> { ) -> DynamicFunc<'static> {
use wasmer_core::types::FuncSig; use wasmer_core::types::FuncSig;
use super::type_converters::itype_to_wtype; use super::type_converters::itype_to_wtype;
let t = T {};
let signature = inputs.iter().map(itype_to_wtype).collect::<Vec<_>>(); let signature = inputs.iter().map(itype_to_wtype).collect::<Vec<_>>();
DynamicFunc::new(Arc::new(FuncSig::new(signature, vec![])), func) DynamicFunc::new(
Arc::new(FuncSig::new(signature, vec![])),
move |_: &mut Ctx, inputs: &[WValue]| -> Vec<WValue> {
use super::type_converters::wval_to_ival;
let t_copied = t.clone();
// copy here because otherwise wit_instance will be consumed by the closure
let wit_instance_callable = wit_instance.clone();
let converted_inputs = inputs.iter().map(wval_to_ival).collect::<Vec<_>>();
unsafe {
// error here will be propagated by the special error instruction
let _ = interpreter.run(
&converted_inputs,
Arc::make_mut(&mut wit_instance_callable.assume_init()),
);
}
// wit import functions should only change the stack state -
// the result will be returned by an export function
vec![]
},
)
} }
// creates a closure that is represent a WIT module import // creates a closure that is represent a WIT module import
@ -220,7 +258,7 @@ impl FCEModule {
}) })
} }
let namespaces = wit let wit_import_funcs = wit
.implementations() .implementations()
.filter_map(|(adapter_function_type, core_function_type)| { .filter_map(|(adapter_function_type, core_function_type)| {
match wit.imports_by_type(*core_function_type) { match wit.imports_by_type(*core_function_type) {
@ -242,13 +280,14 @@ impl FCEModule {
match wit_type { match wit_type {
WITAstType::Function { inputs, .. } => { WITAstType::Function { inputs, .. } => {
let interpreter: WITInterpreter = adapter_instructions.try_into()?; let interpreter: WITInterpreter = adapter_instructions.try_into()?;
let inner_import = create_raw_import(wit_instance.clone(), interpreter);
let wit_import = dyn_func_from_raw_import(inputs.clone(), inner_import);
let mut namespace = Namespace::new(); let wit_import = dyn_func_from_raw_import(
namespace.insert(*import_name, wit_import); inputs.clone(),
wit_instance.clone(),
interpreter,
);
Ok((import_namespace.to_string(), namespace)) Ok((import_namespace.to_string(), (*import_name, wit_import)))
} }
_ => Err(FCEError::IncorrectWIT(format!( _ => Err(FCEError::IncorrectWIT(format!(
"type with idx = {} isn't a function type", "type with idx = {} isn't a function type",
@ -256,23 +295,17 @@ impl FCEModule {
))), ))),
} }
}) })
.collect::<Result<multimap::MultiMap<String, Namespace>, FCEError>>()?; .collect::<Result<multimap::MultiMap<_, _>, FCEError>>()?;
let mut import_object = ImportObject::new(); let mut import_object = ImportObject::new();
// TODO: refactor it // TODO: refactor it
for (namespace_name, namespaces) in namespaces.iter_all() { for (namespace_name, funcs) in wit_import_funcs.into_iter() {
let mut result_namespace = Namespace::new(); let mut namespace = Namespace::new();
for namespace in namespaces { for (import_name, import_func) in funcs.into_iter() {
use wasmer_core::import::LikeNamespace; namespace.insert(import_name.to_string(), import_func);
result_namespace.insert(
namespace.get_exports()[0].0.clone(),
namespace.get_exports()[0].1.clone(),
);
} }
import_object.register(namespace_name, namespace);
import_object.register(namespace_name, result_namespace);
} }
Ok(import_object) Ok(import_object)

View File

@ -45,6 +45,19 @@ pub(super) struct WITFunction {
inner: WITFunctionInner, inner: WITFunctionInner,
} }
impl Drop for WITFunction {
fn drop(&mut self) {
match &self.inner {
WITFunctionInner::Export { func, .. } => {
// println!("WITFunction export dropped: {:?}", func.signature());
}
WITFunctionInner::Import { func_name, .. } => {
// println!("WITFunction import dropped: {:?}", func_name);
}
}
}
}
impl WITFunction { impl WITFunction {
/// Creates functions from a "usual" (not WIT) module export. /// Creates functions from a "usual" (not WIT) module export.
pub(super) fn from_export(dyn_func: DynFunc<'static>) -> Result<Self, FCEError> { pub(super) fn from_export(dyn_func: DynFunc<'static>) -> Result<Self, FCEError> {

View File

@ -33,6 +33,12 @@ pub(super) struct WITInstance {
memories: Vec<WITMemory>, memories: Vec<WITMemory>,
} }
impl Drop for WITInstance {
fn drop(&mut self) {
// println!("WITInstance dropped");
}
}
impl WITInstance { impl WITInstance {
pub(super) fn new( pub(super) fn new(
wasmer_instance: &WasmerInstance, wasmer_instance: &WasmerInstance,
@ -59,8 +65,8 @@ impl WITInstance {
wit.exports() wit.exports()
.enumerate() .enumerate()
.map(|(export_id, (_, export_name))| { .map(|(export_id, export)| {
let export_func = module_exports.get(*export_name)?; let export_func = module_exports.get(export.name)?;
unsafe { unsafe {
// TODO: refactor this with new Wasmer API when it is ready // TODO: refactor this with new Wasmer API when it is ready
// here it is safe because dyn func is never lives WITInstance // here it is safe because dyn func is never lives WITInstance
@ -79,23 +85,17 @@ impl WITInstance {
start_index: usize, start_index: usize,
) -> Result<HashMap<usize, WITFunction>, FCEError> { ) -> Result<HashMap<usize, WITFunction>, FCEError> {
wit.imports() wit.imports()
.filter(|(core_function_type, _)| { .filter(|import| {
// filter out imports that have implementations // filter out imports that have implementations
matches!(wit.adapter_by_type(**core_function_type), None) matches!(wit.adapter_by_type(import.function_type), None)
}) })
.enumerate() .enumerate()
.map(|(idx, (_, (import_namespace, import_name)))| { .map(|(idx, import)| match modules.get(import.namespace) {
match modules.get(*import_namespace) {
Some(module) => { Some(module) => {
let func = let func = WITFunction::from_import(module.clone(), import.name.to_string())?;
WITFunction::from_import(module.clone(), import_name.to_string())?;
Ok((start_index + idx as usize, func)) Ok((start_index + idx as usize, func))
} }
None => { None => Err(FCEError::NoSuchModule),
println!("no such module: {}", import_namespace);
Err(FCEError::NoSuchModule)
}
}
}) })
.collect::<Result<HashMap<_, _>, _>>() .collect::<Result<HashMap<_, _>, _>>()
} }