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::spanned::Spanned;
use proc_macro2::TokenStream;
use serde::export::Formatter;
/// An internal representation of supported Rust types.
#[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! {
#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) => {

View File

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

View File

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

View File

@ -118,7 +118,7 @@ impl RecordDeserializerGlueCodeGenerator for fce_ast_types::AstRecordItem {
quote! {
#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) => {

View File

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