improve interface

This commit is contained in:
vms 2021-04-18 13:29:49 +03:00
parent 12f06f806f
commit 8ea8e219ef
20 changed files with 250 additions and 96 deletions

View File

@ -37,6 +37,7 @@ pub unsafe fn allocate(size: usize) -> usize {
global_alloc(layout) as _
}
/*
/// Allocates memory area of specified size and returns its address.
/// Returns 0 if supplied size is too long.
#[no_mangle]
@ -55,3 +56,4 @@ pub unsafe fn allocate_vec(element_count: usize, align: usize) -> usize {
global_alloc(layout) as _
}
*/

View File

@ -57,14 +57,12 @@ pub use result::add_object_to_release;
pub use module_manifest::MANIFEST_SECTION_NAME;
pub use sdk_version_embedder::VERSION_SECTION_NAME;
// logs will be printed only if debug feature is enabled
#[cfg(feature = "debug")]
#[allow(unused_variables)]
pub(crate) fn log<S: AsRef<str>>(msg: S) {
// logs will be printed only if debug feature is enabled
#[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 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);
}

View File

@ -16,20 +16,15 @@
use crate::parsed_type::ParsedType;
use serde::Serialize;
use serde::Deserialize;
#[derive(Clone, Serialize, Deserialize)]
pub struct AstFnArgument {
#[derive(Clone)]
pub(crate) 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>,
#[derive(Clone)]
pub(crate) struct AstFnSignature {
pub visibility: syn::Visibility,
pub name: String,
pub arguments: Vec<AstFnArgument>,
// fce supports only one return value now,
@ -37,54 +32,43 @@ pub struct AstFnSignature {
pub output_type: Option<ParsedType>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct AstRecordField {
#[derive(Debug, Clone, PartialEq)]
pub(crate) struct AstRecordField {
// fields of tuple structs haven't got name
pub name: Option<String>,
pub ty: ParsedType,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct AstRecordItem {
#[derive(Clone)]
pub(crate) 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>,
pub original: syn::ItemStruct,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct AstExternFnItem {
#[derive(Clone)]
pub(crate) struct AstExternFnItem {
pub link_name: Option<String>,
// only imports are possible here
pub signature: AstFnSignature,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct AstExternModItem {
#[derive(Clone)]
pub(crate) 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>,
pub original: syn::ItemForeignMod,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct AstFnItem {
#[derive(Clone)]
pub(crate) struct AstFnItem {
pub signature: AstFnSignature,
// Option is needed only for skipping serialization/deserialization of syn::ItemFn
#[serde(skip)]
pub original: Option<syn::ItemFn>,
pub original: syn::ItemFn,
}
#[derive(Clone, Serialize, Deserialize)]
#[serde(tag = "ast_type")]
pub enum FCEAst {
#[derive(Clone)]
pub(crate) enum FCEAst {
Function(AstFnItem),
ExternMod(AstExternModItem),
Record(AstRecordItem),

View File

@ -0,0 +1,171 @@
/*
* 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>,
// 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 RecordField {
// fields of tuple structs haven't got name
pub name: Option<String>,
pub ty: ParsedType,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct RecordItem {
pub name: String,
pub fields: Vec<RecordField>,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct ExternFnItem {
pub link_name: Option<String>,
// only imports are possible here
pub signature: FnSignature,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct ExternModItem {
pub namespace: String,
// only imports are possible here
pub imports: Vec<ExternFnItem>,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct FnItem {
pub signature: FnSignature,
}
#[derive(Clone, Serialize, Deserialize)]
#[serde(tag = "ast_type")]
pub enum SDKAst {
Function(FnItem),
ExternMod(ExternModItem),
Record(RecordItem),
}
use crate::ast_types::{
AstFnItem, AstFnSignature, AstFnArgument, AstExternModItem, AstExternFnItem, AstRecordField,
AstRecordItem,
};
impl From<AstFnItem> for SDKAst {
fn from(ast_fn_item: AstFnItem) -> Self {
let fn_item = ast_fn_item.into();
Self::Function(fn_item)
}
}
impl From<AstExternModItem> for SDKAst {
fn from(ast_extern_mod: AstExternModItem) -> Self {
let extern_mod = ast_extern_mod.into();
Self::ExternMod(extern_mod)
}
}
impl From<AstRecordItem> for SDKAst {
fn from(ast_record_item: AstRecordItem) -> Self {
let record_item = ast_record_item.into();
Self::Record(record_item)
}
}
impl From<AstFnItem> for FnItem {
fn from(ast_fn_item: AstFnItem) -> Self {
let signature = ast_fn_item.signature.into();
Self { signature }
}
}
impl From<AstExternModItem> for ExternModItem {
fn from(ast_extern_mod: AstExternModItem) -> Self {
let imports = ast_extern_mod.imports.into_iter().map(Into::into).collect();
Self {
namespace: ast_extern_mod.namespace,
imports,
}
}
}
impl From<AstRecordItem> for RecordItem {
fn from(ast_record_item: AstRecordItem) -> Self {
let fields = ast_record_item.fields.into_iter().map(Into::into).collect();
Self {
name: ast_record_item.name,
fields,
}
}
}
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();
Self {
name: ast_fn_sig.name,
arguments,
output_type: ast_fn_sig.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<AstExternFnItem> for ExternFnItem {
fn from(ast_extern_item: AstExternFnItem) -> 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

@ -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::AstFnItem;
use crate::ast_types::AstFnArgument;
use crate::syn_error;
use syn::Result;
@ -40,7 +40,7 @@ impl ParseMacroInput for syn::ItemFn {
let ast_fn = FCEAst::Function(AstFnItem {
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::AstExternModItem {
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::AstExternFnItem>> {
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::AstExternFnItem, 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::AstExternFnItem> {
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::AstExternFnItem {
link_name,
signature,
};

View File

@ -15,9 +15,9 @@
*/
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::FCEAst;
use crate::syn_error;
use crate::parsed_type::ParsedType;
@ -36,10 +36,10 @@ impl ParseMacroInput for syn::ItemStruct {
let fields = fields_into_ast(fields)?;
let name = self.ident.to_string();
let ast_record_item = fce_ast_types::AstRecordItem {
let ast_record_item = ast_types::AstRecordItem {
name,
fields,
original: Some(self),
original: self,
};
Ok(FCEAst::Record(ast_record_item))

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;

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;

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>,

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::AstFnItem {
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::AstExternModItem {
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::AstExternModItem) -> 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::AstExternModItem) -> TokenStream {
let mut token_stream = TokenStream::new();
for import in &extern_item.imports {

View File

@ -21,9 +21,9 @@ use record_serializer::*;
use record_deserializer::*;
use crate::new_ident;
use crate::fce_ast_types;
use crate::ast_types;
impl quote::ToTokens for fce_ast_types::AstRecordItem {
impl quote::ToTokens for ast_types::AstRecordItem {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let original = &self.original;
crate::prepare_global_data!(
@ -65,7 +65,7 @@ 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: &ast_types::AstRecordItem) -> proc_macro2::TokenStream {
let serializer = record.generate_serializer();
let fields_count = record.fields.len();
@ -83,7 +83,7 @@ fn generate_serializer_fn(record: &fce_ast_types::AstRecordItem) -> proc_macro2:
}
}
fn generate_deserializer_fn(record: &fce_ast_types::AstRecordItem) -> proc_macro2::TokenStream {
fn generate_deserializer_fn(record: &ast_types::AstRecordItem) -> proc_macro2::TokenStream {
let RecordDerDescriptor {
fields_der,
record_ctor,

View File

@ -16,7 +16,7 @@
use crate::new_ident;
use crate::parsed_type::ParsedType;
use crate::fce_ast_types;
use crate::ast_types;
use quote::quote;
@ -30,7 +30,7 @@ pub(super) trait RecordDerGlueCodeGenerator {
fn generate_der(&self) -> RecordDerDescriptor;
}
impl RecordDerGlueCodeGenerator for fce_ast_types::AstRecordItem {
impl RecordDerGlueCodeGenerator for ast_types::AstRecordItem {
fn generate_der(&self) -> RecordDerDescriptor {
let builder = FieldValuesBuilder::build(self.fields.iter());
let record_ctor = build_record_ctor(self.fields.iter(), builder.field_value_idents.iter());
@ -61,7 +61,7 @@ struct FieldValuesOutcome {
impl FieldValuesBuilder {
pub(self) fn build<'a>(
fields: impl ExactSizeIterator<Item = &'a fce_ast_types::AstRecordField>,
fields: impl ExactSizeIterator<Item = &'a ast_types::AstRecordField>,
) -> FieldValuesOutcome {
let values_builder = Self::new(fields.len());
values_builder.build_impl(fields)
@ -77,7 +77,7 @@ impl FieldValuesBuilder {
fn build_impl<'r>(
mut self,
fields: impl ExactSizeIterator<Item = &'r fce_ast_types::AstRecordField>,
fields: impl ExactSizeIterator<Item = &'r ast_types::AstRecordField>,
) -> FieldValuesOutcome {
for (id, ast_field) in fields.enumerate() {
let field_value_ident = new_ident!(format!("field_{}", id));
@ -97,7 +97,7 @@ impl FieldValuesBuilder {
fn field_der(
&mut self,
ast_field: &fce_ast_types::AstRecordField,
ast_field: &ast_types::AstRecordField,
field: &syn::Ident,
) -> proc_macro2::TokenStream {
let value_id = self.value_id;
@ -162,7 +162,7 @@ impl FieldValuesBuilder {
}
fn build_record_ctor<'a, 'v>(
ast_fields: impl ExactSizeIterator<Item = &'a fce_ast_types::AstRecordField>,
ast_fields: impl ExactSizeIterator<Item = &'a ast_types::AstRecordField>,
field_values: impl ExactSizeIterator<Item = &'v syn::Ident>,
) -> proc_macro2::TokenStream {
let mut ast_fields = ast_fields.peekable();
@ -179,7 +179,7 @@ fn build_record_ctor<'a, 'v>(
}
fn build_named_fields_ctor<'a, 'v>(
ast_fields: impl ExactSizeIterator<Item = &'a fce_ast_types::AstRecordField>,
ast_fields: impl ExactSizeIterator<Item = &'a ast_types::AstRecordField>,
field_values: impl ExactSizeIterator<Item = &'v syn::Ident>,
) -> proc_macro2::TokenStream {
let field_names = ast_fields

View File

@ -16,7 +16,7 @@
use crate::new_ident;
use crate::parsed_type::ParsedType;
use crate::fce_ast_types;
use crate::ast_types;
use quote::quote;
@ -25,7 +25,7 @@ pub(super) trait RecordSerializerGlueCodeGenerator {
fn generate_serializer(&self) -> proc_macro2::TokenStream;
}
impl RecordSerializerGlueCodeGenerator for fce_ast_types::AstRecordItem {
impl RecordSerializerGlueCodeGenerator for ast_types::AstRecordItem {
fn generate_serializer(&self) -> proc_macro2::TokenStream {
let mut serializer = proc_macro2::TokenStream::new();
for (id, field) in self.fields.iter().enumerate() {
@ -82,7 +82,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: &ast_types::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());