1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
mod record_serializer;
mod record_deserializer;
use record_serializer::*;
use record_deserializer::*;
use crate::new_ident;
use crate::fce_ast_types;
impl quote::ToTokens for fce_ast_types::AstRecordItem {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let original = &self.original;
crate::prepare_global_data!(
Record,
self,
self.name,
data,
data_size,
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);
let glue_code = quote::quote! {
#original
#[cfg(target_arch = "wasm32")]
#[doc(hidden)]
#[allow(clippy::all)]
impl #record_name {
#serializer_fn
#deserializer_fn
}
#[cfg(target_arch = "wasm32")]
#[doc(hidden)]
#[allow(clippy::all)]
#[link_section = #section_name]
pub static #global_static_name: [u8; #data_size] = { *#data };
};
tokens.extend(glue_code);
}
}
fn generate_serializer_fn(record: &fce_ast_types::AstRecordItem) -> proc_macro2::TokenStream {
let serializer = record.generate_serializer();
quote::quote! {
pub fn __fce_generated_serialize(self) -> *const u8 {
let mut raw_record: Vec<u64> = Vec::new();
#serializer
let raw_record_ptr = raw_record.as_ptr();
std::mem::forget(raw_record);
raw_record_ptr as _
}
}
}
fn generate_deserializer_fn(record: &fce_ast_types::AstRecordItem) -> proc_macro2::TokenStream {
let RecordDeserializerDescriptor {
deserializer,
type_constructor,
} = record.generate_deserializer();
let record_size =
crate::utils::get_record_size(record.fields.iter().map(|ast_field| &ast_field.ty));
quote::quote! {
pub 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
#type_constructor
}
}
}