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