introduce macro prepare_global_data

This commit is contained in:
vms 2020-07-09 00:58:21 +03:00
parent 589daaea45
commit d3f5a15730
7 changed files with 92 additions and 35 deletions

View File

@ -20,3 +20,5 @@ proc-macro2 = "1.0.18"
serde = { version = "1.0.110", features = ["derive"] }
serde_json = "1.0.56"
uuid = { version = "0.8.1", features = ["v4"] }
wasmer-wit = { package = "wasmer-interface-types", git = "http://github.com/fluencelabs/interface-types", branch = "master", features = ["serde"] }

View File

@ -29,8 +29,20 @@ pub struct AstFunctionSignature {
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct AstRecordField {
// fields of tuple structs haven't got name
pub field_name: Option<String>,
pub field_type: ParsedType,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct AstRecordItem {
pub fields: Vec<ParsedType>,
pub name: String,
pub fields: Vec<AstRecordField>,
// Option is needed only for skipping serialization/deserialization of syn::ItemFn
#[serde(skip)]
pub original: Option<syn::ItemStruct>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
use super::ParseMacroInput;
use crate::fce_ast_types;
use crate::{fce_ast_types, AstRecordField};
use crate::fce_ast_types::FCEAst;
use syn::Error;
@ -26,21 +26,31 @@ impl ParseMacroInput for syn::ItemStruct {
fn parse_macro_input(self) -> Result<FCEAst> {
check_record(&self)?;
let fields = match self.fields {
syn::Fields::Named(named_field) => named_field,
let fields = match &self.fields {
syn::Fields::Named(named_fields) => &named_fields.named,
syn::Fields::Unnamed(unnamed_fields) => &unnamed_fields.unnamed,
_ => return Err(Error::new(self.span(), "only named field allowed")),
};
let fields = fields
.named
.iter()
.map(|field| {
check_field(field)?;
ParsedType::from_type(&field.ty)
let field_name = field.ident.as_ref().map(|ident| ident.to_string());
let field_type = ParsedType::from_type(&field.ty)?;
Ok(AstRecordField {
field_name,
field_type,
})
})
.collect::<Result<Vec<_>>>()?;
let ast_record_item = fce_ast_types::AstRecordItem { fields };
let name = self.ident.to_string();
let ast_record_item = fce_ast_types::AstRecordItem {
name,
fields,
original: Some(self),
};
Ok(FCEAst::Record(ast_record_item))
}

View File

@ -23,27 +23,24 @@ use crate::parsed_type::FnPrologDescriptor;
use crate::new_ident;
use proc_macro2::TokenStream;
use quote::quote;
impl quote::ToTokens for fce_ast_types::AstFunctionItem {
fn to_tokens(&self, tokens: &mut TokenStream) {
// TODO: change serialization protocol
let fce_type = fce_ast_types::FCEAst::Function(self.clone());
// there is no condition for serialization to fail
let data = serde_json::to_vec(&fce_type).unwrap();
let data_size = data.len();
let data = syn::LitByteStr::new(&data, proc_macro2::Span::call_site());
crate::prepare_global_data!(
Function,
self,
self.signature.name,
data,
data_size,
global_static_name,
section_name
);
let signature = &self.signature;
let func_name = new_ident!(GENERATED_FUNC_PREFIX.to_string() + &signature.name);
let original_func_ident = new_ident!(signature.name);
let section_name = GENERATED_SECTION_PREFIX.to_string() + &signature.name.replace("-", "_");
let export_func_name = &signature.name;
let global_static_name =
new_ident!(GENERATED_GLOBAL_PREFIX.to_string() + &export_func_name);
let FnPrologDescriptor {
raw_arg_names,
raw_arg_types,
@ -60,7 +57,7 @@ impl quote::ToTokens for fce_ast_types::AstFunctionItem {
// here this Option must be Some
let original_func = &self.original;
let glue_code = quote! {
let glue_code = quote::quote! {
#original_func
#[cfg_attr(

View File

@ -15,8 +15,6 @@
*/
use super::GENERATED_FUNC_PREFIX;
use super::GENERATED_SECTION_PREFIX;
use super::GENERATED_GLOBAL_PREFIX;
use crate::fce_ast_types;
use crate::new_ident;
@ -26,15 +24,15 @@ use crate::parsed_type::*;
impl quote::ToTokens for fce_ast_types::AstExternModItem {
fn to_tokens(&self, tokens: &mut TokenStream) {
// TODO: change serialization protocol
let fce_type = fce_ast_types::FCEAst::ExternMod(self.clone());
let data = serde_json::to_vec(&fce_type).unwrap();
let data_size = data.len();
let data = syn::LitByteStr::new(&data, proc_macro2::Span::call_site());
let global_static_name =
new_ident!(GENERATED_GLOBAL_PREFIX.to_string() + &self.namespace.replace(".", "_"));
let section_name = GENERATED_SECTION_PREFIX.to_string() + &self.namespace.replace(".", "_");
crate::prepare_global_data!(
ExternMod,
self,
self.namespace,
data,
data_size,
global_static_name,
section_name
);
let wasm_import_module_name = &self.namespace;
let generated_imports = generate_extern_section_items(&self);

View File

@ -16,10 +16,30 @@
use crate::fce_ast_types;
use proc_macro2::TokenStream;
impl quote::ToTokens for fce_ast_types::AstRecordItem {
fn to_tokens(&self, _tokens: &mut TokenStream) {
unimplemented!()
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 glue_code = quote::quote! {
#original
// #[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);
}
}

View File

@ -21,3 +21,21 @@ macro_rules! new_ident {
syn::Ident::new(&$string, proc_macro2::Span::call_site());
};
}
#[macro_export]
macro_rules! prepare_global_data {
($fce_type: ident, $self: ident, $name: expr, $data: ident, $data_size: ident, $global_static_name: ident, $section_name: ident) => {
// TODO: change serialization protocol
let fce_type = fce_ast_types::FCEAst::$fce_type($self.clone());
let $data = serde_json::to_vec(&fce_type).unwrap();
let $data_size = $data.len();
let $data = syn::LitByteStr::new(&$data, proc_macro2::Span::call_site());
let $global_static_name = crate::new_ident!(
crate::token_stream_generator::GENERATED_GLOBAL_PREFIX.to_string()
+ &$name.replace(".", "_")
);
let $section_name = crate::token_stream_generator::GENERATED_SECTION_PREFIX.to_string()
+ &$name.replace(".", "_");
};
}