This commit is contained in:
vms 2020-09-21 13:30:24 +03:00
parent c8db3e784c
commit c810e0831f
7 changed files with 84 additions and 58 deletions

View File

@ -34,6 +34,7 @@ use serde::Deserialize;
use syn::parse::Error; use syn::parse::Error;
use syn::spanned::Spanned; use syn::spanned::Spanned;
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use serde::export::Formatter;
/// An internal representation of supported Rust types. /// An internal representation of supported Rust types.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
@ -197,3 +198,26 @@ impl quote::ToTokens for ParsedType {
} }
} }
} }
impl std::fmt::Display for ParsedType {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
match self {
ParsedType::Boolean => f.write_str("bool"),
ParsedType::I8 => f.write_str("i8"),
ParsedType::I16 => f.write_str("i16"),
ParsedType::I32 => f.write_str("i32"),
ParsedType::I64 => f.write_str("i64"),
ParsedType::U8 => f.write_str("u8"),
ParsedType::U16 => f.write_str("u16"),
ParsedType::U32 => f.write_str("u32"),
ParsedType::U64 => f.write_str("u64"),
ParsedType::F32 => f.write_str("f32"),
ParsedType::F64 => f.write_str("u64"),
ParsedType::Utf8String => f.write_str("String"),
ParsedType::Vector(_) => f.write_str("Vec"),
ParsedType::Record(record_name) => f.write_str(&record_name),
}?;
Ok(())
}
}

View File

@ -118,7 +118,7 @@ fn generate_type_prolog(
quote! { quote! {
#vector_deserializer #vector_deserializer
let #generated_arg_id = #generated_deserializer_ident(#ptr, #size); let #generated_arg_id = #generated_deserializer_ident(#ptr as _, #size as _);
} }
} }
ParsedType::Record(record_name) => { ParsedType::Record(record_name) => {

View File

@ -69,7 +69,7 @@ impl ForeignModEpilogGlueCodeGenerator for Option<ParsedType> {
#generated_deserializer_ident( #generated_deserializer_ident(
fluence::internal::get_result_ptr() as _, fluence::internal::get_result_ptr() as _,
fluence::internal::get_result_size() as _, fluence::internal::get_result_size() as _,
); )
} }
} }
Some(ParsedType::Record(record_name)) => { Some(ParsedType::Record(record_name)) => {

View File

@ -77,7 +77,7 @@ impl ForeignModPrologGlueCodeGenerator for Vec<(String, ParsedType)> {
match ty { match ty {
ParsedType::Utf8String => { ParsedType::Utf8String => {
arg_transforms.extend(quote::quote! { let #arg_ident = std::mem::ManuallyDrop::new(#arg_ident); }); arg_transforms.extend(quote::quote! { let mut #arg_ident = std::mem::ManuallyDrop::new(#arg_ident); });
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) => { ParsedType::Vector(ty) => {
@ -88,10 +88,12 @@ impl ForeignModPrologGlueCodeGenerator for Vec<(String, ParsedType)> {
let arg_transform = quote::quote! { let arg_transform = quote::quote! {
#vector_serializer #vector_serializer
let #arg_ident = std::mem::ManuallyDrop::new(#arg_ident);
let #arg_ident = #generated_serializer_ident(#arg_ident); let #arg_ident = #generated_serializer_ident(#arg_ident);
let mut #arg_ident = std::mem::ManuallyDrop::new(#arg_ident);
}; };
arg_transforms.extend(arg_transform); arg_transforms.extend(arg_transform);
arg_drops.extend(quote::quote! { std::mem::ManuallyDrop::drop(&mut #arg_ident); });
} }
_ => {} _ => {}
} }

View File

@ -22,30 +22,21 @@ pub(crate) fn generate_vector_serializer(
arg_name: &str, arg_name: &str,
) -> proc_macro2::TokenStream { ) -> proc_macro2::TokenStream {
let values_serializer = match value_ty { let values_serializer = match value_ty {
ParsedType::Boolean ParsedType::Boolean => {
| ParsedType::I8 quote! {
fluence::internal::transmute_vec::<i32, u8>(arg).unwrap()
}
}
ParsedType::I8
| ParsedType::I16 | ParsedType::I16
| ParsedType::I32 | ParsedType::I32
| ParsedType::I64
| ParsedType::U8 | ParsedType::U8
| ParsedType::U16 | ParsedType::U16
| ParsedType::U32 => { | ParsedType::U32
| ParsedType::U64 => {
quote! { quote! {
let mut result: Vec<u32> = Vec::with_capacity(arg.len()); fluence::internal::transmute_vec::<#value_ty, u8>(arg).unwrap()
for value in arg {
result.push(value as _);
}
fluence::internal::transmute_vec::<u64, u8>(result)
}
}
ParsedType::I64 | ParsedType::U64 => {
quote! {
let mut result: Vec<u64> = Vec::with_capacity(arg.len());
for value in arg {
result.push(value as _);
}
fluence::internal::transmute_vec::<u64, u8>(result)
} }
} }
ParsedType::F32 => { ParsedType::F32 => {
@ -55,7 +46,7 @@ pub(crate) fn generate_vector_serializer(
result.push(value.to_bits()); result.push(value.to_bits());
} }
fluence::internal::transmute_vec::<u32, u8>(result) fluence::internal::transmute_vec::<u32, u8>(result).unwrap()
} }
} }
ParsedType::F64 => { ParsedType::F64 => {
@ -65,7 +56,7 @@ pub(crate) fn generate_vector_serializer(
result.push(value.to_bits()); result.push(value.to_bits());
} }
fluence::internal::transmute_vec::<u64, u8>(result) fluence::internal::transmute_vec::<u64, u8>(result).unwrap()
} }
} }
ParsedType::Utf8String => { ParsedType::Utf8String => {
@ -77,11 +68,11 @@ pub(crate) fn generate_vector_serializer(
result.push(value.len() as _); result.push(value.len() as _);
} }
fluence::internal::transmute_vec::<u32, u8>(result) fluence::internal::transmute_vec::<u32, u8>(result).unwrap()
} }
} }
ParsedType::Vector(ty) => { ParsedType::Vector(ty) => {
let serializer_name = format!("{}_{:?}", arg_name, ty); let serializer_name = format!("{}_{}", arg_name, ty);
let inner_vector_serializer = generate_vector_serializer(&*ty, &serializer_name); let inner_vector_serializer = generate_vector_serializer(&*ty, &serializer_name);
let serializer_ident = crate::new_ident!(serializer_name); let serializer_ident = crate::new_ident!(serializer_name);
@ -90,24 +81,24 @@ pub(crate) fn generate_vector_serializer(
let mut result: Vec<u32> = Vec::with_capacity(2 * arg.len()); let mut result: Vec<u32> = Vec::with_capacity(2 * arg.len());
for value in arg { for value in arg {
result.push(#serializer_ident(arg, &serializer_name)); let value = std::mem::ManuallyDrop::new(#serializer_ident(value));
result.push(value.as_ptr() as _);
result.push(value.len() as _);
} }
fluence::internal::transmute_vec::<u32, u8>(result) fluence::internal::transmute_vec::<u32, u8>(result).unwrap()
} }
} }
ParsedType::Record(record_name) => { ParsedType::Record(_) => {
let record_ident = crate::new_ident!(record_name);
quote! { quote! {
let mut result: Vec<u32> = Vec::with_capacity(arg.len()); let mut result: Vec<u32> = Vec::with_capacity(arg.len());
for value in arg { for value in arg {
result.push(#record_ident.__fce_generated_serialize() as _); result.push(value.__fce_generated_serialize() as _);
} }
fluence::internal::transmute_vec::<u32, u8>(result) fluence::internal::transmute_vec::<u32, u8>(result).unwrap()
} }
} }
}; };
@ -115,9 +106,7 @@ pub(crate) fn generate_vector_serializer(
let arg = crate::new_ident!(arg_name); let arg = crate::new_ident!(arg_name);
quote! { quote! {
fn serialize_vector_#arg(arg: Vec<#value_ty>) -> Vec<u8> { unsafe fn #arg(arg: Vec<#value_ty>) -> Vec<u8> {
std::mem::forget(arg);
if arg.is_empty() { if arg.is_empty() {
return vec![]; return vec![];
} }
@ -134,22 +123,27 @@ pub(crate) fn generate_vector_deserializer(
let arg = crate::new_ident!(arg_name); let arg = crate::new_ident!(arg_name);
let values_deserializer = match value_ty { let values_deserializer = match value_ty {
ParsedType::Boolean => {
quote! {
fluence::internal::transmute_vec::<u8, i32>(arg).unwrap()
}
}
ParsedType::F32 => { ParsedType::F32 => {
quote! { quote! {
let arg = fluence::internal::transmute_vec::<u8, u32>().unwrap(); let mut arg = fluence::internal::transmute_vec::<u8, u32>(arg).unwrap();
arg.iter().map(f32::from_bits).collect::<Vec<_>>() arg.into_iter().map(f32::from_bits).collect::<Vec<_>>()
} }
} }
ParsedType::F64 => { ParsedType::F64 => {
quote! { quote! {
let arg = fluence::internal::transmute_vec::<u8, u64>().unwrap(); let mut arg = fluence::internal::transmute_vec::<u8, u64>(arg).unwrap();
arg.iter().map(f64::from_bits).collect::<Vec<_>>() arg.into_iter().map(f64::from_bits).collect::<Vec<_>>()
} }
} }
ParsedType::Utf8String => { ParsedType::Utf8String => {
quote! { quote! {
let arg = fluence::internal::transmute_vec::<u8, u32>().unwrap(); let mut arg = fluence::internal::transmute_vec::<u8, u32>(arg).unwrap();
let arg = arg.iter(); let mut arg = arg.into_iter();
let mut result = Vec::with_capacity(arg.len() / 2); let mut result = Vec::with_capacity(arg.len() / 2);
while let Some(offset) = arg.next() { while let Some(offset) = arg.next() {
let size = arg.next().unwrap(); let size = arg.next().unwrap();
@ -161,18 +155,21 @@ pub(crate) fn generate_vector_deserializer(
} }
} }
ParsedType::Vector(ty) => { ParsedType::Vector(ty) => {
let deserializer_name = format!("{}_{:?}", arg_name, ty); let deserializer_name = format!("{}_{}", arg_name, ty);
let inner_vector_deserializer = generate_vector_deserializer(&*ty, &deserializer_name); let inner_vector_deserializer = generate_vector_deserializer(&*ty, &deserializer_name);
let deserializer_ident = crate::new_ident!(deserializer_name); let deserializer_ident = crate::new_ident!(deserializer_name);
quote! { quote! {
#inner_vector_deserializer #inner_vector_deserializer
let arg = fluence::internal::transmute_vec::<u8, u32>().unwrap(); let mut arg = fluence::internal::transmute_vec::<u8, u32>(arg).unwrap();
let mut result = Vec::with_capacity(arg.len()); let mut result = Vec::with_capacity(arg.len());
for offset in arg.iter() { let mut arg = arg.into_iter();
let value = #deserializer_ident(offset, &deserializer_name); while let Some(offset) = arg.next() {
let size = arg.next().unwrap();
let value = #deserializer_ident(offset, size);
result.push(value); result.push(value);
} }
@ -180,12 +177,14 @@ pub(crate) fn generate_vector_deserializer(
} }
} }
ParsedType::Record(record_name) => { ParsedType::Record(record_name) => {
let record_name_ident = crate::new_ident!(record_name);
quote! { quote! {
let arg = fluence::internal::transmute_vec::<u8, u32>().unwrap(); let arg = fluence::internal::transmute_vec::<u8, u32>(arg).unwrap();
let mut result = Vec::with_capacity(arg.len()); let mut result = Vec::with_capacity(arg.len());
for offset in arg { for offset in arg {
let value = #record_name.__fce_generated_deserialize(arg.as_ptr()); let value = #record_name_ident::__fce_generated_deserialize(offset as _);
result.push(value); result.push(value);
} }
@ -194,14 +193,14 @@ pub(crate) fn generate_vector_deserializer(
} }
v => { v => {
quote! { quote! {
fluence::internal::transmute_vec::<u8, #v>().unwrap() fluence::internal::transmute_vec::<u8, #v>(arg).unwrap()
} }
} }
}; };
quote! { quote! {
fn deserialize_vector_#arg(offset: u32, size: u32) -> Vec<#value_ty> { unsafe fn #arg(offset: u32, size: u32) -> Vec<#value_ty> {
let arg: Vec<u8> = Vec::from_raw_parts(offset as _, size as _, size _); let arg: Vec<u8> = Vec::from_raw_parts(offset as _, size as _, size as _);
if arg.is_empty() { if arg.is_empty() {
return vec![]; return vec![];
} }

View File

@ -118,7 +118,7 @@ impl RecordDeserializerGlueCodeGenerator for fce_ast_types::AstRecordItem {
quote! { quote! {
#vector_deserializer #vector_deserializer
#generated_deserializer_ident(raw_record[#ptr_id] as _, raw_record[#size_id] as _); let #field = unsafe { #generated_deserializer_ident(raw_record[#ptr_id] as _, raw_record[#size_id] as _) };
} }
} }
ParsedType::Record(record_name) => { ParsedType::Record(record_name) => {

View File

@ -55,13 +55,14 @@ impl RecordSerializerGlueCodeGenerator for fce_ast_types::AstRecordItem {
ty, ty,
&generated_serializer_name, &generated_serializer_name,
); );
let serialized_field_ident = new_ident!(format!("serialized_arg_{}", id));
quote::quote! { quote::quote! {
#vector_serializer #vector_serializer
let #field_ident = #generated_serializer_ident(#field_ident); let #serialized_field_ident = unsafe { #generated_serializer_ident(#field_ident) };
raw_record.push(#field_ident.as_ptr() as _); raw_record.push(#serialized_field_ident.as_ptr() as _);
raw_record.push(#field_ident.len() as _); raw_record.push(#serialized_field_ident.len() as _);
std::mem::forget(#field_ident); std::mem::forget(#serialized_field_ident);
} }
} }
ParsedType::Record(_) => { ParsedType::Record(_) => {