diff --git a/wit_fce/examples/ipfs_node/src/lib.rs b/wit_fce/examples/ipfs_node/src/lib.rs index 27d54f81..4fe56e50 100644 --- a/wit_fce/examples/ipfs_node/src/lib.rs +++ b/wit_fce/examples/ipfs_node/src/lib.rs @@ -32,10 +32,16 @@ pub unsafe fn put(file_content_ptr: *mut u8, file_content_size: usize) { let cmd = format!("put {}", file_content); ipfs(file_content.as_ptr() as _, file_content.len() as _); + + let result = "Hello from IPFS node, take your hash".to_string(); + + *RESULT_PTR.get_mut() = result.as_ptr() as _; + *RESULT_SIZE.get_mut() = result.len(); + std::mem::forget(result); } #[no_mangle] -pub unsafe fn get(hash_ptr: *mut u8, hash_size: usize, t: i32) { +pub unsafe fn get(hash_ptr: *mut u8, hash_size: usize) { let hash = String::from_raw_parts( hash_ptr, hash_size, @@ -47,6 +53,12 @@ pub unsafe fn get(hash_ptr: *mut u8, hash_size: usize, t: i32) { let cmd = format!("get {}", hash); ipfs(cmd.as_ptr() as _, cmd.len() as _); + + let result = "Hello from IPFS node, take your file".to_string(); + + *RESULT_PTR.get_mut() = result.as_ptr() as _; + *RESULT_SIZE.get_mut() = result.len(); + std::mem::forget(result); } #[link(wasm_import_module = "logger")] diff --git a/wit_fce/examples/ipfs_node/src/mem.rs b/wit_fce/examples/ipfs_node/src/mem.rs index e39eb89a..23231126 100644 --- a/wit_fce/examples/ipfs_node/src/mem.rs +++ b/wit_fce/examples/ipfs_node/src/mem.rs @@ -16,12 +16,17 @@ use std::alloc::{alloc as global_alloc, dealloc as global_dealloc, Layout}; +use crate::log_utf8_string; use std::ptr::NonNull; /// Allocates memory area of specified size and returns its address. #[no_mangle] pub unsafe fn allocate(size: usize) -> NonNull { let layout: Layout = Layout::from_size_align(size, std::mem::align_of::()).unwrap(); + + let msg = format!("wasm_node: calling allocate with {}\n", size); + log_utf8_string(msg.as_ptr() as _, msg.len() as _); + NonNull::new_unchecked(global_alloc(layout)) } @@ -29,5 +34,9 @@ pub unsafe fn allocate(size: usize) -> NonNull { #[no_mangle] pub unsafe fn deallocate(ptr: NonNull, size: usize) { let layout = Layout::from_size_align(size, std::mem::align_of::()).unwrap(); + + let msg = format!("wasm_node: calling deallocate with {:?} {}\n", ptr, size); + log_utf8_string(msg.as_ptr() as _, msg.len() as _); + global_dealloc(ptr.as_ptr(), layout); } diff --git a/wit_fce/examples/ipfs_node/src/result.rs b/wit_fce/examples/ipfs_node/src/result.rs index 2530e47a..b0144bf4 100644 --- a/wit_fce/examples/ipfs_node/src/result.rs +++ b/wit_fce/examples/ipfs_node/src/result.rs @@ -16,26 +16,39 @@ use std::sync::atomic::AtomicUsize; +use crate::log_utf8_string; pub static mut RESULT_PTR: AtomicUsize = AtomicUsize::new(0); pub static mut RESULT_SIZE: AtomicUsize = AtomicUsize::new(0); #[no_mangle] pub unsafe fn get_result_ptr() -> usize { + let msg = format!("wasm_node: calling get_result_ptr\n"); + log_utf8_string(msg.as_ptr() as _, msg.len() as _); + *RESULT_PTR.get_mut() } #[no_mangle] pub unsafe fn get_result_size() -> usize { + let msg = format!("wasm_node: calling get_result_size\n"); + log_utf8_string(msg.as_ptr() as _, msg.len() as _); + *RESULT_SIZE.get_mut() } #[no_mangle] pub unsafe fn set_result_ptr(ptr: usize) { + let msg = format!("wasm_node: calling set_result_ptr with {}\n", ptr); + log_utf8_string(msg.as_ptr() as _, msg.len() as _); + *RESULT_PTR.get_mut() = ptr; } #[no_mangle] pub unsafe fn set_result_size(size: usize) { + let msg = format!("wasm_node: calling set_result_size with {}\n", size); + log_utf8_string(msg.as_ptr() as _, msg.len() as _); + *RESULT_SIZE.get_mut() = size; } diff --git a/wit_fce/examples/ipfs_node/wit b/wit_fce/examples/ipfs_node/wit index 22155a13..871def65 100644 --- a/wit_fce/examples/ipfs_node/wit +++ b/wit_fce/examples/ipfs_node/wit @@ -11,10 +11,10 @@ (@interface type (func (result i32))) ;; 3 ;; result setter functions -(@interface type (func (param string))) ;; 4 +(@interface type (func (param string))) ;; 4 ;; import ipfs put/get function -(@interface type (func (param string) (result string))) ;; 5 +(@interface type (func (param i32 i32))) ;; 5 ;; import ipfs put/get function (@interface type (func (param string) (result string))) ;; 6 @@ -24,20 +24,27 @@ (@interface export "allocate" (func 0)) ;; 0 (@interface export "deallocate" (func 1)) ;; 1 -(@interface export "get_result_size" (func 3)) ;; 3 -(@interface export "get_result_ptr" (func 3)) ;; 4 -(@interface export "set_result_size" (func 4)) ;; 5 -(@interface export "set_result_ptr" (func 4)) ;; 6 +(@interface export "get_result_size" (func 3)) ;; 2 +(@interface export "get_result_ptr" (func 3)) ;; 3 +(@interface export "set_result_size" (func 4)) ;; 4 +(@interface export "set_result_ptr" (func 4)) ;; 5 -(@interface export "put" (func 5)) ;; 8 +(@interface export "put" (func 5)) ;; 6 (@interface export "get" (func 5)) ;; 7 (@interface func (type 6) + arg.get 0 + string.size + call-core 0 ;; call allocate arg.get 0 string.lower_memory - call-core 9 ;; call node.get - call-core 5 ;; call set_result_size - call-core 6 ;; call set_result_ptr + call-core 7 ;; call node.get + 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 ) ;; Implementations diff --git a/wit_fce/examples/ipfs_rpc/src/mem.rs b/wit_fce/examples/ipfs_rpc/src/mem.rs index e39eb89a..60dfca94 100644 --- a/wit_fce/examples/ipfs_rpc/src/mem.rs +++ b/wit_fce/examples/ipfs_rpc/src/mem.rs @@ -16,12 +16,17 @@ use std::alloc::{alloc as global_alloc, dealloc as global_dealloc, Layout}; +use crate::log_utf8_string; use std::ptr::NonNull; /// Allocates memory area of specified size and returns its address. #[no_mangle] pub unsafe fn allocate(size: usize) -> NonNull { let layout: Layout = Layout::from_size_align(size, std::mem::align_of::()).unwrap(); + + let msg = format!("wasm_rpc: calling allocate with {}\n", size); + log_utf8_string(msg.as_ptr() as _, msg.len() as _); + NonNull::new_unchecked(global_alloc(layout)) } @@ -29,5 +34,9 @@ pub unsafe fn allocate(size: usize) -> NonNull { #[no_mangle] pub unsafe fn deallocate(ptr: NonNull, size: usize) { let layout = Layout::from_size_align(size, std::mem::align_of::()).unwrap(); + + let msg = format!("wasm_rpc: calling deallocate with {:?} {}\n", ptr, size); + log_utf8_string(msg.as_ptr() as _, msg.len() as _); + global_dealloc(ptr.as_ptr(), layout); } diff --git a/wit_fce/examples/ipfs_rpc/src/result.rs b/wit_fce/examples/ipfs_rpc/src/result.rs index 2530e47a..3091d355 100644 --- a/wit_fce/examples/ipfs_rpc/src/result.rs +++ b/wit_fce/examples/ipfs_rpc/src/result.rs @@ -16,26 +16,39 @@ use std::sync::atomic::AtomicUsize; +use crate::log_utf8_string; pub static mut RESULT_PTR: AtomicUsize = AtomicUsize::new(0); pub static mut RESULT_SIZE: AtomicUsize = AtomicUsize::new(0); #[no_mangle] pub unsafe fn get_result_ptr() -> usize { + let msg = format!("wasm_rpc: calling get_result_ptr\n"); + log_utf8_string(msg.as_ptr() as _, msg.len() as _); + *RESULT_PTR.get_mut() } #[no_mangle] pub unsafe fn get_result_size() -> usize { + let msg = format!("wasm_rpc: calling get_result_size\n"); + log_utf8_string(msg.as_ptr() as _, msg.len() as _); + *RESULT_SIZE.get_mut() } #[no_mangle] pub unsafe fn set_result_ptr(ptr: usize) { + let msg = format!("wasm_rpc: calling set_result_ptr with {}\n", ptr); + log_utf8_string(msg.as_ptr() as _, msg.len() as _); + *RESULT_PTR.get_mut() = ptr; } #[no_mangle] pub unsafe fn set_result_size(size: usize) { + let msg = format!("wasm_rpc: calling set_result_size with {}\n", size); + log_utf8_string(msg.as_ptr() as _, msg.len() as _); + *RESULT_SIZE.get_mut() = size; } diff --git a/wit_fce/examples/ipfs_rpc/wit b/wit_fce/examples/ipfs_rpc/wit index 55f89534..c3dcd3d9 100644 --- a/wit_fce/examples/ipfs_rpc/wit +++ b/wit_fce/examples/ipfs_rpc/wit @@ -59,9 +59,13 @@ arg.get 1 string.lift_memory call-core 7 ;; call node.get that returns string + dup + string.size + call-core 0 ;; call allocate + swap2 string.lower_memory - call-core 5 ;; call set_result_size - call-core 6 ;; call set_result_ptr + call-core 6 ;; call set_result_size + call-core 5 ;; call set_result_ptr ) ;; Implementations diff --git a/wit_fce/src/instance/wit_function.rs b/wit_fce/src/instance/wit_function.rs index 98ca40bc..6cb4127b 100644 --- a/wit_fce/src/instance/wit_function.rs +++ b/wit_fce/src/instance/wit_function.rs @@ -68,7 +68,9 @@ impl WITFunction { } pub fn from_import(wit_module: Arc, func_name: String) -> Result { - let (inputs, outputs) = wit_module.as_ref().get_func_signature(&func_name)?; + let func_type = wit_module.as_ref().get_func_signature(&func_name)?; + let inputs = func_type.0.clone(); + let outputs = func_type.1.clone(); println!("from_import: {:?}", inputs); let inner = WITFunctionInner::Import { @@ -126,7 +128,6 @@ impl wasm::structures::LocalImport for WITFunction { match &self.inner { WITFunctionInner::Export { func, .. } => { - println!("calling with {:?}", arguments); func.as_ref() .call(&arguments.iter().map(ival_to_wval).collect::>()) .map(|results| results.iter().map(wval_to_ival).collect()) @@ -137,14 +138,13 @@ impl wasm::structures::LocalImport for WITFunction { func_name, .. } => { - println!("calling {} with {:?}", func_name, arguments); let mut tt = wit_module.clone(); unsafe { let result = Arc::get_mut_unchecked(&mut tt) .call(func_name, arguments) .map_err(|_| ()); - println!("result is {:?}", result); + // println!("result is {:?}", result); result } } diff --git a/wit_fce/src/instance/wit_instance.rs b/wit_fce/src/instance/wit_instance.rs index bf508053..0e8fadb2 100644 --- a/wit_fce/src/instance/wit_instance.rs +++ b/wit_fce/src/instance/wit_instance.rs @@ -89,12 +89,7 @@ impl WITInstance { let export_func = std::mem::transmute::, DynFunc<'static>>(export_func); let tt = WITFunction::from_export(export_func)?; - println!( - "{}, {} - {:?}", - export_id, - export.name, - tt.inputs() - ); + println!("{}, {} - {:?}", export_id, export.name, tt.inputs()); Ok((export_id, tt)) } }) diff --git a/wit_fce/src/instance/wit_module.rs b/wit_fce/src/instance/wit_module.rs index 2c834557..95107572 100644 --- a/wit_fce/src/instance/wit_module.rs +++ b/wit_fce/src/instance/wit_module.rs @@ -21,7 +21,7 @@ use crate::instance::wit_function::WITFunction; use crate::instance::wit_instance::WITInstance; use wasmer_interface_types as wit; -use wasmer_interface_types::ast::Interfaces; +use wasmer_interface_types::ast::{Interfaces, Type}; use wasmer_interface_types::interpreter::Interpreter; use wasmer_interface_types::values::InterfaceValue; use wasmer_runtime::{compile, ImportObject}; @@ -43,8 +43,7 @@ type WITInterpreter = pub struct WITModule { instance: WasmerInstance, wit_instance: Arc, - func_name_to_idx: HashMap, - funcs: HashMap, + funcs: HashMap, Vec)>, } impl WITModule { @@ -71,7 +70,7 @@ impl WITModule { let mut wit_instance = Arc::new_uninit(); - let callable_exports = Self::extract_exports(&interfaces)?; + let callable_exports = Self::extract_wit_exports(&interfaces)?; let mut import_object = Self::adjust_imports(&interfaces, wit_instance.clone())?; import_object.extend(imports); @@ -86,7 +85,6 @@ impl WITModule { Ok(Self { instance: wasmer_instance, wit_instance, - func_name_to_idx: HashMap::new(), funcs: callable_exports, }) } @@ -96,17 +94,14 @@ impl WITModule { function_name: &str, args: &[InterfaceValue], ) -> Result, WITFCEError> { - println!("here, func name is {}, args = {:?}", function_name, args); match self.funcs.get(function_name) { Some(func) => { let tt = Arc::make_mut(&mut self.wit_instance); - let result = func.run(args, tt)?.as_slice().to_owned(); - println!("here {:?}", result); + let result = func.0.run(args, tt)?.as_slice().to_owned(); Ok(result) } None => { - println!("no func"); Err(WITFCEError::NoSuchFunction(format!( "{} hasn't been found while calling", function_name @@ -118,12 +113,9 @@ impl WITModule { pub fn get_func_signature( &self, function_name: &str, - ) -> Result<(Vec, Vec), WITFCEError> { - match self.func_name_to_idx.get(function_name) { - Some(func_idx) => { - println!("func_idx: {}", func_idx); - self.wit_instance.as_ref().get_func_signature(*func_idx) - }, + ) -> Result<(&Vec, &Vec), WITFCEError> { + match self.funcs.get(function_name) { + Some((_, inputs, outputs)) => Ok((inputs, outputs)), None => Err(WITFCEError::NoSuchFunction(format!( "{} has't been found during its signature looking up", function_name @@ -131,9 +123,12 @@ impl WITModule { } } - fn extract_exports( + fn extract_wit_exports( interfaces: &Interfaces, - ) -> Result, WITFCEError> { + ) -> Result< + HashMap, Vec)>, + WITFCEError, + > { let exports_type_to_names = interfaces .exports .iter() @@ -160,12 +155,32 @@ impl WITModule { format!("adapter function with idx = {} hasn't been found during extracting exports by implementations", i.adapter_function_type) ))?; - for export_function_name in export_function_names.iter() { - println!("export func name {}", export_function_name); + if i.adapter_function_type >= interfaces.types.len() as u32 { + // TODO: change error type + return Err(WITFCEError::NoSuchFunction(format!( + "{} function id is bigger than WIT interface types count", + i.adapter_function_type + ))); + }; - // TODO: handle errors - let interpreter: WITInterpreter = adapter_instructions.try_into().unwrap(); - wit_callable_exports.insert(export_function_name.to_owned(), interpreter); + if let Type::Function { inputs, outputs } = + &interfaces.types[i.adapter_function_type as usize] + { + for export_function_name in export_function_names.iter() { + println!("export func name {}", export_function_name); + + // TODO: handle errors + let interpreter: WITInterpreter = adapter_instructions.try_into().unwrap(); + wit_callable_exports.insert( + export_function_name.to_owned(), + (interpreter, inputs.clone(), outputs.clone()), + ); + } + } else { + return Err(WITFCEError::NoSuchFunction(format!( + "type with idx = {} isn't a function type", + i.adapter_function_type + ))); } } diff --git a/wit_fce/src/main.rs b/wit_fce/src/main.rs index 327a86c9..fa7c1823 100644 --- a/wit_fce/src/main.rs +++ b/wit_fce/src/main.rs @@ -78,7 +78,7 @@ fn ipfs_call(ctx: &mut Ctx, ptr: i32, size: i32) { let wasm_ptr = WasmPtr::::new(ptr as _); match wasm_ptr.get_utf8_string(ctx.memory(0), size as _) { - Some(msg) => print!("ipfs_call {}", msg), - None => print!("fce logger: incorrect UTF8 string's been supplied to logger"), + Some(msg) => println!("host ipfs_call: {}", msg), + None => println!("fce logger: incorrect UTF8 string's been supplied to logger"), } }