Merge pull request #29 from fluencelabs/optimizations

Arrays/Record passing scheme refactoring
This commit is contained in:
vms 2021-04-26 00:41:11 +03:00 committed by GitHub
commit e8bc1db0df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 1264 additions and 744 deletions

View File

@ -14,23 +14,47 @@
* limitations under the License.
*/
use super::log;
use std::alloc::alloc as global_alloc;
use std::alloc::Layout;
/// Allocates memory area of specified size and returns its address.
/// Returns 0 if supplied size is too long.
/// Allocates memory area of specified size and type and returns its address.
/// The allocated memory region is intended to be use as a Vec.
#[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,
// in this case a err may occur only in a case of too long allocated size,
// so just return 0
Err(_) => return 0,
};
pub unsafe fn allocate(elem_count: usize, elem_ty: usize) -> usize {
if elem_count == 0 {
// otherwise 1 would be returned due to the internals of Vec in Rust
return 0;
}
log(format!("sdk.allocate: {:?}\n", size));
let allocated_mem = allocate_impl(elem_count, elem_ty);
crate::debug_log!(format!(
"sdk.allocate: {} {} -> {}\n",
elem_count, elem_ty, allocated_mem
));
global_alloc(layout) as _
allocated_mem
}
fn allocate_impl(elem_count: usize, elem_ty: usize) -> usize {
match elem_ty {
0 => allocate_vec::<u8>(elem_count), // for booleans
1 => allocate_vec::<u8>(elem_count),
2 => allocate_vec::<u16>(elem_count),
3 => allocate_vec::<u32>(elem_count),
4 => allocate_vec::<u64>(elem_count),
5 => allocate_vec::<i8>(elem_count),
6 => allocate_vec::<i16>(elem_count),
7 => allocate_vec::<i32>(elem_count),
8 => allocate_vec::<i64>(elem_count),
9 => allocate_vec::<f32>(elem_count),
10 => allocate_vec::<f64>(elem_count),
_ => 0,
}
}
fn allocate_vec<T>(count: usize) -> usize {
// TODO: handle OOM
// This allocation scheme with vectors is needed to deal with internal Vec layout
let vec = Vec::<T>::with_capacity(count);
let offset = vec.as_ptr() as usize;
std::mem::forget(vec);
offset
}

View File

@ -57,14 +57,16 @@ pub use result::add_object_to_release;
pub use module_manifest::MANIFEST_SECTION_NAME;
pub use sdk_version_embedder::VERSION_SECTION_NAME;
#[allow(unused_variables)]
pub(crate) fn log<S: AsRef<str>>(msg: S) {
// logs will be printed only if debug feature is enabled
// these logs will be printed only if debug feature is enabled
#[macro_export]
macro_rules! debug_log {
($msg_generator:expr) => {
#[cfg(feature = "debug")]
{
let level = log::Level::Info as i32;
let target = 0i32;
let msg = msg.as_ref();
logger::log_utf8_string(level, target, msg.as_ptr() as i32, msg.len() as i32);
let msg = $msg_generator;
crate::logger::log_utf8_string(level, target, msg.as_ptr() as i32, msg.len() as i32);
}
};
}

View File

@ -18,8 +18,6 @@
//! 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;
use std::cell::RefCell;
use std::any::Any;
@ -31,7 +29,7 @@ thread_local!(static OBJECTS_TO_RELEASE: RefCell<Vec<Box<dyn Any>>> = RefCell::n
#[no_mangle]
pub unsafe fn get_result_ptr() -> usize {
log(format!(
crate::debug_log!(format!(
"sdk.get_result_ptr, returns {}\n",
*RESULT_PTR.get_mut()
));
@ -41,7 +39,7 @@ pub unsafe fn get_result_ptr() -> usize {
#[no_mangle]
pub unsafe fn get_result_size() -> usize {
log(format!(
crate::debug_log!(format!(
"sdk.get_result_size, returns {}\n",
*RESULT_SIZE.get_mut()
));
@ -51,14 +49,14 @@ pub unsafe fn get_result_size() -> usize {
#[no_mangle]
pub unsafe fn set_result_ptr(ptr: usize) {
log(format!("sdk.set_result_ptr: {}\n", ptr));
crate::debug_log!(format!("sdk.set_result_ptr: {}\n", ptr));
*RESULT_PTR.get_mut() = ptr;
}
#[no_mangle]
pub unsafe fn set_result_size(size: usize) {
log(format!("sdk.set_result_size: {}\n", size));
crate::debug_log!(format!("sdk.set_result_size: {}\n", size));
*RESULT_SIZE.get_mut() = size;
}

View File

@ -0,0 +1,88 @@
/*
* Copyright 2020 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::parsed_type::ParsedType;
#[derive(Clone)]
pub(crate) struct AstFnArgument {
pub name: String,
pub ty: ParsedType,
}
#[derive(Clone)]
pub(crate) struct AstFnSignature {
pub visibility: syn::Visibility,
pub name: String,
pub arguments: Vec<AstFnArgument>,
// only one or zero return values are supported now,
// waiting for adding multi-value support in Wasmer
pub output_type: Option<ParsedType>,
}
#[derive(Clone)]
pub(crate) struct AstRecord {
pub name: String,
pub fields: AstRecordFields,
pub original: syn::ItemStruct,
}
#[derive(Debug, Clone, PartialEq)]
pub(crate) enum AstRecordFields {
Named(Vec<AstRecordField>),
// named and unnamed variants have the same inner field types because of it's easy to handle it,
// for additional info look at https://github.com/dtolnay/syn/issues/698
#[allow(dead_code)] // at the moment tuple and unit structs aren't supported
Unnamed(Vec<AstRecordField>),
#[allow(dead_code)] // at the moment tuple and unit structs aren't supported
Unit,
}
#[derive(Debug, Clone, PartialEq)]
pub(crate) struct AstRecordField {
/// Name of the field. Can be `None` for tuples.
pub name: Option<String>,
pub ty: ParsedType,
}
#[derive(Clone)]
pub(crate) struct AstExternFn {
pub link_name: Option<String>,
// only imports are possible here
pub signature: AstFnSignature,
}
#[derive(Clone)]
pub(crate) struct AstExternMod {
pub namespace: String,
// only imports are possible here
pub imports: Vec<AstExternFn>,
pub original: syn::ItemForeignMod,
}
#[derive(Clone)]
pub(crate) struct AstFn {
pub signature: AstFnSignature,
pub original: syn::ItemFn,
}
#[derive(Clone)]
pub(crate) enum FCEAst {
Function(AstFn),
ExternMod(AstExternMod),
Record(AstRecord),
}

View File

@ -0,0 +1,196 @@
/*
* Copyright 2020 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::parsed_type::ParsedType;
use serde::Serialize;
use serde::Deserialize;
#[derive(Clone, Serialize, Deserialize)]
pub struct FnArgument {
pub name: String,
pub ty: ParsedType,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct FnSignature {
pub name: String,
pub arguments: Vec<FnArgument>,
pub output_types: Vec<ParsedType>,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct RecordType {
pub name: String,
pub fields: RecordFields,
}
#[derive(Clone, Serialize, Deserialize)]
pub enum RecordFields {
Named(Vec<RecordField>),
// named and unnamed variants have the same inner field types because of it's easy to handle it,
// for additional info look at https://github.com/dtolnay/syn/issues/698
Unnamed(Vec<RecordField>),
Unit,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct RecordField {
// fields of tuple structs haven't got name
pub name: Option<String>,
pub ty: ParsedType,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct ExternFnType {
pub link_name: Option<String>,
// only imports are possible here
pub signature: FnSignature,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct ExternModType {
pub namespace: String,
// only imports are possible here
pub imports: Vec<ExternFnType>,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct FnType {
pub signature: FnSignature,
}
#[derive(Clone, Serialize, Deserialize)]
#[serde(tag = "ast_type")]
pub enum SDKAst {
Function(FnType),
ExternMod(ExternModType),
Record(RecordType),
}
use crate::ast_types::{
AstFn, AstFnSignature, AstFnArgument, AstExternMod, AstExternFn, AstRecordField, AstRecord,
AstRecordFields,
};
impl From<AstFn> for SDKAst {
fn from(ast_fn_item: AstFn) -> Self {
let fn_item = ast_fn_item.into();
Self::Function(fn_item)
}
}
impl From<AstExternMod> for SDKAst {
fn from(ast_extern_mod: AstExternMod) -> Self {
let extern_mod = ast_extern_mod.into();
Self::ExternMod(extern_mod)
}
}
impl From<AstRecord> for SDKAst {
fn from(ast_record_item: AstRecord) -> Self {
let record_item = ast_record_item.into();
Self::Record(record_item)
}
}
impl From<AstFn> for FnType {
fn from(ast_fn_item: AstFn) -> Self {
let signature = ast_fn_item.signature.into();
Self { signature }
}
}
impl From<AstExternMod> for ExternModType {
fn from(ast_extern_mod: AstExternMod) -> Self {
let imports = ast_extern_mod.imports.into_iter().map(Into::into).collect();
Self {
namespace: ast_extern_mod.namespace,
imports,
}
}
}
impl From<AstRecord> for RecordType {
fn from(ast_record_item: AstRecord) -> Self {
Self {
name: ast_record_item.name,
fields: ast_record_item.fields.into(),
}
}
}
impl From<AstRecordFields> for RecordFields {
fn from(ast_record_item: AstRecordFields) -> Self {
match ast_record_item {
AstRecordFields::Named(fields) => {
let fields = fields.into_iter().map(Into::into).collect();
Self::Named(fields)
}
AstRecordFields::Unnamed(fields) => {
let fields = fields.into_iter().map(Into::into).collect();
Self::Unnamed(fields)
}
AstRecordFields::Unit => Self::Unit,
}
}
}
impl From<AstFnSignature> for FnSignature {
fn from(ast_fn_sig: AstFnSignature) -> Self {
// TODO: consider to do transmute here in case of optimization issues.
let arguments = ast_fn_sig.arguments.into_iter().map(Into::into).collect();
let output_type = match ast_fn_sig.output_type {
Some(output_type) => vec![output_type],
None => Vec::new(),
};
Self {
name: ast_fn_sig.name,
arguments,
output_types: output_type,
}
}
}
impl From<AstFnArgument> for FnArgument {
fn from(ast_fn_arg: AstFnArgument) -> Self {
Self {
name: ast_fn_arg.name,
ty: ast_fn_arg.ty,
}
}
}
impl From<AstExternFn> for ExternFnType {
fn from(ast_extern_item: AstExternFn) -> Self {
Self {
link_name: ast_extern_item.link_name,
signature: ast_extern_item.signature.into(),
}
}
}
impl From<AstRecordField> for RecordField {
fn from(ast_record_field: AstRecordField) -> Self {
Self {
name: ast_record_field.name,
ty: ast_record_field.ty,
}
}
}

View File

@ -1,91 +0,0 @@
/*
* Copyright 2020 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::parsed_type::ParsedType;
use serde::Serialize;
use serde::Deserialize;
#[derive(Clone, Serialize, Deserialize)]
pub struct AstFnArgument {
pub name: String,
pub ty: ParsedType,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct AstFnSignature {
// Option is needed only for skipping serialization/deserialization of syn::ItemFn
#[serde(skip)]
pub visibility: Option<syn::Visibility>,
pub name: String,
pub arguments: Vec<AstFnArgument>,
// fce supports only one return value now,
// waiting for adding multi-value support in Wasmer.
pub output_type: Option<ParsedType>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct AstRecordField {
// fields of tuple structs haven't got name
pub name: Option<String>,
pub ty: ParsedType,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct AstRecordItem {
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(Clone, Serialize, Deserialize)]
pub struct AstExternFnItem {
pub link_name: Option<String>,
// only imports are possible here
pub signature: AstFnSignature,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct AstExternModItem {
pub namespace: String,
// only imports are possible here
pub imports: Vec<AstExternFnItem>,
// Option is needed only for skipping serialization/deserialization of syn::ItemFn
#[serde(skip)]
pub original: Option<syn::ItemForeignMod>,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct AstFnItem {
pub signature: AstFnSignature,
// Option is needed only for skipping serialization/deserialization of syn::ItemFn
#[serde(skip)]
pub original: Option<syn::ItemFn>,
}
#[derive(Clone, Serialize, Deserialize)]
#[serde(tag = "ast_type")]
pub enum FCEAst {
Function(AstFnItem),
ExternMod(AstExternModItem),
Record(AstRecordItem),
}

View File

@ -30,7 +30,8 @@
/// This crate contains functions and types to support work with WebAssembly interface-types
/// in Fluence.
mod fce_ast_types;
mod ast_types;
mod export_ast_types;
mod fce_macro_impl;
mod parsed_type;
mod parse_macro_input;
@ -38,7 +39,7 @@ mod token_stream_generator;
mod utils;
mod wasm_type;
pub use fce_ast_types::*;
pub use export_ast_types::*;
pub use fce_macro_impl::fce;
pub use parsed_type::ParsedType;
pub use token_stream_generator::GENERATED_WRAPPER_FUNC_PREFIX;

View File

@ -19,7 +19,7 @@ mod item_foreign_mod;
mod item_record;
mod utils;
use crate::fce_ast_types::FCEAst;
use crate::ast_types::FCEAst;
pub(crate) trait ParseMacroInput {
fn parse_macro_input(self) -> syn::Result<FCEAst>;

View File

@ -15,11 +15,11 @@
*/
use super::ParseMacroInput;
use crate::fce_ast_types;
use crate::ast_types;
use crate::ParsedType;
use crate::fce_ast_types::FCEAst;
use crate::fce_ast_types::AstFnItem;
use crate::fce_ast_types::AstFnArgument;
use crate::ast_types::FCEAst;
use crate::ast_types::AstFn;
use crate::ast_types::AstFnArgument;
use crate::syn_error;
use syn::Result;
@ -38,9 +38,9 @@ impl ParseMacroInput for syn::ItemFn {
check_args(parsed_args)?;
check_output_type(&signature.output_type, self.sig.output.span())?;
let ast_fn = FCEAst::Function(AstFnItem {
let ast_fn = FCEAst::Function(AstFn {
signature,
original: Some(self),
original: self,
});
Ok(ast_fn)
}
@ -49,7 +49,7 @@ impl ParseMacroInput for syn::ItemFn {
pub(super) fn try_to_ast_signature(
signature: syn::Signature,
visibility: syn::Visibility,
) -> Result<fce_ast_types::AstFnSignature> {
) -> Result<ast_types::AstFnSignature> {
use quote::ToTokens;
check_function(&signature)?;
@ -86,8 +86,8 @@ pub(super) fn try_to_ast_signature(
let output_type = ParsedType::from_return_type(&output)?;
let ast_function_item = fce_ast_types::AstFnSignature {
visibility: Some(visibility),
let ast_function_item = ast_types::AstFnSignature {
visibility,
name: signature.ident.to_string(),
arguments,
output_type,

View File

@ -15,8 +15,8 @@
*/
use super::ParseMacroInput;
use crate::fce_ast_types;
use crate::fce_ast_types::FCEAst;
use crate::ast_types;
use crate::ast_types::FCEAst;
use crate::syn_error;
use syn::Result;
@ -36,10 +36,10 @@ impl ParseMacroInput for syn::ItemForeignMod {
let imports = extract_import_functions(&self)?;
check_imports(imports.iter().zip(self.items.iter().map(|i| i.span())))?;
let extern_mod_item = fce_ast_types::AstExternModItem {
let extern_mod_item = ast_types::AstExternMod {
namespace,
imports,
original: Some(self),
original: self,
};
Ok(FCEAst::ExternMod(extern_mod_item))
}
@ -99,7 +99,7 @@ fn try_extract_namespace(
fn extract_import_functions(
foreign_mod: &syn::ItemForeignMod,
) -> Result<Vec<fce_ast_types::AstExternFnItem>> {
) -> Result<Vec<ast_types::AstExternFn>> {
foreign_mod
.items
.iter()
@ -111,7 +111,7 @@ fn extract_import_functions(
/// This function checks whether these imports contains inner references. In this case glue
/// code couldn't be generated.
fn check_imports<'i>(
extern_fns: impl ExactSizeIterator<Item = (&'i fce_ast_types::AstExternFnItem, proc_macro2::Span)>,
extern_fns: impl ExactSizeIterator<Item = (&'i ast_types::AstExternFn, proc_macro2::Span)>,
) -> Result<()> {
use super::utils::contain_inner_ref;
@ -129,7 +129,7 @@ fn check_imports<'i>(
Ok(())
}
fn parse_raw_foreign_item(raw_item: syn::ForeignItem) -> Result<fce_ast_types::AstExternFnItem> {
fn parse_raw_foreign_item(raw_item: syn::ForeignItem) -> Result<ast_types::AstExternFn> {
let function_item = match raw_item {
syn::ForeignItem::Fn(function_item) => function_item,
_ => {
@ -158,7 +158,7 @@ fn parse_raw_foreign_item(raw_item: syn::ForeignItem) -> Result<fce_ast_types::A
};
let signature = super::item_fn::try_to_ast_signature(function_item.sig, function_item.vis)?;
let ast_extern_fn_item = fce_ast_types::AstExternFnItem {
let ast_extern_fn_item = ast_types::AstExternFn {
link_name,
signature,
};

View File

@ -15,9 +15,10 @@
*/
use super::ParseMacroInput;
use crate::fce_ast_types;
use crate::AstRecordField;
use crate::fce_ast_types::FCEAst;
use crate::ast_types;
use crate::ast_types::AstRecordField;
use crate::ast_types::AstRecordFields;
use crate::ast_types::FCEAst;
use crate::syn_error;
use crate::parsed_type::ParsedType;
@ -34,12 +35,13 @@ impl ParseMacroInput for syn::ItemStruct {
};
let fields = fields_into_ast(fields)?;
let fields = AstRecordFields::Named(fields);
let name = self.ident.to_string();
let ast_record_item = fce_ast_types::AstRecordItem {
let ast_record_item = ast_types::AstRecord {
name,
fields,
original: Some(self),
original: self,
};
Ok(FCEAst::Record(ast_record_item))

View File

@ -22,7 +22,7 @@ mod foreign_mod_epilog;
mod foreign_mod_prolog;
mod traits;
mod utils;
mod vector_utils;
mod vector_ser_der;
pub(crate) use fn_arg::*;
pub(crate) use fn_epilog::*;
@ -30,7 +30,7 @@ pub(crate) use fn_prolog::*;
pub(crate) use foreign_mod_prolog::*;
pub(crate) use foreign_mod_epilog::*;
pub(crate) use utils::*;
pub(crate) use vector_utils::*;
pub(crate) use vector_ser_der::*;
use serde::Serialize;
use serde::Deserialize;

View File

@ -15,7 +15,7 @@
*/
use super::ParsedType;
use crate::fce_ast_types::AstFnArgument;
use crate::ast_types::AstFnArgument;
use crate::wasm_type::RustType;
/// This trait could be used to generate raw args needed to construct a export function.

View File

@ -18,7 +18,7 @@ use super::ParsedType;
use super::passing_style_of;
use super::PassingStyle;
use crate::new_ident;
use crate::fce_ast_types::AstFnArgument;
use crate::ast_types::AstFnArgument;
use quote::quote;
@ -116,14 +116,11 @@ fn generate_epilog(ty: &Option<ParsedType>) -> proc_macro2::TokenStream {
fluence::internal::set_result_size(result.len() as _);
}
}
Some(ParsedType::Vector(ty, passing_style)) => {
Some(ParsedType::Vector(ty, _)) => {
let generated_serializer_name = "__fce_generated_vec_serializer";
let generated_serializer_ident = new_ident!(generated_serializer_name);
let vector_serializer = super::vector_utils::generate_vector_serializer(
ty,
*passing_style,
generated_serializer_name,
);
let vector_serializer =
super::vector_ser_der::generate_vector_ser(ty, generated_serializer_name);
quote! {
#vector_serializer

View File

@ -19,7 +19,7 @@ use super::FnArgGlueCodeGenerator;
use super::passing_style_of;
use crate::new_ident;
use crate::wasm_type::RustType;
use crate::fce_ast_types::AstFnArgument;
use crate::ast_types::AstFnArgument;
use crate::parsed_type::PassingStyle;
use quote::quote;
@ -135,7 +135,7 @@ fn generate_type_lifting_prolog(
let generated_der_ident = new_ident!(generated_der_name);
let vector_deserializer =
super::vector_utils::generate_vector_deserializer(ty, &generated_der_name);
super::vector_ser_der::generate_vector_der(ty, &generated_der_name);
quote! {
#vector_deserializer

View File

@ -57,16 +57,14 @@ impl ForeignModEpilogGlueCodeGenerator for Option<ParsedType> {
)
},
Some(ParsedType::Vector(ty, _)) => {
let generated_deserializer_name = "__fce_generated_vec_deserializer";
let generated_deserializer_ident = new_ident!(generated_deserializer_name);
let vector_deserializer = super::vector_utils::generate_vector_deserializer(
ty,
generated_deserializer_name,
);
let generated_der_name = "__fce_generated_vec_deserializer";
let generated_der_ident = new_ident!(generated_der_name);
let vector_deserializer =
super::vector_ser_der::generate_vector_der(ty, generated_der_name);
quote! {
#vector_deserializer
#generated_deserializer_ident(
#generated_der_ident(
fluence::internal::get_result_ptr() as _,
fluence::internal::get_result_size() as _,
)

View File

@ -18,7 +18,7 @@ use super::ParsedType;
use crate::wasm_type::RustType;
use crate::new_ident;
use crate::parsed_type::PassingStyle;
use crate::fce_ast_types::AstFnArgument;
use crate::ast_types::AstFnArgument;
pub(crate) struct WrapperDescriptor {
pub(crate) arg_names: Vec<syn::Ident>,
@ -80,8 +80,8 @@ impl ForeignModPrologGlueCodeGenerator for Vec<AstFnArgument> {
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, passing_style) => {
let vec_arg_transforms = vector_arg_transforms(ty, *passing_style, &arg_name);
ParsedType::Vector(ty, _) => {
let vec_arg_transforms = vector_arg_transforms(ty, &arg_name);
arg_transforms.extend(vec_arg_transforms);
}
_ => {}
@ -127,18 +127,13 @@ impl ForeignModPrologGlueCodeGenerator for Vec<AstFnArgument> {
}
}
fn vector_arg_transforms(
ty: &ParsedType,
passing_style: PassingStyle,
arg_name: &str,
) -> proc_macro2::TokenStream {
fn vector_arg_transforms(ty: &ParsedType, arg_name: &str) -> proc_macro2::TokenStream {
let generated_ser_name = format!("__fce_generated_vec_serializer_{}", arg_name);
let generated_ser_name = crate::utils::prepare_ident(generated_ser_name);
let generated_ser_ident = new_ident!(generated_ser_name);
let arg_ident = new_ident!(arg_name);
let vector_serializer =
super::vector_utils::generate_vector_serializer(ty, passing_style, &generated_ser_name);
let vector_serializer = super::vector_ser_der::generate_vector_ser(ty, &generated_ser_name);
let arg_transform = quote::quote! {
#vector_serializer

View File

@ -0,0 +1,98 @@
/*
* Copyright 2020 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.
*/
mod der;
mod ser;
use ser::*;
use der::*;
use super::ParsedType;
use quote::quote;
pub(crate) fn generate_vector_ser(
value_ty: &ParsedType,
arg_name: &str,
) -> proc_macro2::TokenStream {
let values_ser = match value_ty {
ParsedType::Boolean(_) => {
quote! {
let converted_bool_vector: Vec<u8> = arg.into_iter().map(|v| *v as u8).collect::<_>();
let ptr = converted_bool_vector.as_ptr();
let len = converted_bool_vector.len();
fluence::internal::add_object_to_release(Box::new(converted_bool_vector));
(ptr as _, len as _)
}
}
ParsedType::I8(_)
| ParsedType::U8(_)
| ParsedType::I16(_)
| ParsedType::U16(_)
| ParsedType::I32(_)
| ParsedType::U32(_)
| ParsedType::I64(_)
| ParsedType::U64(_)
| ParsedType::F32(_)
| ParsedType::F64(_) => {
quote! {
(arg.as_ptr() as _, arg.len() as _)
}
}
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => string_ser(),
ParsedType::Vector(ty, _) => vector_ser(arg_name, ty),
ParsedType::Record(..) => record_ser(),
};
let arg = crate::new_ident!(arg_name);
quote! {
unsafe fn #arg(arg: &Vec<#value_ty>) -> (u32, u32) {
#values_ser
}
}
}
pub(crate) fn generate_vector_der(
value_ty: &ParsedType,
arg_name: &str,
) -> proc_macro2::TokenStream {
let arg = crate::new_ident!(arg_name);
let values_deserializer = match value_ty {
ParsedType::Boolean(_) => {
quote! {
let arg: Vec<u8> = Vec::from_raw_parts(offset as _, size as _, size as _);
arg.into_iter().map(|v| v != 0).collect::<Vec<bool>>()
}
}
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => string_der(),
ParsedType::Vector(ty, _) => vector_der(arg_name, ty),
ParsedType::Record(record_name, _) => record_der(record_name),
_ => {
quote! {
Vec::from_raw_parts(offset as _, size as _, size as _)
}
}
};
quote! {
unsafe fn #arg(offset: u32, size: u32) -> Vec<#value_ty> {
#values_deserializer
}
}
}

View File

@ -0,0 +1,78 @@
/*
* Copyright 2020 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::ParsedType;
use quote::quote;
pub(super) fn string_der() -> proc_macro2::TokenStream {
quote! {
let vec_passing_size = 2;
let mut arg: Vec<u32> = Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * size) as _);
let mut arg = arg.into_iter();
let mut result = Vec::with_capacity(arg.len() / 2);
while let Some(offset) = arg.next() {
let size = arg.next().unwrap();
let value = String::from_raw_parts(offset as _, size as _, size as _);
result.push(value);
}
result
}
}
pub(super) fn vector_der(arg_name: &str, ty: &ParsedType) -> proc_macro2::TokenStream {
let deserializer_name = format!("{}_{}", arg_name, ty);
let deserializer_name = crate::utils::prepare_ident(deserializer_name);
let deserializer_ident = crate::new_ident!(deserializer_name);
let inner_vector_deserializer = super::generate_vector_der(&*ty, &deserializer_name);
quote! {
#inner_vector_deserializer
let vec_passing_size = 2;
let mut arg: Vec<u32> = Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * 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 = #deserializer_ident(offset as _, size as _);
result.push(value);
}
result
}
}
pub(super) fn record_der(record_name: &str) -> proc_macro2::TokenStream {
let record_name_ident = crate::new_ident!(record_name);
quote! {
let mut arg: Vec<u32> = Vec::from_raw_parts(offset as _, size as _, size as _);
let mut result = Vec::with_capacity(arg.len());
for offset in arg {
let value = #record_name_ident::__fce_generated_deserialize(offset as _);
result.push(value);
}
result
}
}

View File

@ -0,0 +1,77 @@
/*
* Copyright 2020 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 super::ParsedType;
use quote::quote;
pub(super) fn string_ser() -> proc_macro2::TokenStream {
quote! {
let mut result: Vec<u32> = Vec::with_capacity(arg.len());
for value in arg {
result.push(value.as_ptr() as _);
result.push(value.len() as _);
}
let result_ptr = result.as_ptr();
let result_len = result.len() / 2;
fluence::internal::add_object_to_release(Box::new(result));
(result_ptr as _, result_len as _)
}
}
pub(super) fn vector_ser(arg_name: &str, ty: &ParsedType) -> proc_macro2::TokenStream {
let ser_name = format!("{}_{}", arg_name, ty);
let ser_name = crate::utils::prepare_ident(ser_name);
let ser_ident = crate::new_ident!(ser_name);
let inner_vector_ser = super::generate_vector_ser(ty, &ser_name);
quote! {
#inner_vector_ser
let mut result: Vec<u32> = Vec::with_capacity(2 * arg.len());
for value in arg {
let (ptr, size) = #ser_ident(&value);
result.push(ptr as _);
result.push(size as _);
}
let result_ptr = result.as_ptr();
let result_len = result.len() / 2;
fluence::internal::add_object_to_release(Box::new(result));
(result_ptr as _, result_len as _)
}
}
pub(super) fn record_ser() -> proc_macro2::TokenStream {
quote! {
let mut result: Vec<u32> = Vec::with_capacity(arg.len());
for value in arg {
result.push(value.__fce_generated_serialize() as _);
}
let result_ptr = result.as_ptr();
let result_len = result.len();
fluence::internal::add_object_to_release(Box::new(result));
(result_ptr as _, result_len as _)
}
}

View File

@ -1,258 +0,0 @@
/*
* Copyright 2020 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 super::ParsedType;
use super::PassingStyle;
use quote::quote;
pub(crate) fn generate_vector_serializer(
value_ty: &ParsedType,
_vec_passing_style: PassingStyle,
arg_name: &str,
) -> proc_macro2::TokenStream {
let values_serializer = match value_ty {
ParsedType::Boolean(_) => {
quote! {
unimplemented!()
}
}
ParsedType::I8(_) | ParsedType::U8(_) => {
quote! {
(arg.as_ptr() as _, arg.len() as _)
}
}
ParsedType::I16(_) | ParsedType::U16(_) => {
quote! {
(arg.as_ptr() as _, (2 * arg.len()) as _)
}
}
ParsedType::I32(_) | ParsedType::U32(_) => {
quote! {
(arg.as_ptr() as _, (4 * arg.len()) as _)
}
}
ParsedType::I64(_) | ParsedType::U64(_) => {
quote! {
(arg.as_ptr() as _, (8 * arg.len()) as _)
}
}
ParsedType::F32(_) => {
quote! {
let mut result: Vec<u32> = Vec::with_capacity(arg.len());
for value in arg {
result.push(value.to_bits());
}
let result_ptr = result.as_ptr();
let result_len = 4 * result.len();
fluence::internal::add_object_to_release(Box::new(result));
(result_ptr as _, result_len as _)
}
}
ParsedType::F64(_) => {
quote! {
let mut result: Vec<u64> = Vec::with_capacity(arg.len());
for value in arg {
result.push(value.to_bits());
}
let result_ptr = result.as_ptr();
let result_len = 8 * result.len();
fluence::internal::add_object_to_release(Box::new(result));
(result_ptr as _, result_len as _)
}
}
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => {
quote! {
let mut result: Vec<u32> = Vec::with_capacity(arg.len());
for value in arg {
result.push(value.as_ptr() as _);
result.push(value.len() as _);
}
let result_ptr = result.as_ptr();
let result_len = 4 * result.len();
fluence::internal::add_object_to_release(Box::new(result));
(result_ptr as _, result_len as _)
}
}
ParsedType::Vector(ty, passing_style) => {
let serializer_name = format!("{}_{}", arg_name, ty);
let serializer_name = crate::utils::prepare_ident(serializer_name);
let serializer_ident = crate::new_ident!(serializer_name);
let inner_vector_serializer =
generate_vector_serializer(&*ty, *passing_style, &serializer_name);
quote! {
#inner_vector_serializer
let mut result: Vec<u32> = Vec::with_capacity(2 * arg.len());
for value in arg {
let (ptr, size) = #serializer_ident(&value);
result.push(ptr as _);
result.push(size as _);
}
let result_ptr = result.as_ptr();
let result_len = 4 * result.len();
fluence::internal::add_object_to_release(Box::new(result));
(result_ptr as _, result_len as _)
}
}
ParsedType::Record(..) => {
quote! {
let mut result: Vec<u32> = Vec::with_capacity(arg.len());
for value in arg {
result.push(value.__fce_generated_serialize() as _);
}
let result_ptr = result.as_ptr();
let result_len = 4 * result.len();
fluence::internal::add_object_to_release(Box::new(result));
(result_ptr as _, result_len as _)
}
}
};
let arg = crate::new_ident!(arg_name);
quote! {
unsafe fn #arg(arg: &Vec<#value_ty>) -> (u32, u32) {
#values_serializer
}
}
}
pub(crate) fn generate_vector_deserializer(
value_ty: &ParsedType,
arg_name: &str,
) -> proc_macro2::TokenStream {
let arg = crate::new_ident!(arg_name);
let values_deserializer = match value_ty {
ParsedType::Boolean(_) => {
quote! {
unimplemented!("Vector of booleans is not supported")
}
}
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());
for value in arg {
result.push(f32::from_bits(value as _));
}
result
}
}
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());
for value in arg {
result.push(f64::from_bits(value as _));
}
result
}
}
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();
let mut result = Vec::with_capacity(arg.len() / 2);
while let Some(offset) = arg.next() {
let size = arg.next().unwrap();
let value = String::from_raw_parts(offset as _, size as _, size as _);
result.push(value);
}
result
}
}
ParsedType::Vector(ty, _) => {
let deserializer_name = format!("{}_{}", arg_name, ty);
let deserializer_name = crate::utils::prepare_ident(deserializer_name);
let deserializer_ident = crate::new_ident!(deserializer_name);
let inner_vector_deserializer = generate_vector_deserializer(&*ty, &deserializer_name);
quote! {
#inner_vector_deserializer
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 = #deserializer_ident(offset as _, size as _);
result.push(value);
}
result
}
}
ParsedType::Record(record_name, _) => {
let record_name_ident = crate::new_ident!(record_name);
quote! {
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 = #record_name_ident::__fce_generated_deserialize(offset as _);
result.push(value);
}
result
}
}
_ => {
quote! {
let mut arg: Vec<u64> = Vec::from_raw_parts(offset as _, size as _, size as _);
let mut result = Vec::with_capacity(arg.len());
for value in arg {
result.push(value as _);
}
result
}
}
};
quote! {
unsafe fn #arg(offset: u32, size: u32) -> Vec<#value_ty> {
let size = size / 8;
#values_deserializer
}
}
}

View File

@ -18,7 +18,7 @@ mod fn_generator;
mod foreign_mod_generator;
mod record_generator;
use crate::fce_ast_types::FCEAst;
use crate::ast_types::FCEAst;
pub const GENERATED_WRAPPER_FUNC_PREFIX: &str = "__fce_generated_wrapper_func_";
pub const GENERATED_SECTION_PREFIX: &str = "__fce_generated_section__";

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
use crate::fce_ast_types;
use crate::ast_types;
use crate::parsed_type::FnEpilogGlueCodeGenerator;
use crate::parsed_type::FnEpilogDescriptor;
use crate::parsed_type::FnEpilogIngredients;
@ -25,7 +25,7 @@ use crate::new_ident;
use proc_macro2::TokenStream;
impl quote::ToTokens for fce_ast_types::AstFnItem {
impl quote::ToTokens for ast_types::AstFn {
fn to_tokens(&self, tokens: &mut TokenStream) {
crate::prepare_global_data!(
Function,

View File

@ -14,14 +14,14 @@
* limitations under the License.
*/
use crate::fce_ast_types;
use crate::ast_types;
use crate::new_ident;
use crate::parsed_type::*;
use proc_macro2::TokenStream;
use quote::quote;
impl quote::ToTokens for fce_ast_types::AstExternModItem {
impl quote::ToTokens for ast_types::AstExternMod {
fn to_tokens(&self, tokens: &mut TokenStream) {
crate::prepare_global_data!(
ExternMod,
@ -61,9 +61,7 @@ impl quote::ToTokens for fce_ast_types::AstExternModItem {
}
}
fn generate_extern_section_items(
extern_item: &fce_ast_types::AstExternModItem,
) -> Vec<TokenStream> {
fn generate_extern_section_items(extern_item: &ast_types::AstExternMod) -> Vec<TokenStream> {
let mut section_items = Vec::with_capacity(extern_item.imports.len());
for import in &extern_item.imports {
@ -92,7 +90,7 @@ fn generate_import_name(import_name: &str) -> syn::Ident {
crate::new_ident!(format!("{}_{}", super::GENERATED_WRAPPER_FUNC_PREFIX, import_name))
}
fn generate_wrapper_functions(extern_item: &fce_ast_types::AstExternModItem) -> TokenStream {
fn generate_wrapper_functions(extern_item: &ast_types::AstExternMod) -> TokenStream {
let mut token_stream = TokenStream::new();
for import in &extern_item.imports {

View File

@ -16,14 +16,17 @@
mod record_serializer;
mod record_deserializer;
mod field_values_builder;
use record_serializer::*;
use field_values_builder::*;
use record_deserializer::*;
use record_serializer::*;
use crate::new_ident;
use crate::fce_ast_types;
use crate::ast_types::AstRecord;
use crate::ast_types::AstRecordFields;
impl quote::ToTokens for fce_ast_types::AstRecordItem {
impl quote::ToTokens for AstRecord {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let original = &self.original;
crate::prepare_global_data!(
@ -65,13 +68,18 @@ impl quote::ToTokens for fce_ast_types::AstRecordItem {
}
}
fn generate_serializer_fn(record: &fce_ast_types::AstRecordItem) -> proc_macro2::TokenStream {
fn generate_serializer_fn(record: &AstRecord) -> proc_macro2::TokenStream {
let serializer = record.generate_serializer();
let fields_count = record.fields.len();
let fields_count = match &record.fields {
AstRecordFields::Named(fields) => fields.len(),
AstRecordFields::Unnamed(fields) => fields.len(),
AstRecordFields::Unit => return proc_macro2::TokenStream::new(),
};
quote::quote! {
pub fn __fce_generated_serialize(&self) -> *const u8 {
let mut raw_record: Vec<u64> = Vec::with_capacity(2 * #fields_count);
// 4 is an average size of a possible record field
let mut raw_record: Vec<u8> = Vec::with_capacity(4 * #fields_count);
#serializer
@ -83,22 +91,27 @@ fn generate_serializer_fn(record: &fce_ast_types::AstRecordItem) -> proc_macro2:
}
}
fn generate_deserializer_fn(record: &fce_ast_types::AstRecordItem) -> proc_macro2::TokenStream {
let RecordDeserializerDescriptor {
deserializer,
type_constructor,
} = record.generate_deserializer();
fn generate_deserializer_fn(record: &AstRecord) -> proc_macro2::TokenStream {
let RecordDerDescriptor {
fields_der,
record_ctor,
} = record.generate_der();
let record_size =
crate::utils::get_record_size(record.fields.iter().map(|ast_field| &ast_field.ty));
let fields = match &record.fields {
AstRecordFields::Named(fields) => fields,
AstRecordFields::Unnamed(fields) => fields,
AstRecordFields::Unit => return proc_macro2::TokenStream::new(),
};
let record_size = crate::utils::get_record_size(fields.iter().map(|ast_field| &ast_field.ty));
quote::quote! {
pub unsafe fn __fce_generated_deserialize(record_ptr: *const u8) -> Self {
let raw_record: Vec<u64> = Vec::from_raw_parts(record_ptr as _, #record_size, #record_size);
let raw_record: Vec<u8> = Vec::from_raw_parts(record_ptr as _, #record_size, #record_size);
#deserializer
#fields_der
#type_constructor
#record_ctor
}
}
}

View File

@ -0,0 +1,318 @@
/*
* Copyright 2021 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::new_ident;
use crate::parsed_type::ParsedType;
use crate::ast_types::*;
use proc_macro2::TokenStream;
use quote::quote;
pub(super) struct FieldValuesBuilder {
value_id: usize,
fields_der: TokenStream,
field_value_idents: Vec<syn::Ident>,
}
/// Contains all necessary info to construct record fields.
pub(super) struct FieldValuesOutcome {
/// Generated deserializer for each record field.
pub(super) fields_der: TokenStream,
/// Idents of each record field.
pub(super) field_value_idents: Vec<syn::Ident>,
}
impl FieldValuesBuilder {
pub(super) fn build<'a>(
fields: impl ExactSizeIterator<Item = &'a AstRecordField>,
) -> FieldValuesOutcome {
let values_builder = Self::new(fields.len());
values_builder.build_impl(fields)
}
fn new(fields_count: usize) -> Self {
Self {
value_id: 0,
fields_der: TokenStream::new(),
field_value_idents: Vec::with_capacity(fields_count),
}
}
fn build_impl<'r>(
mut self,
fields: impl ExactSizeIterator<Item = &'r AstRecordField>,
) -> FieldValuesOutcome {
for (id, ast_field) in fields.enumerate() {
let field_value_ident = new_ident!(format!("field_{}", id));
let field_der = self.field_der(ast_field, &field_value_ident);
self.field_value_idents.push(field_value_ident);
self.fields_der.extend(field_der);
}
let outcome = FieldValuesOutcome {
fields_der: self.fields_der,
field_value_idents: self.field_value_idents,
};
outcome
}
fn field_der(&mut self, ast_field: &AstRecordField, field: &syn::Ident) -> TokenStream {
let der = match &ast_field.ty {
ParsedType::Boolean(_) => self.bool_der(field),
ParsedType::I8(_) => self.i8_der(field),
ParsedType::I16(_) => self.i16_der(field),
ParsedType::I32(_) => self.i32_der(field),
ParsedType::I64(_) => self.i64_der(field),
ParsedType::U8(_) => self.u8_der(field),
ParsedType::U16(_) => self.u16_der(field),
ParsedType::U32(_) => self.u32_der(field),
ParsedType::U64(_) => self.u64_der(field),
ParsedType::F32(_) => self.f32_der(field),
ParsedType::F64(_) => self.f64_der(field),
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => self.string_der(field),
ParsedType::Vector(ty, _) => self.vector_der(ty, field),
ParsedType::Record(name, _) => self.record_der(name, field),
};
der
}
fn bool_der(&mut self, field: &syn::Ident) -> TokenStream {
let value_id = self.value_id;
let result = quote! { let #field = raw_record[#value_id] != 0; };
self.value_id += std::mem::size_of::<u8>();
result
}
fn i8_der(&mut self, field: &syn::Ident) -> TokenStream {
let value_id = self.value_id;
let result = quote! { let #field = raw_record[#value_id] as i8; };
self.value_id += std::mem::size_of::<i8>();
result
}
fn i16_der(&mut self, field: &syn::Ident) -> TokenStream {
let value_id = self.value_id;
let result = quote! { let #field = i16::from_le_bytes([
raw_record[#value_id],
raw_record[#value_id + 1],
]);
};
self.value_id += std::mem::size_of::<i16>();
result
}
fn i32_der(&mut self, field: &syn::Ident) -> TokenStream {
let value_id = self.value_id;
let result = quote! { let #field = i32::from_le_bytes([
raw_record[#value_id],
raw_record[#value_id + 1],
raw_record[#value_id + 2],
raw_record[#value_id + 3],
]);
};
self.value_id += std::mem::size_of::<i32>();
result
}
fn i64_der(&mut self, field: &syn::Ident) -> TokenStream {
let value_id = self.value_id;
let result = quote! { let #field = i64::from_le_bytes([
raw_record[#value_id],
raw_record[#value_id + 1],
raw_record[#value_id + 2],
raw_record[#value_id + 3],
raw_record[#value_id + 4],
raw_record[#value_id + 5],
raw_record[#value_id + 6],
raw_record[#value_id + 7],
]);
};
self.value_id += std::mem::size_of::<i64>();
result
}
fn u8_der(&mut self, field: &syn::Ident) -> TokenStream {
let value_id = self.value_id;
let result = quote! { let #field = raw_record[#value_id] as u8; };
self.value_id += std::mem::size_of::<u8>();
result
}
fn u16_der(&mut self, field: &syn::Ident) -> TokenStream {
let value_id = self.value_id;
let result = quote! { let #field = u16::from_le_bytes([
raw_record[#value_id],
raw_record[#value_id + 1],
]);
};
self.value_id += std::mem::size_of::<u16>();
result
}
fn u32_der(&mut self, field: &syn::Ident) -> TokenStream {
let value_id = self.value_id;
let result = quote! { let #field = u32::from_le_bytes([
raw_record[#value_id],
raw_record[#value_id + 1],
raw_record[#value_id + 2],
raw_record[#value_id + 3],
]);
};
self.value_id += std::mem::size_of::<u32>();
result
}
fn u64_der(&mut self, field: &syn::Ident) -> TokenStream {
let value_id = self.value_id;
let result = quote! { let #field = u64::from_le_bytes([
raw_record[#value_id],
raw_record[#value_id + 1],
raw_record[#value_id + 2],
raw_record[#value_id + 3],
raw_record[#value_id + 4],
raw_record[#value_id + 5],
raw_record[#value_id + 6],
raw_record[#value_id + 7],
]);
};
self.value_id += std::mem::size_of::<u64>();
result
}
fn f32_der(&mut self, field: &syn::Ident) -> TokenStream {
let value_id = self.value_id;
let result = quote! { let #field = f32::from_le_bytes([
raw_record[#value_id],
raw_record[#value_id + 1],
raw_record[#value_id + 2],
raw_record[#value_id + 3],
]);
};
self.value_id += std::mem::size_of::<f32>();
result
}
fn f64_der(&mut self, field: &syn::Ident) -> TokenStream {
let value_id = self.value_id;
let result = quote! { let #field = f64::from_le_bytes([
raw_record[#value_id],
raw_record[#value_id + 1],
raw_record[#value_id + 2],
raw_record[#value_id + 3],
raw_record[#value_id + 4],
raw_record[#value_id + 5],
raw_record[#value_id + 6],
raw_record[#value_id + 7],
]);
};
self.value_id += std::mem::size_of::<f64>();
result
}
fn string_der(&mut self, field: &syn::Ident) -> TokenStream {
let value_id = self.value_id;
let result = quote! {
let #field = unsafe {
let offset = u32::from_le_bytes([
raw_record[#value_id],
raw_record[#value_id + 1],
raw_record[#value_id + 2],
raw_record[#value_id + 3],
]);
let size = u32::from_le_bytes([
raw_record[#value_id + 4],
raw_record[#value_id + 5],
raw_record[#value_id + 6],
raw_record[#value_id + 7],
]);
String::from_raw_parts(offset as _, size as _, size as _)
};
};
self.value_id += 2 * std::mem::size_of::<u32>();
result
}
fn vector_der(&mut self, ty: &ParsedType, field: &syn::Ident) -> TokenStream {
let generated_der_name = format!("__fce_generated_vec_deserializer_{}", self.value_id);
let generated_der_name = crate::utils::prepare_ident(generated_der_name);
let generated_der_ident = new_ident!(generated_der_name);
let vector_deserializer = crate::parsed_type::generate_vector_der(ty, &generated_der_name);
let value_id = self.value_id;
let result = quote! {
#vector_deserializer
let offset = u32::from_le_bytes([
raw_record[#value_id],
raw_record[#value_id + 1],
raw_record[#value_id + 2],
raw_record[#value_id + 3],
]);
let size = u32::from_le_bytes([
raw_record[#value_id + 4],
raw_record[#value_id + 5],
raw_record[#value_id + 6],
raw_record[#value_id + 7],
]);
let #field = unsafe { #generated_der_ident(offset as _, size as _) };
};
self.value_id += 2 * std::mem::size_of::<u32>();
result
}
fn record_der(&mut self, name: &str, field: &syn::Ident) -> TokenStream {
let value_id = self.value_id;
let record_ident = new_ident!(name);
let result = quote! {
let offset = u32::from_le_bytes([
raw_record[#value_id],
raw_record[#value_id + 1],
raw_record[#value_id + 2],
raw_record[#value_id + 3],
]);
let #field = #record_ident::__fce_generated_deserialize(offset as _);
};
self.value_id += std::mem::size_of::<u32>();
result
}
}

View File

@ -15,136 +15,63 @@
*/
use crate::new_ident;
use crate::parsed_type::ParsedType;
use crate::fce_ast_types;
use crate::ast_types::*;
use super::FieldValuesBuilder;
use proc_macro2::TokenStream;
use quote::quote;
pub(super) struct RecordDeserializerDescriptor {
pub(super) deserializer: proc_macro2::TokenStream,
pub(super) type_constructor: proc_macro2::TokenStream,
#[derive(Default)]
pub(super) struct RecordDerDescriptor {
pub(super) fields_der: TokenStream,
pub(super) record_ctor: TokenStream,
}
/// This trait could be used to generate various parts of a record serializer func.
pub(super) trait RecordDeserializerGlueCodeGenerator {
fn generate_deserializer(&self) -> RecordDeserializerDescriptor;
pub(super) trait RecordDerGlueCodeGenerator {
fn generate_der(&self) -> RecordDerDescriptor;
}
impl RecordDeserializerGlueCodeGenerator for fce_ast_types::AstRecordItem {
fn generate_deserializer(&self) -> RecordDeserializerDescriptor {
let mut field_values = Vec::with_capacity(self.fields.len());
let mut deserializer = proc_macro2::TokenStream::new();
let mut value_id: usize = 0;
impl RecordDerGlueCodeGenerator for AstRecord {
fn generate_der(&self) -> RecordDerDescriptor {
match &self.fields {
AstRecordFields::Named(fields) => record_der_from_named(fields),
AstRecordFields::Unnamed(fields) => record_der_from_unnamed(fields),
AstRecordFields::Unit => RecordDerDescriptor::default(),
}
}
}
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(_) => {
quote! {
let #field = raw_record[#value_id] != 0;
}
}
ParsedType::I8(_) => {
quote! {
let #field = raw_record[#value_id] as i8;
}
}
ParsedType::I16(_) => {
quote! {
let #field = raw_record[#value_id] as i16;
}
}
ParsedType::I32(_) => {
quote! {
let #field = raw_record[#value_id] as i32;
}
}
ParsedType::I64(_) => {
quote! {
let #field = raw_record[#value_id] as i64;
}
}
ParsedType::U8(_) => {
quote! {
let #field = raw_record[#value_id] as u8;
}
}
ParsedType::U16(_) => {
quote! {
let #field = raw_record[#value_id] as u16;
}
}
ParsedType::U32(_) => {
quote! {
let #field = raw_record[#value_id] as u32;
}
}
ParsedType::U64(_) => {
quote! {
let #field = raw_record[#value_id] as u64;
}
}
ParsedType::F32(_) => {
quote! {
let #field = raw_record[#value_id] as f32;
}
}
ParsedType::F64(_) => {
quote! {
let #field = f64::from_bits(raw_record[#value_id]);
}
}
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => {
let ptr_id = value_id;
let size_id = value_id + 1;
value_id += 1;
fn record_der_from_named(fields: &[AstRecordField]) -> RecordDerDescriptor {
let builder = FieldValuesBuilder::build(fields.iter());
let record_ctor = field_ctors_from_named(fields.iter(), builder.field_value_idents.iter());
quote! {
let #field = unsafe { String::from_raw_parts(raw_record[#ptr_id] as _, raw_record[#size_id] as _, raw_record[#size_id] as _) };
RecordDerDescriptor {
fields_der: builder.fields_der,
record_ctor,
}
}
ParsedType::Vector(ty, _) => {
let generated_deserializer_name =
format!("__fce_generated_vec_deserializer_{}", value_id);
let generated_deserializer_name =
crate::utils::prepare_ident(generated_deserializer_name);
let generated_deserializer_ident = new_ident!(generated_deserializer_name);
}
let vector_deserializer = crate::parsed_type::generate_vector_deserializer(
ty,
&generated_deserializer_name,
);
fn record_der_from_unnamed(fields: &[AstRecordField]) -> RecordDerDescriptor {
let builder = FieldValuesBuilder::build(fields.iter());
let record_ctor = field_ctor_from_unnamed(builder.field_value_idents.iter());
let ptr_id = value_id;
let size_id = value_id + 1;
value_id += 1;
RecordDerDescriptor {
fields_der: builder.fields_der,
record_ctor,
}
}
quote! {
#vector_deserializer
let #field = unsafe { #generated_deserializer_ident(raw_record[#ptr_id] as _, raw_record[#size_id] as _) };
}
}
ParsedType::Record(record_name, _) => {
let ptr_id = value_id;
let record_ident = new_ident!(record_name);
quote! {
let #field = #record_ident::__fce_generated_deserialize(raw_record[#ptr_id] as _);
}
}
};
field_values.push(field);
deserializer.extend(field_d);
value_id += 1;
}
let type_constructor = match self.fields.first() {
Some(ast_field) if ast_field.name.is_some() => {
let field_names = self
.fields
.iter()
.map(|field| {
new_ident!(field.name.clone().expect("all fields should have name"))
fn field_ctors_from_named<'a, 'v>(
ast_fields: impl ExactSizeIterator<Item = &'a AstRecordField>,
field_values: impl ExactSizeIterator<Item = &'v syn::Ident>,
) -> TokenStream {
let field_names = ast_fields
.map(|ast_field| {
new_ident!(ast_field
.name
.as_ref()
.expect("all fields should have name"))
})
.collect::<Vec<_>>();
@ -153,20 +80,14 @@ impl RecordDeserializerGlueCodeGenerator for fce_ast_types::AstRecordItem {
#(#field_names: #field_values),*
}
}
}
Some(_) => {
quote! {
Self (
#(#field_values),*
)
}
}
_ => quote! {},
};
}
RecordDeserializerDescriptor {
deserializer,
type_constructor,
fn field_ctor_from_unnamed<'v>(
field_values: impl ExactSizeIterator<Item = &'v syn::Ident>,
) -> TokenStream {
quote! {
Self {
#(#field_values),*
}
}
}

View File

@ -16,62 +16,68 @@
use crate::new_ident;
use crate::parsed_type::ParsedType;
use crate::fce_ast_types;
use crate::ast_types::AstRecord;
use crate::ast_types::AstRecordField;
use crate::ast_types::AstRecordFields;
use quote::quote;
/// This trait could be used to generate various parts of a record serializer func.
pub(super) trait RecordSerializerGlueCodeGenerator {
pub(super) trait RecordSerGlueCodeGenerator {
fn generate_serializer(&self) -> proc_macro2::TokenStream;
}
impl RecordSerializerGlueCodeGenerator for fce_ast_types::AstRecordItem {
impl RecordSerGlueCodeGenerator for AstRecord {
fn generate_serializer(&self) -> proc_macro2::TokenStream {
let mut serializer = proc_macro2::TokenStream::new();
for (id, field) in self.fields.iter().enumerate() {
let fields = match &self.fields {
AstRecordFields::Named(fields) => fields,
AstRecordFields::Unnamed(fields) => fields,
AstRecordFields::Unit => return proc_macro2::TokenStream::new(),
};
for (id, field) in fields.iter().enumerate() {
let field_ident = field_ident(field, id);
let field_serialization = match &field.ty {
ParsedType::F64(_) => {
quote! {
raw_record.push(#field_ident.to_bits());
}
ParsedType::Boolean(_) => {
quote! { raw_record.push(*&#field_ident as _); }
}
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => {
quote! {
raw_record.push(#field_ident.as_ptr() as _);
raw_record.push(#field_ident.len() as _);
let field_ident_ptr = #field_ident.as_ptr() as u32;
raw_record.extend(&field_ident_ptr.to_le_bytes());
raw_record.extend(&(#field_ident.len() as u32).to_le_bytes());
}
}
ParsedType::Vector(ty, passing_style) => {
let generated_serializer_name = format!(
ParsedType::Vector(ty, _) => {
let generated_ser_name = format!(
"__fce_generated_vec_serializer_{}_{}",
field.name.as_ref().unwrap(),
id
);
let generated_serializer_ident = new_ident!(generated_serializer_name);
let vector_serializer = crate::parsed_type::generate_vector_serializer(
ty,
*passing_style,
&generated_serializer_name,
);
let generated_ser_ident = new_ident!(generated_ser_name);
let vector_ser =
crate::parsed_type::generate_vector_ser(ty, &generated_ser_name);
let serialized_field_ident = new_ident!(format!("serialized_arg_{}", id));
quote::quote! {
#vector_serializer
let #serialized_field_ident = unsafe { #generated_serializer_ident(&#field_ident) };
raw_record.push(#serialized_field_ident.0 as _);
raw_record.push(#serialized_field_ident.1 as _);
#vector_ser
let #serialized_field_ident = unsafe { #generated_ser_ident(&#field_ident) };
raw_record.extend(&#serialized_field_ident.0.to_le_bytes());
raw_record.extend(&#serialized_field_ident.1.to_le_bytes());
}
}
ParsedType::Record(..) => {
quote! {
raw_record.push(#field_ident.__fce_generated_serialize() as _);
let serialized_struct_ptr = #field_ident.__fce_generated_serialize() as usize;
raw_record.extend(&serialized_struct_ptr.to_le_bytes());
}
}
_ => quote! {
raw_record.push(#field_ident as u64);
raw_record.extend(&#field_ident.to_le_bytes());
},
};
@ -82,7 +88,7 @@ impl RecordSerializerGlueCodeGenerator for fce_ast_types::AstRecordItem {
}
}
fn field_ident(field: &fce_ast_types::AstRecordField, id: usize) -> proc_macro2::TokenStream {
fn field_ident(field: &AstRecordField, id: usize) -> proc_macro2::TokenStream {
match &field.name {
Some(name) => {
let name = new_ident!(name);

View File

@ -26,7 +26,7 @@ macro_rules! new_ident {
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 fce_type = crate::export_ast_types::SDKAst::$fce_type($self.clone().into());
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());
@ -60,13 +60,14 @@ pub fn get_record_size<'a>(
let mut size = 0;
for field in fields {
let params_count = match field {
ParsedType::Vector(..) | ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => 2,
_ => 1,
size += match field {
ParsedType::U8(_) | ParsedType::I8(_) | ParsedType::Boolean(_) => 1,
ParsedType::U16(_) | ParsedType::I16(_) => 2,
ParsedType::U32(_) | ParsedType::I32(_) | ParsedType::F32(_) => 4,
ParsedType::U64(_) | ParsedType::I64(_) | ParsedType::F64(_) => 8,
ParsedType::Record(..) => 4,
ParsedType::Vector(..) | ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => 2 * 4,
};
// internally record is being serialized to a vector of u64.
size += std::mem::size_of::<u64>() * params_count;
}
size

View File

@ -8,30 +8,23 @@ pub fn inner_arrays_1(arg: Vec<Vec<Vec<Vec<u8>>>>) -> Vec<Vec<Vec<Vec<u8>>>> {
#[allow(clippy::all)]
pub unsafe fn __fce_generated_wrapper_func_inner_arrays_1(arg_0: u32, arg_1: u32) {
unsafe fn __fce_generated_vec_deserializer_0(offset: u32, size: u32) -> Vec<Vec<Vec<Vec<u8>>>> {
let size = size / 8;
unsafe fn __fce_generated_vec_deserializer_0_Vec_Vec_u8__(
offset: u32,
size: u32
) -> Vec<Vec<Vec<u8>>> {
let size = size / 8;
unsafe fn __fce_generated_vec_deserializer_0_Vec_Vec_u8___Vec_u8_(
offset: u32,
size: u32
) -> Vec<Vec<u8>> {
let size = size / 8;
unsafe fn __fce_generated_vec_deserializer_0_Vec_Vec_u8___Vec_u8__u8(
offset: u32,
size: u32
) -> Vec<u8> {
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 value in arg {
result.push(value as _);
Vec::from_raw_parts(offset as _, size as _, size as _)
}
result
}
let mut arg: Vec<u64> = Vec::from_raw_parts(offset as _, size as _, size as _);
let vec_passing_size = 2;
let mut arg: Vec<u32> =
Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * size) as _);
let mut result = Vec::with_capacity(arg.len());
let mut arg = arg.into_iter();
while let Some(offset) = arg.next() {
@ -44,7 +37,9 @@ pub unsafe fn __fce_generated_wrapper_func_inner_arrays_1(arg_0: u32, arg_1: u32
}
result
}
let mut arg: Vec<u64> = Vec::from_raw_parts(offset as _, size as _, size as _);
let vec_passing_size = 2;
let mut arg: Vec<u32> =
Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * size) as _);
let mut result = Vec::with_capacity(arg.len());
let mut arg = arg.into_iter();
while let Some(offset) = arg.next() {
@ -55,7 +50,8 @@ pub unsafe fn __fce_generated_wrapper_func_inner_arrays_1(arg_0: u32, arg_1: u32
}
result
}
let mut arg: Vec<u64> = Vec::from_raw_parts(offset as _, size as _, size as _);
let vec_passing_size = 2;
let mut arg: Vec<u32> = Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * size) as _);
let mut result = Vec::with_capacity(arg.len());
let mut arg = arg.into_iter();
while let Some(offset) = arg.next() {
@ -87,7 +83,7 @@ pub unsafe fn __fce_generated_wrapper_func_inner_arrays_1(arg_0: u32, arg_1: u32
result.push(size as _);
}
let result_ptr = result.as_ptr();
let result_len = 4 * result.len();
let result_len = result.len() / 2;
fluence::internal::add_object_to_release(Box::new(result));
(result_ptr as _, result_len as _)
}
@ -98,7 +94,7 @@ pub unsafe fn __fce_generated_wrapper_func_inner_arrays_1(arg_0: u32, arg_1: u32
result.push(size as _);
}
let result_ptr = result.as_ptr();
let result_len = 4 * result.len();
let result_len = result.len() / 2;
fluence::internal::add_object_to_release(Box::new(result));
(result_ptr as _, result_len as _)
}
@ -109,7 +105,7 @@ pub unsafe fn __fce_generated_wrapper_func_inner_arrays_1(arg_0: u32, arg_1: u32
result.push(size as _);
}
let result_ptr = result.as_ptr();
let result_len = 4 * result.len();
let result_len = result.len() / 2;
fluence::internal::add_object_to_release(Box::new(result));
(result_ptr as _, result_len as _)
}
@ -124,6 +120,6 @@ pub unsafe fn __fce_generated_wrapper_func_inner_arrays_1(arg_0: u32, arg_1: u32
#[doc(hidden)]
#[allow(clippy::all)]
#[link_section = "__fce_generated_section__inner_arrays_1"]
pub static __fce_generated_static_global_inner_arrays_1: [u8; 327usize] = {
* b"{\"ast_type\":\"Function\",\"signature\":{\"name\":\"inner_arrays_1\",\"arguments\":[{\"name\":\"arg\",\"ty\":{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"U8\":\"ByValue\"},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]}}],\"output_type\":{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"U8\":\"ByValue\"},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]}}}"
pub static __fce_generated_static_global_inner_arrays_1: [u8; 330usize] = {
* b"{\"ast_type\":\"Function\",\"signature\":{\"name\":\"inner_arrays_1\",\"arguments\":[{\"name\":\"arg\",\"ty\":{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"U8\":\"ByValue\"},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]}}],\"output_types\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"U8\":\"ByValue\"},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]}]}}"
};

View File

@ -47,13 +47,7 @@ pub unsafe fn __fce_generated_wrapper_func_all_types(
let converted_arg_9 = arg_9 as _;
let converted_arg_10 = String::from_raw_parts(arg_10 as _, arg_11 as _, arg_11 as _);
unsafe fn __fce_generated_vec_deserializer_12(offset: u32, size: u32) -> Vec<u8> {
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 value in arg {
result.push(value as _);
}
result
Vec::from_raw_parts(offset as _, size as _, size as _)
}
let converted_arg_12 = __fce_generated_vec_deserializer_12(arg_12 as _, arg_13 as _);
let result = all_types(
@ -84,6 +78,6 @@ pub unsafe fn __fce_generated_wrapper_func_all_types(
#[doc(hidden)]
#[allow(clippy::all)]
#[link_section = "__fce_generated_section__all_types"]
pub static __fce_generated_static_global_all_types: [u8; 633usize] = {
* b"{\"ast_type\":\"Function\",\"signature\":{\"name\":\"all_types\",\"arguments\":[{\"name\":\"arg_0\",\"ty\":{\"I8\":\"ByValue\"}},{\"name\":\"arg_1\",\"ty\":{\"I16\":\"ByValue\"}},{\"name\":\"arg_2\",\"ty\":{\"I32\":\"ByValue\"}},{\"name\":\"arg_3\",\"ty\":{\"I64\":\"ByValue\"}},{\"name\":\"arg_4\",\"ty\":{\"U8\":\"ByValue\"}},{\"name\":\"arg_5\",\"ty\":{\"U16\":\"ByValue\"}},{\"name\":\"arg_6\",\"ty\":{\"U32\":\"ByValue\"}},{\"name\":\"arg_7\",\"ty\":{\"U64\":\"ByValue\"}},{\"name\":\"arg_8\",\"ty\":{\"F32\":\"ByValue\"}},{\"name\":\"arg_9\",\"ty\":{\"F64\":\"ByValue\"}},{\"name\":\"arg_10\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"arg_11\",\"ty\":{\"Vector\":[{\"U8\":\"ByValue\"},\"ByValue\"]}}],\"output_type\":{\"Vector\":[{\"U8\":\"ByValue\"},\"ByValue\"]}}}"
pub static __fce_generated_static_global_all_types: [u8; 636usize] = {
* b"{\"ast_type\":\"Function\",\"signature\":{\"name\":\"all_types\",\"arguments\":[{\"name\":\"arg_0\",\"ty\":{\"I8\":\"ByValue\"}},{\"name\":\"arg_1\",\"ty\":{\"I16\":\"ByValue\"}},{\"name\":\"arg_2\",\"ty\":{\"I32\":\"ByValue\"}},{\"name\":\"arg_3\",\"ty\":{\"I64\":\"ByValue\"}},{\"name\":\"arg_4\",\"ty\":{\"U8\":\"ByValue\"}},{\"name\":\"arg_5\",\"ty\":{\"U16\":\"ByValue\"}},{\"name\":\"arg_6\",\"ty\":{\"U32\":\"ByValue\"}},{\"name\":\"arg_7\",\"ty\":{\"U64\":\"ByValue\"}},{\"name\":\"arg_8\",\"ty\":{\"F32\":\"ByValue\"}},{\"name\":\"arg_9\",\"ty\":{\"F64\":\"ByValue\"}},{\"name\":\"arg_10\",\"ty\":{\"Utf8String\":\"ByValue\"}},{\"name\":\"arg_11\",\"ty\":{\"Vector\":[{\"U8\":\"ByValue\"},\"ByValue\"]}}],\"output_types\":[{\"Vector\":[{\"U8\":\"ByValue\"},\"ByValue\"]}]}}"
};

View File

@ -8,10 +8,10 @@ pub fn test_array_refs(arg: &Vec<Vec<String>>) -> &Vec<Vec<Vec<Vec<String>>>> {
#[allow(clippy::all)]
pub unsafe fn __fce_generated_wrapper_func_test_array_refs(arg_0: u32, arg_1: u32) {
unsafe fn __fce_generated_vec_deserializer_0(offset: u32, size: u32) -> Vec<Vec<String>> {
let size = size / 8;
unsafe fn __fce_generated_vec_deserializer_0_String(offset: u32, size: u32) -> Vec<String> {
let size = size / 8;
let mut arg: Vec<u64> = Vec::from_raw_parts(offset as _, size as _, size as _);
let vec_passing_size = 2;
let mut arg: Vec<u32> =
Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * size) as _);
let mut arg = arg.into_iter();
let mut result = Vec::with_capacity(arg.len() / 2);
while let Some(offset) = arg.next() {
@ -21,7 +21,8 @@ pub unsafe fn __fce_generated_wrapper_func_test_array_refs(arg_0: u32, arg_1: u3
}
result
}
let mut arg: Vec<u64> = Vec::from_raw_parts(offset as _, size as _, size as _);
let vec_passing_size = 2;
let mut arg: Vec<u32> = Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * size) as _);
let mut result = Vec::with_capacity(arg.len());
let mut arg = arg.into_iter();
while let Some(offset) = arg.next() {
@ -49,7 +50,7 @@ pub unsafe fn __fce_generated_wrapper_func_test_array_refs(arg_0: u32, arg_1: u3
result.push(value.len() as _);
}
let result_ptr = result.as_ptr();
let result_len = 4 * result.len();
let result_len = result.len() / 2;
fluence::internal::add_object_to_release(Box::new(result));
(result_ptr as _, result_len as _)
}
@ -61,7 +62,7 @@ pub unsafe fn __fce_generated_wrapper_func_test_array_refs(arg_0: u32, arg_1: u3
result.push(size as _);
}
let result_ptr = result.as_ptr();
let result_len = 4 * result.len();
let result_len = result.len() / 2;
fluence::internal::add_object_to_release(Box::new(result));
(result_ptr as _, result_len as _)
}
@ -73,7 +74,7 @@ pub unsafe fn __fce_generated_wrapper_func_test_array_refs(arg_0: u32, arg_1: u3
result.push(size as _);
}
let result_ptr = result.as_ptr();
let result_len = 4 * result.len();
let result_len = result.len() / 2;
fluence::internal::add_object_to_release(Box::new(result));
(result_ptr as _, result_len as _)
}
@ -84,7 +85,7 @@ pub unsafe fn __fce_generated_wrapper_func_test_array_refs(arg_0: u32, arg_1: u3
result.push(size as _);
}
let result_ptr = result.as_ptr();
let result_len = 4 * result.len();
let result_len = result.len() / 2;
fluence::internal::add_object_to_release(Box::new(result));
(result_ptr as _, result_len as _)
}
@ -99,6 +100,6 @@ pub unsafe fn __fce_generated_wrapper_func_test_array_refs(arg_0: u32, arg_1: u3
#[doc(hidden)]
#[allow(clippy::all)]
#[link_section = "__fce_generated_section__test_array_refs"]
pub static __fce_generated_static_global_test_array_refs: [u8; 294usize] = {
* b"{\"ast_type\":\"Function\",\"signature\":{\"name\":\"test_array_refs\",\"arguments\":[{\"name\":\"arg\",\"ty\":{\"Vector\":[{\"Vector\":[{\"Utf8String\":\"ByValue\"},\"ByValue\"]},\"ByRef\"]}}],\"output_type\":{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Utf8String\":\"ByValue\"},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByRef\"]}}}"
pub static __fce_generated_static_global_test_array_refs: [u8; 297usize] = {
* b"{\"ast_type\":\"Function\",\"signature\":{\"name\":\"test_array_refs\",\"arguments\":[{\"name\":\"arg\",\"ty\":{\"Vector\":[{\"Vector\":[{\"Utf8String\":\"ByValue\"},\"ByValue\"]},\"ByRef\"]}}],\"output_types\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Utf8String\":\"ByValue\"},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByRef\"]}]}}"
};

View File

@ -17,17 +17,22 @@ pub struct CallParameters {
#[allow(clippy::all)]
impl CallParameters {
pub fn __fce_generated_serialize(&self) -> *const u8 {
let mut raw_record: Vec<u64> = Vec::with_capacity(2 * 6usize);
raw_record.push(self.init_peer_id.as_ptr() as _);
raw_record.push(self.init_peer_id.len() as _);
raw_record.push(self.service_id.as_ptr() as _);
raw_record.push(self.service_id.len() as _);
raw_record.push(self.service_creator_peer_id.as_ptr() as _);
raw_record.push(self.service_creator_peer_id.len() as _);
raw_record.push(self.host_id.as_ptr() as _);
raw_record.push(self.host_id.len() as _);
raw_record.push(self.particle_id.as_ptr() as _);
raw_record.push(self.particle_id.len() as _);
let mut raw_record: Vec<u8> = Vec::with_capacity(4 * 6usize);
let field_ident_ptr = self.init_peer_id.as_ptr() as u32;
raw_record.extend(&field_ident_ptr.to_le_bytes());
raw_record.extend(&(self.init_peer_id.len() as u32).to_le_bytes());
let field_ident_ptr = self.service_id.as_ptr() as u32;
raw_record.extend(&field_ident_ptr.to_le_bytes());
raw_record.extend(&(self.service_id.len() as u32).to_le_bytes());
let field_ident_ptr = self.service_creator_peer_id.as_ptr() as u32;
raw_record.extend(&field_ident_ptr.to_le_bytes());
raw_record.extend(&(self.service_creator_peer_id.len() as u32).to_le_bytes());
let field_ident_ptr = self.host_id.as_ptr() as u32;
raw_record.extend(&field_ident_ptr.to_le_bytes());
raw_record.extend(&(self.host_id.len() as u32).to_le_bytes());
let field_ident_ptr = self.particle_id.as_ptr() as u32;
raw_record.extend(&field_ident_ptr.to_le_bytes());
raw_record.extend(&(self.particle_id.len() as u32).to_le_bytes());
unsafe fn __fce_generated_vec_serializer_tetraplets_5(
arg: &Vec<Vec<SecurityTetraplet>>
) -> (u32, u32) {
@ -39,7 +44,7 @@ impl CallParameters {
result.push(value.__fce_generated_serialize() as _);
}
let result_ptr = result.as_ptr();
let result_len = 4 * result.len();
let result_len = result.len();
fluence::internal::add_object_to_release(Box::new(result));
(result_ptr as _, result_len as _)
}
@ -51,66 +56,104 @@ impl CallParameters {
result.push(size as _);
}
let result_ptr = result.as_ptr();
let result_len = 4 * result.len();
let result_len = result.len() / 2;
fluence::internal::add_object_to_release(Box::new(result));
(result_ptr as _, 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 _);
raw_record.extend(&serialized_arg_5.0.to_le_bytes());
raw_record.extend(&serialized_arg_5.1.to_le_bytes());
let raw_record_ptr = raw_record.as_ptr();
fluence::internal::add_object_to_release(Box::new(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 raw_record: Vec<u8> = Vec::from_raw_parts(record_ptr as _, 48usize, 48usize);
let field_0 = unsafe {
String::from_raw_parts(
raw_record[0usize] as _,
raw_record[1usize] as _,
raw_record[1usize] as _
)
let offset = u32::from_le_bytes([
raw_record[0usize],
raw_record[0usize + 1],
raw_record[0usize + 2],
raw_record[0usize + 3],
]);
let size = u32::from_le_bytes([
raw_record[0usize + 4],
raw_record[0usize + 5],
raw_record[0usize + 6],
raw_record[0usize + 7],
]);
String::from_raw_parts(offset as _, size as _, size as _)
};
let field_1 = unsafe {
String::from_raw_parts(
raw_record[2usize] as _,
raw_record[3usize] as _,
raw_record[3usize] as _
)
let offset = u32::from_le_bytes([
raw_record[8usize],
raw_record[8usize + 1],
raw_record[8usize + 2],
raw_record[8usize + 3],
]);
let size = u32::from_le_bytes([
raw_record[8usize + 4],
raw_record[8usize + 5],
raw_record[8usize + 6],
raw_record[8usize + 7],
]);
String::from_raw_parts(offset as _, size as _, size as _)
};
let field_2 = unsafe {
String::from_raw_parts(
raw_record[4usize] as _,
raw_record[5usize] as _,
raw_record[5usize] as _
)
let offset = u32::from_le_bytes([
raw_record[16usize],
raw_record[16usize + 1],
raw_record[16usize + 2],
raw_record[16usize + 3],
]);
let size = u32::from_le_bytes([
raw_record[16usize + 4],
raw_record[16usize + 5],
raw_record[16usize + 6],
raw_record[16usize + 7],
]);
String::from_raw_parts(offset as _, size as _, size as _)
};
let field_3 = unsafe {
String::from_raw_parts(
raw_record[6usize] as _,
raw_record[7usize] as _,
raw_record[7usize] as _
)
let offset = u32::from_le_bytes([
raw_record[24usize],
raw_record[24usize + 1],
raw_record[24usize + 2],
raw_record[24usize + 3],
]);
let size = u32::from_le_bytes([
raw_record[24usize + 4],
raw_record[24usize + 5],
raw_record[24usize + 6],
raw_record[24usize + 7],
]);
String::from_raw_parts(offset as _, size as _, size as _)
};
let field_4 = unsafe {
String::from_raw_parts(
raw_record[8usize] as _,
raw_record[9usize] as _,
raw_record[9usize] as _
)
let offset = u32::from_le_bytes([
raw_record[32usize],
raw_record[32usize + 1],
raw_record[32usize + 2],
raw_record[32usize + 3],
]);
let size = u32::from_le_bytes([
raw_record[32usize + 4],
raw_record[32usize + 5],
raw_record[32usize + 6],
raw_record[32usize + 7],
]);
String::from_raw_parts(offset as _, size as _, size as _)
};
unsafe fn __fce_generated_vec_deserializer_10(
unsafe fn __fce_generated_vec_deserializer_40(
offset: u32,
size: u32
) -> Vec<Vec<SecurityTetraplet>> {
let size = size / 8;
unsafe fn __fce_generated_vec_deserializer_10_SecurityTetraplet(
unsafe fn __fce_generated_vec_deserializer_40_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 arg: Vec<u32> = 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 _);
@ -118,12 +161,14 @@ impl CallParameters {
}
result
}
let mut arg: Vec<u64> = Vec::from_raw_parts(offset as _, size as _, size as _);
let vec_passing_size = 2;
let mut arg: Vec<u32> =
Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * 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(
let value = __fce_generated_vec_deserializer_40_SecurityTetraplet(
offset as _,
size as _
);
@ -131,12 +176,19 @@ impl CallParameters {
}
result
}
let field_5 = unsafe {
__fce_generated_vec_deserializer_10(
raw_record[10usize] as _,
raw_record[11usize] as _
)
};
let offset = u32::from_le_bytes([
raw_record[40usize],
raw_record[40usize + 1],
raw_record[40usize + 2],
raw_record[40usize + 3],
]);
let size = u32::from_le_bytes([
raw_record[40usize + 4],
raw_record[40usize + 5],
raw_record[40usize + 6],
raw_record[40usize + 7],
]);
let field_5 = unsafe { __fce_generated_vec_deserializer_40(offset as _, size as _) };
Self {
init_peer_id: field_0,
service_id: field_1,
@ -151,6 +203,6 @@ impl CallParameters {
#[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\"]}}]}"
pub static __fce_generated_static_global_CallParameters: [u8; 455usize] = {
* b"{\"ast_type\":\"Record\",\"name\":\"CallParameters\",\"fields\":{\"Named\":[{\"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\"]}}]}}"
};

View File

@ -11,23 +11,19 @@ pub unsafe fn __fce_generated_wrapper_func_inner_arrays_2(arg_0: u32, arg_1: u32
offset: u32,
size: u32
) -> Vec<Vec<Vec<Vec<TestRecord>>>> {
let size = size / 8;
unsafe fn __fce_generated_vec_deserializer_0_Vec_Vec_TestRecord__(
offset: u32,
size: u32
) -> Vec<Vec<Vec<TestRecord>>> {
let size = size / 8;
unsafe fn __fce_generated_vec_deserializer_0_Vec_Vec_TestRecord___Vec_TestRecord_(
offset: u32,
size: u32
) -> Vec<Vec<TestRecord>> {
let size = size / 8;
unsafe fn __fce_generated_vec_deserializer_0_Vec_Vec_TestRecord___Vec_TestRecord__TestRecord(
offset: u32,
size: u32
) -> Vec<TestRecord> {
let size = size / 8;
let mut arg: Vec<u64> = Vec::from_raw_parts(offset as _, size as _, size as _);
let mut arg: Vec<u32> = Vec::from_raw_parts(offset as _, size as _, size as _);
let mut result = Vec::with_capacity(arg.len());
for offset in arg {
let value = TestRecord::__fce_generated_deserialize(offset as _);
@ -35,7 +31,9 @@ pub unsafe fn __fce_generated_wrapper_func_inner_arrays_2(arg_0: u32, arg_1: u32
}
result
}
let mut arg: Vec<u64> = Vec::from_raw_parts(offset as _, size as _, size as _);
let vec_passing_size = 2;
let mut arg: Vec<u32> =
Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * size) as _);
let mut result = Vec::with_capacity(arg.len());
let mut arg = arg.into_iter();
while let Some(offset) = arg.next() {
@ -45,7 +43,9 @@ pub unsafe fn __fce_generated_wrapper_func_inner_arrays_2(arg_0: u32, arg_1: u32
}
result
}
let mut arg: Vec<u64> = Vec::from_raw_parts(offset as _, size as _, size as _);
let vec_passing_size = 2;
let mut arg: Vec<u32> =
Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * size) as _);
let mut result = Vec::with_capacity(arg.len());
let mut arg = arg.into_iter();
while let Some(offset) = arg.next() {
@ -58,7 +58,8 @@ pub unsafe fn __fce_generated_wrapper_func_inner_arrays_2(arg_0: u32, arg_1: u32
}
result
}
let mut arg: Vec<u64> = Vec::from_raw_parts(offset as _, size as _, size as _);
let vec_passing_size = 2;
let mut arg: Vec<u32> = Vec::from_raw_parts(offset as _, (vec_passing_size * size) as _, (vec_passing_size * size) as _);
let mut result = Vec::with_capacity(arg.len());
let mut arg = arg.into_iter();
while let Some(offset) = arg.next() {
@ -86,7 +87,7 @@ pub unsafe fn __fce_generated_wrapper_func_inner_arrays_2(arg_0: u32, arg_1: u32
result.push(value.__fce_generated_serialize() as _);
}
let result_ptr = result.as_ptr();
let result_len = 4 * result.len();
let result_len = result.len();
fluence::internal::add_object_to_release(Box::new(result));
(result_ptr as _, result_len as _)
}
@ -97,7 +98,7 @@ pub unsafe fn __fce_generated_wrapper_func_inner_arrays_2(arg_0: u32, arg_1: u32
result.push(size as _);
}
let result_ptr = result.as_ptr();
let result_len = 4 * result.len();
let result_len = result.len() / 2;
fluence::internal::add_object_to_release(Box::new(result));
(result_ptr as _, result_len as _)
}
@ -109,7 +110,7 @@ pub unsafe fn __fce_generated_wrapper_func_inner_arrays_2(arg_0: u32, arg_1: u32
result.push(size as _);
}
let result_ptr = result.as_ptr();
let result_len = 4 * result.len();
let result_len = result.len() / 2;
fluence::internal::add_object_to_release(Box::new(result));
(result_ptr as _, result_len as _)
}
@ -120,7 +121,7 @@ pub unsafe fn __fce_generated_wrapper_func_inner_arrays_2(arg_0: u32, arg_1: u32
result.push(size as _);
}
let result_ptr = result.as_ptr();
let result_len = 4 * result.len();
let result_len = result.len() / 2;
fluence::internal::add_object_to_release(Box::new(result));
(result_ptr as _, result_len as _)
}
@ -135,6 +136,6 @@ pub unsafe fn __fce_generated_wrapper_func_inner_arrays_2(arg_0: u32, arg_1: u32
#[doc(hidden)]
#[allow(clippy::all)]
#[link_section = "__fce_generated_section__inner_arrays_2"]
pub static __fce_generated_static_global_inner_arrays_2: [u8; 365usize] = {
* b"{\"ast_type\":\"Function\",\"signature\":{\"name\":\"inner_arrays_2\",\"arguments\":[{\"name\":\"arg\",\"ty\":{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Record\":[\"TestRecord\",\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]}}],\"output_type\":{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Record\":[\"TestRecord\",\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]}}}"
pub static __fce_generated_static_global_inner_arrays_2: [u8; 368usize] = {
* b"{\"ast_type\":\"Function\",\"signature\":{\"name\":\"inner_arrays_2\",\"arguments\":[{\"name\":\"arg\",\"ty\":{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Record\":[\"TestRecord\",\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]}}],\"output_types\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Vector\":[{\"Record\":[\"TestRecord\",\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]},\"ByValue\"]}]}}"
};

View File

@ -31,6 +31,11 @@ pub fn string_type(_arg: Vec<String>) -> Vec<String> {
unimplemented!()
}
#[fce]
pub fn bool_type(_arg: Vec<bool>) -> Vec<bool> {
unimplemented!()
}
#[fce]
pub fn f32_type(_arg: Vec<f32>) -> Vec<f32> {
unimplemented!()

View File

@ -31,6 +31,11 @@ pub fn string_type(_arg: &Vec<String>) -> &Vec<String> {
unimplemented!()
}
#[fce]
pub fn bool_type(_arg: &Vec<bool>) -> &Vec<bool> {
unimplemented!()
}
#[fce]
pub fn f32_type(_arg: &Vec<f32>) -> &Vec<f32> {
unimplemented!()

View File

@ -22,6 +22,8 @@ extern "C" {
pub fn string_type(arg: Vec<String>) -> Vec<String>;
pub fn bool_type(arg: Vec<bool>) -> Vec<bool>;
pub fn byte_type(arg: Vec<u8>) -> Vec<u8>;
pub fn f32_type(arg: Vec<f32>) -> Vec<f32>;

View File

@ -42,6 +42,8 @@ extern "C" {
pub fn string_type(arg: &Vec<String>) -> Vec<String>;
pub fn bool_type(arg: &Vec<bool>) -> Vec<bool>;
pub fn byte_type(arg: &Vec<u8>) -> Vec<u8>;
pub fn f32_type(arg: &Vec<f32>) -> Vec<f32>;