various fixes

This commit is contained in:
vms 2021-03-01 14:38:48 +03:00
parent 7f6075b52a
commit 4e3c2fdf3e
7 changed files with 50 additions and 13 deletions

View File

@ -177,14 +177,14 @@ fn parse_vec_bracket(args: &syn::PathArguments) -> syn::Result<&syn::Type> {
syn::PathArguments::AngleBracketed(args) => Ok(args), syn::PathArguments::AngleBracketed(args) => Ok(args),
_ => Err(Error::new( _ => Err(Error::new(
args.span(), args.span(),
"It has to be a bracketed value after Vec", "expected value in angle brackets (<>)",
)), )),
}?; }?;
let arg = generic_arg.args.first().ok_or_else(|| { let arg = generic_arg.args.first().ok_or_else(|| {
Error::new( Error::new(
generic_arg.span(), generic_arg.span(),
"Unsuitable type in Vec brackets, lifetimes, bindings, constraints and consts are unsupported", "Invalid type in Vec brackets. (NOTE: lifetimes, bindings, constraints and consts are not supported)",
) )
})?; })?;
@ -193,7 +193,7 @@ fn parse_vec_bracket(args: &syn::PathArguments) -> syn::Result<&syn::Type> {
syn::GenericArgument::Type(ty) => Ok(ty), syn::GenericArgument::Type(ty) => Ok(ty),
_ => Err(Error::new( _ => Err(Error::new(
arg.span(), arg.span(),
"Unsuitable type in Vec brackets, lifetimes, bindings, constraints and consts are unsupported", "Invalid type in Vec brackets. (NOTE: lifetimes, bindings, constraints and consts are not supported)",
)), )),
} }
} }

View File

@ -44,7 +44,13 @@ pub(crate) trait FnEpilogGlueCodeGenerator {
fn generate_fn_epilog(&self) -> FnEpilogDescriptor; fn generate_fn_epilog(&self) -> FnEpilogDescriptor;
} }
impl FnEpilogGlueCodeGenerator for (&Vec<(String, ParsedType)>, &Vec<syn::Ident>, &Option<ParsedType>) { impl FnEpilogGlueCodeGenerator
for (
&Vec<(String, ParsedType)>,
&Vec<syn::Ident>,
&Option<ParsedType>,
)
{
fn generate_fn_epilog(&self) -> FnEpilogDescriptor { fn generate_fn_epilog(&self) -> FnEpilogDescriptor {
FnEpilogDescriptor { FnEpilogDescriptor {
fn_return_type: generate_fn_return_type(self.2), fn_return_type: generate_fn_return_type(self.2),
@ -107,7 +113,7 @@ fn generate_epilog(ty: &Option<ParsedType>) -> proc_macro2::TokenStream {
fluence::internal::set_result_ptr(result.as_ptr() as _); fluence::internal::set_result_ptr(result.as_ptr() as _);
fluence::internal::set_result_size(result.len() as _); fluence::internal::set_result_size(result.len() as _);
} }
}, }
Some(ParsedType::Vector(ty, _)) => { Some(ParsedType::Vector(ty, _)) => {
let generated_serializer_name = String::from("__fce_generated_vec_serializer"); let generated_serializer_name = String::from("__fce_generated_vec_serializer");
let generated_serializer_ident = new_ident!(generated_serializer_name); let generated_serializer_ident = new_ident!(generated_serializer_name);
@ -130,13 +136,18 @@ fn generate_epilog(ty: &Option<ParsedType>) -> proc_macro2::TokenStream {
/// If an export function returns a reference, probably this reference is to one /// If an export function returns a reference, probably this reference is to one
/// of these function arguments. In this case they should preserve after the end /// of these function arguments. In this case they should preserve after the end
/// of the function and then deleted by IT with explicitly call of deallocate. /// of the function and then deleted by IT with explicitly call of deallocate.
fn generate_mem_forget(args: &Vec<(String, ParsedType)>, converted_args: &Vec<syn::Ident>, ret_type: &Option<ParsedType>) -> proc_macro2::TokenStream { fn generate_mem_forget(
args: &Vec<(String, ParsedType)>,
converted_args: &Vec<syn::Ident>,
ret_type: &Option<ParsedType>,
) -> proc_macro2::TokenStream {
let passing_style = ret_type.as_ref().map(passing_style_of); let passing_style = ret_type.as_ref().map(passing_style_of);
match passing_style { match passing_style {
Some(PassingStyle::ByValue) => mem_forget_by_ret_type(ret_type), Some(PassingStyle::ByValue) => mem_forget_by_ret_type(ret_type),
Some(PassingStyle::ByRef) | Some(PassingStyle::ByMutRef) => mem_forget_by_args(args, converted_args), Some(PassingStyle::ByRef) | Some(PassingStyle::ByMutRef) => {
mem_forget_by_args(args, converted_args)
}
None => quote! {}, None => quote! {},
} }
} }
@ -148,7 +159,10 @@ fn mem_forget_by_ret_type(ret_type: &Option<ParsedType>) -> proc_macro2::TokenSt
} }
} }
fn mem_forget_by_args(args: &Vec<(String, ParsedType)>, converted_args: &Vec<syn::Ident>) -> proc_macro2::TokenStream { fn mem_forget_by_args(
args: &Vec<(String, ParsedType)>,
converted_args: &Vec<syn::Ident>,
) -> proc_macro2::TokenStream {
debug_assert!(args.len() == converted_args.len()); debug_assert!(args.len() == converted_args.len());
let mut res = proc_macro2::TokenStream::new(); let mut res = proc_macro2::TokenStream::new();
@ -156,7 +170,7 @@ fn mem_forget_by_args(args: &Vec<(String, ParsedType)>, converted_args: &Vec<syn
let arg_passing_style = passing_style_of(arg); let arg_passing_style = passing_style_of(arg);
match arg_passing_style { match arg_passing_style {
// such values will be deleted inside an export function because they are being moved // such values will be deleted inside an export function because they are being moved
PassingStyle::ByValue => {}, PassingStyle::ByValue => {}
_ => res.extend(quote! { std::mem::forget(#converted_arg); }), _ => res.extend(quote! { std::mem::forget(#converted_arg); }),
} }
} }

View File

@ -156,7 +156,7 @@ fn generate_type_lifting_prolog(
TypeLifter { TypeLifter {
converted_arg_ident, converted_arg_ident,
type_lifter_glue_code type_lifter_glue_code,
} }
} }

View File

@ -76,6 +76,7 @@ impl ForeignModPrologGlueCodeGenerator for Vec<(String, ParsedType)> {
let arg_ident = new_ident!(arg_name); let arg_ident = new_ident!(arg_name);
arg_names.push(arg_ident.clone()); arg_names.push(arg_ident.clone());
// arguments of following two types shouldn't be deleted after transformation to raw view
match ty { match ty {
ParsedType::Utf8String(PassingStyle::ByValue) => { ParsedType::Utf8String(PassingStyle::ByValue) => {
arg_transforms.extend(quote::quote! { let mut #arg_ident = std::mem::ManuallyDrop::new(#arg_ident); }); arg_transforms.extend(quote::quote! { let mut #arg_ident = std::mem::ManuallyDrop::new(#arg_ident); });

View File

@ -57,7 +57,12 @@ impl quote::ToTokens for fce_ast_types::AstFunctionItem {
return_expression, return_expression,
epilog, epilog,
mem_forget, mem_forget,
} = (&signature.arguments, converted_arg_idents, &signature.output_type).generate_fn_epilog(); } = (
&signature.arguments,
converted_arg_idents,
&signature.output_type,
)
.generate_fn_epilog();
// here this Option must be Some // here this Option must be Some
let original_func = &self.original; let original_func = &self.original;

View File

@ -67,7 +67,8 @@ fn generate_extern_section_items(extern_item: &fce_ast_types::AstExternModItem)
for import in &extern_item.imports { for import in &extern_item.imports {
let signature = &import.signature; let signature = &import.signature;
let FnEpilogDescriptor { fn_return_type, .. } = (&vec![], &vec![], &signature.output_type).generate_fn_epilog(); let FnEpilogDescriptor { fn_return_type, .. } =
(&vec![], &vec![], &signature.output_type).generate_fn_epilog();
let link_name = import.link_name.as_ref().unwrap_or(&signature.name); let link_name = import.link_name.as_ref().unwrap_or(&signature.name);
let import_name = generate_import_name(&signature.name); let import_name = generate_import_name(&signature.name);

View File

@ -1,3 +1,19 @@
/*
* Copyright 2020 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
/// Raw Wasm types according to the spec except i128. /// Raw Wasm types according to the spec except i128.