mirror of
https://github.com/fluencelabs/marine-rs-sdk
synced 2025-03-15 22:30:50 +00:00
introduce macro prepare_global_data
This commit is contained in:
parent
589daaea45
commit
d3f5a15730
@ -20,3 +20,5 @@ proc-macro2 = "1.0.18"
|
|||||||
serde = { version = "1.0.110", features = ["derive"] }
|
serde = { version = "1.0.110", features = ["derive"] }
|
||||||
serde_json = "1.0.56"
|
serde_json = "1.0.56"
|
||||||
uuid = { version = "0.8.1", features = ["v4"] }
|
uuid = { version = "0.8.1", features = ["v4"] }
|
||||||
|
|
||||||
|
wasmer-wit = { package = "wasmer-interface-types", git = "http://github.com/fluencelabs/interface-types", branch = "master", features = ["serde"] }
|
||||||
|
@ -29,8 +29,20 @@ pub struct AstFunctionSignature {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[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 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)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
use super::ParseMacroInput;
|
use super::ParseMacroInput;
|
||||||
use crate::fce_ast_types;
|
use crate::{fce_ast_types, AstRecordField};
|
||||||
use crate::fce_ast_types::FCEAst;
|
use crate::fce_ast_types::FCEAst;
|
||||||
|
|
||||||
use syn::Error;
|
use syn::Error;
|
||||||
@ -26,21 +26,31 @@ impl ParseMacroInput for syn::ItemStruct {
|
|||||||
fn parse_macro_input(self) -> Result<FCEAst> {
|
fn parse_macro_input(self) -> Result<FCEAst> {
|
||||||
check_record(&self)?;
|
check_record(&self)?;
|
||||||
|
|
||||||
let fields = match self.fields {
|
let fields = match &self.fields {
|
||||||
syn::Fields::Named(named_field) => named_field,
|
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")),
|
_ => return Err(Error::new(self.span(), "only named field allowed")),
|
||||||
};
|
};
|
||||||
|
|
||||||
let fields = fields
|
let fields = fields
|
||||||
.named
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|field| {
|
.map(|field| {
|
||||||
check_field(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<_>>>()?;
|
.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))
|
Ok(FCEAst::Record(ast_record_item))
|
||||||
}
|
}
|
||||||
|
@ -23,27 +23,24 @@ use crate::parsed_type::FnPrologDescriptor;
|
|||||||
use crate::new_ident;
|
use crate::new_ident;
|
||||||
|
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::quote;
|
|
||||||
|
|
||||||
impl quote::ToTokens for fce_ast_types::AstFunctionItem {
|
impl quote::ToTokens for fce_ast_types::AstFunctionItem {
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||||
// TODO: change serialization protocol
|
crate::prepare_global_data!(
|
||||||
let fce_type = fce_ast_types::FCEAst::Function(self.clone());
|
Function,
|
||||||
// there is no condition for serialization to fail
|
self,
|
||||||
let data = serde_json::to_vec(&fce_type).unwrap();
|
self.signature.name,
|
||||||
let data_size = data.len();
|
data,
|
||||||
let data = syn::LitByteStr::new(&data, proc_macro2::Span::call_site());
|
data_size,
|
||||||
|
global_static_name,
|
||||||
|
section_name
|
||||||
|
);
|
||||||
|
|
||||||
let signature = &self.signature;
|
let signature = &self.signature;
|
||||||
|
|
||||||
let func_name = new_ident!(GENERATED_FUNC_PREFIX.to_string() + &signature.name);
|
let func_name = new_ident!(GENERATED_FUNC_PREFIX.to_string() + &signature.name);
|
||||||
let original_func_ident = new_ident!(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 export_func_name = &signature.name;
|
||||||
|
|
||||||
let global_static_name =
|
|
||||||
new_ident!(GENERATED_GLOBAL_PREFIX.to_string() + &export_func_name);
|
|
||||||
|
|
||||||
let FnPrologDescriptor {
|
let FnPrologDescriptor {
|
||||||
raw_arg_names,
|
raw_arg_names,
|
||||||
raw_arg_types,
|
raw_arg_types,
|
||||||
@ -60,7 +57,7 @@ impl quote::ToTokens for fce_ast_types::AstFunctionItem {
|
|||||||
// here this Option must be Some
|
// here this Option must be Some
|
||||||
let original_func = &self.original;
|
let original_func = &self.original;
|
||||||
|
|
||||||
let glue_code = quote! {
|
let glue_code = quote::quote! {
|
||||||
#original_func
|
#original_func
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
|
@ -15,8 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use super::GENERATED_FUNC_PREFIX;
|
use super::GENERATED_FUNC_PREFIX;
|
||||||
use super::GENERATED_SECTION_PREFIX;
|
|
||||||
use super::GENERATED_GLOBAL_PREFIX;
|
|
||||||
use crate::fce_ast_types;
|
use crate::fce_ast_types;
|
||||||
use crate::new_ident;
|
use crate::new_ident;
|
||||||
|
|
||||||
@ -26,15 +24,15 @@ use crate::parsed_type::*;
|
|||||||
|
|
||||||
impl quote::ToTokens for fce_ast_types::AstExternModItem {
|
impl quote::ToTokens for fce_ast_types::AstExternModItem {
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||||
// TODO: change serialization protocol
|
crate::prepare_global_data!(
|
||||||
let fce_type = fce_ast_types::FCEAst::ExternMod(self.clone());
|
ExternMod,
|
||||||
let data = serde_json::to_vec(&fce_type).unwrap();
|
self,
|
||||||
let data_size = data.len();
|
self.namespace,
|
||||||
let data = syn::LitByteStr::new(&data, proc_macro2::Span::call_site());
|
data,
|
||||||
|
data_size,
|
||||||
let global_static_name =
|
global_static_name,
|
||||||
new_ident!(GENERATED_GLOBAL_PREFIX.to_string() + &self.namespace.replace(".", "_"));
|
section_name
|
||||||
let section_name = GENERATED_SECTION_PREFIX.to_string() + &self.namespace.replace(".", "_");
|
);
|
||||||
|
|
||||||
let wasm_import_module_name = &self.namespace;
|
let wasm_import_module_name = &self.namespace;
|
||||||
let generated_imports = generate_extern_section_items(&self);
|
let generated_imports = generate_extern_section_items(&self);
|
||||||
|
@ -16,10 +16,30 @@
|
|||||||
|
|
||||||
use crate::fce_ast_types;
|
use crate::fce_ast_types;
|
||||||
|
|
||||||
use proc_macro2::TokenStream;
|
|
||||||
|
|
||||||
impl quote::ToTokens for fce_ast_types::AstRecordItem {
|
impl quote::ToTokens for fce_ast_types::AstRecordItem {
|
||||||
fn to_tokens(&self, _tokens: &mut TokenStream) {
|
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
|
||||||
unimplemented!()
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,3 +21,21 @@ macro_rules! new_ident {
|
|||||||
syn::Ident::new(&$string, proc_macro2::Span::call_site());
|
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(".", "_");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user