From 9ae4910c11e70e5bf37dd1ba2ab578c52dc7980a Mon Sep 17 00:00:00 2001 From: vms Date: Mon, 12 Apr 2021 20:41:04 +0300 Subject: [PATCH] fix imports with basic types passed by references --- crates/wit/src/parsed_type/foreign_mod_arg.rs | 13 +++++- .../wit/src/parsed_type/foreign_mod_prolog.rs | 39 ++++++++++------ .../import_functions/basic_ref_types.rs | 44 +++++++++++++++++++ .../records/basic_structs.rs | 2 - .../compilation_tests/records/empty_struct.rs | 2 - .../records/struct_with_improper_types.rs | 2 - .../records/struct_with_improper_types.stderr | 12 ++--- fluence/tests/compilation_tests_runner.rs | 1 + 8 files changed, 88 insertions(+), 27 deletions(-) create mode 100644 fluence/tests/compilation_tests/import_functions/basic_ref_types.rs diff --git a/crates/wit/src/parsed_type/foreign_mod_arg.rs b/crates/wit/src/parsed_type/foreign_mod_arg.rs index 48f6934..1da4902 100644 --- a/crates/wit/src/parsed_type/foreign_mod_arg.rs +++ b/crates/wit/src/parsed_type/foreign_mod_arg.rs @@ -38,7 +38,18 @@ impl ForeignModArgGlueCodeGenerator for ParsedType { #arg.__fce_generated_serialize() as _ }, ParsedType::Boolean(_) => quote! { #arg as _ }, - _ => quote! { #arg }, + ty => arg_for_basic_type(ty, &arg), } } } + +fn arg_for_basic_type(ty: &ParsedType, arg: &syn::Ident) -> proc_macro2::TokenStream { + use crate::parsed_type::PassingStyle; + + let passing_style = crate::parsed_type::passing_style_of(ty); + + match passing_style { + PassingStyle::ByValue => quote! { #arg }, + _ => quote! { *#arg }, + } +} diff --git a/crates/wit/src/parsed_type/foreign_mod_prolog.rs b/crates/wit/src/parsed_type/foreign_mod_prolog.rs index 87d6a0c..b85fb12 100644 --- a/crates/wit/src/parsed_type/foreign_mod_prolog.rs +++ b/crates/wit/src/parsed_type/foreign_mod_prolog.rs @@ -73,7 +73,6 @@ impl ForeignModPrologGlueCodeGenerator for Vec { .fold((Vec::new(), proc_macro2::TokenStream::new(), proc_macro2::TokenStream::new()), |(mut arg_names, mut arg_transforms, mut arg_drops), (id, arg)| { let arg_name = format!("arg_{}", id); let arg_ident = new_ident!(arg_name); - arg_names.push(arg_ident.clone()); // arguments of following two types shouldn't be deleted after transformation to raw view match &arg.ty { @@ -82,23 +81,13 @@ impl ForeignModPrologGlueCodeGenerator for Vec { arg_drops.extend(quote::quote! { std::mem::ManuallyDrop::drop(&mut #arg_ident); }); }, ParsedType::Vector(ty, passing_style) => { - let generated_ser_name = format!("__fce_generated_vec_serializer_{}", arg_name); - let generated_ser_name = crate::utils::prepare_ident(generated_ser_name); - let generated_ser_ident = new_ident!(generated_ser_name); - - let vector_serializer = super::vector_utils::generate_vector_serializer(ty, *passing_style, &generated_ser_name); - - let arg_transform = quote::quote! { - #vector_serializer - - let #arg_ident = #generated_ser_ident(&#arg_ident); - }; - arg_transforms.extend(arg_transform); - + let vec_arg_transforms = vector_arg_transforms(ty, *passing_style, &arg_name); + arg_transforms.extend(vec_arg_transforms); } _ => {} } + arg_names.push(arg_ident); (arg_names, arg_transforms, arg_drops) }); @@ -137,3 +126,25 @@ impl ForeignModPrologGlueCodeGenerator for Vec { } } } + +fn vector_arg_transforms( + ty: &ParsedType, + passing_style: PassingStyle, + arg_name: &str, +) -> proc_macro2::TokenStream { + let generated_ser_name = format!("__fce_generated_vec_serializer_{}", arg_name); + let generated_ser_name = crate::utils::prepare_ident(generated_ser_name); + let generated_ser_ident = new_ident!(generated_ser_name); + let arg_ident = new_ident!(arg_name); + + let vector_serializer = + super::vector_utils::generate_vector_serializer(ty, passing_style, &generated_ser_name); + + let arg_transform = quote::quote! { + #vector_serializer + + let #arg_ident = #generated_ser_ident(&#arg_ident); + }; + + arg_transform +} diff --git a/fluence/tests/compilation_tests/import_functions/basic_ref_types.rs b/fluence/tests/compilation_tests/import_functions/basic_ref_types.rs new file mode 100644 index 0000000..7972815 --- /dev/null +++ b/fluence/tests/compilation_tests/import_functions/basic_ref_types.rs @@ -0,0 +1,44 @@ +#![allow(improper_ctypes)] + +use fluence::fce; + +fn main() {} + +#[fce] +#[link(wasm_import_module = "arguments_passing_effector")] +extern "C" { + pub fn all_ref_types( + arg_0: &i8, + arg_1: &i16, + arg_2: &i32, + arg_3: &i64, + arg_4: &u8, + arg_5: &u16, + arg_6: &u32, + arg_7: &u64, + arg_8: &f32, + arg_9: &f64, + arg_10: &String, + arg_11: &Vec, + ) -> Vec; + + pub fn string_ref_type(arg: &String) -> String; + + pub fn str_type(arg: &str) -> String; + + pub fn bytearray_ref_type(arg: &Vec) -> Vec; + + pub fn bool_ref_type(arg: &bool) -> bool; + + pub fn f32_ref_type(arg: &f32) -> f32; + + pub fn f64_ref_type(arg: &f64) -> f64; + + pub fn u32_ref_type(arg: &u32) -> u32; + + pub fn u64_ref_type(arg: &u64) -> u64; + + pub fn i32_ref_type(arg: &i32) -> i32; + + pub fn i64_ref_type(arg: &i64) -> i64; +} diff --git a/fluence/tests/compilation_tests/records/basic_structs.rs b/fluence/tests/compilation_tests/records/basic_structs.rs index 34d8b79..b1daa76 100644 --- a/fluence/tests/compilation_tests/records/basic_structs.rs +++ b/fluence/tests/compilation_tests/records/basic_structs.rs @@ -1,5 +1,3 @@ -#![allow(improper_ctypes)] - use fluence::fce; fn main() {} diff --git a/fluence/tests/compilation_tests/records/empty_struct.rs b/fluence/tests/compilation_tests/records/empty_struct.rs index 7a8bce1..86e72e2 100644 --- a/fluence/tests/compilation_tests/records/empty_struct.rs +++ b/fluence/tests/compilation_tests/records/empty_struct.rs @@ -1,5 +1,3 @@ -#![allow(improper_ctypes)] - use fluence::fce; fn main() {} diff --git a/fluence/tests/compilation_tests/records/struct_with_improper_types.rs b/fluence/tests/compilation_tests/records/struct_with_improper_types.rs index 40889a4..f8743dc 100644 --- a/fluence/tests/compilation_tests/records/struct_with_improper_types.rs +++ b/fluence/tests/compilation_tests/records/struct_with_improper_types.rs @@ -1,5 +1,3 @@ -#![allow(improper_ctypes)] - use fluence::fce; fn main() {} diff --git a/fluence/tests/compilation_tests/records/struct_with_improper_types.stderr b/fluence/tests/compilation_tests/records/struct_with_improper_types.stderr index c6584d4..4b519f7 100644 --- a/fluence/tests/compilation_tests/records/struct_with_improper_types.stderr +++ b/fluence/tests/compilation_tests/records/struct_with_improper_types.stderr @@ -1,17 +1,17 @@ error: types with lifetimes or generics aren't allowed - --> $DIR/struct_with_improper_types.rs:9:12 + --> $DIR/struct_with_improper_types.rs:7:12 | -9 | pub a: Box, +7 | pub a: Box, | ^^^^^^^^ error: types with lifetimes or generics aren't allowed - --> $DIR/struct_with_improper_types.rs:14:21 + --> $DIR/struct_with_improper_types.rs:12:21 | -14 | pub a: std::rc::Rc, +12 | pub a: std::rc::Rc, | ^^^^^^^ error: types with lifetimes or generics aren't allowed - --> $DIR/struct_with_improper_types.rs:19:30 + --> $DIR/struct_with_improper_types.rs:17:30 | -19 | pub a: std::collections::HashMap, +17 | pub a: std::collections::HashMap, | ^^^^^^^^^^^^^^^^^^^^ diff --git a/fluence/tests/compilation_tests_runner.rs b/fluence/tests/compilation_tests_runner.rs index ba0ca3a..c6ab271 100644 --- a/fluence/tests/compilation_tests_runner.rs +++ b/fluence/tests/compilation_tests_runner.rs @@ -13,6 +13,7 @@ fn fce_compilation_tests() { tests.pass("tests/compilation_tests/import_functions/arrays.rs"); tests.pass("tests/compilation_tests/import_functions/ref_arrays.rs"); tests.pass("tests/compilation_tests/import_functions/basic_types.rs"); + tests.pass("tests/compilation_tests/import_functions/basic_ref_types.rs"); tests.pass("tests/compilation_tests/import_functions/ref_basic_types.rs"); tests.compile_fail("tests/compilation_tests/import_functions/improper_types.rs");