mirror of
https://github.com/fluencelabs/marine-rs-sdk
synced 2025-03-15 22:30:50 +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"
|
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"] }
|
||||||
|
|
||||||
fluence-sdk-main = { path = "../main", version = "=0.1.11" }
|
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>;
|
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(
|
fn generate_fn_prolog(
|
||||||
&self,
|
&self,
|
||||||
generated_arg_id: usize,
|
generated_arg_id: usize,
|
||||||
supplied_arg_start_id: usize,
|
supplied_arg_start_id: usize,
|
||||||
) -> proc_macro2::TokenStream;
|
) -> proc_macro2::TokenStream;
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) trait EpilogGenerator {
|
|
||||||
fn generate_fn_epilog(&self) -> proc_macro2::TokenStream;
|
fn generate_fn_epilog(&self) -> proc_macro2::TokenStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ArgumentsGenerator for ParsedType {
|
impl MacroPartsGenerator for ParsedType {
|
||||||
fn generate_arguments(&self) -> Vec<WasmType> {
|
fn generate_arguments(&self) -> Vec<WasmType> {
|
||||||
// TODO: investigate possible issues in conversion between signed and unsigned types
|
// TODO: investigate possible issues in conversion between signed and unsigned types
|
||||||
match self {
|
match self {
|
||||||
@ -201,9 +202,37 @@ impl ArgumentsGenerator for ParsedType {
|
|||||||
ParsedType::Record(_) => vec![WasmType::I32, WasmType::I32],
|
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(
|
fn generate_fn_prolog(
|
||||||
&self,
|
&self,
|
||||||
generated_ard_id: usize,
|
generated_ard_id: usize,
|
||||||
@ -266,44 +295,42 @@ impl PrologGenerator for ParsedType {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl EpilogGenerator for ParsedType {
|
|
||||||
fn generate_fn_epilog(&self) -> proc_macro2::TokenStream {
|
fn generate_fn_epilog(&self) -> proc_macro2::TokenStream {
|
||||||
match self {
|
match self {
|
||||||
ParsedType::Empty => quote! {},
|
ParsedType::Empty => quote! {},
|
||||||
ParsedType::I8 => quote! {
|
ParsedType::I8 => quote! {
|
||||||
return result;
|
return result as _;
|
||||||
},
|
},
|
||||||
ParsedType::I16 => quote! {
|
ParsedType::I16 => quote! {
|
||||||
return result;
|
return result as _;
|
||||||
},
|
},
|
||||||
ParsedType::I32 => quote! {
|
ParsedType::I32 => quote! {
|
||||||
return result;
|
return result as _;
|
||||||
},
|
},
|
||||||
ParsedType::I64 => quote! {
|
ParsedType::I64 => quote! {
|
||||||
return result;
|
return result as _;
|
||||||
},
|
},
|
||||||
ParsedType::U8 => quote! {
|
ParsedType::U8 => quote! {
|
||||||
return result;
|
return result as _;
|
||||||
},
|
},
|
||||||
ParsedType::U16 => quote! {
|
ParsedType::U16 => quote! {
|
||||||
return result;
|
return result as _;
|
||||||
},
|
},
|
||||||
ParsedType::U32 => quote! {
|
ParsedType::U32 => quote! {
|
||||||
return result;
|
return result as _;
|
||||||
},
|
},
|
||||||
ParsedType::U64 => quote! {
|
ParsedType::U64 => quote! {
|
||||||
return result;
|
return result as _;
|
||||||
},
|
},
|
||||||
ParsedType::F32 => quote! {
|
ParsedType::F32 => quote! {
|
||||||
return result;
|
return result as _;
|
||||||
},
|
},
|
||||||
ParsedType::F64 => quote! {
|
ParsedType::F64 => quote! {
|
||||||
return result;
|
return result as _;
|
||||||
},
|
},
|
||||||
ParsedType::Boolean => quote! {
|
ParsedType::Boolean => quote! {
|
||||||
return result;
|
return result as _;
|
||||||
},
|
},
|
||||||
ParsedType::Utf8String => quote! {
|
ParsedType::Utf8String => quote! {
|
||||||
fluence::set_result_ptr(result.as_ptr() as _);
|
fluence::set_result_ptr(result.as_ptr() as _);
|
||||||
|
@ -23,6 +23,8 @@ use crate::fce_ast_types::FCEAst;
|
|||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
|
|
||||||
const GENERATED_FUNCS_PREFIX: &str = "__fce_generated_func_";
|
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 {
|
pub(crate) trait TokenStreamGenerator {
|
||||||
fn generate_token_stream(self) -> syn::Result<TokenStream>;
|
fn generate_token_stream(self) -> syn::Result<TokenStream>;
|
||||||
|
@ -15,19 +15,50 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::fce_ast_types;
|
use crate::fce_ast_types;
|
||||||
use crate::parsed_type::ArgumentsGenerator;
|
use crate::parsed_type::MacroPartsGenerator;
|
||||||
use crate::parsed_type::EpilogGenerator;
|
|
||||||
use crate::parsed_type::PrologGenerator;
|
|
||||||
use super::GENERATED_FUNCS_PREFIX;
|
use super::GENERATED_FUNCS_PREFIX;
|
||||||
|
use super::GENERATED_SECTION_NAME;
|
||||||
|
use super::GENERATED_SECTION_PREFIX;
|
||||||
use super::TokenStreamGenerator;
|
use super::TokenStreamGenerator;
|
||||||
|
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
|
use crate::wasm_type::WasmType;
|
||||||
|
|
||||||
impl TokenStreamGenerator for fce_ast_types::AstFunctionItem {
|
impl TokenStreamGenerator for fce_ast_types::AstFunctionItem {
|
||||||
fn generate_token_stream(self) -> syn::Result<TokenStream> {
|
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 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! {
|
let embedded_tokens = quote! {
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
@ -36,10 +67,10 @@ impl TokenStreamGenerator for fce_ast_types::AstFunctionItem {
|
|||||||
)]
|
)]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[allow(clippy::all)]
|
#[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
|
#prolog
|
||||||
|
|
||||||
#ret_expression #func_name(#(#args)*);
|
#return_expression #func_name(#(#args)*);
|
||||||
|
|
||||||
#epilog
|
#epilog
|
||||||
}
|
}
|
||||||
@ -48,7 +79,7 @@ impl TokenStreamGenerator for fce_ast_types::AstFunctionItem {
|
|||||||
#[allow(clippy::all)]
|
#[allow(clippy::all)]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[link_section = #section_name]
|
#[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)
|
Ok(embedded_tokens)
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::TokenStreamExt;
|
|
||||||
|
|
||||||
pub(crate) enum WasmType {
|
pub(crate) enum WasmType {
|
||||||
I32,
|
I32,
|
||||||
@ -10,6 +9,11 @@ pub(crate) enum WasmType {
|
|||||||
|
|
||||||
impl quote::ToTokens for WasmType {
|
impl quote::ToTokens for WasmType {
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
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…
x
Reference in New Issue
Block a user