From 736927119b44064d553727e3c0bcdc8bbf0ae31a Mon Sep 17 00:00:00 2001 From: Valery Antopol Date: Mon, 20 Feb 2023 19:22:10 +0300 Subject: [PATCH] pr fixes --- core/src/host_imports/imports.rs | 253 ++++++++++-------- .../marine-wasmtime-backend/src/function.rs | 2 +- marine/src/marine.rs | 2 +- 3 files changed, 142 insertions(+), 115 deletions(-) diff --git a/core/src/host_imports/imports.rs b/core/src/host_imports/imports.rs index e7a5413a..802bf285 100644 --- a/core/src/host_imports/imports.rs +++ b/core/src/host_imports/imports.rs @@ -22,7 +22,7 @@ use super::lowering::LoHelper; use super::utils::itypes_args_to_wtypes; use super::utils::itypes_output_to_wtypes; -use crate::MRecordTypes; +use crate::{IType, IValue, MRecordTypes}; use crate::init_wasm_func; use crate::call_wasm_func; use crate::HostImportDescriptor; @@ -46,120 +46,12 @@ pub(crate) fn create_host_import_func( descriptor: HostImportDescriptor, record_types: Arc, ) -> ::Function { - let HostImportDescriptor { - host_exported_func, - argument_types, - output_type, - error_handler, - } = descriptor; - let output_type_to_types = |output_type| match output_type { - Some(ty) => vec![ty], - None => vec![], - }; + let raw_args = itypes_args_to_wtypes(&descriptor.argument_types); + let raw_output = itypes_output_to_wtypes(&output_type_to_types(descriptor.output_type.as_ref())); - let raw_args = itypes_args_to_wtypes(&argument_types); - let raw_output = itypes_output_to_wtypes(&output_type_to_types(output_type)); - - let func = move |mut caller: ::Caller<'_>, - inputs: &[WValue]| - -> Vec { - let result = { - let memory_index = 0; - let memory_view = caller.memory(memory_index).unwrap().view(); // todo handle error - let li_helper = LiHelper::new(record_types.clone()); - let lifter = ILifter::new(memory_view, &li_helper); - let rets = wvalues_to_ivalues( - &mut caller.as_context_mut(), - &lifter, - inputs, - &argument_types, - ); - match rets { - Ok(ivalues) => host_exported_func(&mut caller, ivalues), - Err(e) => { - log::error!("error occurred while lifting values in host import: {}", e); - error_handler - .as_ref() - .map_or_else(|| default_error_handler(&e), |h| h(&e)) - } - } - }; - - init_wasm_func!( - allocate_func, - caller, - (i32, i32), - i32, - ALLOCATE_FUNC_NAME, - 2 - ); - - let memory_index = 0; - let memory_view = caller.memory(memory_index).unwrap().view(); // todo handle error - let mut lo_helper = LoHelper::new(&mut allocate_func, caller.memory(memory_index).unwrap()); // todo handle error - let lowering_result = - ILowerer::<'_, _, _, DelayedContextLifetime>::new(memory_view, &mut lo_helper) - .map_err(HostImportError::LowererError) - .and_then(|mut lowerer| { - ivalue_to_wvalues(&mut caller.as_context_mut(), &mut lowerer, result) - }); - - let wvalues = match lowering_result { - Ok(wvalues) => wvalues, - Err(e) => { - log::error!("host closure failed: {}", e); - - // returns 0 to a Wasm module in case of errors - init_wasm_func!(set_result_ptr_func, caller, i32, (), SET_PTR_FUNC_NAME, 4); - init_wasm_func!(set_result_size_func, caller, i32, (), SET_SIZE_FUNC_NAME, 4); - - call_wasm_func!(set_result_ptr_func, &mut caller.as_context_mut(), 0); - call_wasm_func!(set_result_size_func, &mut caller.as_context_mut(), 0); - return vec![WValue::I32(0)]; - } - }; - - // TODO: refactor this when multi-value is supported - match wvalues.len() { - // strings and arrays are passed back to the Wasm module by pointer and size - 2 => { - init_wasm_func!(set_result_ptr_func, caller, i32, (), SET_PTR_FUNC_NAME, 4); - init_wasm_func!(set_result_size_func, caller, i32, (), SET_SIZE_FUNC_NAME, 4); - - call_wasm_func!( - set_result_ptr_func, - &mut caller.as_context_mut(), - wvalues[0].to_u128() as _ - ); - call_wasm_func!( - set_result_size_func, - &mut caller.as_context_mut(), - wvalues[1].to_u128() as _ - ); - vec![] - } - - // records and primitive types are passed to the Wasm module by pointer - // and value on the stack - 1 => { - init_wasm_func!(set_result_ptr_func, caller, i32, (), SET_PTR_FUNC_NAME, 3); - - call_wasm_func!( - set_result_ptr_func, - &mut caller.as_context_mut(), - wvalues[0].to_u128() as _ - ); - vec![wvalues[0].clone()] - } - - // when None is passed - 0 => vec![], - - // at now while multi-values aren't supported ivalue_to_wvalues returns only Vec with - // 0, 1, 2 values - _ => unimplemented!(), - } + let func = move |caller: ::Caller<'_>, inputs: &[WValue]| -> Vec { + call_host_import(caller, inputs, &descriptor, record_types.clone()) }; ::Function::new_with_ctx( @@ -169,6 +61,141 @@ pub(crate) fn create_host_import_func( ) } +fn call_host_import( + mut caller: ::Caller<'_>, + inputs: &[WValue], + descriptor: &HostImportDescriptor, + record_types: Arc, +) -> Vec { + let HostImportDescriptor { + host_exported_func, + argument_types, + error_handler, + .. + } = descriptor; + + let memory_index = 0; + let memory = caller + .memory(memory_index) + .unwrap_or_else(|| panic!("Host import called directly, not from wasm")); + + let inputs = lift_inputs::(&mut caller, memory.clone(), record_types, inputs, &argument_types); + let output = match inputs { + Ok(ivalues) => host_exported_func(&mut caller, ivalues), + Err(e) => { + log::error!("error occurred while lifting values in host import: {}", e); + error_handler + .as_ref() + .map_or_else(|| default_error_handler(&e), |h| h(&e)) + } + }; + + lower_outputs::(&mut caller, memory, output) +} + +fn lift_inputs( + caller: &mut ::Caller<'_>, + memory: ::Memory, + record_types: Arc, + inputs: &[WValue], + argument_types: &[IType] +) -> HostImportResult> { + let memory_view = memory.view(); + let li_helper = LiHelper::new(record_types.clone()); + let lifter = ILifter::new(memory_view, &li_helper); + wvalues_to_ivalues( + &mut caller.as_context_mut(), + &lifter, + inputs, + &argument_types, + ) +} + +fn lower_outputs(caller: &mut ::Caller<'_>, + memory: ::Memory, + output: Option, ) -> Vec { + init_wasm_func!( + allocate_func, + caller, + (i32, i32), + i32, + ALLOCATE_FUNC_NAME, + 2 + ); + + let memory_view = memory.view(); + let mut lo_helper = LoHelper::new(&mut allocate_func, memory.clone()); + let lowering_result = + ILowerer::<'_, _, _, DelayedContextLifetime>::new(memory_view, &mut lo_helper) + .map_err(HostImportError::LowererError) + .and_then(|mut lowerer| { + ivalue_to_wvalues(&mut caller.as_context_mut(), &mut lowerer, output) + }); + + let wvalues = match lowering_result { + Ok(wvalues) => wvalues, + Err(e) => { + log::error!("host closure failed: {}", e); + + // returns 0 to a Wasm module in case of errors + init_wasm_func!(set_result_ptr_func, caller, i32, (), SET_PTR_FUNC_NAME, 4); + init_wasm_func!(set_result_size_func, caller, i32, (), SET_SIZE_FUNC_NAME, 4); + + call_wasm_func!(set_result_ptr_func, &mut caller.as_context_mut(), 0); + call_wasm_func!(set_result_size_func, &mut caller.as_context_mut(), 0); + return vec![WValue::I32(0)]; + } + }; + + // TODO: refactor this when multi-value is supported + match wvalues.len() { + // strings and arrays are passed back to the Wasm module by pointer and size + 2 => { + init_wasm_func!(set_result_ptr_func, caller, i32, (), SET_PTR_FUNC_NAME, 4); + init_wasm_func!(set_result_size_func, caller, i32, (), SET_SIZE_FUNC_NAME, 4); + + call_wasm_func!( + set_result_ptr_func, + &mut caller.as_context_mut(), + wvalues[0].to_u128() as _ + ); + call_wasm_func!( + set_result_size_func, + &mut caller.as_context_mut(), + wvalues[1].to_u128() as _ + ); + vec![] + } + + // records and primitive types are passed to the Wasm module by pointer + // and value on the stack + 1 => { + init_wasm_func!(set_result_ptr_func, caller, i32, (), SET_PTR_FUNC_NAME, 3); + + call_wasm_func!( + set_result_ptr_func, + &mut caller.as_context_mut(), + wvalues[0].to_u128() as _ + ); + vec![wvalues[0].clone()] + } + + // when None is passed + 0 => vec![], + + // at now while multi-values aren't supported ivalue_to_wvalues returns only Vec with + // 0, 1, 2 values + _ => unimplemented!(), + } +} + +fn output_type_to_types(output_type: Option<&IType>) -> Vec{ + match output_type { + Some(ty) => vec![ty.clone()], + None => vec![], + } +} + fn default_error_handler(err: &HostImportError) -> Option { panic!( "an error is occurred while lifting values to interface values: {}", diff --git a/crates/marine-wasmtime-backend/src/function.rs b/crates/marine-wasmtime-backend/src/function.rs index ff4dc85c..48390eb7 100644 --- a/crates/marine-wasmtime-backend/src/function.rs +++ b/crates/marine-wasmtime-backend/src/function.rs @@ -169,4 +169,4 @@ macro_rules! impl_func_construction { impl FuncConstructor for WasmtimeFunction { impl_for_each_function_signature!(impl_func_construction); -} \ No newline at end of file +} diff --git a/marine/src/marine.rs b/marine/src/marine.rs index 400bd426..dd37f1d6 100644 --- a/marine/src/marine.rs +++ b/marine/src/marine.rs @@ -26,7 +26,7 @@ use crate::host_imports::logger::LoggerFilter; use crate::host_imports::logger::WASM_LOG_ENV_NAME; use crate::json_to_marine_err; -use marine_wasm_backend_traits::WasmB ackend; +use marine_wasm_backend_traits::WasmBackend; use marine_core::MarineCore; use marine_core::IFunctionArg;