fix imports with basic types passed by references

This commit is contained in:
vms 2021-04-12 20:41:04 +03:00
parent e2a1e66e17
commit 9ae4910c11
8 changed files with 88 additions and 27 deletions

View File

@ -38,7 +38,18 @@ impl ForeignModArgGlueCodeGenerator for ParsedType {
#arg.__fce_generated_serialize() as _ #arg.__fce_generated_serialize() as _
}, },
ParsedType::Boolean(_) => quote! { #arg 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 },
}
}

View File

@ -73,7 +73,6 @@ impl ForeignModPrologGlueCodeGenerator for Vec<AstFnArgument> {
.fold((Vec::new(), proc_macro2::TokenStream::new(), proc_macro2::TokenStream::new()), |(mut arg_names, mut arg_transforms, mut arg_drops), (id, arg)| { .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_name = format!("arg_{}", id);
let arg_ident = new_ident!(arg_name); 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 // arguments of following two types shouldn't be deleted after transformation to raw view
match &arg.ty { match &arg.ty {
@ -82,23 +81,13 @@ impl ForeignModPrologGlueCodeGenerator for Vec<AstFnArgument> {
arg_drops.extend(quote::quote! { std::mem::ManuallyDrop::drop(&mut #arg_ident); }); arg_drops.extend(quote::quote! { std::mem::ManuallyDrop::drop(&mut #arg_ident); });
}, },
ParsedType::Vector(ty, passing_style) => { ParsedType::Vector(ty, passing_style) => {
let generated_ser_name = format!("__fce_generated_vec_serializer_{}", arg_name); let vec_arg_transforms = vector_arg_transforms(ty, *passing_style, &arg_name);
let generated_ser_name = crate::utils::prepare_ident(generated_ser_name); arg_transforms.extend(vec_arg_transforms);
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);
} }
_ => {} _ => {}
} }
arg_names.push(arg_ident);
(arg_names, arg_transforms, arg_drops) (arg_names, arg_transforms, arg_drops)
}); });
@ -137,3 +126,25 @@ impl ForeignModPrologGlueCodeGenerator for Vec<AstFnArgument> {
} }
} }
} }
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
}

View File

@ -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<u8>,
) -> Vec<u8>;
pub fn string_ref_type(arg: &String) -> String;
pub fn str_type(arg: &str) -> String;
pub fn bytearray_ref_type(arg: &Vec<u8>) -> Vec<u8>;
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;
}

View File

@ -1,5 +1,3 @@
#![allow(improper_ctypes)]
use fluence::fce; use fluence::fce;
fn main() {} fn main() {}

View File

@ -1,5 +1,3 @@
#![allow(improper_ctypes)]
use fluence::fce; use fluence::fce;
fn main() {} fn main() {}

View File

@ -1,5 +1,3 @@
#![allow(improper_ctypes)]
use fluence::fce; use fluence::fce;
fn main() {} fn main() {}

View File

@ -1,17 +1,17 @@
error: types with lifetimes or generics aren't allowed 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<i32>, 7 | pub a: Box<i32>,
| ^^^^^^^^ | ^^^^^^^^
error: types with lifetimes or generics aren't allowed 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<i32>, 12 | pub a: std::rc::Rc<i32>,
| ^^^^^^^ | ^^^^^^^
error: types with lifetimes or generics aren't allowed 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<i32, String>, 17 | pub a: std::collections::HashMap<i32, String>,
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^

View File

@ -13,6 +13,7 @@ fn fce_compilation_tests() {
tests.pass("tests/compilation_tests/import_functions/arrays.rs"); 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/ref_arrays.rs");
tests.pass("tests/compilation_tests/import_functions/basic_types.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.pass("tests/compilation_tests/import_functions/ref_basic_types.rs");
tests.compile_fail("tests/compilation_tests/import_functions/improper_types.rs"); tests.compile_fail("tests/compilation_tests/import_functions/improper_types.rs");