diff --git a/crates/fce-test-macro-impl/src/fce_test/config_utils.rs b/crates/fce-test-macro-impl/src/fce_test/config_utils.rs index 77450da..22f462e 100644 --- a/crates/fce-test-macro-impl/src/fce_test/config_utils.rs +++ b/crates/fce-test-macro-impl/src/fce_test/config_utils.rs @@ -59,7 +59,7 @@ fn collect_module_paths( .module .iter() .map(|m| { - let module_file_name = m.file_name.as_ref().unwrap_or_else(|| &m.name); + let module_file_name = m.file_name.as_ref().unwrap_or(&m.name); let module_file_name = PathBuf::from(module_file_name); // TODO: is it correct to always have .wasm extension? let module_path = modules_dir.join(module_file_name).with_extension("wasm"); @@ -83,6 +83,6 @@ pub(super) fn resolve_modules_dir( .toml_faas_config .modules_dir .as_ref() - .map(|p| PathBuf::from(p)), + .map(PathBuf::from), } } diff --git a/crates/fce-test-macro-impl/src/fce_test/glue_code_generator.rs b/crates/fce-test-macro-impl/src/fce_test/glue_code_generator.rs index 9f6b135..5c51423 100644 --- a/crates/fce-test-macro-impl/src/fce_test/glue_code_generator.rs +++ b/crates/fce-test-macro-impl/src/fce_test/glue_code_generator.rs @@ -25,7 +25,7 @@ use proc_macro2::TokenStream; use quote::quote; use quote::ToTokens; -use std::path::PathBuf; +use std::path::Path; /// Generates glue code for tests. /// F.e. for this test for the greeting service @@ -153,7 +153,7 @@ pub(super) fn generate_test_glue_code( Ok(glue_code) } -fn generate_app_service_ctor(config_path: &str, modules_dir: &PathBuf) -> TokenStream { +fn generate_app_service_ctor(config_path: &str, modules_dir: &Path) -> TokenStream { let config_path = config_path.to_token_stream(); let modules_dir = modules_dir.to_string_lossy().to_string(); diff --git a/crates/fce-test-macro-impl/src/fce_test/utils.rs b/crates/fce-test-macro-impl/src/fce_test/utils.rs index a39f823..8f34f13 100644 --- a/crates/fce-test-macro-impl/src/fce_test/utils.rs +++ b/crates/fce-test-macro-impl/src/fce_test/utils.rs @@ -27,7 +27,7 @@ pub(super) fn generate_module_name(module_name: &str) -> TResult { } pub(super) fn generate_record_name(record_name: &str) -> TResult { - let extended_record_name = format!("{}", record_name); + let extended_record_name = record_name.to_string(); new_ident(&extended_record_name) } diff --git a/crates/wit/src/parse_macro_input/item_fn.rs b/crates/wit/src/parse_macro_input/item_fn.rs index bfe4fb5..8c38a11 100644 --- a/crates/wit/src/parse_macro_input/item_fn.rs +++ b/crates/wit/src/parse_macro_input/item_fn.rs @@ -34,7 +34,9 @@ impl ParseMacroInput for syn::ItemFn { .arguments .iter() .zip(self.sig.inputs.iter().map(|arg| arg.span())); - check_parsed_functions(parsed_args)?; + + check_args(parsed_args)?; + check_output_type(&signature.output_type, self.sig.output.span())?; let ast_fn = FCEAst::Function(AstFnItem { signature, @@ -126,19 +128,35 @@ fn check_function(signature: &syn::Signature) -> Result<()> { Ok(()) } -fn check_parsed_functions<'a>( +fn check_args<'a>( args: impl ExactSizeIterator, ) -> Result<()> { for (arg, span) in args { if contains_inner_ref(&arg.ty) { return crate::syn_error!( span, - "vector type in export functions should take arguments only by value" + "a vector type in arguments of export functions shouldn't contain references" ); } } - return Ok(()); + Ok(()) +} + +fn check_output_type(output_type: &Option, span: proc_macro2::Span) -> Result<()> { + let ty = match output_type { + Some(ty) => ty, + None => return Ok(()), + }; + + if contains_inner_ref(ty) { + return crate::syn_error!( + span, + "a vector type in output types of export functions shouldn't contain references" + ); + } + + Ok(()) } /// Returns true if the given type is a vector contains a reference inside it's parameter type. diff --git a/crates/wit/src/parsed_type/fn_epilog.rs b/crates/wit/src/parsed_type/fn_epilog.rs index 2da818b..a304918 100644 --- a/crates/wit/src/parsed_type/fn_epilog.rs +++ b/crates/wit/src/parsed_type/fn_epilog.rs @@ -27,7 +27,7 @@ pub(crate) struct FnEpilogDescriptor { pub(crate) fn_return_type: proc_macro2::TokenStream, pub(crate) return_expression: proc_macro2::TokenStream, pub(crate) epilog: proc_macro2::TokenStream, - pub(crate) mem_forget: proc_macro2::TokenStream, + pub(crate) objs_savings: proc_macro2::TokenStream, } /// Contains all ingredients needed for epilog creation. @@ -58,7 +58,7 @@ impl FnEpilogGlueCodeGenerator for FnEpilogIngredients<'_> { fn_return_type: generate_fn_return_type(self.return_type), return_expression: generate_return_expression(self.return_type), epilog: generate_epilog(self.return_type), - mem_forget: generate_mem_forgets(self), + objs_savings: generate_objs_savings(self), } } } @@ -127,9 +127,11 @@ fn generate_epilog(ty: &Option) -> proc_macro2::TokenStream { quote! { #vector_serializer - let result = #generated_serializer_ident(&result); - fluence::internal::set_result_ptr(result.0 as _); - fluence::internal::set_result_size(result.1 as _); + { + let (serialized_vec_ptr, serialized_vec_size) = #generated_serializer_ident(&result); + fluence::internal::set_result_ptr(serialized_vec_ptr as _); + fluence::internal::set_result_size(serialized_vec_size as _); + } } } Some(_) => quote! { @@ -141,7 +143,14 @@ fn generate_epilog(ty: &Option) -> proc_macro2::TokenStream { /// If an export function returns a reference, this is probably a reference to one /// of the function arguments. If that's the case, reference must be still valid after /// the end of the function. Their deletion will be handled by IT with calling `release_objects`. -fn generate_mem_forgets(ingredients: &FnEpilogIngredients<'_>) -> proc_macro2::TokenStream { +fn generate_objs_savings(ingredients: &FnEpilogIngredients<'_>) -> proc_macro2::TokenStream { + match ingredients.return_type { + // if type is empty we don't need to save arguments or objects + Some(ty) if !ty.is_complex_type() => return proc_macro2::TokenStream::new(), + None => return proc_macro2::TokenStream::new(), + _ => {} + }; + let passing_style = ingredients.return_type.as_ref().map(passing_style_of); match passing_style { @@ -150,13 +159,13 @@ fn generate_mem_forgets(ingredients: &FnEpilogIngredients<'_>) -> proc_macro2::T quote! { fluence::internal::add_object_to_release(Box::new(result)); } } Some(PassingStyle::ByRef) | Some(PassingStyle::ByMutRef) => { - mem_forget_by_args(ingredients.args, ingredients.converted_args) + generate_args_savings(ingredients.args, ingredients.converted_args) } None => quote! {}, } } -fn mem_forget_by_args( +fn generate_args_savings( args: &[AstFnArgument], converted_args: &[syn::Ident], ) -> proc_macro2::TokenStream { diff --git a/crates/wit/src/parsed_type/foreign_mod_prolog.rs b/crates/wit/src/parsed_type/foreign_mod_prolog.rs index f46781c..edf51e9 100644 --- a/crates/wit/src/parsed_type/foreign_mod_prolog.rs +++ b/crates/wit/src/parsed_type/foreign_mod_prolog.rs @@ -90,7 +90,7 @@ impl ForeignModPrologGlueCodeGenerator for Vec { let arg_transform = quote::quote! { #vector_serializer - let #arg_ident = #generated_serializer_ident(#arg_ident); + let #arg_ident = #generated_serializer_ident(&#arg_ident); }; arg_transforms.extend(arg_transform); @@ -110,9 +110,9 @@ impl ForeignModPrologGlueCodeGenerator for Vec { WrapperDescriptor { arg_names, arg_types, + raw_args, arg_transforms, arg_drops, - raw_args, } } diff --git a/crates/wit/src/parsed_type/vector_utils.rs b/crates/wit/src/parsed_type/vector_utils.rs index 9eb93bd..8fa495a 100644 --- a/crates/wit/src/parsed_type/vector_utils.rs +++ b/crates/wit/src/parsed_type/vector_utils.rs @@ -57,7 +57,11 @@ pub(crate) fn generate_vector_serializer( result.push(value.to_bits()); } - (result.as_ptr() as _, (4 * result.len()) as _) + let result_ptr = result.as_ptr(); + let result_len = 4 * result.len(); + fluence::internal::add_object_to_release(Box::new(result)); + + (result_ptr as _, result_len as _) } } ParsedType::F64(_) => { @@ -67,7 +71,11 @@ pub(crate) fn generate_vector_serializer( result.push(value.to_bits()); } - (result.as_ptr() as _, (8 * result.len()) as _) + let result_ptr = result.as_ptr(); + let result_len = 8 * result.len(); + fluence::internal::add_object_to_release(Box::new(result)); + + (result_ptr as _, result_len as _) } } ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => { @@ -79,7 +87,11 @@ pub(crate) fn generate_vector_serializer( result.push(value.len() as _); } - (result.as_ptr() as _, (4 * result.len()) as _) + let result_ptr = result.as_ptr(); + let result_len = 4 * result.len(); + fluence::internal::add_object_to_release(Box::new(result)); + + (result_ptr as _, result_len as _) } } ParsedType::Vector(ty, passing_style) => { @@ -101,7 +113,11 @@ pub(crate) fn generate_vector_serializer( result.push(size as _); } - (result.as_ptr() as _, (4 * result.len()) as _) + let result_ptr = result.as_ptr(); + let result_len = 4 * result.len(); + fluence::internal::add_object_to_release(Box::new(result)); + + (result_ptr as _, result_len as _) } } @@ -113,7 +129,11 @@ pub(crate) fn generate_vector_serializer( result.push(value.__fce_generated_serialize() as _); } - (result.as_ptr() as _, (4 * result.len()) as _) + let result_ptr = result.as_ptr(); + let result_len = 4 * result.len(); + fluence::internal::add_object_to_release(Box::new(result)); + + (result_ptr as _, result_len as _) } } }; diff --git a/crates/wit/src/token_stream_generator/fn_generator.rs b/crates/wit/src/token_stream_generator/fn_generator.rs index 3dd3224..f5e2aec 100644 --- a/crates/wit/src/token_stream_generator/fn_generator.rs +++ b/crates/wit/src/token_stream_generator/fn_generator.rs @@ -64,7 +64,7 @@ impl quote::ToTokens for fce_ast_types::AstFnItem { fn_return_type, return_expression, epilog, - mem_forget, + objs_savings, } = epilog_ingredients.generate_fn_epilog(); // here this Option must be Some @@ -88,8 +88,8 @@ impl quote::ToTokens for fce_ast_types::AstFnItem { // return value conversation from Rust type to a Wasm type #epilog - // forget result or arguments - #mem_forget + // save objects to keep them in memory that allows IT side + #objs_savings } #[cfg(target_arch = "wasm32")] diff --git a/crates/wit/src/token_stream_generator/record_generator.rs b/crates/wit/src/token_stream_generator/record_generator.rs index 7842918..b00cb63 100644 --- a/crates/wit/src/token_stream_generator/record_generator.rs +++ b/crates/wit/src/token_stream_generator/record_generator.rs @@ -67,15 +67,16 @@ impl quote::ToTokens for fce_ast_types::AstRecordItem { fn generate_serializer_fn(record: &fce_ast_types::AstRecordItem) -> proc_macro2::TokenStream { let serializer = record.generate_serializer(); + let fields_count = record.fields.len(); quote::quote! { - pub fn __fce_generated_serialize(self) -> *const u8 { - let mut raw_record: Vec = Vec::new(); + pub fn __fce_generated_serialize(&self) -> *const u8 { + let mut raw_record: Vec = Vec::with_capacity(2 * #fields_count); #serializer let raw_record_ptr = raw_record.as_ptr(); - fluence::internal::add_object_to_release(Box::new(self)); + fluence::internal::add_object_to_release(Box::new(raw_record)); raw_record_ptr as _ } diff --git a/crates/wit/tests/generation_tests/exports/arrays/expanded.rs b/crates/wit/tests/generation_tests/exports/arrays/expanded.rs new file mode 100644 index 0000000..06cee7a --- /dev/null +++ b/crates/wit/tests/generation_tests/exports/arrays/expanded.rs @@ -0,0 +1,129 @@ +pub fn inner_arrays_1(arg: Vec>>>) -> Vec>>> { + unimplemented!() +} +#[cfg(target_arch = "wasm32")] +#[export_name = "inner_arrays_1"] +#[no_mangle] +#[doc(hidden)] +#[allow(clippy::all)] +pub unsafe fn __fce_generated_wrapper_func_inner_arrays_1(arg_0: u32, arg_1: u32) { + unsafe fn __fce_generated_vec_deserializer_0(offset: u32, size: u32) -> Vec>>> { + let size = size / 8; + unsafe fn __fce_generated_vec_deserializer_0_Vec_Vec_u8__( + offset: u32, + size: u32 + ) -> Vec>> { + let size = size / 8; + unsafe fn __fce_generated_vec_deserializer_0_Vec_Vec_u8___Vec_u8_( + offset: u32, + size: u32 + ) -> Vec> { + let size = size / 8; + unsafe fn __fce_generated_vec_deserializer_0_Vec_Vec_u8___Vec_u8__u8( + offset: u32, + size: u32 + ) -> Vec { + let size = size / 8; + let mut arg: Vec = Vec::from_raw_parts(offset as _, size as _, size as _); + let mut result = Vec::with_capacity(arg.len()); + for value in arg { + result.push(value as _); + } + result + } + let mut arg: Vec = Vec::from_raw_parts(offset as _, size as _, size as _); + let mut result = Vec::with_capacity(arg.len()); + let mut arg = arg.into_iter(); + while let Some(offset) = arg.next() { + let size = arg.next().unwrap(); + let value = __fce_generated_vec_deserializer_0_Vec_Vec_u8___Vec_u8__u8( + offset as _, + size as _ + ); + result.push(value); + } + result + } + let mut arg: Vec = Vec::from_raw_parts(offset as _, size as _, size as _); + let mut result = Vec::with_capacity(arg.len()); + let mut arg = arg.into_iter(); + while let Some(offset) = arg.next() { + let size = arg.next().unwrap(); + let value = + __fce_generated_vec_deserializer_0_Vec_Vec_u8___Vec_u8_(offset as _, size as _); + result.push(value); + } + result + } + let mut arg: Vec = Vec::from_raw_parts(offset as _, size as _, size as _); + let mut result = Vec::with_capacity(arg.len()); + let mut arg = arg.into_iter(); + while let Some(offset) = arg.next() { + let size = arg.next().unwrap(); + let value = __fce_generated_vec_deserializer_0_Vec_Vec_u8__(offset as _, size as _); + result.push(value); + } + result + } + let converted_arg_0 = __fce_generated_vec_deserializer_0(arg_0 as _, arg_1 as _); + let result = inner_arrays_1(converted_arg_0); + unsafe fn __fce_generated_vec_serializer(arg: &Vec>>>) -> (u32, u32) { + unsafe fn __fce_generated_vec_serializer_Vec_Vec_u8__( + arg: &Vec>> + ) -> (u32, u32) { + unsafe fn __fce_generated_vec_serializer_Vec_Vec_u8___Vec_u8_( + arg: &Vec> + ) -> (u32, u32) { + unsafe fn __fce_generated_vec_serializer_Vec_Vec_u8___Vec_u8__u8( + arg: &Vec + ) -> (u32, u32) { + (arg.as_ptr() as _, arg.len() as _) + } + let mut result: Vec = Vec::with_capacity(2 * arg.len()); + for value in arg { + let (ptr, size) = + __fce_generated_vec_serializer_Vec_Vec_u8___Vec_u8__u8(&value); + result.push(ptr as _); + result.push(size as _); + } + let result_ptr = result.as_ptr(); + let result_len = 4 * result.len(); + fluence::internal::add_object_to_release(Box::new(result)); + (result_ptr as _, result_len as _) + } + let mut result: Vec = Vec::with_capacity(2 * arg.len()); + for value in arg { + let (ptr, size) = __fce_generated_vec_serializer_Vec_Vec_u8___Vec_u8_(&value); + result.push(ptr as _); + result.push(size as _); + } + let result_ptr = result.as_ptr(); + let result_len = 4 * result.len(); + fluence::internal::add_object_to_release(Box::new(result)); + (result_ptr as _, result_len as _) + } + let mut result: Vec = Vec::with_capacity(2 * arg.len()); + for value in arg { + let (ptr, size) = __fce_generated_vec_serializer_Vec_Vec_u8__(&value); + result.push(ptr as _); + result.push(size as _); + } + let result_ptr = result.as_ptr(); + let result_len = 4 * result.len(); + fluence::internal::add_object_to_release(Box::new(result)); + (result_ptr as _, result_len as _) + } + { + let (serialized_vec_ptr, serialized_vec_size) = __fce_generated_vec_serializer(&result); + fluence::internal::set_result_ptr(serialized_vec_ptr as _); + fluence::internal::set_result_size(serialized_vec_size as _); + } + fluence::internal::add_object_to_release(Box::new(result)); +} +#[cfg(target_arch = "wasm32")] +#[doc(hidden)] +#[allow(clippy::all)] +#[link_section = "__fce_generated_section__inner_arrays_1"] +pub static __fce_generated_static_global_inner_arrays_1: [u8; 327usize] = { + * b"{\"ast_type\":\"Function\",\"signature\":{\"name\":\"inner_arrays_1\",\"arguments\":[{\"name\":\"arg\",\"ty\":{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"U8\":\"ByValue\"},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]}}],\"output_type\":{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"U8\":\"ByValue\"},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]}}}" +}; diff --git a/crates/wit/tests/generation_tests/exports/arrays/fce.rs b/crates/wit/tests/generation_tests/exports/arrays/fce.rs new file mode 100644 index 0000000..8746641 --- /dev/null +++ b/crates/wit/tests/generation_tests/exports/arrays/fce.rs @@ -0,0 +1,3 @@ +pub fn inner_arrays_1(arg: Vec>>>) -> Vec>>> { + unimplemented!() +} diff --git a/crates/wit/tests/generation_tests/export_functions/basic_types/expanded.rs b/crates/wit/tests/generation_tests/exports/basic_types/expanded.rs similarity index 92% rename from crates/wit/tests/generation_tests/export_functions/basic_types/expanded.rs rename to crates/wit/tests/generation_tests/exports/basic_types/expanded.rs index 6498cb4..40125d9 100644 --- a/crates/wit/tests/generation_tests/export_functions/basic_types/expanded.rs +++ b/crates/wit/tests/generation_tests/exports/basic_types/expanded.rs @@ -73,9 +73,11 @@ pub unsafe fn __fce_generated_wrapper_func_all_types( unsafe fn __fce_generated_vec_serializer(arg: &Vec) -> (u32, u32) { (arg.as_ptr() as _, arg.len() as _) } - let result = __fce_generated_vec_serializer(&result); - fluence::internal::set_result_ptr(result.0 as _); - fluence::internal::set_result_size(result.1 as _); + { + let (serialized_vec_ptr, serialized_vec_size) = __fce_generated_vec_serializer(&result); + fluence::internal::set_result_ptr(serialized_vec_ptr as _); + fluence::internal::set_result_size(serialized_vec_size as _); + } fluence::internal::add_object_to_release(Box::new(result)); } #[cfg(target_arch = "wasm32")] diff --git a/crates/wit/tests/generation_tests/export_functions/basic_types/fce.rs b/crates/wit/tests/generation_tests/exports/basic_types/fce.rs similarity index 100% rename from crates/wit/tests/generation_tests/export_functions/basic_types/fce.rs rename to crates/wit/tests/generation_tests/exports/basic_types/fce.rs diff --git a/crates/wit/tests/generation_tests/exports/refs/expanded.rs b/crates/wit/tests/generation_tests/exports/refs/expanded.rs new file mode 100644 index 0000000..90df287 --- /dev/null +++ b/crates/wit/tests/generation_tests/exports/refs/expanded.rs @@ -0,0 +1,104 @@ +pub fn test_array_refs(arg: &Vec>) -> &Vec>>> { + unimplemented!() +} +#[cfg(target_arch = "wasm32")] +#[export_name = "test_array_refs"] +#[no_mangle] +#[doc(hidden)] +#[allow(clippy::all)] +pub unsafe fn __fce_generated_wrapper_func_test_array_refs(arg_0: u32, arg_1: u32) { + unsafe fn __fce_generated_vec_deserializer_0(offset: u32, size: u32) -> Vec> { + let size = size / 8; + unsafe fn __fce_generated_vec_deserializer_0_String(offset: u32, size: u32) -> Vec { + let size = size / 8; + let mut arg: Vec = Vec::from_raw_parts(offset as _, size as _, size as _); + let mut arg = arg.into_iter(); + let mut result = Vec::with_capacity(arg.len() / 2); + while let Some(offset) = arg.next() { + let size = arg.next().unwrap(); + let value = String::from_raw_parts(offset as _, size as _, size as _); + result.push(value); + } + result + } + let mut arg: Vec = Vec::from_raw_parts(offset as _, size as _, size as _); + let mut result = Vec::with_capacity(arg.len()); + let mut arg = arg.into_iter(); + while let Some(offset) = arg.next() { + let size = arg.next().unwrap(); + let value = __fce_generated_vec_deserializer_0_String(offset as _, size as _); + result.push(value); + } + result + } + let converted_arg_0 = __fce_generated_vec_deserializer_0(arg_0 as _, arg_1 as _); + let result = test_array_refs(&converted_arg_0); + unsafe fn __fce_generated_vec_serializer(arg: &Vec>>>) -> (u32, u32) { + unsafe fn __fce_generated_vec_serializer_Vec_Vec_String__( + arg: &Vec>> + ) -> (u32, u32) { + unsafe fn __fce_generated_vec_serializer_Vec_Vec_String___Vec_String_( + arg: &Vec> + ) -> (u32, u32) { + unsafe fn __fce_generated_vec_serializer_Vec_Vec_String___Vec_String__String( + arg: &Vec + ) -> (u32, u32) { + let mut result: Vec = Vec::with_capacity(arg.len()); + for value in arg { + result.push(value.as_ptr() as _); + result.push(value.len() as _); + } + let result_ptr = result.as_ptr(); + let result_len = 4 * result.len(); + fluence::internal::add_object_to_release(Box::new(result)); + (result_ptr as _, result_len as _) + } + let mut result: Vec = Vec::with_capacity(2 * arg.len()); + for value in arg { + let (ptr, size) = + __fce_generated_vec_serializer_Vec_Vec_String___Vec_String__String(&value); + result.push(ptr as _); + result.push(size as _); + } + let result_ptr = result.as_ptr(); + let result_len = 4 * result.len(); + fluence::internal::add_object_to_release(Box::new(result)); + (result_ptr as _, result_len as _) + } + let mut result: Vec = Vec::with_capacity(2 * arg.len()); + for value in arg { + let (ptr, size) = + __fce_generated_vec_serializer_Vec_Vec_String___Vec_String_(&value); + result.push(ptr as _); + result.push(size as _); + } + let result_ptr = result.as_ptr(); + let result_len = 4 * result.len(); + fluence::internal::add_object_to_release(Box::new(result)); + (result_ptr as _, result_len as _) + } + let mut result: Vec = Vec::with_capacity(2 * arg.len()); + for value in arg { + let (ptr, size) = __fce_generated_vec_serializer_Vec_Vec_String__(&value); + result.push(ptr as _); + result.push(size as _); + } + let result_ptr = result.as_ptr(); + let result_len = 4 * result.len(); + fluence::internal::add_object_to_release(Box::new(result)); + (result_ptr as _, result_len as _) + } + { + let (serialized_vec_ptr, serialized_vec_size) = __fce_generated_vec_serializer(&result); + fluence::internal::set_result_ptr(serialized_vec_ptr as _); + fluence::internal::set_result_size(serialized_vec_size as _); + } + fluence::internal::add_object_to_release(Box::new(converted_arg_0)); +} +#[cfg(target_arch = "wasm32")] +#[doc(hidden)] +#[allow(clippy::all)] +#[link_section = "__fce_generated_section__test_array_refs"] +pub static __fce_generated_static_global_test_array_refs: [u8; 294usize] = { + * b"{\"ast_type\":\"Function\",\"signature\":{\"name\":\"test_array_refs\",\"arguments\":[{\"name\":\"arg\",\"ty\":{\"Vector\":[{\"Vector\":[{\"Utf8String\":\"ByValue\"},\"ByValue\"]},\"ByRef\"]}}],\"output_type\":{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Utf8String\":\"ByValue\"},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByRef\"]}}}" +}; diff --git a/crates/wit/tests/generation_tests/exports/refs/fce.rs b/crates/wit/tests/generation_tests/exports/refs/fce.rs new file mode 100644 index 0000000..66bf871 --- /dev/null +++ b/crates/wit/tests/generation_tests/exports/refs/fce.rs @@ -0,0 +1,3 @@ +pub fn test_array_refs(arg: &Vec>) -> &Vec>>> { + unimplemented!() +} diff --git a/crates/wit/tests/generation_tests/records/call_parameters/expanded.rs b/crates/wit/tests/generation_tests/records/call_parameters/expanded.rs index 8347588..b3cd6e3 100644 --- a/crates/wit/tests/generation_tests/records/call_parameters/expanded.rs +++ b/crates/wit/tests/generation_tests/records/call_parameters/expanded.rs @@ -16,8 +16,8 @@ pub struct CallParameters { #[doc(hidden)] #[allow(clippy::all)] impl CallParameters { - pub fn __fce_generated_serialize(self) -> *const u8 { - let mut raw_record: Vec = Vec::new(); + pub fn __fce_generated_serialize(&self) -> *const u8 { + let mut raw_record: Vec = Vec::with_capacity(2 * 6usize); raw_record.push(self.init_peer_id.as_ptr() as _); raw_record.push(self.init_peer_id.len() as _); raw_record.push(self.service_id.as_ptr() as _); @@ -38,7 +38,10 @@ impl CallParameters { for value in arg { result.push(value.__fce_generated_serialize() as _); } - (result.as_ptr() as _, (4 * result.len()) as _) + let result_ptr = result.as_ptr(); + let result_len = 4 * result.len(); + fluence::internal::add_object_to_release(Box::new(result)); + (result_ptr as _, result_len as _) } let mut result: Vec = Vec::with_capacity(2 * arg.len()); for value in arg { @@ -47,14 +50,17 @@ impl CallParameters { result.push(ptr as _); result.push(size as _); } - (result.as_ptr() as _, (4 * result.len()) as _) + let result_ptr = result.as_ptr(); + let result_len = 4 * result.len(); + fluence::internal::add_object_to_release(Box::new(result)); + (result_ptr as _, result_len as _) } let serialized_arg_5 = unsafe { __fce_generated_vec_serializer_tetraplets_5(&self.tetraplets) }; raw_record.push(serialized_arg_5.0 as _); raw_record.push(serialized_arg_5.1 as _); let raw_record_ptr = raw_record.as_ptr(); - fluence::internal::add_object_to_release(Box::new(self)); + fluence::internal::add_object_to_release(Box::new(raw_record)); raw_record_ptr as _ } pub unsafe fn __fce_generated_deserialize(record_ptr: *const u8) -> Self { @@ -147,4 +153,4 @@ impl CallParameters { #[link_section = "__fce_generated_section__CallParameters"] pub static __fce_generated_static_global_CallParameters: [u8; 445usize] = { * b"{\"ast_type\":\"Record\",\"name\":\"CallParameters\",\"fields\":[{\"name\":\"init_peer_id\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"service_id\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"service_creator_peer_id\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"host_id\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"particle_id\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"tetraplets\",\"ty\":{\"Vector\":[{\"Vector\":[{\"Record\":[\"SecurityTetraplet\",\"ByValue\"]},\"ByValue\"]},\"ByValue\"]}}]}" -}; \ No newline at end of file +}; diff --git a/crates/wit/tests/generation_tests/records/use_as_type/expanded.rs b/crates/wit/tests/generation_tests/records/use_as_type/expanded.rs new file mode 100644 index 0000000..e2fab5d --- /dev/null +++ b/crates/wit/tests/generation_tests/records/use_as_type/expanded.rs @@ -0,0 +1,140 @@ +pub fn inner_arrays_2(arg: Vec>>>) -> Vec>>> { + unimplemented!() +} +#[cfg(target_arch = "wasm32")] +#[export_name = "inner_arrays_2"] +#[no_mangle] +#[doc(hidden)] +#[allow(clippy::all)] +pub unsafe fn __fce_generated_wrapper_func_inner_arrays_2(arg_0: u32, arg_1: u32) { + unsafe fn __fce_generated_vec_deserializer_0( + offset: u32, + size: u32 + ) -> Vec>>> { + let size = size / 8; + unsafe fn __fce_generated_vec_deserializer_0_Vec_Vec_TestRecord__( + offset: u32, + size: u32 + ) -> Vec>> { + let size = size / 8; + unsafe fn __fce_generated_vec_deserializer_0_Vec_Vec_TestRecord___Vec_TestRecord_( + offset: u32, + size: u32 + ) -> Vec> { + let size = size / 8; + unsafe fn __fce_generated_vec_deserializer_0_Vec_Vec_TestRecord___Vec_TestRecord__TestRecord( + offset: u32, + size: u32 + ) -> Vec { + let size = size / 8; + let mut arg: Vec = Vec::from_raw_parts(offset as _, size as _, size as _); + let mut result = Vec::with_capacity(arg.len()); + for offset in arg { + let value = TestRecord::__fce_generated_deserialize(offset as _); + result.push(value); + } + result + } + let mut arg: Vec = Vec::from_raw_parts(offset as _, size as _, size as _); + let mut result = Vec::with_capacity(arg.len()); + let mut arg = arg.into_iter(); + while let Some(offset) = arg.next() { + let size = arg.next().unwrap(); + let value = __fce_generated_vec_deserializer_0_Vec_Vec_TestRecord___Vec_TestRecord__TestRecord ( offset as _ , size as _ ) ; + result.push(value); + } + result + } + let mut arg: Vec = Vec::from_raw_parts(offset as _, size as _, size as _); + let mut result = Vec::with_capacity(arg.len()); + let mut arg = arg.into_iter(); + while let Some(offset) = arg.next() { + let size = arg.next().unwrap(); + let value = __fce_generated_vec_deserializer_0_Vec_Vec_TestRecord___Vec_TestRecord_( + offset as _, + size as _ + ); + result.push(value); + } + result + } + let mut arg: Vec = Vec::from_raw_parts(offset as _, size as _, size as _); + let mut result = Vec::with_capacity(arg.len()); + let mut arg = arg.into_iter(); + while let Some(offset) = arg.next() { + let size = arg.next().unwrap(); + let value = + __fce_generated_vec_deserializer_0_Vec_Vec_TestRecord__(offset as _, size as _); + result.push(value); + } + result + } + let converted_arg_0 = __fce_generated_vec_deserializer_0(arg_0 as _, arg_1 as _); + let result = inner_arrays_2(converted_arg_0); + unsafe fn __fce_generated_vec_serializer(arg: &Vec>>>) -> (u32, u32) { + unsafe fn __fce_generated_vec_serializer_Vec_Vec_TestRecord__( + arg: &Vec>> + ) -> (u32, u32) { + unsafe fn __fce_generated_vec_serializer_Vec_Vec_TestRecord___Vec_TestRecord_( + arg: &Vec> + ) -> (u32, u32) { + unsafe fn __fce_generated_vec_serializer_Vec_Vec_TestRecord___Vec_TestRecord__TestRecord( + arg: &Vec + ) -> (u32, u32) { + let mut result: Vec = Vec::with_capacity(arg.len()); + for value in arg { + result.push(value.__fce_generated_serialize() as _); + } + let result_ptr = result.as_ptr(); + let result_len = 4 * result.len(); + fluence::internal::add_object_to_release(Box::new(result)); + (result_ptr as _, result_len as _) + } + let mut result: Vec = Vec::with_capacity(2 * arg.len()); + for value in arg { + let ( ptr , size ) = __fce_generated_vec_serializer_Vec_Vec_TestRecord___Vec_TestRecord__TestRecord ( & value ) ; + result.push(ptr as _); + result.push(size as _); + } + let result_ptr = result.as_ptr(); + let result_len = 4 * result.len(); + fluence::internal::add_object_to_release(Box::new(result)); + (result_ptr as _, result_len as _) + } + let mut result: Vec = Vec::with_capacity(2 * arg.len()); + for value in arg { + let (ptr, size) = + __fce_generated_vec_serializer_Vec_Vec_TestRecord___Vec_TestRecord_(&value); + result.push(ptr as _); + result.push(size as _); + } + let result_ptr = result.as_ptr(); + let result_len = 4 * result.len(); + fluence::internal::add_object_to_release(Box::new(result)); + (result_ptr as _, result_len as _) + } + let mut result: Vec = Vec::with_capacity(2 * arg.len()); + for value in arg { + let (ptr, size) = __fce_generated_vec_serializer_Vec_Vec_TestRecord__(&value); + result.push(ptr as _); + result.push(size as _); + } + let result_ptr = result.as_ptr(); + let result_len = 4 * result.len(); + fluence::internal::add_object_to_release(Box::new(result)); + (result_ptr as _, result_len as _) + } + { + let (serialized_vec_ptr, serialized_vec_size) = __fce_generated_vec_serializer(&result); + fluence::internal::set_result_ptr(serialized_vec_ptr as _); + fluence::internal::set_result_size(serialized_vec_size as _); + } + fluence::internal::add_object_to_release(Box::new(result)); +} +#[cfg(target_arch = "wasm32")] +#[doc(hidden)] +#[allow(clippy::all)] +#[link_section = "__fce_generated_section__inner_arrays_2"] +pub static __fce_generated_static_global_inner_arrays_2: [u8; 365usize] = { + * b"{\"ast_type\":\"Function\",\"signature\":{\"name\":\"inner_arrays_2\",\"arguments\":[{\"name\":\"arg\",\"ty\":{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Record\":[\"TestRecord\",\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]}}],\"output_type\":{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Record\":[\"TestRecord\",\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]}}}" +}; diff --git a/crates/wit/tests/generation_tests/records/use_as_type/fce.rs b/crates/wit/tests/generation_tests/records/use_as_type/fce.rs new file mode 100644 index 0000000..36e326c --- /dev/null +++ b/crates/wit/tests/generation_tests/records/use_as_type/fce.rs @@ -0,0 +1,3 @@ +pub fn inner_arrays_2(arg: Vec>>>) -> Vec>>> { + unimplemented!() +} diff --git a/crates/wit/tests/generation_tests_runner.rs b/crates/wit/tests/generation_tests_runner.rs index fe3504f..0b112a9 100644 --- a/crates/wit/tests/generation_tests_runner.rs +++ b/crates/wit/tests/generation_tests_runner.rs @@ -3,14 +3,41 @@ mod utils; use utils::test_fce_token_streams; #[test] -fn test() { - test_fce_token_streams( - "tests/generation_tests/export_functions/basic_types/fce.rs", - "tests/generation_tests/export_functions/basic_types/expanded.rs", - ); +fn exports_arrays() { + assert!(test_fce_token_streams( + "tests/generation_tests/exports/arrays/fce.rs", + "tests/generation_tests/exports/arrays/expanded.rs", + )); +} - test_fce_token_streams( +#[test] +fn exports_basic_types() { + assert!(test_fce_token_streams( + "tests/generation_tests/exports/basic_types/fce.rs", + "tests/generation_tests/exports/basic_types/expanded.rs", + )); +} + +#[test] +fn exports_refs() { + assert!(test_fce_token_streams( + "tests/generation_tests/exports/refs/fce.rs", + "tests/generation_tests/exports/refs/expanded.rs", + )); +} + +#[test] +fn records_call_parameters() { + assert!(test_fce_token_streams( "tests/generation_tests/records/call_parameters/fce.rs", "tests/generation_tests/records/call_parameters/expanded.rs", - ); + )); +} + +#[test] +fn records_use_as_type() { + assert!(test_fce_token_streams( + "tests/generation_tests/records/use_as_type/fce.rs", + "tests/generation_tests/records/use_as_type/expanded.rs", + )); } diff --git a/crates/wit/tests/utils.rs b/crates/wit/tests/utils.rs index e00d5f3..d5ed28d 100644 --- a/crates/wit/tests/utils.rs +++ b/crates/wit/tests/utils.rs @@ -21,7 +21,7 @@ use pretty_assertions::assert_eq; use std::io::Read; use std::path::Path; -pub fn test_fce_token_streams(fce_path: FP, expanded_path: EP) +pub fn test_fce_token_streams(fce_path: FP, expanded_path: EP) -> bool where FP: AsRef, EP: AsRef, @@ -34,7 +34,9 @@ where let expanded_item = items_from_file(expanded_path); let fce_item = to_syn_item(fce_token_streams); - assert_eq!(fce_item, expanded_item); + assert_eq!(expanded_item, fce_item); + + fce_item == expanded_item } fn stream_from_file

(path: P) -> proc_macro2::TokenStream diff --git a/fluence/src/call_parameters.rs b/fluence/src/call_parameters.rs index be09f8c..e6eab8a 100644 --- a/fluence/src/call_parameters.rs +++ b/fluence/src/call_parameters.rs @@ -16,12 +16,12 @@ use fluence_sdk_macro::fce; -use serde::Serialize; -use serde::Deserialize; +//use serde::Serialize; +//use serde::Deserialize; /// Describes an origin that set an argument. #[fce] -#[derive(Clone, PartialEq, Default, Eq, Debug, Serialize, Deserialize)] +//#[derive(Clone, PartialEq, Default, Eq, Debug, Serialize, Deserialize)] pub struct SecurityTetraplet { pub peer_pk: String, pub service_id: String, @@ -31,7 +31,7 @@ pub struct SecurityTetraplet { /// This struct contains parameters that would be accessible by Wasm modules. #[fce] -#[derive(Clone, PartialEq, Default, Eq, Debug, Serialize, Deserialize)] +//#[derive(Clone, PartialEq, Default, Eq, Debug, Serialize, Deserialize)] pub struct CallParameters { /// Peer id of the AIR script initiator. pub init_peer_id: String, diff --git a/fluence/tests/compilation_tests_runner.rs b/fluence/tests/compilation_tests_runner.rs index 2ae229f..3fa3371 100644 --- a/fluence/tests/compilation_tests_runner.rs +++ b/fluence/tests/compilation_tests_runner.rs @@ -1,5 +1,5 @@ #[test] -fn test() { +fn fce_compilation_tests() { let tests = trybuild::TestCases::new(); tests.compile_fail("tests/compilation_tests/export_functions/array_inner_refs.rs"); tests.pass("tests/compilation_tests/export_functions/arrays.rs");