mirror of
https://github.com/fluencelabs/marine-rs-sdk-test
synced 2024-12-04 23:30:18 +00:00
add ManuallyDrop for all foreign parameters in extern blocks
This commit is contained in:
parent
ff447a3258
commit
00a2a19289
@ -88,13 +88,15 @@ fn check_field(field: &syn::Field) -> Result<()> {
|
||||
const DOC_ATTR_NAME: &str = "doc";
|
||||
|
||||
// Check that all attributes are doc attributes
|
||||
if !field.attrs.iter().all(|attr| {
|
||||
let is_all_attrs_public = field.attrs.iter().all(|attr| {
|
||||
let meta = match attr.parse_meta() {
|
||||
Ok(meta) => meta,
|
||||
Err(_) => return false,
|
||||
};
|
||||
meta.path().is_ident(DOC_ATTR_NAME)
|
||||
}) {
|
||||
});
|
||||
|
||||
if !is_all_attrs_public {
|
||||
return Err(Error::new(field.span(), "field attributes isn't allowed"));
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@ pub(crate) struct WrapperDescriptor {
|
||||
pub(crate) arg_names: Vec<syn::Ident>,
|
||||
pub(crate) arg_types: Vec<proc_macro2::TokenStream>,
|
||||
pub(crate) raw_args: Vec<proc_macro2::TokenStream>,
|
||||
pub(crate) arg_transforms: proc_macro2::TokenStream,
|
||||
pub(crate) arg_drops: proc_macro2::TokenStream,
|
||||
}
|
||||
|
||||
pub(crate) struct ExternDescriptor {
|
||||
@ -34,7 +36,9 @@ pub(crate) struct ExternDescriptor {
|
||||
/// ```
|
||||
/// quote! {
|
||||
/// fn foo(#(#arg_names: #arg_types), *) {
|
||||
/// let arg_1 = std::mem::ManuallyDrop::new(arg_1);
|
||||
/// let result = original_foo(#(#raw_args), *);
|
||||
/// std::mem::ManuallyDrop::drop(&mut arg_1);
|
||||
/// ...
|
||||
/// }
|
||||
/// }
|
||||
@ -62,11 +66,20 @@ impl ForeignModPrologGlueCodeGenerator for Vec<ParsedType> {
|
||||
.map(|input_type| input_type.to_token_stream())
|
||||
.collect();
|
||||
|
||||
let arg_names: Vec<syn::Ident> = arg_types
|
||||
let (arg_names, arg_transforms, arg_drops) = self
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(id, _)| new_ident!(format!("arg_{}", id)))
|
||||
.collect();
|
||||
.fold((Vec::new(), proc_macro2::TokenStream::new(), proc_macro2::TokenStream::new()), |(mut arg_names, mut arg_transforms, mut arg_drops), (id, ty)| {
|
||||
let arg_ident = new_ident!(format!("arg_{}", id));
|
||||
arg_names.push(arg_ident.clone());
|
||||
|
||||
if ty.is_complex_type() {
|
||||
arg_transforms.extend(quote::quote! { let #arg_ident = std::mem::ManuallyDrop::new(#arg_ident); });
|
||||
arg_drops.extend(quote::quote! { std::mem::ManuallyDrop::drop(&mut #arg_ident); });
|
||||
}
|
||||
|
||||
(arg_names, arg_transforms, arg_drops)
|
||||
});
|
||||
|
||||
let raw_args: Vec<proc_macro2::TokenStream> = self
|
||||
.iter()
|
||||
@ -77,6 +90,8 @@ impl ForeignModPrologGlueCodeGenerator for Vec<ParsedType> {
|
||||
WrapperDescriptor {
|
||||
arg_names,
|
||||
arg_types,
|
||||
arg_transforms,
|
||||
arg_drops,
|
||||
raw_args,
|
||||
}
|
||||
}
|
||||
|
@ -108,6 +108,8 @@ fn generate_wrapper_functions(extern_item: &fce_ast_types::AstExternModItem) ->
|
||||
arg_names,
|
||||
arg_types,
|
||||
raw_args,
|
||||
arg_transforms,
|
||||
arg_drops,
|
||||
} = signature.input_types.generate_wrapper_prolog();
|
||||
|
||||
let FnEpilogDescriptor {
|
||||
@ -121,9 +123,15 @@ fn generate_wrapper_functions(extern_item: &fce_ast_types::AstExternModItem) ->
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
#visibility unsafe fn #func_name(#(#arg_names: #arg_types), *) #return_type {
|
||||
// make complex arguments manually droppable
|
||||
#arg_transforms
|
||||
|
||||
// calling the original function with converted args
|
||||
#return_expression #import_func_name(#(#raw_args), *);
|
||||
|
||||
// drop complex arguments
|
||||
#arg_drops
|
||||
|
||||
// return value conversation from Wasm type to a Rust type
|
||||
#epilog
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user