mirror of
https://github.com/fluencelabs/marine-rs-sdk-test
synced 2024-12-04 23:30:18 +00:00
introduce trait FCERecordSerializer
This commit is contained in:
parent
88afe8feaa
commit
141807945e
@ -45,6 +45,19 @@ pub use result::get_result_size;
|
||||
pub use result::set_result_ptr;
|
||||
pub use result::set_result_size;
|
||||
|
||||
/// This trait is used to convert structs to a form compatible with
|
||||
/// record.lift_memory and record.lower_memory instructions.
|
||||
/// Normally, this trait shouldn't be used directly.
|
||||
pub trait FCEStructSerializable {
|
||||
// Serialize the provided record to a Vec<u8>, returns pointer to it in a form compatible with
|
||||
// record.lift_memory.
|
||||
// The caller should manage the lifetime of returned pointer.
|
||||
fn __fce_generated_serialize(self) -> *const u8;
|
||||
|
||||
// Deserialize record from a pointer (normally, come from record.lower_memory).
|
||||
unsafe fn __fce_generated_deserialize(record_ptr: *const u8) -> Self;
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub(crate) fn log<S: AsRef<str>>(msg: S) {
|
||||
// logs will be printed only if debug feature is enabled
|
||||
|
@ -20,6 +20,7 @@
|
||||
nonstandard_style,
|
||||
unused_imports,
|
||||
unused_mut,
|
||||
unused_variables,
|
||||
unused_unsafe,
|
||||
unreachable_patterns
|
||||
)]
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
use super::ParsedType;
|
||||
use crate::new_ident;
|
||||
use crate::token_stream_generator::GENERATED_RECORD_SERIALIZER_PREFIX;
|
||||
|
||||
use quote::quote;
|
||||
|
||||
@ -97,11 +96,9 @@ fn generate_epilog(ty: &Option<ParsedType>) -> proc_macro2::TokenStream {
|
||||
Some(ty) if !ty.is_complex_type() => quote! {
|
||||
return result as _;
|
||||
},
|
||||
Some(ParsedType::Record(record_name)) => {
|
||||
let record_serializer =
|
||||
crate::new_ident!(GENERATED_RECORD_SERIALIZER_PREFIX.to_string() + record_name);
|
||||
Some(ParsedType::Record(_)) => {
|
||||
quote! {
|
||||
let result_ptr = crate::#record_serializer(result);
|
||||
let result_ptr = result.__fce_generated_serialize();
|
||||
fluence::internal::set_result_ptr(result_ptr as _);
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
use super::ParsedType;
|
||||
use super::FnArgGlueCodeGenerator;
|
||||
use crate::token_stream_generator::GENERATED_RECORD_DESERIALIZER_PREFIX;
|
||||
use crate::new_ident;
|
||||
use crate::wasm_type::WasmType;
|
||||
|
||||
@ -106,11 +105,9 @@ fn generate_type_prolog(
|
||||
let #generated_arg_id = Vec::from_raw_parts(#ptr as _, #size as _, #size as _);
|
||||
},
|
||||
ParsedType::Record(record_name) => {
|
||||
let record_deserializer = crate::new_ident!(
|
||||
GENERATED_RECORD_DESERIALIZER_PREFIX.to_string() + record_name
|
||||
);
|
||||
let record_ident = new_ident!(record_name);
|
||||
quote! {
|
||||
let #generated_arg_id = crate::#record_deserializer(#ptr);
|
||||
let #generated_arg_id = #record_ident::__fce_generated_deserialize(#ptr as _);
|
||||
}
|
||||
}
|
||||
_ => panic!(
|
||||
|
@ -31,13 +31,9 @@ impl ForeignModArgGlueCodeGenerator for ParsedType {
|
||||
ParsedType::Utf8String | ParsedType::ByteVector => {
|
||||
quote! { #arg.as_ptr() as _, #arg.len() as _ }
|
||||
}
|
||||
ParsedType::Record(record_name) => {
|
||||
let record_serializer = crate::new_ident!(
|
||||
crate::token_stream_generator::GENERATED_RECORD_SERIALIZER_PREFIX.to_string()
|
||||
+ record_name
|
||||
);
|
||||
ParsedType::Record(_) => {
|
||||
quote! {
|
||||
crate::#record_serializer(#arg)
|
||||
#arg.__fce_generated_serialize() as _
|
||||
}
|
||||
}
|
||||
_ => quote! { arg },
|
||||
|
@ -59,12 +59,9 @@ impl ForeignModEpilogGlueCodeGenerator for Option<ParsedType> {
|
||||
)
|
||||
},
|
||||
Some(ParsedType::Record(record_name)) => {
|
||||
let record_deserializer = crate::new_ident!(
|
||||
crate::token_stream_generator::GENERATED_RECORD_DESERIALIZER_PREFIX.to_string()
|
||||
+ record_name
|
||||
);
|
||||
let record_ident = new_ident!(record_name);
|
||||
quote! {
|
||||
crate::#record_deserializer(fluence::internal::get_result_ptr() as _)
|
||||
#record_ident::__fce_generated_deserialize(fluence::internal::get_result_ptr() as _)
|
||||
}
|
||||
}
|
||||
_ => panic!(
|
||||
|
@ -23,8 +23,6 @@ use crate::fce_ast_types::FCEAst;
|
||||
use proc_macro2::TokenStream;
|
||||
|
||||
pub const GENERATED_WRAPPER_FUNC_PREFIX: &str = "__fce_generated_wrapper_func_";
|
||||
pub const GENERATED_RECORD_SERIALIZER_PREFIX: &str = "__fce_generated_record_serializer_";
|
||||
pub const GENERATED_RECORD_DESERIALIZER_PREFIX: &str = "__fce_generated_record_deserializer_";
|
||||
pub const GENERATED_SECTION_PREFIX: &str = "__fce_generated_section__";
|
||||
pub const GENERATED_GLOBAL_PREFIX: &str = "__fce_generated_static_global_";
|
||||
|
||||
|
@ -68,6 +68,10 @@ impl quote::ToTokens for fce_ast_types::AstFunctionItem {
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
pub unsafe fn #func_name(#(#raw_arg_names: #raw_arg_types),*) #fn_return_type {
|
||||
// brings serialize/deserialize methods for records
|
||||
#[allow(dead_code)]
|
||||
use fluence::internal::FCEStructSerializable;
|
||||
|
||||
// arguments conversation from Wasm types to Rust types
|
||||
#prolog
|
||||
|
||||
|
@ -121,6 +121,10 @@ fn generate_wrapper_functions(extern_item: &fce_ast_types::AstExternModItem) ->
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
#visibility fn #func_name(#(#arg_names: #arg_types), *) #return_type {
|
||||
// brings serialize/deserialize methods for records
|
||||
#[allow(dead_code)]
|
||||
use fluence::internal::FCEStructSerializable;
|
||||
|
||||
unsafe {
|
||||
// calling the original function with converted args
|
||||
#return_expression #import_func_name(#(#raw_args), *);
|
||||
|
@ -20,9 +20,6 @@ mod record_deserializer;
|
||||
use record_serializer::*;
|
||||
use record_deserializer::*;
|
||||
|
||||
use super::GENERATED_RECORD_SERIALIZER_PREFIX;
|
||||
use super::GENERATED_RECORD_DESERIALIZER_PREFIX;
|
||||
|
||||
use crate::new_ident;
|
||||
use crate::fce_ast_types;
|
||||
|
||||
@ -38,6 +35,7 @@ impl quote::ToTokens for fce_ast_types::AstRecordItem {
|
||||
global_static_name,
|
||||
section_name
|
||||
);
|
||||
let record_name = new_ident!(self.name);
|
||||
|
||||
let serializer_fn = generate_serializer_fn(self);
|
||||
let deserializer_fn = generate_deserializer_fn(self);
|
||||
@ -48,12 +46,11 @@ impl quote::ToTokens for fce_ast_types::AstRecordItem {
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
impl fluence::internal::FCEStructSerializable for #record_name {
|
||||
#serializer_fn
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
#deserializer_fn
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
@ -67,16 +64,10 @@ impl quote::ToTokens for fce_ast_types::AstRecordItem {
|
||||
}
|
||||
|
||||
fn generate_serializer_fn(record: &fce_ast_types::AstRecordItem) -> proc_macro2::TokenStream {
|
||||
let serializer_fn_name =
|
||||
new_ident!(GENERATED_RECORD_SERIALIZER_PREFIX.to_string() + &record.name);
|
||||
|
||||
let RecordSerializerDescriptor {
|
||||
serializer,
|
||||
record_type,
|
||||
} = record.generate_serializer(&record.name);
|
||||
let serializer = record.generate_serializer();
|
||||
|
||||
quote::quote! {
|
||||
pub(in crate) fn #serializer_fn_name(record: #record_type) -> i32 {
|
||||
fn __fce_generated_serialize(self) -> *const u8 {
|
||||
let mut raw_record = Vec::new();
|
||||
|
||||
#serializer
|
||||
@ -90,21 +81,17 @@ fn generate_serializer_fn(record: &fce_ast_types::AstRecordItem) -> proc_macro2:
|
||||
}
|
||||
|
||||
fn generate_deserializer_fn(record: &fce_ast_types::AstRecordItem) -> proc_macro2::TokenStream {
|
||||
let deserializer_fn_name =
|
||||
new_ident!(GENERATED_RECORD_DESERIALIZER_PREFIX.to_string() + &record.name);
|
||||
|
||||
let RecordDeserializerDescriptor {
|
||||
deserializer,
|
||||
type_constructor,
|
||||
return_type,
|
||||
} = record.generate_deserializer(&record.name);
|
||||
} = record.generate_deserializer();
|
||||
|
||||
let record_size =
|
||||
crate::utils::get_record_size(record.fields.iter().map(|ast_field| &ast_field.ty));
|
||||
|
||||
quote::quote! {
|
||||
pub(in crate) unsafe fn #deserializer_fn_name(offset: i32) -> #return_type {
|
||||
let raw_record: Vec<u64> = Vec::from_raw_parts(offset as _, #record_size, #record_size);
|
||||
unsafe fn __fce_generated_deserialize(record_ptr: *const u8) -> Self {
|
||||
let raw_record: Vec<u64> = Vec::from_raw_parts(record_ptr as _, #record_size, #record_size);
|
||||
|
||||
#deserializer
|
||||
|
||||
|
@ -17,25 +17,21 @@
|
||||
use crate::new_ident;
|
||||
use crate::parsed_type::ParsedType;
|
||||
use crate::fce_ast_types;
|
||||
use crate::token_stream_generator::GENERATED_RECORD_DESERIALIZER_PREFIX;
|
||||
|
||||
use quote::quote;
|
||||
|
||||
pub(super) struct RecordDeserializerDescriptor {
|
||||
pub(super) deserializer: proc_macro2::TokenStream,
|
||||
pub(super) type_constructor: proc_macro2::TokenStream,
|
||||
pub(super) return_type: syn::Ident,
|
||||
}
|
||||
|
||||
/// This trait could be used to generate various parts of a record serializer func.
|
||||
pub(super) trait RecordDeserializerGlueCodeGenerator {
|
||||
fn generate_deserializer(&self, record_name: &str) -> RecordDeserializerDescriptor;
|
||||
fn generate_deserializer(&self) -> RecordDeserializerDescriptor;
|
||||
}
|
||||
|
||||
impl RecordDeserializerGlueCodeGenerator for fce_ast_types::AstRecordItem {
|
||||
fn generate_deserializer(&self, record_name: &str) -> RecordDeserializerDescriptor {
|
||||
let return_type = new_ident!(record_name);
|
||||
|
||||
fn generate_deserializer(&self) -> RecordDeserializerDescriptor {
|
||||
let mut field_values = Vec::with_capacity(self.fields.len());
|
||||
let mut deserializer = proc_macro2::TokenStream::new();
|
||||
let mut value_id: usize = 0;
|
||||
@ -118,11 +114,9 @@ impl RecordDeserializerGlueCodeGenerator for fce_ast_types::AstRecordItem {
|
||||
}
|
||||
ParsedType::Record(record_name) => {
|
||||
let ptr_id = value_id;
|
||||
let record_deserializer =
|
||||
new_ident!(GENERATED_RECORD_DESERIALIZER_PREFIX.to_string() + record_name);
|
||||
|
||||
let record_ident = new_ident!(record_name);
|
||||
quote! {
|
||||
let #field = crate::#record_deserializer(raw_record[#ptr_id] as _);
|
||||
let #field = #record_ident::__fce_generated_deserialize(raw_record[#ptr_id] as _);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -143,14 +137,14 @@ impl RecordDeserializerGlueCodeGenerator for fce_ast_types::AstRecordItem {
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
quote! {
|
||||
#return_type {
|
||||
Self {
|
||||
#(#field_names: #field_values),*
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(_) => {
|
||||
quote! {
|
||||
#return_type (
|
||||
Self (
|
||||
#(#field_values),*
|
||||
)
|
||||
}
|
||||
@ -161,7 +155,6 @@ impl RecordDeserializerGlueCodeGenerator for fce_ast_types::AstRecordItem {
|
||||
RecordDeserializerDescriptor {
|
||||
deserializer,
|
||||
type_constructor,
|
||||
return_type,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,22 +17,16 @@
|
||||
use crate::new_ident;
|
||||
use crate::parsed_type::ParsedType;
|
||||
use crate::fce_ast_types;
|
||||
use crate::token_stream_generator::GENERATED_RECORD_SERIALIZER_PREFIX;
|
||||
|
||||
use quote::quote;
|
||||
|
||||
pub(super) struct RecordSerializerDescriptor {
|
||||
pub(super) serializer: proc_macro2::TokenStream,
|
||||
pub(super) record_type: syn::Ident,
|
||||
}
|
||||
|
||||
/// This trait could be used to generate various parts of a record serializer func.
|
||||
pub(super) trait RecordSerializerGlueCodeGenerator {
|
||||
fn generate_serializer(&self, record_name: &str) -> RecordSerializerDescriptor;
|
||||
fn generate_serializer(&self) -> proc_macro2::TokenStream;
|
||||
}
|
||||
|
||||
impl RecordSerializerGlueCodeGenerator for fce_ast_types::AstRecordItem {
|
||||
fn generate_serializer(&self, record_name: &str) -> RecordSerializerDescriptor {
|
||||
fn generate_serializer(&self) -> proc_macro2::TokenStream {
|
||||
let mut serializer = proc_macro2::TokenStream::new();
|
||||
for (id, field) in self.fields.iter().enumerate() {
|
||||
let field_ident = field_ident(field, id);
|
||||
@ -50,11 +44,9 @@ impl RecordSerializerGlueCodeGenerator for fce_ast_types::AstRecordItem {
|
||||
std::mem::forget(#field_ident);
|
||||
}
|
||||
}
|
||||
ParsedType::Record(record_name) => {
|
||||
let record_serializer =
|
||||
new_ident!(GENERATED_RECORD_SERIALIZER_PREFIX.to_string() + &record_name);
|
||||
ParsedType::Record(_) => {
|
||||
quote! {
|
||||
raw_record.push(crate::#record_serializer(#field_ident) as _);
|
||||
raw_record.push(#field_ident.__fce_generated_serialize() as _);
|
||||
}
|
||||
}
|
||||
_ => quote! {
|
||||
@ -64,12 +56,8 @@ impl RecordSerializerGlueCodeGenerator for fce_ast_types::AstRecordItem {
|
||||
|
||||
serializer.extend(field_serialization);
|
||||
}
|
||||
let record_type = new_ident!(record_name);
|
||||
|
||||
RecordSerializerDescriptor {
|
||||
serializer,
|
||||
record_type,
|
||||
}
|
||||
serializer
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,11 +65,11 @@ fn field_ident(field: &fce_ast_types::AstRecordField, id: usize) -> proc_macro2:
|
||||
match &field.name {
|
||||
Some(name) => {
|
||||
let name = new_ident!(name);
|
||||
quote! { record.#name }
|
||||
quote! { self.#name }
|
||||
}
|
||||
None => {
|
||||
let id = new_ident!(format!("{}", id));
|
||||
quote! { record.#id }
|
||||
quote! { self.#id }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,4 +45,6 @@ pub mod internal {
|
||||
pub use fluence_sdk_main::get_result_size;
|
||||
pub use fluence_sdk_main::set_result_ptr;
|
||||
pub use fluence_sdk_main::set_result_size;
|
||||
|
||||
pub use fluence_sdk_main::FCEStructSerializable;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user