mirror of
https://github.com/fluencelabs/marine-rs-sdk-test
synced 2024-12-04 15:20:18 +00:00
improve function parsing
This commit is contained in:
parent
2c68bb7a2c
commit
06dc49e6e3
@ -23,5 +23,6 @@ quote = "1.0.7"
|
||||
proc-macro2 = "1.0.18"
|
||||
serde = { version = "1.0.110", features = ["derive"] }
|
||||
serde_json = "1.0.56"
|
||||
uuid = { version = "0.8.1", features = ["v4"] }
|
||||
|
||||
fluence-sdk-main = { path = "../main", version = "=0.1.11" }
|
||||
|
@ -164,23 +164,24 @@ impl ParsedType {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait ArgumentsGenerator {
|
||||
// TODO: replace String with Ident
|
||||
pub(crate) trait MacroPartsGenerator {
|
||||
fn generate_arguments(&self) -> Vec<WasmType>;
|
||||
}
|
||||
|
||||
pub(crate) trait PrologGenerator {
|
||||
fn generate_return_expression(&self) -> proc_macro2::TokenStream;
|
||||
|
||||
fn generate_return_type(&self) -> String;
|
||||
|
||||
fn generate_fn_prolog(
|
||||
&self,
|
||||
generated_arg_id: usize,
|
||||
supplied_arg_start_id: usize,
|
||||
) -> proc_macro2::TokenStream;
|
||||
}
|
||||
|
||||
pub(crate) trait EpilogGenerator {
|
||||
fn generate_fn_epilog(&self) -> proc_macro2::TokenStream;
|
||||
}
|
||||
|
||||
impl ArgumentsGenerator for ParsedType {
|
||||
impl MacroPartsGenerator for ParsedType {
|
||||
fn generate_arguments(&self) -> Vec<WasmType> {
|
||||
// TODO: investigate possible issues in conversion between signed and unsigned types
|
||||
match self {
|
||||
@ -201,9 +202,37 @@ impl ArgumentsGenerator for ParsedType {
|
||||
ParsedType::Record(_) => vec![WasmType::I32, WasmType::I32],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PrologGenerator for ParsedType {
|
||||
fn generate_return_expression(&self) -> proc_macro2::TokenStream {
|
||||
match self {
|
||||
ParsedType::Empty => quote! {},
|
||||
ParsedType::Utf8String => quote! {},
|
||||
ParsedType::ByteVector => quote! {},
|
||||
ParsedType::Record(_) => quote! {},
|
||||
_ => quote! {
|
||||
let result =
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_return_type(&self) -> String {
|
||||
match self {
|
||||
ParsedType::I8 => "-> i32",
|
||||
ParsedType::I16 => "-> i32",
|
||||
ParsedType::I32 => "-> i32",
|
||||
ParsedType::I64 => "-> i64",
|
||||
ParsedType::U8 => "-> i32",
|
||||
ParsedType::U16 => "-> i32",
|
||||
ParsedType::U32 => "-> i32",
|
||||
ParsedType::U64 => "-> i64",
|
||||
ParsedType::F32 => "-> f32",
|
||||
ParsedType::F64 => "-> f64",
|
||||
ParsedType::Boolean => "-> i32",
|
||||
_ => "",
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
|
||||
fn generate_fn_prolog(
|
||||
&self,
|
||||
generated_ard_id: usize,
|
||||
@ -266,44 +295,42 @@ impl PrologGenerator for ParsedType {
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EpilogGenerator for ParsedType {
|
||||
fn generate_fn_epilog(&self) -> proc_macro2::TokenStream {
|
||||
match self {
|
||||
ParsedType::Empty => quote! {},
|
||||
ParsedType::I8 => quote! {
|
||||
return result;
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::I16 => quote! {
|
||||
return result;
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::I32 => quote! {
|
||||
return result;
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::I64 => quote! {
|
||||
return result;
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::U8 => quote! {
|
||||
return result;
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::U16 => quote! {
|
||||
return result;
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::U32 => quote! {
|
||||
return result;
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::U64 => quote! {
|
||||
return result;
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::F32 => quote! {
|
||||
return result;
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::F64 => quote! {
|
||||
return result;
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::Boolean => quote! {
|
||||
return result;
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::Utf8String => quote! {
|
||||
fluence::set_result_ptr(result.as_ptr() as _);
|
||||
|
@ -23,6 +23,8 @@ use crate::fce_ast_types::FCEAst;
|
||||
use proc_macro2::TokenStream;
|
||||
|
||||
const GENERATED_FUNCS_PREFIX: &str = "__fce_generated_func_";
|
||||
const GENERATED_SECTION_NAME: &str = "fce_generated_section";
|
||||
const GENERATED_SECTION_PREFIX: &str = "__fce_generated_section";
|
||||
|
||||
pub(crate) trait TokenStreamGenerator {
|
||||
fn generate_token_stream(self) -> syn::Result<TokenStream>;
|
||||
|
@ -15,19 +15,50 @@
|
||||
*/
|
||||
|
||||
use crate::fce_ast_types;
|
||||
use crate::parsed_type::ArgumentsGenerator;
|
||||
use crate::parsed_type::EpilogGenerator;
|
||||
use crate::parsed_type::PrologGenerator;
|
||||
use crate::parsed_type::MacroPartsGenerator;
|
||||
use super::GENERATED_FUNCS_PREFIX;
|
||||
use super::GENERATED_SECTION_NAME;
|
||||
use super::GENERATED_SECTION_PREFIX;
|
||||
use super::TokenStreamGenerator;
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
use crate::wasm_type::WasmType;
|
||||
|
||||
impl TokenStreamGenerator for fce_ast_types::AstFunctionItem {
|
||||
fn generate_token_stream(self) -> syn::Result<TokenStream> {
|
||||
let data = serde_json::to_string(&self).unwrap();
|
||||
let data_size = data.len();
|
||||
let func_name = self.name;
|
||||
let prefix = "__fce_generated_func_";
|
||||
|
||||
let prefix = GENERATED_FUNCS_PREFIX;
|
||||
let section_name = GENERATED_SECTION_NAME;
|
||||
let section_prefix = GENERATED_SECTION_PREFIX;
|
||||
let generated_global_name = uuid::Uuid::new_v4().to_string();
|
||||
|
||||
let return_type = self.output_type.generate_return_type();
|
||||
let return_expression = self.output_type.generate_return_expression();
|
||||
let epilog = self.output_type.generate_fn_epilog();
|
||||
|
||||
let mut prolog = TokenStream::new();
|
||||
let mut args: Vec<String> = Vec::with_capacity(self.input_types.len());
|
||||
let mut raw_args: Vec<WasmType> = Vec::with_capacity(self.input_types.len());
|
||||
let mut input_type_id = 0;
|
||||
for input_type in self.input_types {
|
||||
let type_prolog = input_type.generate_fn_prolog(input_type_id, input_type_id);
|
||||
let type_raw_args = input_type.generate_arguments();
|
||||
|
||||
args.extend(
|
||||
type_raw_args
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(id, _)| format!("converted_arg_{}", input_type_id + id)),
|
||||
);
|
||||
|
||||
input_type_id += type_raw_args.len();
|
||||
raw_args.extend(type_raw_args);
|
||||
prolog.extend(type_prolog);
|
||||
}
|
||||
|
||||
let embedded_tokens = quote! {
|
||||
#[cfg_attr(
|
||||
@ -36,10 +67,10 @@ impl TokenStreamGenerator for fce_ast_types::AstFunctionItem {
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
pub extern "C" fn #prefix_#func_name(#(#raw_args)*) #ret_type {
|
||||
pub extern "C" fn #prefix#func_name(#(#raw_args)*) #return_type {
|
||||
#prolog
|
||||
|
||||
#ret_expression #func_name(#(#args)*);
|
||||
#return_expression #func_name(#(#args)*);
|
||||
|
||||
#epilog
|
||||
}
|
||||
@ -48,7 +79,7 @@ impl TokenStreamGenerator for fce_ast_types::AstFunctionItem {
|
||||
#[allow(clippy::all)]
|
||||
#[doc(hidden)]
|
||||
#[link_section = #section_name]
|
||||
pub static #generated_global_name: [u8; #size] = { #data };
|
||||
pub static #func_name#section_prefix#generated_global_name: [u8; #data_size] = { #data };
|
||||
};
|
||||
|
||||
Ok(embedded_tokens)
|
||||
|
@ -1,5 +1,4 @@
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::TokenStreamExt;
|
||||
|
||||
pub(crate) enum WasmType {
|
||||
I32,
|
||||
@ -10,6 +9,11 @@ pub(crate) enum WasmType {
|
||||
|
||||
impl quote::ToTokens for WasmType {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
tokens.append(self.clone());
|
||||
match self {
|
||||
WasmType::I32 => "i32".to_tokens(tokens),
|
||||
WasmType::I64 => "i64".to_tokens(tokens),
|
||||
WasmType::F32 => "f32".to_tokens(tokens),
|
||||
WasmType::F64 => "f64".to_tokens(tokens),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user