This commit is contained in:
vms 2021-02-08 12:06:36 +03:00
parent ba2c5a80fd
commit 849042d4db
14 changed files with 526 additions and 93 deletions

404
crates/main/expand.rs Normal file
View File

@ -0,0 +1,404 @@
#![feature(prelude_import)]
//! The main part of Fluence backend SDK. Contains `export_allocator`, `logger` and `result`
//! modules.
#![allow(clippy::missing_safety_doc)]
#![allow(clippy::needless_doctest_main)]
#![doc(html_root_url = "https://docs.rs/fluence-sdk-main/0.2.18")]
#![deny(
dead_code,
nonstandard_style,
unused_imports,
unused_mut,
unused_variables,
unused_unsafe,
unreachable_patterns
)]
#![warn(rust_2018_idioms)]
#[prelude_import]
use std::prelude::v1::*;
#[macro_use]
extern crate std;
mod call_parameters {
use fluence_sdk_macro::fce;
/// Describes an origin that set an argument.
pub struct SecurityTetraplet {
pub peer_pk: String,
pub service_id: String,
pub function_name: String,
pub json_path: String,
}
#[cfg(target_arch = "wasm32")]
#[doc(hidden)]
#[allow(clippy::all)]
impl SecurityTetraplet {
pub fn __fce_generated_serialize(self) -> *const u8 {
let mut raw_record: Vec<u64> = Vec::new();
raw_record.push(self.peer_pk.as_ptr() as _);
raw_record.push(self.peer_pk.len() as _);
std::mem::forget(self.peer_pk);
raw_record.push(self.service_id.as_ptr() as _);
raw_record.push(self.service_id.len() as _);
std::mem::forget(self.service_id);
raw_record.push(self.function_name.as_ptr() as _);
raw_record.push(self.function_name.len() as _);
std::mem::forget(self.function_name);
raw_record.push(self.json_path.as_ptr() as _);
raw_record.push(self.json_path.len() as _);
std::mem::forget(self.json_path);
let raw_record_ptr = raw_record.as_ptr();
std::mem::forget(raw_record);
raw_record_ptr as _
}
pub unsafe fn __fce_generated_deserialize(record_ptr: *const u8) -> Self {
let raw_record: Vec<u64> = Vec::from_raw_parts(record_ptr as _, 64usize, 64usize);
let field_0 = unsafe {
String::from_raw_parts(
raw_record[0usize] as _,
raw_record[1usize] as _,
raw_record[1usize] as _,
)
};
let field_1 = unsafe {
String::from_raw_parts(
raw_record[2usize] as _,
raw_record[3usize] as _,
raw_record[3usize] as _,
)
};
let field_2 = unsafe {
String::from_raw_parts(
raw_record[4usize] as _,
raw_record[5usize] as _,
raw_record[5usize] as _,
)
};
let field_3 = unsafe {
String::from_raw_parts(
raw_record[6usize] as _,
raw_record[7usize] as _,
raw_record[7usize] as _,
)
};
Self {
peer_pk: field_0,
service_id: field_1,
function_name: field_2,
json_path: field_3,
}
}
}
#[cfg(target_arch = "wasm32")]
#[doc(hidden)]
#[allow(clippy::all)]
#[link_section = "__fce_generated_section__SecurityTetraplet"]
pub static __fce_generated_static_global_SecurityTetraplet: [u8; 266usize] = {
* b"{\"ast_type\":\"Record\",\"name\":\"SecurityTetraplet\",\"fields\":[{\"name\":\"peer_pk\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"service_id\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"function_name\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"json_path\",\"ty\":{\"Utf8String\":\"ByValue\"}}]}"
};
/// This struct contains parameters that would be accessible by Wasm modules.
pub struct CallParameters {
/// Peer id of the AIR script initiator.
pub init_peer_id: String,
/// Id of the current service.
pub service_id: String,
/// Id of the service creator.
pub service_creator_peer_id: String,
/// Id of the host which run this service.
pub host_id: String,
/// Id of the particle which execution resulted a call this service.
pub particle_id: String,
/// Security tetraplets which described origin of the arguments.
pub tetraplets: Vec<Vec<SecurityTetraplet>>,
}
#[cfg(target_arch = "wasm32")]
#[doc(hidden)]
#[allow(clippy::all)]
impl CallParameters {
pub fn __fce_generated_serialize(self) -> *const u8 {
let mut raw_record: Vec<u64> = Vec::new();
raw_record.push(self.init_peer_id.as_ptr() as _);
raw_record.push(self.init_peer_id.len() as _);
std::mem::forget(self.init_peer_id);
raw_record.push(self.service_id.as_ptr() as _);
raw_record.push(self.service_id.len() as _);
std::mem::forget(self.service_id);
raw_record.push(self.service_creator_peer_id.as_ptr() as _);
raw_record.push(self.service_creator_peer_id.len() as _);
std::mem::forget(self.service_creator_peer_id);
raw_record.push(self.host_id.as_ptr() as _);
raw_record.push(self.host_id.len() as _);
std::mem::forget(self.host_id);
raw_record.push(self.particle_id.as_ptr() as _);
raw_record.push(self.particle_id.len() as _);
std::mem::forget(self.particle_id);
unsafe fn __fce_generated_vec_serializer_tetraplets_5(
arg: Vec<Vec<SecurityTetraplet>>,
) -> (u32, u32) {
unsafe fn __fce_generated_vec_serializer_tetraplets_5_SecurityTetraplet(
arg: Vec<SecurityTetraplet>,
) -> (u32, u32) {
let mut result: Vec<u32> = Vec::with_capacity(arg.len());
for value in arg {
result.push(value.__fce_generated_serialize() as _);
}
let result = std::mem::ManuallyDrop::new(result);
(result.as_ptr() as _, (4 * result.len()) as _)
}
let mut result: Vec<u32> = Vec::with_capacity(2 * arg.len());
for value in arg {
let (ptr, size) =
__fce_generated_vec_serializer_tetraplets_5_SecurityTetraplet(value);
result.push(ptr as _);
result.push(size as _);
}
let result = std::mem::ManuallyDrop::new(result);
(result.as_ptr() as _, (4 * result.len()) as _)
}
let serialized_arg_5 =
unsafe { __fce_generated_vec_serializer_tetraplets_5(self.tetraplets) };
raw_record.push(serialized_arg_5.0 as _);
raw_record.push(serialized_arg_5.1 as _);
let raw_record_ptr = raw_record.as_ptr();
std::mem::forget(raw_record);
raw_record_ptr as _
}
pub unsafe fn __fce_generated_deserialize(record_ptr: *const u8) -> Self {
let raw_record: Vec<u64> = Vec::from_raw_parts(record_ptr as _, 96usize, 96usize);
let field_0 = unsafe {
String::from_raw_parts(
raw_record[0usize] as _,
raw_record[1usize] as _,
raw_record[1usize] as _,
)
};
let field_1 = unsafe {
String::from_raw_parts(
raw_record[2usize] as _,
raw_record[3usize] as _,
raw_record[3usize] as _,
)
};
let field_2 = unsafe {
String::from_raw_parts(
raw_record[4usize] as _,
raw_record[5usize] as _,
raw_record[5usize] as _,
)
};
let field_3 = unsafe {
String::from_raw_parts(
raw_record[6usize] as _,
raw_record[7usize] as _,
raw_record[7usize] as _,
)
};
let field_4 = unsafe {
String::from_raw_parts(
raw_record[8usize] as _,
raw_record[9usize] as _,
raw_record[9usize] as _,
)
};
unsafe fn __fce_generated_vec_deserializer_10(
offset: u32,
size: u32,
) -> Vec<Vec<SecurityTetraplet>> {
let size = size / 8;
unsafe fn __fce_generated_vec_deserializer_10_SecurityTetraplet(
offset: u32,
size: u32,
) -> Vec<SecurityTetraplet> {
let size = size / 8;
let mut arg: Vec<u64> = Vec::from_raw_parts(offset as _, size as _, size as _);
let mut result = Vec::with_capacity(arg.len());
for offset in arg {
let value = SecurityTetraplet::__fce_generated_deserialize(offset as _);
result.push(value);
}
result
}
let mut arg: Vec<u64> = Vec::from_raw_parts(offset as _, size as _, size as _);
let mut result = Vec::with_capacity(arg.len());
let mut arg = arg.into_iter();
while let Some(offset) = arg.next() {
let size = arg.next().unwrap();
let value = __fce_generated_vec_deserializer_10_SecurityTetraplet(
offset as _,
size as _,
);
result.push(value);
}
result
}
let field_5 = unsafe {
__fce_generated_vec_deserializer_10(
raw_record[10usize] as _,
raw_record[11usize] as _,
)
};
Self {
init_peer_id: field_0,
service_id: field_1,
service_creator_peer_id: field_2,
host_id: field_3,
particle_id: field_4,
tetraplets: field_5,
}
}
}
#[cfg(target_arch = "wasm32")]
#[doc(hidden)]
#[allow(clippy::all)]
#[link_section = "__fce_generated_section__CallParameters"]
pub static __fce_generated_static_global_CallParameters: [u8; 445usize] = {
* b"{\"ast_type\":\"Record\",\"name\":\"CallParameters\",\"fields\":[{\"name\":\"init_peer_id\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"service_id\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"service_creator_peer_id\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"host_id\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"particle_id\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"tetraplets\",\"ty\":{\"Vector\":[{\"Vector\":[{\"Record\":[\"SecurityTetraplet\",\"ByValue\"]},\"ByValue\"]},\"ByValue\"]}}]}"
};
/// This functions takes from host current call parameters.
/// Beware that this implies import function call which takes some time.
#[cfg(target_arch = "wasm32")]
pub fn get_call_parameters() -> CallParameters {
unsafe {
get_call_raw_parameters();
let raw_call_parameters = crate::result::get_result_ptr();
CallParameters::__fce_generated_deserialize(raw_call_parameters as _)
}
}
#[cfg(target_arch = "wasm32")]
#[link(wasm_import_module = "host")]
#[allow(improper_ctypes)]
extern "C" {
#[link_name = "get_call_parameters"]
fn get_call_raw_parameters();
}
}
mod export_allocator {
use super::log;
use std::alloc::alloc as global_alloc;
use std::alloc::dealloc as global_dealloc;
use std::alloc::Layout;
/// Allocates memory area of specified size and returns its address.
/// Returns 0 if supplied size is too long.
#[no_mangle]
pub unsafe fn allocate(size: usize) -> usize {
let layout = match Layout::from_size_align(size, std::mem::align_of::<u8>()) {
Ok(layout) => layout,
Err(_) => return 0,
};
log({
let res = ::alloc::fmt::format(::core::fmt::Arguments::new_v1(
&["sdk.allocate: ", "\n"],
&match (&size,) {
(arg0,) => [::core::fmt::ArgumentV1::new(arg0, ::core::fmt::Debug::fmt)],
},
));
res
});
global_alloc(layout) as _
}
/// Deallocates memory area for provided memory pointer and size.
/// Does nothing if supplied size is too long.
#[no_mangle]
pub unsafe fn deallocate(ptr: *mut u8, size: usize) {
let layout = match Layout::from_size_align(size, std::mem::align_of::<u8>()) {
Ok(layout) => layout,
Err(_) => return,
};
log({
let res = ::alloc::fmt::format(::core::fmt::Arguments::new_v1(
&["sdk.deallocate: ", " ", "\n"],
&match (&ptr, &size) {
(arg0, arg1) => [
::core::fmt::ArgumentV1::new(arg0, ::core::fmt::Debug::fmt),
::core::fmt::ArgumentV1::new(arg1, ::core::fmt::Display::fmt),
],
},
));
res
});
global_dealloc(ptr, layout);
}
}
mod result {
//! Contains ad-hoc implementations of returning complex data types from function calls
//! by two global variables that contain pointer and size. Will be refactored after multi-value
//! support in Wasmer.
use super::log;
use std::sync::atomic::AtomicUsize;
static mut RESULT_PTR: AtomicUsize = AtomicUsize::new(0);
static mut RESULT_SIZE: AtomicUsize = AtomicUsize::new(0);
#[no_mangle]
pub unsafe fn get_result_ptr() -> usize {
log({
let res = ::alloc::fmt::format(::core::fmt::Arguments::new_v1(
&["sdk.get_result_ptr, returns ", "\n"],
&match (&*RESULT_PTR.get_mut(),) {
(arg0,) => [::core::fmt::ArgumentV1::new(
arg0,
::core::fmt::Display::fmt,
)],
},
));
res
});
*RESULT_PTR.get_mut()
}
#[no_mangle]
pub unsafe fn get_result_size() -> usize {
log({
let res = ::alloc::fmt::format(::core::fmt::Arguments::new_v1(
&["sdk.get_result_size, returns ", "\n"],
&match (&*RESULT_SIZE.get_mut(),) {
(arg0,) => [::core::fmt::ArgumentV1::new(
arg0,
::core::fmt::Display::fmt,
)],
},
));
res
});
*RESULT_SIZE.get_mut()
}
#[no_mangle]
pub unsafe fn set_result_ptr(ptr: usize) {
log({
let res = ::alloc::fmt::format(::core::fmt::Arguments::new_v1(
&["sdk.set_result_ptr: ", "\n"],
&match (&ptr,) {
(arg0,) => [::core::fmt::ArgumentV1::new(
arg0,
::core::fmt::Display::fmt,
)],
},
));
res
});
*RESULT_PTR.get_mut() = ptr;
}
#[no_mangle]
pub unsafe fn set_result_size(size: usize) {
log({
let res = ::alloc::fmt::format(::core::fmt::Arguments::new_v1(
&["sdk.set_result_size: ", "\n"],
&match (&size,) {
(arg0,) => [::core::fmt::ArgumentV1::new(
arg0,
::core::fmt::Display::fmt,
)],
},
));
res
});
*RESULT_SIZE.get_mut() = size;
}
}
pub use call_parameters::CallParameters;
pub use call_parameters::SecurityTetraplet;
#[cfg(target_arch = "wasm32")]
pub use call_parameters::get_call_parameters;
pub use export_allocator::allocate;
pub use export_allocator::deallocate;
pub use result::get_result_ptr;
pub use result::get_result_size;
pub use result::set_result_ptr;
pub use result::set_result_size;
#[allow(unused_variables)]
pub(crate) fn log<S: AsRef<str>>(msg: S) {}

View File

@ -16,12 +16,12 @@
use fluence_sdk_macro::fce;
use serde::Serialize;
use serde::Deserialize;
// use serde::Serialize;
// use serde::Deserialize;
/// Describes an origin that set an argument.
#[fce]
#[derive(Clone, PartialEq, Default, Eq, Debug, Serialize, Deserialize)]
// #[derive(Clone, PartialEq, Default, Eq, Debug, Serialize, Deserialize)]
pub struct SecurityTetraplet {
pub peer_pk: String,
pub service_id: String,
@ -31,7 +31,7 @@ pub struct SecurityTetraplet {
/// This struct contains parameters that would be accessible by Wasm modules.
#[fce]
#[derive(Clone, PartialEq, Default, Eq, Debug, Serialize, Deserialize)]
// #[derive(Clone, PartialEq, Default, Eq, Debug, Serialize, Deserialize)]
pub struct CallParameters {
/// Peer id of the AIR script initiator.
pub init_peer_id: String,

View File

@ -34,7 +34,6 @@ use serde::Serialize;
use serde::Deserialize;
use syn::parse::Error;
use syn::spanned::Spanned;
use proc_macro2::TokenStream;
/// An internal representation of supported Rust types.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
@ -56,6 +55,7 @@ pub enum ParsedType {
Record(String, PassingStyle), // short type name
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum PassingStyle {
ByValue,
ByRef,
@ -145,9 +145,10 @@ impl ParsedType {
fn type_to_path_passing_style(input_type: &syn::Type) -> syn::Result<(&syn::Path, PassingStyle)> {
match input_type {
syn::Type::Path(path) => Ok((&path.path, PassingStyle::ByRef)),
syn::Type::Path(path) => Ok((&path.path, PassingStyle::ByValue)),
syn::Type::Reference(type_reference) => match &*type_reference.elem {
syn::Type::Path(path) => {
// TODO: support lifetimes
if type_reference.lifetime.is_some() {
return Err(Error::new(
input_type.span(),

View File

@ -25,19 +25,21 @@ pub(crate) trait FnArgGlueCodeGenerator {
impl FnArgGlueCodeGenerator for (String, ParsedType) {
fn generate_arguments(&self) -> Vec<RustType> {
match self.1 {
ParsedType::Boolean => vec![RustType::I32],
ParsedType::I8 => vec![RustType::I8],
ParsedType::I16 => vec![RustType::I16],
ParsedType::I32 => vec![RustType::I32],
ParsedType::I64 => vec![RustType::I64],
ParsedType::U8 => vec![RustType::U8],
ParsedType::U16 => vec![RustType::U16],
ParsedType::U32 => vec![RustType::U32],
ParsedType::U64 => vec![RustType::U64],
ParsedType::Record(_) => vec![RustType::U32],
ParsedType::F32 => vec![RustType::F32],
ParsedType::F64 => vec![RustType::F64],
ParsedType::Utf8String | ParsedType::Vector(_) => vec![RustType::U32, RustType::U32],
ParsedType::Boolean(_) => vec![RustType::I32],
ParsedType::I8(_) => vec![RustType::I8],
ParsedType::I16(_) => vec![RustType::I16],
ParsedType::I32(_) => vec![RustType::I32],
ParsedType::I64(_) => vec![RustType::I64],
ParsedType::U8(_) => vec![RustType::U8],
ParsedType::U16(_) => vec![RustType::U16],
ParsedType::U32(_) => vec![RustType::U32],
ParsedType::U64(_) => vec![RustType::U64],
ParsedType::Record(..) => vec![RustType::U32],
ParsedType::F32(_) => vec![RustType::F32],
ParsedType::F64(_) => vec![RustType::F64],
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) | ParsedType::Vector(..) => {
vec![RustType::U32, RustType::U32]
}
}
}
}

View File

@ -53,21 +53,22 @@ impl FnEpilogGlueCodeGenerator for Option<ParsedType> {
fn generate_fn_return_type(ty: &Option<ParsedType>) -> proc_macro2::TokenStream {
let ty = match ty {
Some(ParsedType::Boolean) => Some("i32"),
Some(ParsedType::I8) => Some("i8"),
Some(ParsedType::I16) => Some("i16"),
Some(ParsedType::I32) => Some("i32"),
Some(ParsedType::I64) => Some("i64"),
Some(ParsedType::U8) => Some("u8"),
Some(ParsedType::U16) => Some("u16"),
Some(ParsedType::U32) => Some("u32"),
Some(ParsedType::U64) => Some("u64"),
Some(ParsedType::F32) => Some("f32"),
Some(ParsedType::F64) => Some("f64"),
Some(ParsedType::Boolean(_)) => Some("i32"),
Some(ParsedType::I8(_)) => Some("i8"),
Some(ParsedType::I16(_)) => Some("i16"),
Some(ParsedType::I32(_)) => Some("i32"),
Some(ParsedType::I64(_)) => Some("i64"),
Some(ParsedType::U8(_)) => Some("u8"),
Some(ParsedType::U16(_)) => Some("u16"),
Some(ParsedType::U32(_)) => Some("u32"),
Some(ParsedType::U64(_)) => Some("u64"),
Some(ParsedType::F32(_)) => Some("f32"),
Some(ParsedType::F64(_)) => Some("f64"),
None
| Some(ParsedType::Utf8String)
| Some(ParsedType::Vector(_))
| Some(ParsedType::Record(_)) => None,
| Some(ParsedType::Utf8Str(_))
| Some(ParsedType::Utf8String(_))
| Some(ParsedType::Vector(..))
| Some(ParsedType::Record(..)) => None,
};
match ty {
@ -91,18 +92,18 @@ fn generate_return_expression(ty: &Option<ParsedType>) -> proc_macro2::TokenStre
fn generate_epilog(ty: &Option<ParsedType>) -> proc_macro2::TokenStream {
match ty {
None => quote!(),
Some(ParsedType::Record(_)) => {
Some(ParsedType::Record(..)) => {
quote! {
let result_ptr = result.__fce_generated_serialize();
fluence::internal::set_result_ptr(result_ptr as _);
}
}
Some(ParsedType::Utf8String) => quote! {
Some(ParsedType::Utf8Str(_)) | Some(ParsedType::Utf8String(_)) => quote! {
fluence::internal::set_result_ptr(result.as_ptr() as _);
fluence::internal::set_result_size(result.len() as _);
std::mem::forget(result);
},
Some(ParsedType::Vector(ty)) => {
Some(ParsedType::Vector(ty, _)) => {
let generated_serializer_name = String::from("__fce_generated_vec_serializer");
let generated_serializer_ident = new_ident!(generated_serializer_name);
let vector_serializer =

View File

@ -18,6 +18,7 @@ use super::ParsedType;
use super::FnArgGlueCodeGenerator;
use crate::new_ident;
use crate::wasm_type::RustType;
use crate::parsed_type::PassingStyle;
use quote::quote;
@ -26,7 +27,7 @@ pub(crate) struct FnPrologDescriptor {
pub(crate) raw_arg_names: Vec<syn::Ident>,
pub(crate) raw_arg_types: Vec<RustType>,
pub(crate) prolog: proc_macro2::TokenStream,
pub(crate) args: Vec<syn::Ident>,
pub(crate) args: Vec<proc_macro2::TokenStream>,
}
/// This trait could be used to generate various parts needed to construct prolog of an export
@ -47,16 +48,19 @@ pub(crate) trait FnPrologGlueCodeGenerator {
impl FnPrologGlueCodeGenerator for Vec<(String, ParsedType)> {
fn generate_prolog(&self) -> FnPrologDescriptor {
let mut prolog = proc_macro2::TokenStream::new();
let mut args: Vec<syn::Ident> = Vec::with_capacity(self.len());
let mut args: Vec<proc_macro2::TokenStream> = Vec::with_capacity(self.len());
let mut raw_arg_names = Vec::with_capacity(self.len());
let mut raw_arg_types = Vec::with_capacity(self.len());
let mut input_type_id = 0;
for arg in self {
let type_prolog = generate_type_prolog(&arg.1, input_type_id, input_type_id);
let type_prolog = generate_type_lifting_prolog(&arg.1, input_type_id, input_type_id);
let curr_raw_arg_types = arg.generate_arguments();
let passing_style = passing_style_of(&arg.1);
args.push(new_ident!(format!("converted_arg_{}", input_type_id)));
let arg = new_ident!(format!("converted_arg_{}", input_type_id));
let arg = quote! { #passing_style #arg };
args.push(arg);
raw_arg_names.extend(
curr_raw_arg_types
@ -79,7 +83,7 @@ impl FnPrologGlueCodeGenerator for Vec<(String, ParsedType)> {
}
}
fn generate_type_prolog(
fn generate_type_lifting_prolog(
ty: &ParsedType,
generated_arg_id: usize,
supplied_arg_start_id: usize,
@ -87,7 +91,7 @@ fn generate_type_prolog(
let generated_arg_id = new_ident!(format!("converted_arg_{}", generated_arg_id));
match ty {
ParsedType::Boolean => {
ParsedType::Boolean(_) => {
let supplied_arg_start_id = new_ident!(format!("arg_{}", supplied_arg_start_id));
quote! {
let #generated_arg_id = #supplied_arg_start_id != 0;
@ -104,10 +108,10 @@ fn generate_type_prolog(
let ptr = new_ident!(format!("arg_{}", supplied_arg_start_id));
let size = new_ident!(format!("arg_{}", supplied_arg_start_id + 1));
match ty {
ParsedType::Utf8String => quote! {
ParsedType::Utf8String(_) => quote! {
let #generated_arg_id = String::from_raw_parts(#ptr as _, #size as _ , #size as _);
},
ParsedType::Vector(ty) => {
ParsedType::Vector(ty, _) => {
let generated_deserializer_name =
format!("__fce_generated_vec_deserializer_{}", supplied_arg_start_id);
let generated_deserializer_ident = new_ident!(generated_deserializer_name);
@ -121,7 +125,7 @@ fn generate_type_prolog(
let #generated_arg_id = #generated_deserializer_ident(#ptr as _, #size as _);
}
}
ParsedType::Record(record_name) => {
ParsedType::Record(record_name, _) => {
let record_ident = new_ident!(record_name);
quote! {
let #generated_arg_id = #record_ident::__fce_generated_deserialize(#ptr as _);
@ -134,3 +138,25 @@ fn generate_type_prolog(
}
}
}
fn passing_style_of(ty: &ParsedType) -> &PassingStyle {
use ParsedType::*;
match ty {
Boolean(passing_style) => passing_style,
U8(passing_style) => passing_style,
U16(passing_style) => passing_style,
U32(passing_style) => passing_style,
U64(passing_style) => passing_style,
I8(passing_style) => passing_style,
I16(passing_style) => passing_style,
I32(passing_style) => passing_style,
I64(passing_style) => passing_style,
F32(passing_style) => passing_style,
F64(passing_style) => passing_style,
Utf8Str(passing_style) => passing_style,
Utf8String(passing_style) => passing_style,
Vector(_, passing_style) => passing_style,
Record(_, passing_style) => passing_style,
}
}

View File

@ -28,16 +28,16 @@ impl ForeignModArgGlueCodeGenerator for ParsedType {
let arg = crate::new_ident!(format!("arg_{}", arg_start_id));
match self {
ParsedType::Utf8String => {
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => {
quote! { #arg.as_ptr() as _, #arg.len() as _ }
}
ParsedType::Vector(_) => {
ParsedType::Vector(..) => {
quote! { #arg.0 as _, #arg.1 as _ }
}
ParsedType::Record(_) => quote! {
ParsedType::Record(..) => quote! {
#arg.__fce_generated_serialize() as _
},
ParsedType::Boolean => quote! { #arg as _ },
ParsedType::Boolean(_) => quote! { #arg as _ },
_ => quote! { #arg },
}
}

View File

@ -43,20 +43,20 @@ impl ForeignModEpilogGlueCodeGenerator for Option<ParsedType> {
fn generate_wrapper_epilog(&self) -> proc_macro2::TokenStream {
match self {
None => quote!(),
Some(ParsedType::Boolean) => quote! {
Some(ParsedType::Boolean(_)) => quote! {
return result != 0;
},
Some(ty) if !ty.is_complex_type() => quote! {
return result as _;
},
Some(ParsedType::Utf8String) => quote! {
Some(ParsedType::Utf8String(_)) => quote! {
String::from_raw_parts(
fluence::internal::get_result_ptr() as _,
fluence::internal::get_result_size() as _,
fluence::internal::get_result_size() as _
)
},
Some(ParsedType::Vector(ty)) => {
Some(ParsedType::Vector(ty, _)) => {
let generated_deserializer_name = String::from("__fce_generated_vec_deserializer");
let generated_deserializer_ident = new_ident!(generated_deserializer_name);
let vector_deserializer = super::vector_utils::generate_vector_deserializer(
@ -72,7 +72,7 @@ impl ForeignModEpilogGlueCodeGenerator for Option<ParsedType> {
)
}
}
Some(ParsedType::Record(record_name)) => {
Some(ParsedType::Record(record_name, _)) => {
let record_ident = new_ident!(record_name);
quote! {

View File

@ -17,6 +17,7 @@
use super::ParsedType;
use crate::wasm_type::RustType;
use crate::new_ident;
use crate::parsed_type::PassingStyle;
pub(crate) struct WrapperDescriptor {
pub(crate) arg_names: Vec<syn::Ident>,
@ -76,11 +77,11 @@ impl ForeignModPrologGlueCodeGenerator for Vec<(String, ParsedType)> {
arg_names.push(arg_ident.clone());
match ty {
ParsedType::Utf8String => {
ParsedType::Utf8String(PassingStyle::ByValue) => {
arg_transforms.extend(quote::quote! { let mut #arg_ident = std::mem::ManuallyDrop::new(#arg_ident); });
arg_drops.extend(quote::quote! { std::mem::ManuallyDrop::drop(&mut #arg_ident); });
},
ParsedType::Vector(ty) => {
ParsedType::Vector(ty, _) => {
let generated_serializer_name = format!("__fce_generated_vec_serializer_{}", arg_name);
let generated_serializer_ident = new_ident!(generated_serializer_name);
let vector_serializer = super::vector_utils::generate_vector_serializer(ty, &generated_serializer_name);

View File

@ -18,8 +18,6 @@ use super::PassingStyle;
use super::ParsedType;
use quote::quote;
use syn::parse::Error;
use syn::spanned::Spanned;
use proc_macro2::TokenStream;
use std::fmt;
@ -29,7 +27,7 @@ impl quote::ToTokens for PassingStyle {
tokens.extend(self.to_token_stream());
}
fn to_token_stream(&self) -> proc_macro2::TokenStream {
fn to_token_stream(&self) -> TokenStream {
match self {
PassingStyle::ByValue => quote! {},
PassingStyle::ByRef => quote! { & },

View File

@ -22,36 +22,36 @@ pub(crate) fn generate_vector_serializer(
arg_name: &str,
) -> proc_macro2::TokenStream {
let values_serializer = match value_ty {
ParsedType::Boolean => {
ParsedType::Boolean(_) => {
quote! {
unimplemented!()
}
}
ParsedType::I8 | ParsedType::U8 => {
ParsedType::I8(_) | ParsedType::U8(_) => {
quote! {
let arg = std::mem::ManuallyDrop::new(arg);
(arg.as_ptr() as _, arg.len() as _)
}
}
ParsedType::I16 | ParsedType::U16 => {
ParsedType::I16(_) | ParsedType::U16(_) => {
quote! {
let arg = std::mem::ManuallyDrop::new(arg);
(arg.as_ptr() as _, (2 * arg.len()) as _)
}
}
ParsedType::I32 | ParsedType::U32 => {
ParsedType::I32(_) | ParsedType::U32(_) => {
quote! {
let arg = std::mem::ManuallyDrop::new(arg);
(arg.as_ptr() as _, (4 * arg.len()) as _)
}
}
ParsedType::I64 | ParsedType::U64 => {
ParsedType::I64(_) | ParsedType::U64(_) => {
quote! {
let arg = std::mem::ManuallyDrop::new(arg);
(arg.as_ptr() as _, (8 * arg.len()) as _)
}
}
ParsedType::F32 => {
ParsedType::F32(_) => {
quote! {
let mut result: Vec<u32> = Vec::with_capacity(arg.len());
for value in arg {
@ -62,7 +62,7 @@ pub(crate) fn generate_vector_serializer(
(result.as_ptr() as _, (4 * result.len()) as _)
}
}
ParsedType::F64 => {
ParsedType::F64(_) => {
quote! {
let mut result: Vec<u64> = Vec::with_capacity(arg.len());
for value in arg {
@ -73,7 +73,7 @@ pub(crate) fn generate_vector_serializer(
(result.as_ptr() as _, (8 * result.len()) as _)
}
}
ParsedType::Utf8String => {
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => {
quote! {
let mut result: Vec<u32> = Vec::with_capacity(arg.len());
@ -87,7 +87,7 @@ pub(crate) fn generate_vector_serializer(
(result.as_ptr() as _, (4 * result.len()) as _)
}
}
ParsedType::Vector(ty) => {
ParsedType::Vector(ty, _) => {
let serializer_name = format!("{}_{}", arg_name, ty);
let inner_vector_serializer = generate_vector_serializer(&*ty, &serializer_name);
let serializer_ident = crate::new_ident!(serializer_name);
@ -107,7 +107,7 @@ pub(crate) fn generate_vector_serializer(
}
}
ParsedType::Record(_) => {
ParsedType::Record(..) => {
quote! {
let mut result: Vec<u32> = Vec::with_capacity(arg.len());
@ -137,12 +137,12 @@ pub(crate) fn generate_vector_deserializer(
let arg = crate::new_ident!(arg_name);
let values_deserializer = match value_ty {
ParsedType::Boolean => {
ParsedType::Boolean(_) => {
quote! {
unimplemented!()
}
}
ParsedType::F32 => {
ParsedType::F32(_) => {
quote! {
let mut arg: Vec<u64> = Vec::from_raw_parts(offset as _, size as _, size as _);
let mut result = Vec::with_capacity(arg.len());
@ -154,7 +154,7 @@ pub(crate) fn generate_vector_deserializer(
result
}
}
ParsedType::F64 => {
ParsedType::F64(_) => {
quote! {
let mut arg: Vec<u64> = Vec::from_raw_parts(offset as _, size as _, size as _);
let mut result = Vec::with_capacity(arg.len());
@ -166,7 +166,7 @@ pub(crate) fn generate_vector_deserializer(
result
}
}
ParsedType::Utf8String => {
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => {
quote! {
let mut arg: Vec<u64> = Vec::from_raw_parts(offset as _, size as _, size as _);
let mut arg = arg.into_iter();
@ -180,7 +180,7 @@ pub(crate) fn generate_vector_deserializer(
result
}
}
ParsedType::Vector(ty) => {
ParsedType::Vector(ty, _) => {
let deserializer_name = format!("{}_{}", arg_name, ty);
let inner_vector_deserializer = generate_vector_deserializer(&*ty, &deserializer_name);
let deserializer_ident = crate::new_ident!(deserializer_name);
@ -202,7 +202,7 @@ pub(crate) fn generate_vector_deserializer(
result
}
}
ParsedType::Record(record_name) => {
ParsedType::Record(record_name, _) => {
let record_name_ident = crate::new_ident!(record_name);
quote! {

View File

@ -39,62 +39,62 @@ impl RecordDeserializerGlueCodeGenerator for fce_ast_types::AstRecordItem {
for (id, ast_field) in self.fields.iter().enumerate() {
let field = new_ident!(format!("field_{}", id));
let field_d = match &ast_field.ty {
ParsedType::Boolean => {
ParsedType::Boolean(_) => {
quote! {
let #field = raw_record[#value_id] != 0;
}
}
ParsedType::I8 => {
ParsedType::I8(_) => {
quote! {
let #field = raw_record[#value_id] as i8;
}
}
ParsedType::I16 => {
ParsedType::I16(_) => {
quote! {
let #field = raw_record[#value_id] as i16;
}
}
ParsedType::I32 => {
ParsedType::I32(_) => {
quote! {
let #field = raw_record[#value_id] as i32;
}
}
ParsedType::I64 => {
ParsedType::I64(_) => {
quote! {
let #field = raw_record[#value_id] as i64;
}
}
ParsedType::U8 => {
ParsedType::U8(_) => {
quote! {
let #field = raw_record[#value_id] as u8;
}
}
ParsedType::U16 => {
ParsedType::U16(_) => {
quote! {
let #field = raw_record[#value_id] as u16;
}
}
ParsedType::U32 => {
ParsedType::U32(_) => {
quote! {
let #field = raw_record[#value_id] as u32;
}
}
ParsedType::U64 => {
ParsedType::U64(_) => {
quote! {
let #field = raw_record[#value_id] as u64;
}
}
ParsedType::F32 => {
ParsedType::F32(_) => {
quote! {
let #field = raw_record[#value_id] as f32;
}
}
ParsedType::F64 => {
ParsedType::F64(_) => {
quote! {
let #field = f64::from_bits(raw_record[#value_id]);
}
}
ParsedType::Utf8String => {
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => {
let ptr_id = value_id;
let size_id = value_id + 1;
value_id += 1;
@ -103,7 +103,7 @@ impl RecordDeserializerGlueCodeGenerator for fce_ast_types::AstRecordItem {
let #field = unsafe { String::from_raw_parts(raw_record[#ptr_id] as _, raw_record[#size_id] as _, raw_record[#size_id] as _) };
}
}
ParsedType::Vector(ty) => {
ParsedType::Vector(ty, _) => {
let generated_deserializer_name =
format!("__fce_generated_vec_deserializer_{}", value_id);
let generated_deserializer_ident = new_ident!(generated_deserializer_name);
@ -121,7 +121,7 @@ impl RecordDeserializerGlueCodeGenerator for fce_ast_types::AstRecordItem {
let #field = unsafe { #generated_deserializer_ident(raw_record[#ptr_id] as _, raw_record[#size_id] as _) };
}
}
ParsedType::Record(record_name) => {
ParsedType::Record(record_name, _) => {
let ptr_id = value_id;
let record_ident = new_ident!(record_name);
quote! {

View File

@ -32,19 +32,19 @@ impl RecordSerializerGlueCodeGenerator for fce_ast_types::AstRecordItem {
let field_ident = field_ident(field, id);
let field_serialization = match &field.ty {
ParsedType::F64 => {
ParsedType::F64(_) => {
quote! {
raw_record.push(#field_ident.to_bits());
}
}
ParsedType::Utf8String => {
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => {
quote! {
raw_record.push(#field_ident.as_ptr() as _);
raw_record.push(#field_ident.len() as _);
std::mem::forget(#field_ident);
}
}
ParsedType::Vector(ty) => {
ParsedType::Vector(ty, _) => {
let generated_serializer_name = format!(
"__fce_generated_vec_serializer_{}_{}",
field.name.as_ref().unwrap(),
@ -64,7 +64,7 @@ impl RecordSerializerGlueCodeGenerator for fce_ast_types::AstRecordItem {
raw_record.push(#serialized_field_ident.1 as _);
}
}
ParsedType::Record(_) => {
ParsedType::Record(..) => {
quote! {
raw_record.push(#field_ident.__fce_generated_serialize() as _);
}

View File

@ -54,7 +54,7 @@ pub fn get_record_size<'a>(
for field in fields {
let params_count = match field {
ParsedType::Vector(_) | ParsedType::Utf8String => 2,
ParsedType::Vector(..) | ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => 2,
_ => 1,
};