mirror of
https://github.com/fluencelabs/marine.git
synced 2024-12-12 14:55:32 +00:00
allow several host imports
This commit is contained in:
parent
7d5ae2f9b0
commit
fe716cd078
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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"
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -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<_>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
|
@ -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")]
|
||||||
|
@ -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))
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
|
@ -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> {
|
||||||
|
@ -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 = WITFunction::from_import(module.clone(), import.name.to_string())?;
|
||||||
let func =
|
Ok((start_index + idx as usize, func))
|
||||||
WITFunction::from_import(module.clone(), import_name.to_string())?;
|
|
||||||
Ok((start_index + idx as usize, func))
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
println!("no such module: {}", import_namespace);
|
|
||||||
Err(FCEError::NoSuchModule)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
None => Err(FCEError::NoSuchModule),
|
||||||
})
|
})
|
||||||
.collect::<Result<HashMap<_, _>, _>>()
|
.collect::<Result<HashMap<_, _>, _>>()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user