mirror of
https://github.com/fluencelabs/marine-rs-sdk-test
synced 2024-12-04 15:20:18 +00:00
improve foreign item parsing
This commit is contained in:
parent
06dc49e6e3
commit
1b76203c91
@ -21,7 +21,7 @@ use serde::Deserialize;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub(crate) struct AstFunctionItem {
|
||||
pub(crate) name: String,
|
||||
pub(crate) rust_name: String,
|
||||
pub(crate) input_types: Vec<ParsedType>,
|
||||
// fce supports only one return value now,
|
||||
// waiting for adding multi-value support in Wasmer.
|
||||
@ -33,11 +33,18 @@ pub(crate) struct AstRecordItem {
|
||||
pub(crate) fields: Vec<ParsedType>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub(crate) struct AstExternFnItem {
|
||||
pub(crate) link_name: Option<String>,
|
||||
// only imports are possible here
|
||||
pub(crate) function: AstFunctionItem,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub(crate) struct AstExternModItem {
|
||||
pub(crate) namespace: String,
|
||||
// only imports are possible here
|
||||
pub(crate) imports: Vec<AstFunctionItem>,
|
||||
pub(crate) imports: Vec<AstExternFnItem>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
|
@ -44,7 +44,7 @@ pub(super) fn parse_function(
|
||||
let output_type = ParsedType::from_return_type(&output)?;
|
||||
|
||||
let ast_function_item = fce_ast_types::AstFunctionItem {
|
||||
name: function_sig.ident.to_string(),
|
||||
rust_name: function_sig.ident.to_string(),
|
||||
input_types,
|
||||
output_type,
|
||||
};
|
||||
|
@ -80,13 +80,13 @@ impl ParseMacroInput for syn::ItemForeignMod {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_raw_foreign_item(raw_item: syn::ForeignItem) -> Result<fce_ast_types::AstFunctionItem> {
|
||||
fn parse_raw_foreign_item(raw_item: syn::ForeignItem) -> Result<fce_ast_types::AstExternFnItem> {
|
||||
let function_item = match raw_item {
|
||||
syn::ForeignItem::Fn(function_item) => function_item,
|
||||
_ => {
|
||||
return Err(Error::new(
|
||||
raw_item.span(),
|
||||
"#[fce] could be upplied only to a function, struct ot extern block",
|
||||
"#[fce] could be applied only to a function, struct ot extern block",
|
||||
))
|
||||
}
|
||||
};
|
||||
@ -102,13 +102,13 @@ fn parse_raw_foreign_item(raw_item: syn::ForeignItem) -> Result<fce_ast_types::A
|
||||
.map(extract_value)
|
||||
.collect();
|
||||
|
||||
let mut function_item = super::item_fn::parse_function(function_item.sig, function_item.vis)?;
|
||||
let function = super::item_fn::parse_function(function_item.sig, function_item.vis)?;
|
||||
let ast_extern_fn_item = fce_ast_types::AstExternFnItem {
|
||||
link_name,
|
||||
function,
|
||||
};
|
||||
|
||||
if let Some(link_name) = link_name {
|
||||
function_item.name = link_name;
|
||||
}
|
||||
|
||||
Ok(function_item)
|
||||
Ok(ast_extern_fn_item)
|
||||
}
|
||||
|
||||
fn extract_value(nested_meta: syn::Meta) -> Option<String> {
|
||||
|
@ -14,9 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use crate::wasm_type::WasmType;
|
||||
mod glue_code_generator;
|
||||
|
||||
pub(crate) use glue_code_generator::GlueCodeGenerator;
|
||||
|
||||
use quote::quote;
|
||||
use serde::Serialize;
|
||||
use serde::Deserialize;
|
||||
use syn::parse::Error;
|
||||
@ -163,190 +164,3 @@ impl ParsedType {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: replace String with Ident
|
||||
pub(crate) trait MacroPartsGenerator {
|
||||
fn generate_arguments(&self) -> Vec<WasmType>;
|
||||
|
||||
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;
|
||||
|
||||
fn generate_fn_epilog(&self) -> proc_macro2::TokenStream;
|
||||
}
|
||||
|
||||
impl MacroPartsGenerator for ParsedType {
|
||||
fn generate_arguments(&self) -> Vec<WasmType> {
|
||||
// TODO: investigate possible issues in conversion between signed and unsigned types
|
||||
match self {
|
||||
ParsedType::Empty => vec![],
|
||||
ParsedType::I8 => vec![WasmType::I32],
|
||||
ParsedType::I16 => vec![WasmType::I32],
|
||||
ParsedType::I32 => vec![WasmType::I32],
|
||||
ParsedType::I64 => vec![WasmType::I64],
|
||||
ParsedType::U8 => vec![WasmType::I32],
|
||||
ParsedType::U16 => vec![WasmType::I32],
|
||||
ParsedType::U32 => vec![WasmType::I32],
|
||||
ParsedType::U64 => vec![WasmType::I64],
|
||||
ParsedType::F32 => vec![WasmType::F32],
|
||||
ParsedType::F64 => vec![WasmType::F64],
|
||||
ParsedType::Boolean => vec![WasmType::I32],
|
||||
ParsedType::Utf8String => vec![WasmType::I32, WasmType::I32],
|
||||
ParsedType::ByteVector => vec![WasmType::I32, WasmType::I32],
|
||||
ParsedType::Record(_) => vec![WasmType::I32, WasmType::I32],
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
supplied_arg_start_id: usize,
|
||||
) -> proc_macro2::TokenStream {
|
||||
match self {
|
||||
ParsedType::Empty => unimplemented!(),
|
||||
ParsedType::I8 => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as i8;
|
||||
},
|
||||
ParsedType::I16 => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as i16;
|
||||
},
|
||||
ParsedType::I32 => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as i32;
|
||||
},
|
||||
ParsedType::I64 => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as i64;
|
||||
},
|
||||
ParsedType::U8 => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as u8;
|
||||
},
|
||||
ParsedType::U16 => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as u16;
|
||||
},
|
||||
ParsedType::U32 => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as u32;
|
||||
},
|
||||
ParsedType::U64 => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as u64;
|
||||
},
|
||||
ParsedType::F32 => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as f32;
|
||||
},
|
||||
ParsedType::F64 => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as f64;
|
||||
},
|
||||
ParsedType::Boolean => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as bool;
|
||||
},
|
||||
ParsedType::Utf8String => quote! {
|
||||
let converted_arg_#generated_ard_id = String::from_raw_parts(
|
||||
arg_#supplied_arg_start_id,
|
||||
arg_#(supplied_arg_start_id+1),
|
||||
arg_#(supplied_arg_start_id+1)
|
||||
);
|
||||
},
|
||||
ParsedType::ByteVector => quote! {
|
||||
let converted_arg_#generated_ard_id = Vec::from_raw_parts(
|
||||
arg_#supplied_arg_start_id,
|
||||
arg_#(supplied_arg_start_id+1),
|
||||
arg_#(supplied_arg_start_id+1)
|
||||
);
|
||||
},
|
||||
ParsedType::Record(record_name) => quote! {
|
||||
let converted_arg_#generated_ard_id = __fce_generated_converter_#record_name(
|
||||
arg_#supplied_arg_start_id,
|
||||
arg_#(supplied_arg_start_id+1)
|
||||
);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_fn_epilog(&self) -> proc_macro2::TokenStream {
|
||||
match self {
|
||||
ParsedType::Empty => quote! {},
|
||||
ParsedType::I8 => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::I16 => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::I32 => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::I64 => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::U8 => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::U16 => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::U32 => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::U64 => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::F32 => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::F64 => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::Boolean => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::Utf8String => quote! {
|
||||
fluence::set_result_ptr(result.as_ptr() as _);
|
||||
fluence::set_result_size(result.len() as _);
|
||||
std::mem::forget(result);
|
||||
},
|
||||
ParsedType::ByteVector => quote! {
|
||||
fluence::set_result_ptr(result.as_ptr() as _);
|
||||
fluence::set_result_size(result.len() as _);
|
||||
std::mem::forget(result);
|
||||
},
|
||||
ParsedType::Record(_) => quote! {
|
||||
fluence::set_result_ptr(result.as_ptr() as _);
|
||||
fluence::set_result_size(result.len() as _);
|
||||
std::mem::forget(result);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
207
crates/macro/src/parsed_type/glue_code_generator.rs
Normal file
207
crates/macro/src/parsed_type/glue_code_generator.rs
Normal file
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright 2018 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use crate::wasm_type::WasmType;
|
||||
use super::ParsedType;
|
||||
|
||||
use quote::quote;
|
||||
|
||||
pub(crate) trait GlueCodeGenerator {
|
||||
fn generate_arguments(&self) -> Vec<WasmType>;
|
||||
|
||||
fn generate_return_expression(&self) -> proc_macro2::TokenStream;
|
||||
|
||||
// TODO: replace String with Ident
|
||||
fn generate_return_type(&self) -> String;
|
||||
|
||||
fn generate_fn_prolog(
|
||||
&self,
|
||||
generated_arg_id: usize,
|
||||
supplied_arg_start_id: usize,
|
||||
) -> proc_macro2::TokenStream;
|
||||
|
||||
fn generate_fn_epilog(&self) -> proc_macro2::TokenStream;
|
||||
}
|
||||
|
||||
impl GlueCodeGenerator for ParsedType {
|
||||
fn generate_arguments(&self) -> Vec<WasmType> {
|
||||
// TODO: investigate possible issues in conversion between signed and unsigned types
|
||||
match self {
|
||||
ParsedType::Empty => vec![],
|
||||
ParsedType::I8 => vec![WasmType::I32],
|
||||
ParsedType::I16 => vec![WasmType::I32],
|
||||
ParsedType::I32 => vec![WasmType::I32],
|
||||
ParsedType::I64 => vec![WasmType::I64],
|
||||
ParsedType::U8 => vec![WasmType::I32],
|
||||
ParsedType::U16 => vec![WasmType::I32],
|
||||
ParsedType::U32 => vec![WasmType::I32],
|
||||
ParsedType::U64 => vec![WasmType::I64],
|
||||
ParsedType::F32 => vec![WasmType::F32],
|
||||
ParsedType::F64 => vec![WasmType::F64],
|
||||
ParsedType::Boolean => vec![WasmType::I32],
|
||||
ParsedType::Utf8String => vec![WasmType::I32, WasmType::I32],
|
||||
ParsedType::ByteVector => vec![WasmType::I32, WasmType::I32],
|
||||
ParsedType::Record(_) => vec![WasmType::I32, WasmType::I32],
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
supplied_arg_start_id: usize,
|
||||
) -> proc_macro2::TokenStream {
|
||||
match self {
|
||||
ParsedType::Empty => unimplemented!(),
|
||||
ParsedType::I8 => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as i8;
|
||||
},
|
||||
ParsedType::I16 => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as i16;
|
||||
},
|
||||
ParsedType::I32 => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as i32;
|
||||
},
|
||||
ParsedType::I64 => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as i64;
|
||||
},
|
||||
ParsedType::U8 => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as u8;
|
||||
},
|
||||
ParsedType::U16 => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as u16;
|
||||
},
|
||||
ParsedType::U32 => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as u32;
|
||||
},
|
||||
ParsedType::U64 => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as u64;
|
||||
},
|
||||
ParsedType::F32 => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as f32;
|
||||
},
|
||||
ParsedType::F64 => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as f64;
|
||||
},
|
||||
ParsedType::Boolean => quote! {
|
||||
let converted_arg_#generated_ard_id = arg_#supplied_arg_start_id as bool;
|
||||
},
|
||||
ParsedType::Utf8String => quote! {
|
||||
let converted_arg_#generated_ard_id = String::from_raw_parts(
|
||||
arg_#supplied_arg_start_id,
|
||||
arg_#(supplied_arg_start_id+1),
|
||||
arg_#(supplied_arg_start_id+1)
|
||||
);
|
||||
},
|
||||
ParsedType::ByteVector => quote! {
|
||||
let converted_arg_#generated_ard_id = Vec::from_raw_parts(
|
||||
arg_#supplied_arg_start_id,
|
||||
arg_#(supplied_arg_start_id+1),
|
||||
arg_#(supplied_arg_start_id+1)
|
||||
);
|
||||
},
|
||||
ParsedType::Record(record_name) => quote! {
|
||||
let converted_arg_#generated_ard_id = __fce_generated_converter_#record_name(
|
||||
arg_#supplied_arg_start_id,
|
||||
arg_#(supplied_arg_start_id+1)
|
||||
);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_fn_epilog(&self) -> proc_macro2::TokenStream {
|
||||
match self {
|
||||
ParsedType::Empty => quote! {},
|
||||
ParsedType::I8 => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::I16 => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::I32 => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::I64 => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::U8 => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::U16 => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::U32 => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::U64 => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::F32 => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::F64 => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::Boolean => quote! {
|
||||
return result as _;
|
||||
},
|
||||
ParsedType::Utf8String => quote! {
|
||||
fluence::set_result_ptr(result.as_ptr() as _);
|
||||
fluence::set_result_size(result.len() as _);
|
||||
std::mem::forget(result);
|
||||
},
|
||||
ParsedType::ByteVector => quote! {
|
||||
fluence::set_result_ptr(result.as_ptr() as _);
|
||||
fluence::set_result_size(result.len() as _);
|
||||
std::mem::forget(result);
|
||||
},
|
||||
ParsedType::Record(_) => quote! {
|
||||
fluence::set_result_ptr(result.as_ptr() as _);
|
||||
fluence::set_result_size(result.len() as _);
|
||||
std::mem::forget(result);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
@ -14,12 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use crate::fce_ast_types;
|
||||
use crate::parsed_type::MacroPartsGenerator;
|
||||
use super::GENERATED_FUNCS_PREFIX;
|
||||
use super::GENERATED_SECTION_NAME;
|
||||
use super::GENERATED_SECTION_PREFIX;
|
||||
use super::TokenStreamGenerator;
|
||||
use crate::fce_ast_types;
|
||||
use crate::parsed_type::GlueCodeGenerator;
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
@ -29,7 +29,7 @@ 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 func_name = self.rust_name;
|
||||
|
||||
let prefix = GENERATED_FUNCS_PREFIX;
|
||||
let section_name = GENERATED_SECTION_NAME;
|
||||
@ -67,17 +67,19 @@ impl TokenStreamGenerator for fce_ast_types::AstFunctionItem {
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
pub extern "C" fn #prefix#func_name(#(#raw_args)*) #return_type {
|
||||
pub extern "C" unsafe fn #prefix#func_name(#(#raw_args)*) #return_type {
|
||||
#prolog
|
||||
|
||||
// calling the original function with converted args
|
||||
#return_expression #func_name(#(#args)*);
|
||||
|
||||
// return value conversation from Rust type to a Wasm type
|
||||
#epilog
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[allow(clippy::all)]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
#[link_section = #section_name]
|
||||
pub static #func_name#section_prefix#generated_global_name: [u8; #data_size] = { #data };
|
||||
};
|
||||
|
@ -14,13 +14,63 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use crate::fce_ast_types;
|
||||
use super::TokenStreamGenerator;
|
||||
use super::GENERATED_FUNCS_PREFIX;
|
||||
use super::GENERATED_SECTION_NAME;
|
||||
use super::GENERATED_SECTION_PREFIX;
|
||||
use crate::fce_ast_types;
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
|
||||
impl TokenStreamGenerator for fce_ast_types::AstExternModItem {
|
||||
fn generate_token_stream(self) -> syn::Result<TokenStream> {
|
||||
unimplemented!()
|
||||
let data = serde_json::to_string(&self).unwrap();
|
||||
let data_size = data.len();
|
||||
|
||||
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 visibility = "pub";
|
||||
|
||||
let wasm_import_module_name = self.namespace;
|
||||
|
||||
let glue_code = quote! {
|
||||
#[link(wasm_import_module = #wasm_import_module_name)]
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
extern "C" {
|
||||
fn #import_name(#(#raw_args),*) #import_ret_type;
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
unsafe fn #glue_import_name(#(#args),*) #glue_ret_type {
|
||||
#prolog
|
||||
|
||||
#import_name();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
#visibility unsafe fn #prefix#func_name(#(#args)*) #return_type {
|
||||
// arg conversations from Rust types to Wasm types
|
||||
#prolog
|
||||
|
||||
// calling the original function with converted args
|
||||
#return_expression #func_name(#(#raw_args)*);
|
||||
|
||||
// return value conversation from Wasm type to a Rust type
|
||||
#epilog
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::all)]
|
||||
#[link_section = #section_name]
|
||||
pub static #func_name#section_prefix#generated_global_name: [u8; #data_size] = { #data };
|
||||
};
|
||||
|
||||
Ok(glue_code)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user