mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-08 19:28:01 +00:00
Run cargo fmt on the whole code base (#9394)
* Run cargo fmt on the whole code base * Second run * Add CI check * Fix compilation * More unnecessary braces * Handle weights * Use --all * Use correct attributes... * Fix UI tests * AHHHHHHHHH * 🤦 * Docs * Fix compilation * 🤷 * Please stop * 🤦 x 2 * More * make rustfmt.toml consistent with polkadot Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
@@ -26,8 +26,10 @@
|
||||
//! 3. The [`PassByEnum`](derive.PassByInner.html) derive macro for implementing `PassBy` with `Enum`.
|
||||
//! 4. The [`PassByInner`](derive.PassByInner.html) derive macro for implementing `PassBy` with `Inner`.
|
||||
|
||||
use syn::{parse_macro_input, ItemTrait, DeriveInput, Result, Token};
|
||||
use syn::parse::{Parse, ParseStream};
|
||||
use syn::{
|
||||
parse::{Parse, ParseStream},
|
||||
parse_macro_input, DeriveInput, ItemTrait, Result, Token,
|
||||
};
|
||||
|
||||
mod pass_by;
|
||||
mod runtime_interface;
|
||||
@@ -35,7 +37,7 @@ mod utils;
|
||||
|
||||
struct Options {
|
||||
wasm_only: bool,
|
||||
tracing: bool
|
||||
tracing: bool,
|
||||
}
|
||||
|
||||
impl Options {
|
||||
@@ -86,17 +88,21 @@ pub fn runtime_interface(
|
||||
#[proc_macro_derive(PassByCodec)]
|
||||
pub fn pass_by_codec(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
pass_by::codec_derive_impl(input).unwrap_or_else(|e| e.to_compile_error()).into()
|
||||
pass_by::codec_derive_impl(input)
|
||||
.unwrap_or_else(|e| e.to_compile_error())
|
||||
.into()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(PassByInner)]
|
||||
pub fn pass_by_inner(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
pass_by::inner_derive_impl(input).unwrap_or_else(|e| e.to_compile_error()).into()
|
||||
pass_by::inner_derive_impl(input)
|
||||
.unwrap_or_else(|e| e.to_compile_error())
|
||||
.into()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(PassByEnum)]
|
||||
pub fn pass_by_enum(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
pass_by::enum_derive_impl(input).unwrap_or_else(|e| e.to_compile_error()).into()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
use crate::utils::{generate_crate_access, generate_runtime_interface_include};
|
||||
|
||||
use syn::{DeriveInput, Result, Generics, parse_quote};
|
||||
use syn::{parse_quote, DeriveInput, Generics, Result};
|
||||
|
||||
use quote::quote;
|
||||
|
||||
@@ -53,7 +53,7 @@ pub fn derive_impl(mut input: DeriveInput) -> Result<TokenStream> {
|
||||
fn add_trait_bounds(generics: &mut Generics) {
|
||||
let crate_ = generate_crate_access();
|
||||
|
||||
generics.type_params_mut()
|
||||
generics
|
||||
.type_params_mut()
|
||||
.for_each(|type_param| type_param.bounds.push(parse_quote!(#crate_::codec::Codec)));
|
||||
}
|
||||
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
|
||||
use crate::utils::{generate_crate_access, generate_runtime_interface_include};
|
||||
|
||||
use syn::{DeriveInput, Result, Data, Fields, Error, Ident};
|
||||
use syn::{Data, DeriveInput, Error, Fields, Ident, Result};
|
||||
|
||||
use quote::quote;
|
||||
|
||||
use proc_macro2::{TokenStream, Span};
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
|
||||
/// The derive implementation for `PassBy` with `Enum`.
|
||||
pub fn derive_impl(input: DeriveInput) -> Result<TokenStream> {
|
||||
@@ -81,22 +81,21 @@ pub fn derive_impl(input: DeriveInput) -> Result<TokenStream> {
|
||||
/// enum or a variant is not an unit.
|
||||
fn get_enum_field_idents<'a>(data: &'a Data) -> Result<impl Iterator<Item = Result<&'a Ident>>> {
|
||||
match data {
|
||||
Data::Enum(d) => {
|
||||
Data::Enum(d) =>
|
||||
if d.variants.len() <= 256 {
|
||||
Ok(
|
||||
d.variants.iter().map(|v| if let Fields::Unit = v.fields {
|
||||
Ok(d.variants.iter().map(|v| {
|
||||
if let Fields::Unit = v.fields {
|
||||
Ok(&v.ident)
|
||||
} else {
|
||||
Err(Error::new(
|
||||
Span::call_site(),
|
||||
"`PassByEnum` only supports unit variants.",
|
||||
))
|
||||
})
|
||||
)
|
||||
}
|
||||
}))
|
||||
} else {
|
||||
Err(Error::new(Span::call_site(), "`PassByEnum` only supports `256` variants."))
|
||||
}
|
||||
},
|
||||
_ => Err(Error::new(Span::call_site(), "`PassByEnum` only supports enums as input type."))
|
||||
},
|
||||
_ => Err(Error::new(Span::call_site(), "`PassByEnum` only supports enums as input type.")),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,11 +22,11 @@
|
||||
|
||||
use crate::utils::{generate_crate_access, generate_runtime_interface_include};
|
||||
|
||||
use syn::{DeriveInput, Result, Generics, parse_quote, Type, Data, Error, Fields, Ident};
|
||||
use syn::{parse_quote, Data, DeriveInput, Error, Fields, Generics, Ident, Result, Type};
|
||||
|
||||
use quote::quote;
|
||||
|
||||
use proc_macro2::{TokenStream, Span};
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
|
||||
/// The derive implementation for `PassBy` with `Inner` and `PassByInner`.
|
||||
pub fn derive_impl(mut input: DeriveInput) -> Result<TokenStream> {
|
||||
@@ -80,7 +80,8 @@ pub fn derive_impl(mut input: DeriveInput) -> Result<TokenStream> {
|
||||
fn add_trait_bounds(generics: &mut Generics) {
|
||||
let crate_ = generate_crate_access();
|
||||
|
||||
generics.type_params_mut()
|
||||
generics
|
||||
.type_params_mut()
|
||||
.for_each(|type_param| type_param.bounds.push(parse_quote!(#crate_::RIType)));
|
||||
}
|
||||
|
||||
@@ -97,15 +98,13 @@ fn extract_inner_ty_and_name(data: &Data) -> Result<(Type, Option<Ident>)> {
|
||||
Fields::Unnamed(ref unnamed) if unnamed.unnamed.len() == 1 => {
|
||||
let field = &unnamed.unnamed[0];
|
||||
return Ok((field.ty.clone(), field.ident.clone()))
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
Err(
|
||||
Error::new(
|
||||
Span::call_site(),
|
||||
"Only newtype/one field structs are supported by `PassByInner`!",
|
||||
)
|
||||
)
|
||||
Err(Error::new(
|
||||
Span::call_site(),
|
||||
"Only newtype/one field structs are supported by `PassByInner`!",
|
||||
))
|
||||
}
|
||||
|
||||
+49
-61
@@ -30,15 +30,16 @@
|
||||
//! are feature-gated, so that one is compiled for the native and the other for the wasm side.
|
||||
|
||||
use crate::utils::{
|
||||
generate_crate_access, create_exchangeable_host_function_ident, get_function_arguments,
|
||||
get_function_argument_names, get_runtime_interface, create_function_ident_with_version,
|
||||
create_exchangeable_host_function_ident, create_function_ident_with_version,
|
||||
generate_crate_access, get_function_argument_names, get_function_arguments,
|
||||
get_runtime_interface,
|
||||
};
|
||||
|
||||
use syn::{
|
||||
Ident, ItemTrait, TraitItemMethod, FnArg, Signature, Result, spanned::Spanned, parse_quote,
|
||||
parse_quote, spanned::Spanned, FnArg, Ident, ItemTrait, Result, Signature, TraitItemMethod,
|
||||
};
|
||||
|
||||
use proc_macro2::{TokenStream, Span};
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
|
||||
use quote::{quote, quote_spanned};
|
||||
|
||||
@@ -51,21 +52,22 @@ pub fn generate(trait_def: &ItemTrait, is_wasm_only: bool, tracing: bool) -> Res
|
||||
let runtime_interface = get_runtime_interface(trait_def)?;
|
||||
|
||||
// latest version dispatch
|
||||
let token_stream: Result<TokenStream> = runtime_interface.latest_versions()
|
||||
.try_fold(
|
||||
TokenStream::new(),
|
||||
|mut t, (latest_version, method)| {
|
||||
t.extend(function_for_method(method, latest_version, is_wasm_only)?);
|
||||
Ok(t)
|
||||
}
|
||||
);
|
||||
let token_stream: Result<TokenStream> = runtime_interface.latest_versions().try_fold(
|
||||
TokenStream::new(),
|
||||
|mut t, (latest_version, method)| {
|
||||
t.extend(function_for_method(method, latest_version, is_wasm_only)?);
|
||||
Ok(t)
|
||||
},
|
||||
);
|
||||
|
||||
// earlier versions compatibility dispatch (only std variant)
|
||||
let result: Result<TokenStream> = runtime_interface.all_versions().try_fold(token_stream?, |mut t, (version, method)|
|
||||
{
|
||||
t.extend(function_std_impl(trait_name, method, version, is_wasm_only, tracing)?);
|
||||
Ok(t)
|
||||
});
|
||||
let result: Result<TokenStream> =
|
||||
runtime_interface
|
||||
.all_versions()
|
||||
.try_fold(token_stream?, |mut t, (version, method)| {
|
||||
t.extend(function_std_impl(trait_name, method, version, is_wasm_only, tracing)?);
|
||||
Ok(t)
|
||||
});
|
||||
|
||||
result
|
||||
}
|
||||
@@ -76,21 +78,16 @@ fn function_for_method(
|
||||
latest_version: u32,
|
||||
is_wasm_only: bool,
|
||||
) -> Result<TokenStream> {
|
||||
let std_impl = if !is_wasm_only {
|
||||
function_std_latest_impl(method, latest_version)?
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
let std_impl =
|
||||
if !is_wasm_only { function_std_latest_impl(method, latest_version)? } else { quote!() };
|
||||
|
||||
let no_std_impl = function_no_std_impl(method)?;
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
#std_impl
|
||||
Ok(quote! {
|
||||
#std_impl
|
||||
|
||||
#no_std_impl
|
||||
}
|
||||
)
|
||||
#no_std_impl
|
||||
})
|
||||
}
|
||||
|
||||
/// Generates the bare function implementation for `cfg(not(feature = "std"))`.
|
||||
@@ -102,31 +99,27 @@ fn function_no_std_impl(method: &TraitItemMethod) -> Result<TokenStream> {
|
||||
let return_value = &method.sig.output;
|
||||
let attrs = method.attrs.iter().filter(|a| !a.path.is_ident("version"));
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
#[cfg(not(feature = "std"))]
|
||||
#( #attrs )*
|
||||
pub fn #function_name( #( #args, )* ) #return_value {
|
||||
// Call the host function
|
||||
#host_function_name.get()( #( #arg_names, )* )
|
||||
}
|
||||
Ok(quote! {
|
||||
#[cfg(not(feature = "std"))]
|
||||
#( #attrs )*
|
||||
pub fn #function_name( #( #args, )* ) #return_value {
|
||||
// Call the host function
|
||||
#host_function_name.get()( #( #arg_names, )* )
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate call to latest function version for `cfg((feature = "std")`
|
||||
///
|
||||
/// This should generate simple `fn func(..) { func_version_<latest_version>(..) }`.
|
||||
fn function_std_latest_impl(
|
||||
method: &TraitItemMethod,
|
||||
latest_version: u32,
|
||||
) -> Result<TokenStream> {
|
||||
fn function_std_latest_impl(method: &TraitItemMethod, latest_version: u32) -> Result<TokenStream> {
|
||||
let function_name = &method.sig.ident;
|
||||
let args = get_function_arguments(&method.sig).map(FnArg::Typed);
|
||||
let arg_names = get_function_argument_names(&method.sig).collect::<Vec<_>>();
|
||||
let return_value = &method.sig.output;
|
||||
let attrs = method.attrs.iter().filter(|a| !a.path.is_ident("version"));
|
||||
let latest_function_name = create_function_ident_with_version(&method.sig.ident, latest_version);
|
||||
let latest_function_name =
|
||||
create_function_ident_with_version(&method.sig.ident, latest_version);
|
||||
|
||||
Ok(quote_spanned! { method.span() =>
|
||||
#[cfg(feature = "std")]
|
||||
@@ -153,17 +146,16 @@ fn function_std_impl(
|
||||
let crate_ = generate_crate_access();
|
||||
let args = get_function_arguments(&method.sig).map(FnArg::Typed).chain(
|
||||
// Add the function context as last parameter when this is a wasm only interface.
|
||||
iter::from_fn(||
|
||||
iter::from_fn(|| {
|
||||
if is_wasm_only {
|
||||
Some(
|
||||
parse_quote!(
|
||||
mut __function_context__: &mut dyn #crate_::sp_wasm_interface::FunctionContext
|
||||
)
|
||||
)
|
||||
Some(parse_quote!(
|
||||
mut __function_context__: &mut dyn #crate_::sp_wasm_interface::FunctionContext
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
).take(1),
|
||||
})
|
||||
.take(1),
|
||||
);
|
||||
let return_value = &method.sig.output;
|
||||
let attrs = method.attrs.iter().filter(|a| !a.path.is_ident("version"));
|
||||
@@ -179,15 +171,13 @@ fn function_std_impl(
|
||||
)
|
||||
};
|
||||
|
||||
Ok(
|
||||
quote_spanned! { method.span() =>
|
||||
#[cfg(feature = "std")]
|
||||
#( #attrs )*
|
||||
fn #function_name( #( #args, )* ) #return_value {
|
||||
#call_to_trait
|
||||
}
|
||||
Ok(quote_spanned! { method.span() =>
|
||||
#[cfg(feature = "std")]
|
||||
#( #attrs )*
|
||||
fn #function_name( #( #args, )* ) #return_value {
|
||||
#call_to_trait
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate the call to the interface trait.
|
||||
@@ -199,10 +189,8 @@ fn generate_call_to_trait(
|
||||
) -> TokenStream {
|
||||
let crate_ = generate_crate_access();
|
||||
let method_name = create_function_ident_with_version(&method.sig.ident, version);
|
||||
let expect_msg = format!(
|
||||
"`{}` called outside of an Externalities-provided environment.",
|
||||
method_name,
|
||||
);
|
||||
let expect_msg =
|
||||
format!("`{}` called outside of an Externalities-provided environment.", method_name,);
|
||||
let arg_names = get_function_argument_names(&method.sig);
|
||||
|
||||
if takes_self_argument(&method.sig) {
|
||||
|
||||
+157
-171
@@ -22,35 +22,36 @@
|
||||
//! executor. These implementations call the bare function interface.
|
||||
|
||||
use crate::utils::{
|
||||
generate_crate_access, create_host_function_ident, get_function_argument_names,
|
||||
get_function_argument_types_without_ref, get_function_argument_types_ref_and_mut,
|
||||
get_function_argument_names_and_types_without_ref, get_function_arguments,
|
||||
get_function_argument_types, create_exchangeable_host_function_ident, get_runtime_interface,
|
||||
create_function_ident_with_version,
|
||||
create_exchangeable_host_function_ident, create_function_ident_with_version,
|
||||
create_host_function_ident, generate_crate_access, get_function_argument_names,
|
||||
get_function_argument_names_and_types_without_ref, get_function_argument_types,
|
||||
get_function_argument_types_ref_and_mut, get_function_argument_types_without_ref,
|
||||
get_function_arguments, get_runtime_interface,
|
||||
};
|
||||
|
||||
use syn::{
|
||||
ItemTrait, TraitItemMethod, Result, ReturnType, Ident, Pat, Error, Signature, spanned::Spanned,
|
||||
spanned::Spanned, Error, Ident, ItemTrait, Pat, Result, ReturnType, Signature, TraitItemMethod,
|
||||
};
|
||||
|
||||
use proc_macro2::{TokenStream, Span};
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
|
||||
use quote::{quote, ToTokens};
|
||||
|
||||
use inflector::Inflector;
|
||||
|
||||
use std::iter::{Iterator, self};
|
||||
use std::iter::{self, Iterator};
|
||||
|
||||
/// Generate the extern host functions for wasm and the `HostFunctions` struct that provides the
|
||||
/// implementations for the host functions on the host.
|
||||
pub fn generate(trait_def: &ItemTrait, is_wasm_only: bool) -> Result<TokenStream> {
|
||||
let trait_name = &trait_def.ident;
|
||||
let extern_host_function_impls = get_runtime_interface(trait_def)?
|
||||
.latest_versions()
|
||||
.try_fold(TokenStream::new(), |mut t, (version, method)| {
|
||||
let extern_host_function_impls = get_runtime_interface(trait_def)?.latest_versions().try_fold(
|
||||
TokenStream::new(),
|
||||
|mut t, (version, method)| {
|
||||
t.extend(generate_extern_host_function(method, version, trait_name)?);
|
||||
Ok::<_, Error>(t)
|
||||
})?;
|
||||
},
|
||||
)?;
|
||||
let exchangeable_host_functions = get_runtime_interface(trait_def)?
|
||||
.latest_versions()
|
||||
.try_fold(TokenStream::new(), |mut t, (_, m)| {
|
||||
@@ -59,27 +60,29 @@ pub fn generate(trait_def: &ItemTrait, is_wasm_only: bool) -> Result<TokenStream
|
||||
})?;
|
||||
let host_functions_struct = generate_host_functions_struct(trait_def, is_wasm_only)?;
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
/// The implementations of the extern host functions. This special implementation module
|
||||
/// is required to change the extern host functions signature to
|
||||
/// `unsafe fn name(args) -> ret` to make the function implementations exchangeable.
|
||||
#[cfg(not(feature = "std"))]
|
||||
mod extern_host_function_impls {
|
||||
use super::*;
|
||||
Ok(quote! {
|
||||
/// The implementations of the extern host functions. This special implementation module
|
||||
/// is required to change the extern host functions signature to
|
||||
/// `unsafe fn name(args) -> ret` to make the function implementations exchangeable.
|
||||
#[cfg(not(feature = "std"))]
|
||||
mod extern_host_function_impls {
|
||||
use super::*;
|
||||
|
||||
#extern_host_function_impls
|
||||
}
|
||||
|
||||
#exchangeable_host_functions
|
||||
|
||||
#host_functions_struct
|
||||
#extern_host_function_impls
|
||||
}
|
||||
)
|
||||
|
||||
#exchangeable_host_functions
|
||||
|
||||
#host_functions_struct
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate the extern host function for the given method.
|
||||
fn generate_extern_host_function(method: &TraitItemMethod, version: u32, trait_name: &Ident) -> Result<TokenStream> {
|
||||
fn generate_extern_host_function(
|
||||
method: &TraitItemMethod,
|
||||
version: u32,
|
||||
trait_name: &Ident,
|
||||
) -> Result<TokenStream> {
|
||||
let crate_ = generate_crate_access();
|
||||
let args = get_function_arguments(&method.sig);
|
||||
let arg_types = get_function_argument_types_without_ref(&method.sig);
|
||||
@@ -106,33 +109,31 @@ fn generate_extern_host_function(method: &TraitItemMethod, version: u32, trait_n
|
||||
ReturnType::Default => quote!(),
|
||||
ReturnType::Type(_, ref ty) => quote! {
|
||||
<#ty as #crate_::wasm::FromFFIValue>::from_ffi_value(result)
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
#[doc = #doc_string]
|
||||
pub fn #function ( #( #args ),* ) #return_value {
|
||||
extern "C" {
|
||||
/// The extern function.
|
||||
pub fn #ext_function (
|
||||
#( #arg_names: <#arg_types as #crate_::RIType>::FFIType ),*
|
||||
) #ffi_return_value;
|
||||
}
|
||||
|
||||
// Generate all wrapped ffi values.
|
||||
#(
|
||||
let #arg_names2 = <#arg_types2 as #crate_::wasm::IntoFFIValue>::into_ffi_value(
|
||||
&#arg_names2,
|
||||
);
|
||||
)*
|
||||
|
||||
let result = unsafe { #ext_function( #( #arg_names3.get() ),* ) };
|
||||
|
||||
#convert_return_value
|
||||
Ok(quote! {
|
||||
#[doc = #doc_string]
|
||||
pub fn #function ( #( #args ),* ) #return_value {
|
||||
extern "C" {
|
||||
/// The extern function.
|
||||
pub fn #ext_function (
|
||||
#( #arg_names: <#arg_types as #crate_::RIType>::FFIType ),*
|
||||
) #ffi_return_value;
|
||||
}
|
||||
|
||||
// Generate all wrapped ffi values.
|
||||
#(
|
||||
let #arg_names2 = <#arg_types2 as #crate_::wasm::IntoFFIValue>::into_ffi_value(
|
||||
&#arg_names2,
|
||||
);
|
||||
)*
|
||||
|
||||
let result = unsafe { #ext_function( #( #arg_names3.get() ),* ) };
|
||||
|
||||
#convert_return_value
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate the host exchangeable function for the given method.
|
||||
@@ -144,44 +145,43 @@ fn generate_exchangeable_host_function(method: &TraitItemMethod) -> Result<Token
|
||||
let doc_string = format!(" Exchangeable host function used by [`{}`].", method.sig.ident);
|
||||
let output = &method.sig.output;
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
#[cfg(not(feature = "std"))]
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[doc = #doc_string]
|
||||
pub static #exchangeable_function : #crate_::wasm::ExchangeableFunction<
|
||||
fn ( #( #arg_types ),* ) #output
|
||||
> = #crate_::wasm::ExchangeableFunction::new(extern_host_function_impls::#function);
|
||||
}
|
||||
)
|
||||
Ok(quote! {
|
||||
#[cfg(not(feature = "std"))]
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[doc = #doc_string]
|
||||
pub static #exchangeable_function : #crate_::wasm::ExchangeableFunction<
|
||||
fn ( #( #arg_types ),* ) #output
|
||||
> = #crate_::wasm::ExchangeableFunction::new(extern_host_function_impls::#function);
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate the `HostFunctions` struct that implements `wasm-interface::HostFunctions` to provide
|
||||
/// implementations for the extern host functions.
|
||||
fn generate_host_functions_struct(trait_def: &ItemTrait, is_wasm_only: bool) -> Result<TokenStream> {
|
||||
fn generate_host_functions_struct(
|
||||
trait_def: &ItemTrait,
|
||||
is_wasm_only: bool,
|
||||
) -> Result<TokenStream> {
|
||||
let crate_ = generate_crate_access();
|
||||
|
||||
let host_functions = get_runtime_interface(trait_def)?
|
||||
.all_versions()
|
||||
.map(|(version, method)|
|
||||
.map(|(version, method)| {
|
||||
generate_host_function_implementation(&trait_def.ident, method, version, is_wasm_only)
|
||||
)
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
/// Provides implementations for the extern host functions.
|
||||
#[cfg(feature = "std")]
|
||||
pub struct HostFunctions;
|
||||
Ok(quote! {
|
||||
/// Provides implementations for the extern host functions.
|
||||
#[cfg(feature = "std")]
|
||||
pub struct HostFunctions;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl #crate_::sp_wasm_interface::HostFunctions for HostFunctions {
|
||||
fn host_functions() -> Vec<&'static dyn #crate_::sp_wasm_interface::Function> {
|
||||
vec![ #( #host_functions ),* ]
|
||||
}
|
||||
#[cfg(feature = "std")]
|
||||
impl #crate_::sp_wasm_interface::HostFunctions for HostFunctions {
|
||||
fn host_functions() -> Vec<&'static dyn #crate_::sp_wasm_interface::Function> {
|
||||
vec![ #( #host_functions ),* ]
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Generates the host function struct that implements `wasm_interface::Function` and returns a static
|
||||
@@ -199,71 +199,65 @@ fn generate_host_function_implementation(
|
||||
let struct_name = Ident::new(&name.to_pascal_case(), Span::call_site());
|
||||
let crate_ = generate_crate_access();
|
||||
let signature = generate_wasm_interface_signature_for_host_function(&method.sig)?;
|
||||
let wasm_to_ffi_values = generate_wasm_to_ffi_values(
|
||||
&method.sig,
|
||||
trait_name,
|
||||
).collect::<Result<Vec<_>>>()?;
|
||||
let wasm_to_ffi_values =
|
||||
generate_wasm_to_ffi_values(&method.sig, trait_name).collect::<Result<Vec<_>>>()?;
|
||||
let ffi_to_host_values = generate_ffi_to_host_value(&method.sig).collect::<Result<Vec<_>>>()?;
|
||||
let host_function_call = generate_host_function_call(&method.sig, version, is_wasm_only);
|
||||
let into_preallocated_ffi_value = generate_into_preallocated_ffi_value(&method.sig)?;
|
||||
let convert_return_value = generate_return_value_into_wasm_value(&method.sig);
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
{
|
||||
struct #struct_name;
|
||||
Ok(quote! {
|
||||
{
|
||||
struct #struct_name;
|
||||
|
||||
impl #crate_::sp_wasm_interface::Function for #struct_name {
|
||||
fn name(&self) -> &str {
|
||||
#name
|
||||
}
|
||||
|
||||
fn signature(&self) -> #crate_::sp_wasm_interface::Signature {
|
||||
#signature
|
||||
}
|
||||
|
||||
fn execute(
|
||||
&self,
|
||||
__function_context__: &mut dyn #crate_::sp_wasm_interface::FunctionContext,
|
||||
args: &mut dyn Iterator<Item = #crate_::sp_wasm_interface::Value>,
|
||||
) -> std::result::Result<Option<#crate_::sp_wasm_interface::Value>, String> {
|
||||
#( #wasm_to_ffi_values )*
|
||||
#( #ffi_to_host_values )*
|
||||
#host_function_call
|
||||
#into_preallocated_ffi_value
|
||||
#convert_return_value
|
||||
}
|
||||
impl #crate_::sp_wasm_interface::Function for #struct_name {
|
||||
fn name(&self) -> &str {
|
||||
#name
|
||||
}
|
||||
|
||||
&#struct_name as &dyn #crate_::sp_wasm_interface::Function
|
||||
fn signature(&self) -> #crate_::sp_wasm_interface::Signature {
|
||||
#signature
|
||||
}
|
||||
|
||||
fn execute(
|
||||
&self,
|
||||
__function_context__: &mut dyn #crate_::sp_wasm_interface::FunctionContext,
|
||||
args: &mut dyn Iterator<Item = #crate_::sp_wasm_interface::Value>,
|
||||
) -> std::result::Result<Option<#crate_::sp_wasm_interface::Value>, String> {
|
||||
#( #wasm_to_ffi_values )*
|
||||
#( #ffi_to_host_values )*
|
||||
#host_function_call
|
||||
#into_preallocated_ffi_value
|
||||
#convert_return_value
|
||||
}
|
||||
}
|
||||
|
||||
&#struct_name as &dyn #crate_::sp_wasm_interface::Function
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate the `wasm_interface::Signature` for the given host function `sig`.
|
||||
fn generate_wasm_interface_signature_for_host_function(sig: &Signature) -> Result<TokenStream> {
|
||||
let crate_ = generate_crate_access();
|
||||
let return_value = match &sig.output {
|
||||
ReturnType::Type(_, ty) =>
|
||||
quote! {
|
||||
Some( <<#ty as #crate_::RIType>::FFIType as #crate_::sp_wasm_interface::IntoValue>::VALUE_TYPE )
|
||||
},
|
||||
ReturnType::Default => quote!( None ),
|
||||
ReturnType::Type(_, ty) => quote! {
|
||||
Some( <<#ty as #crate_::RIType>::FFIType as #crate_::sp_wasm_interface::IntoValue>::VALUE_TYPE )
|
||||
},
|
||||
ReturnType::Default => quote!(None),
|
||||
};
|
||||
let arg_types = get_function_argument_types_without_ref(sig)
|
||||
.map(|ty| quote! {
|
||||
<<#ty as #crate_::RIType>::FFIType as #crate_::sp_wasm_interface::IntoValue>::VALUE_TYPE
|
||||
});
|
||||
|
||||
Ok(
|
||||
let arg_types = get_function_argument_types_without_ref(sig).map(|ty| {
|
||||
quote! {
|
||||
#crate_::sp_wasm_interface::Signature {
|
||||
args: std::borrow::Cow::Borrowed(&[ #( #arg_types ),* ][..]),
|
||||
return_value: #return_value,
|
||||
}
|
||||
<<#ty as #crate_::RIType>::FFIType as #crate_::sp_wasm_interface::IntoValue>::VALUE_TYPE
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
Ok(quote! {
|
||||
#crate_::sp_wasm_interface::Signature {
|
||||
args: std::borrow::Cow::Borrowed(&[ #( #arg_types ),* ][..]),
|
||||
return_value: #return_value,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate the code that converts the wasm values given to `HostFunctions::execute` into the FFI
|
||||
@@ -279,24 +273,23 @@ fn generate_wasm_to_ffi_values<'a>(
|
||||
function_name,
|
||||
);
|
||||
|
||||
get_function_argument_names_and_types_without_ref(sig)
|
||||
.map(move |(name, ty)| {
|
||||
let try_from_error = format!(
|
||||
"Could not instantiate `{}` from wasm value while executing `{}` from interface `{}`!",
|
||||
name.to_token_stream(),
|
||||
function_name,
|
||||
trait_name,
|
||||
);
|
||||
get_function_argument_names_and_types_without_ref(sig).map(move |(name, ty)| {
|
||||
let try_from_error = format!(
|
||||
"Could not instantiate `{}` from wasm value while executing `{}` from interface `{}`!",
|
||||
name.to_token_stream(),
|
||||
function_name,
|
||||
trait_name,
|
||||
);
|
||||
|
||||
let var_name = generate_ffi_value_var_name(&name)?;
|
||||
let var_name = generate_ffi_value_var_name(&name)?;
|
||||
|
||||
Ok(quote! {
|
||||
let val = args.next().ok_or_else(|| #error_message)?;
|
||||
let #var_name = <
|
||||
<#ty as #crate_::RIType>::FFIType as #crate_::sp_wasm_interface::TryFromValue
|
||||
>::try_from_value(val).ok_or_else(|| #try_from_error)?;
|
||||
})
|
||||
Ok(quote! {
|
||||
let val = args.next().ok_or_else(|| #error_message)?;
|
||||
let #var_name = <
|
||||
<#ty as #crate_::RIType>::FFIType as #crate_::sp_wasm_interface::TryFromValue
|
||||
>::try_from_value(val).ok_or_else(|| #try_from_error)?;
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate the code to convert the ffi values on the host to the host values using `FromFFIValue`.
|
||||
@@ -311,14 +304,12 @@ fn generate_ffi_to_host_value<'a>(
|
||||
.map(move |((name, ty), mut_access)| {
|
||||
let ffi_value_var_name = generate_ffi_value_var_name(&name)?;
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
let #mut_access #name = <#ty as #crate_::host::FromFFIValue>::from_ffi_value(
|
||||
__function_context__,
|
||||
#ffi_value_var_name,
|
||||
)?;
|
||||
}
|
||||
)
|
||||
Ok(quote! {
|
||||
let #mut_access #name = <#ty as #crate_::host::FromFFIValue>::from_ffi_value(
|
||||
__function_context__,
|
||||
#ffi_value_var_name,
|
||||
)?;
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -326,19 +317,17 @@ fn generate_ffi_to_host_value<'a>(
|
||||
fn generate_host_function_call(sig: &Signature, version: u32, is_wasm_only: bool) -> TokenStream {
|
||||
let host_function_name = create_function_ident_with_version(&sig.ident, version);
|
||||
let result_var_name = generate_host_function_result_var_name(&sig.ident);
|
||||
let ref_and_mut = get_function_argument_types_ref_and_mut(sig).map(|ram|
|
||||
ram.map(|(vr, vm)| quote!(#vr #vm))
|
||||
);
|
||||
let ref_and_mut =
|
||||
get_function_argument_types_ref_and_mut(sig).map(|ram| ram.map(|(vr, vm)| quote!(#vr #vm)));
|
||||
let names = get_function_argument_names(sig);
|
||||
|
||||
let var_access = names.zip(ref_and_mut)
|
||||
.map(|(n, ref_and_mut)| {
|
||||
quote!( #ref_and_mut #n )
|
||||
})
|
||||
let var_access = names
|
||||
.zip(ref_and_mut)
|
||||
.map(|(n, ref_and_mut)| quote!( #ref_and_mut #n ))
|
||||
// If this is a wasm only interface, we add the function context as last parameter.
|
||||
.chain(
|
||||
iter::from_fn(|| if is_wasm_only { Some(quote!(__function_context__)) } else { None })
|
||||
.take(1)
|
||||
.take(1),
|
||||
);
|
||||
|
||||
quote! {
|
||||
@@ -354,16 +343,15 @@ fn generate_host_function_result_var_name(name: &Ident) -> Ident {
|
||||
/// Generate the variable name that stores the FFI value.
|
||||
fn generate_ffi_value_var_name(pat: &Pat) -> Result<Ident> {
|
||||
match pat {
|
||||
Pat::Ident(pat_ident) => {
|
||||
Pat::Ident(pat_ident) =>
|
||||
if let Some(by_ref) = pat_ident.by_ref {
|
||||
Err(Error::new(by_ref.span(), "`ref` not supported!"))
|
||||
} else if let Some(sub_pattern) = &pat_ident.subpat {
|
||||
Err(Error::new(sub_pattern.0.span(), "Not supported!"))
|
||||
} else {
|
||||
Ok(Ident::new(&format!("{}_ffi_value", pat_ident.ident), Span::call_site()))
|
||||
}
|
||||
}
|
||||
_ => Err(Error::new(pat.span(), "Not supported as variable name!"))
|
||||
},
|
||||
_ => Err(Error::new(pat.span(), "Not supported as variable name!")),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,25 +361,23 @@ fn generate_ffi_value_var_name(pat: &Pat) -> Result<Ident> {
|
||||
/// that the type implements `IntoPreAllocatedFFIValue`.
|
||||
fn generate_into_preallocated_ffi_value(sig: &Signature) -> Result<TokenStream> {
|
||||
let crate_ = generate_crate_access();
|
||||
let ref_and_mut = get_function_argument_types_ref_and_mut(sig).map(|ram|
|
||||
ram.and_then(|(vr, vm)| vm.map(|v| (vr, v)))
|
||||
);
|
||||
let ref_and_mut = get_function_argument_types_ref_and_mut(sig)
|
||||
.map(|ram| ram.and_then(|(vr, vm)| vm.map(|v| (vr, v))));
|
||||
let names_and_types = get_function_argument_names_and_types_without_ref(sig);
|
||||
|
||||
ref_and_mut.zip(names_and_types)
|
||||
ref_and_mut
|
||||
.zip(names_and_types)
|
||||
.filter_map(|(ram, (name, ty))| ram.map(|_| (name, ty)))
|
||||
.map(|(name, ty)| {
|
||||
let ffi_var_name = generate_ffi_value_var_name(&name)?;
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
<#ty as #crate_::host::IntoPreallocatedFFIValue>::into_preallocated_ffi_value(
|
||||
#name,
|
||||
__function_context__,
|
||||
#ffi_var_name,
|
||||
)?;
|
||||
}
|
||||
)
|
||||
Ok(quote! {
|
||||
<#ty as #crate_::host::IntoPreallocatedFFIValue>::into_preallocated_ffi_value(
|
||||
#name,
|
||||
__function_context__,
|
||||
#ffi_var_name,
|
||||
)?;
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
@@ -401,7 +387,7 @@ fn generate_return_value_into_wasm_value(sig: &Signature) -> TokenStream {
|
||||
let crate_ = generate_crate_access();
|
||||
|
||||
match &sig.output {
|
||||
ReturnType::Default => quote!( Ok(None) ),
|
||||
ReturnType::Default => quote!(Ok(None)),
|
||||
ReturnType::Type(_, ty) => {
|
||||
let result_var_name = generate_host_function_result_var_name(&sig.ident);
|
||||
|
||||
@@ -411,6 +397,6 @@ fn generate_return_value_into_wasm_value(sig: &Signature) -> TokenStream {
|
||||
__function_context__,
|
||||
).map(#crate_::sp_wasm_interface::IntoValue::into_value).map(Some)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
+27
-36
@@ -19,15 +19,14 @@
|
||||
//! default implementations and implements the trait for `&mut dyn Externalities`.
|
||||
|
||||
use crate::utils::{
|
||||
generate_crate_access,
|
||||
get_function_argument_types_without_ref,
|
||||
get_runtime_interface,
|
||||
create_function_ident_with_version,
|
||||
create_function_ident_with_version, generate_crate_access,
|
||||
get_function_argument_types_without_ref, get_runtime_interface,
|
||||
};
|
||||
|
||||
use syn::{
|
||||
ItemTrait, TraitItemMethod, Result, Error, fold::{self, Fold}, spanned::Spanned,
|
||||
Visibility, Receiver, Type, Generics,
|
||||
fold::{self, Fold},
|
||||
spanned::Spanned,
|
||||
Error, Generics, ItemTrait, Receiver, Result, TraitItemMethod, Type, Visibility,
|
||||
};
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
@@ -40,13 +39,11 @@ pub fn process(trait_def: &ItemTrait, is_wasm_only: bool) -> Result<TokenStream>
|
||||
let impl_trait = impl_trait_for_externalities(trait_def, is_wasm_only)?;
|
||||
let essential_trait_def = declare_essential_trait(trait_def)?;
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
#impl_trait
|
||||
Ok(quote! {
|
||||
#impl_trait
|
||||
|
||||
#essential_trait_def
|
||||
}
|
||||
)
|
||||
#essential_trait_def
|
||||
})
|
||||
}
|
||||
|
||||
/// Converts the given trait definition into the essential trait definition without method
|
||||
@@ -66,12 +63,10 @@ impl ToEssentialTraitDef {
|
||||
let mut errors = self.errors;
|
||||
let methods = self.methods;
|
||||
if let Some(first_error) = errors.pop() {
|
||||
Err(
|
||||
errors.into_iter().fold(first_error, |mut o, n| {
|
||||
o.combine(n);
|
||||
o
|
||||
})
|
||||
)
|
||||
Err(errors.into_iter().fold(first_error, |mut o, n| {
|
||||
o.combine(n);
|
||||
o
|
||||
}))
|
||||
} else {
|
||||
Ok(methods)
|
||||
}
|
||||
@@ -101,12 +96,12 @@ impl Fold for ToEssentialTraitDef {
|
||||
}
|
||||
|
||||
let arg_types = get_function_argument_types_without_ref(&method.sig);
|
||||
arg_types.filter_map(|ty|
|
||||
match *ty {
|
||||
arg_types
|
||||
.filter_map(|ty| match *ty {
|
||||
Type::ImplTrait(impl_trait) => Some(impl_trait),
|
||||
_ => None
|
||||
}
|
||||
).for_each(|invalid| self.push_error(&invalid, "`impl Trait` syntax not supported."));
|
||||
_ => None,
|
||||
})
|
||||
.for_each(|invalid| self.push_error(&invalid, "`impl Trait` syntax not supported."));
|
||||
|
||||
self.error_on_generic_parameters(&method.sig.generics);
|
||||
|
||||
@@ -145,13 +140,11 @@ fn declare_essential_trait(trait_def: &ItemTrait) -> Result<TokenStream> {
|
||||
}
|
||||
let methods = folder.into_methods()?;
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
trait #trait_ {
|
||||
#( #methods )*
|
||||
}
|
||||
Ok(quote! {
|
||||
trait #trait_ {
|
||||
#( #methods )*
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Implements the given trait definition for `dyn Externalities`.
|
||||
@@ -172,12 +165,10 @@ fn impl_trait_for_externalities(trait_def: &ItemTrait, is_wasm_only: bool) -> Re
|
||||
quote!( &mut dyn #crate_::Externalities )
|
||||
};
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
#[cfg(feature = "std")]
|
||||
impl #trait_ for #impl_type {
|
||||
#( #methods )*
|
||||
}
|
||||
Ok(quote! {
|
||||
#[cfg(feature = "std")]
|
||||
impl #trait_ for #impl_type {
|
||||
#( #methods )*
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -17,16 +17,19 @@
|
||||
|
||||
//! Util function used by this crate.
|
||||
|
||||
use proc_macro2::{TokenStream, Span};
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
|
||||
use syn::{
|
||||
Ident, Error, Signature, Pat, PatType, FnArg, Type, token, TraitItemMethod, ItemTrait,
|
||||
TraitItem, parse_quote, spanned::Spanned, Result, Meta, NestedMeta, Lit, Attribute,
|
||||
parse_quote, spanned::Spanned, token, Attribute, Error, FnArg, Ident, ItemTrait, Lit, Meta,
|
||||
NestedMeta, Pat, PatType, Result, Signature, TraitItem, TraitItemMethod, Type,
|
||||
};
|
||||
|
||||
use proc_macro_crate::{crate_name, FoundCrate};
|
||||
|
||||
use std::{env, collections::{BTreeMap, btree_map::Entry}};
|
||||
use std::{
|
||||
collections::{btree_map::Entry, BTreeMap},
|
||||
env,
|
||||
};
|
||||
|
||||
use quote::quote;
|
||||
|
||||
@@ -53,8 +56,9 @@ impl<'a> RuntimeInterfaceFunction<'a> {
|
||||
pub fn latest_version(&self) -> (u32, &TraitItemMethod) {
|
||||
(
|
||||
self.latest_version,
|
||||
self.versions.get(&self.latest_version)
|
||||
.expect("If latest_version has a value, the key with this value is in the versions; qed")
|
||||
self.versions.get(&self.latest_version).expect(
|
||||
"If latest_version has a value, the key with this value is in the versions; qed",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -70,9 +74,12 @@ impl<'a> RuntimeInterface<'a> {
|
||||
}
|
||||
|
||||
pub fn all_versions(&self) -> impl Iterator<Item = (u32, &TraitItemMethod)> {
|
||||
self.items.iter().flat_map(|(_, item)| item.versions.iter()).map(|(v, i)| (*v, *i))
|
||||
self.items
|
||||
.iter()
|
||||
.flat_map(|(_, item)| item.versions.iter())
|
||||
.map(|(v, i)| (*v, *i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates the include for the runtime-interface crate.
|
||||
pub fn generate_runtime_interface_include() -> TokenStream {
|
||||
@@ -88,16 +95,16 @@ pub fn generate_runtime_interface_include() -> TokenStream {
|
||||
Err(e) => {
|
||||
let err = Error::new(Span::call_site(), e).to_compile_error();
|
||||
quote!( #err )
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates the access to the `sp-runtime-interface` crate.
|
||||
pub fn generate_crate_access() -> TokenStream {
|
||||
if env::var("CARGO_PKG_NAME").unwrap() == "sp-runtime-interface" {
|
||||
quote!( sp_runtime_interface )
|
||||
quote!(sp_runtime_interface)
|
||||
} else {
|
||||
quote!( proc_macro_runtime_interface )
|
||||
quote!(proc_macro_runtime_interface)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,26 +116,14 @@ pub fn create_exchangeable_host_function_ident(name: &Ident) -> Ident {
|
||||
/// Create the host function identifier for the given function name.
|
||||
pub fn create_host_function_ident(name: &Ident, version: u32, trait_name: &Ident) -> Ident {
|
||||
Ident::new(
|
||||
&format!(
|
||||
"ext_{}_{}_version_{}",
|
||||
trait_name.to_string().to_snake_case(),
|
||||
name,
|
||||
version,
|
||||
),
|
||||
&format!("ext_{}_{}_version_{}", trait_name.to_string().to_snake_case(), name, version,),
|
||||
Span::call_site(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Create the host function identifier for the given function name.
|
||||
pub fn create_function_ident_with_version(name: &Ident, version: u32) -> Ident {
|
||||
Ident::new(
|
||||
&format!(
|
||||
"{}_version_{}",
|
||||
name,
|
||||
version,
|
||||
),
|
||||
Span::call_site(),
|
||||
)
|
||||
Ident::new(&format!("{}_version_{}", name, version,), Span::call_site())
|
||||
}
|
||||
|
||||
/// Returns the function arguments of the given `Signature`, minus any `self` arguments.
|
||||
@@ -143,10 +138,8 @@ pub fn get_function_arguments<'a>(sig: &'a Signature) -> impl Iterator<Item = Pa
|
||||
.map(|(i, arg)| {
|
||||
let mut res = arg.clone();
|
||||
if let Pat::Wild(wild) = &*arg.pat {
|
||||
let ident = Ident::new(
|
||||
&format!("__runtime_interface_generated_{}_", i),
|
||||
wild.span(),
|
||||
);
|
||||
let ident =
|
||||
Ident::new(&format!("__runtime_interface_generated_{}_", i), wild.span());
|
||||
|
||||
res.pat = Box::new(parse_quote!( #ident ))
|
||||
}
|
||||
@@ -170,12 +163,10 @@ pub fn get_function_argument_types<'a>(sig: &'a Signature) -> impl Iterator<Item
|
||||
pub fn get_function_argument_types_without_ref<'a>(
|
||||
sig: &'a Signature,
|
||||
) -> impl Iterator<Item = Box<Type>> + 'a {
|
||||
get_function_arguments(sig)
|
||||
.map(|pt| pt.ty)
|
||||
.map(|ty| match *ty {
|
||||
Type::Reference(type_ref) => type_ref.elem,
|
||||
_ => ty,
|
||||
})
|
||||
get_function_arguments(sig).map(|pt| pt.ty).map(|ty| match *ty {
|
||||
Type::Reference(type_ref) => type_ref.elem,
|
||||
_ => ty,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the function argument names and types, minus any `self`. If any of the arguments
|
||||
@@ -183,11 +174,10 @@ pub fn get_function_argument_types_without_ref<'a>(
|
||||
pub fn get_function_argument_names_and_types_without_ref<'a>(
|
||||
sig: &'a Signature,
|
||||
) -> impl Iterator<Item = (Box<Pat>, Box<Type>)> + 'a {
|
||||
get_function_arguments(sig)
|
||||
.map(|pt| match *pt.ty {
|
||||
Type::Reference(type_ref) => (pt.pat, type_ref.elem),
|
||||
_ => (pt.pat, pt.ty),
|
||||
})
|
||||
get_function_arguments(sig).map(|pt| match *pt.ty {
|
||||
Type::Reference(type_ref) => (pt.pat, type_ref.elem),
|
||||
_ => (pt.pat, pt.ty),
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the `&`/`&mut` for all function argument types, minus the `self` arg. If a function
|
||||
@@ -195,23 +185,18 @@ pub fn get_function_argument_names_and_types_without_ref<'a>(
|
||||
pub fn get_function_argument_types_ref_and_mut<'a>(
|
||||
sig: &'a Signature,
|
||||
) -> impl Iterator<Item = Option<(token::And, Option<token::Mut>)>> + 'a {
|
||||
get_function_arguments(sig)
|
||||
.map(|pt| pt.ty)
|
||||
.map(|ty| match *ty {
|
||||
Type::Reference(type_ref) => Some((type_ref.and_token, type_ref.mutability)),
|
||||
_ => None,
|
||||
})
|
||||
get_function_arguments(sig).map(|pt| pt.ty).map(|ty| match *ty {
|
||||
Type::Reference(type_ref) => Some((type_ref.and_token, type_ref.mutability)),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns an iterator over all trait methods for the given trait definition.
|
||||
fn get_trait_methods<'a>(trait_def: &'a ItemTrait) -> impl Iterator<Item = &'a TraitItemMethod> {
|
||||
trait_def
|
||||
.items
|
||||
.iter()
|
||||
.filter_map(|i| match i {
|
||||
TraitItem::Method(ref method) => Some(method),
|
||||
_ => None,
|
||||
})
|
||||
trait_def.items.iter().filter_map(|i| match i {
|
||||
TraitItem::Method(ref method) => Some(method),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse version attribute.
|
||||
@@ -221,36 +206,34 @@ fn parse_version_attribute(version: &Attribute) -> Result<u32> {
|
||||
let meta = version.parse_meta()?;
|
||||
|
||||
let err = Err(Error::new(
|
||||
meta.span(),
|
||||
"Unexpected `version` attribute. The supported format is `#[version(1)]`",
|
||||
)
|
||||
);
|
||||
meta.span(),
|
||||
"Unexpected `version` attribute. The supported format is `#[version(1)]`",
|
||||
));
|
||||
|
||||
match meta {
|
||||
Meta::List(list) => {
|
||||
Meta::List(list) =>
|
||||
if list.nested.len() != 1 {
|
||||
err
|
||||
} else if let Some(NestedMeta::Lit(Lit::Int(i))) = list.nested.first() {
|
||||
i.base10_parse()
|
||||
} else {
|
||||
err
|
||||
}
|
||||
},
|
||||
},
|
||||
_ => err,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return item version (`#[version(X)]`) attribute, if present.
|
||||
fn get_item_version(item: &TraitItemMethod) -> Result<Option<u32>> {
|
||||
item.attrs.iter().find(|attr| attr.path.is_ident("version"))
|
||||
item.attrs
|
||||
.iter()
|
||||
.find(|attr| attr.path.is_ident("version"))
|
||||
.map(|attr| parse_version_attribute(attr))
|
||||
.transpose()
|
||||
}
|
||||
|
||||
/// Returns all runtime interface members, with versions.
|
||||
pub fn get_runtime_interface<'a>(trait_def: &'a ItemTrait)
|
||||
-> Result<RuntimeInterface<'a>>
|
||||
{
|
||||
pub fn get_runtime_interface<'a>(trait_def: &'a ItemTrait) -> Result<RuntimeInterface<'a>> {
|
||||
let mut functions: BTreeMap<syn::Ident, RuntimeInterfaceFunction<'a>> = BTreeMap::new();
|
||||
|
||||
for item in get_trait_methods(trait_def) {
|
||||
@@ -258,25 +241,26 @@ pub fn get_runtime_interface<'a>(trait_def: &'a ItemTrait)
|
||||
let version = get_item_version(item)?.unwrap_or(1);
|
||||
|
||||
match functions.entry(name.clone()) {
|
||||
Entry::Vacant(entry) => { entry.insert(RuntimeInterfaceFunction::new(version, item)); },
|
||||
Entry::Vacant(entry) => {
|
||||
entry.insert(RuntimeInterfaceFunction::new(version, item));
|
||||
},
|
||||
Entry::Occupied(mut entry) => {
|
||||
if let Some(existing_item) = entry.get().versions.get(&version) {
|
||||
let mut err = Error::new(
|
||||
item.span(),
|
||||
"Duplicated version attribute",
|
||||
);
|
||||
let mut err = Error::new(item.span(), "Duplicated version attribute");
|
||||
err.combine(Error::new(
|
||||
existing_item.span(),
|
||||
"Previous version with the same number defined here",
|
||||
));
|
||||
|
||||
return Err(err);
|
||||
return Err(err)
|
||||
}
|
||||
|
||||
let interface_item = entry.get_mut();
|
||||
if interface_item.latest_version < version { interface_item.latest_version = version; }
|
||||
if interface_item.latest_version < version {
|
||||
interface_item.latest_version = version;
|
||||
}
|
||||
interface_item.versions.insert(version, item);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,8 +270,11 @@ pub fn get_runtime_interface<'a>(trait_def: &'a ItemTrait)
|
||||
if next_expected != *version {
|
||||
return Err(Error::new(
|
||||
item.span(),
|
||||
format!("Unexpected version attribute: missing version '{}' for this function", next_expected),
|
||||
));
|
||||
format!(
|
||||
"Unexpected version attribute: missing version '{}' for this function",
|
||||
next_expected
|
||||
),
|
||||
))
|
||||
}
|
||||
next_expected += 1;
|
||||
}
|
||||
|
||||
@@ -17,14 +17,15 @@
|
||||
|
||||
//! Provides implementations for the runtime interface traits.
|
||||
|
||||
use crate::{
|
||||
RIType, Pointer, pass_by::{PassBy, Codec, Inner, PassByInner, Enum},
|
||||
util::{unpack_ptr_and_len, pack_ptr_and_len},
|
||||
};
|
||||
#[cfg(feature = "std")]
|
||||
use crate::host::*;
|
||||
#[cfg(not(feature = "std"))]
|
||||
use crate::wasm::*;
|
||||
use crate::{
|
||||
pass_by::{Codec, Enum, Inner, PassBy, PassByInner},
|
||||
util::{pack_ptr_and_len, unpack_ptr_and_len},
|
||||
Pointer, RIType,
|
||||
};
|
||||
|
||||
#[cfg(all(not(feature = "std"), not(feature = "disable_target_static_assertions")))]
|
||||
use static_assertions::assert_eq_size;
|
||||
@@ -32,7 +33,7 @@ use static_assertions::assert_eq_size;
|
||||
#[cfg(feature = "std")]
|
||||
use sp_wasm_interface::{FunctionContext, Result};
|
||||
|
||||
use codec::{Encode, Decode};
|
||||
use codec::{Decode, Encode};
|
||||
|
||||
use sp_std::{any::TypeId, mem, vec::Vec};
|
||||
|
||||
@@ -195,7 +196,7 @@ impl<T: 'static + Decode> FromFFIValue for Vec<T> {
|
||||
let len = len as usize;
|
||||
|
||||
if len == 0 {
|
||||
return Vec::new();
|
||||
return Vec::new()
|
||||
}
|
||||
|
||||
let data = unsafe { Vec::from_raw_parts(ptr as *mut u8, len, len) };
|
||||
@@ -230,7 +231,8 @@ impl<T: 'static + Decode> FromFFIValue for [T] {
|
||||
if TypeId::of::<T>() == TypeId::of::<u8>() {
|
||||
Ok(unsafe { mem::transmute(vec) })
|
||||
} else {
|
||||
Ok(Vec::<T>::decode(&mut &vec[..]).expect("Wasm to host values are encoded correctly; qed"))
|
||||
Ok(Vec::<T>::decode(&mut &vec[..])
|
||||
.expect("Wasm to host values are encoded correctly; qed"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -247,13 +249,11 @@ impl IntoPreallocatedFFIValue for [u8] {
|
||||
let (ptr, len) = unpack_ptr_and_len(allocated);
|
||||
|
||||
if (len as usize) < self_instance.len() {
|
||||
Err(
|
||||
format!(
|
||||
"Preallocated buffer is not big enough (given {} vs needed {})!",
|
||||
len,
|
||||
self_instance.len()
|
||||
)
|
||||
)
|
||||
Err(format!(
|
||||
"Preallocated buffer is not big enough (given {} vs needed {})!",
|
||||
len,
|
||||
self_instance.len()
|
||||
))
|
||||
} else {
|
||||
context.write_memory(Pointer::new(ptr), &self_instance)
|
||||
}
|
||||
@@ -367,7 +367,10 @@ impl<T: codec::Codec> PassBy for Option<T> {
|
||||
|
||||
#[impl_trait_for_tuples::impl_for_tuples(30)]
|
||||
#[tuple_types_no_default_trait_bound]
|
||||
impl PassBy for Tuple where Self: codec::Codec {
|
||||
impl PassBy for Tuple
|
||||
where
|
||||
Self: codec::Codec,
|
||||
{
|
||||
type PassBy = Codec<Self>;
|
||||
}
|
||||
|
||||
@@ -511,7 +514,8 @@ macro_rules! for_u128_i128 {
|
||||
type SelfInstance = $type;
|
||||
|
||||
fn from_ffi_value(context: &mut dyn FunctionContext, arg: u32) -> Result<$type> {
|
||||
let data = context.read_memory(Pointer::new(arg), mem::size_of::<$type>() as u32)?;
|
||||
let data =
|
||||
context.read_memory(Pointer::new(arg), mem::size_of::<$type>() as u32)?;
|
||||
let mut res = [0u8; mem::size_of::<$type>()];
|
||||
res.copy_from_slice(&data);
|
||||
Ok(<$type>::from_le_bytes(res))
|
||||
@@ -526,7 +530,7 @@ macro_rules! for_u128_i128 {
|
||||
Ok(addr.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
for_u128_i128!(u128);
|
||||
|
||||
@@ -292,28 +292,28 @@ pub use sp_std;
|
||||
/// the case when that would create a circular dependency. You usually _do not_ want to add this
|
||||
/// flag, as tracing doesn't cost you anything by default anyways (it is added as a no-op) but is
|
||||
/// super useful for debugging later.
|
||||
///
|
||||
pub use sp_runtime_interface_proc_macro::runtime_interface;
|
||||
|
||||
#[doc(hidden)]
|
||||
#[cfg(feature = "std")]
|
||||
pub use sp_externalities::{
|
||||
set_and_run_with_externalities, with_externalities, Externalities, ExternalitiesExt, ExtensionStore,
|
||||
set_and_run_with_externalities, with_externalities, ExtensionStore, Externalities,
|
||||
ExternalitiesExt,
|
||||
};
|
||||
|
||||
#[doc(hidden)]
|
||||
pub use codec;
|
||||
|
||||
pub(crate) mod impls;
|
||||
#[cfg(feature = "std")]
|
||||
pub mod host;
|
||||
pub(crate) mod impls;
|
||||
pub mod pass_by;
|
||||
#[cfg(any(not(feature = "std"), doc))]
|
||||
pub mod wasm;
|
||||
pub mod pass_by;
|
||||
|
||||
mod util;
|
||||
|
||||
pub use util::{unpack_ptr_and_len, pack_ptr_and_len};
|
||||
pub use util::{pack_ptr_and_len, unpack_ptr_and_len};
|
||||
|
||||
/// Something that can be used by the runtime interface as type to communicate between wasm and the
|
||||
/// host.
|
||||
|
||||
@@ -20,7 +20,10 @@
|
||||
//!
|
||||
//! [`Codec`], [`Inner`] and [`Enum`] are the provided strategy implementations.
|
||||
|
||||
use crate::{RIType, util::{unpack_ptr_and_len, pack_ptr_and_len}};
|
||||
use crate::{
|
||||
util::{pack_ptr_and_len, unpack_ptr_and_len},
|
||||
RIType,
|
||||
};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use crate::host::*;
|
||||
@@ -30,7 +33,7 @@ use crate::wasm::*;
|
||||
#[cfg(feature = "std")]
|
||||
use sp_wasm_interface::{FunctionContext, Pointer, Result};
|
||||
|
||||
use sp_std::{marker::PhantomData, convert::TryFrom};
|
||||
use sp_std::{convert::TryFrom, marker::PhantomData};
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
use sp_std::vec::Vec;
|
||||
@@ -119,18 +122,12 @@ pub trait PassByImpl<T>: RIType {
|
||||
/// Convert the given instance to the ffi value.
|
||||
///
|
||||
/// For more information see: [`crate::host::IntoFFIValue::into_ffi_value`]
|
||||
fn into_ffi_value(
|
||||
instance: T,
|
||||
context: &mut dyn FunctionContext,
|
||||
) -> Result<Self::FFIType>;
|
||||
fn into_ffi_value(instance: T, context: &mut dyn FunctionContext) -> Result<Self::FFIType>;
|
||||
|
||||
/// Create `T` from the given ffi value.
|
||||
///
|
||||
/// For more information see: [`crate::host::FromFFIValue::from_ffi_value`]
|
||||
fn from_ffi_value(
|
||||
context: &mut dyn FunctionContext,
|
||||
arg: Self::FFIType,
|
||||
) -> Result<T>;
|
||||
fn from_ffi_value(context: &mut dyn FunctionContext, arg: Self::FFIType) -> Result<T>;
|
||||
}
|
||||
|
||||
/// Something that provides a strategy for passing a type between wasm and the host.
|
||||
@@ -220,10 +217,7 @@ pub struct Codec<T: codec::Codec>(PhantomData<T>);
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<T: codec::Codec> PassByImpl<T> for Codec<T> {
|
||||
fn into_ffi_value(
|
||||
instance: T,
|
||||
context: &mut dyn FunctionContext,
|
||||
) -> Result<Self::FFIType> {
|
||||
fn into_ffi_value(instance: T, context: &mut dyn FunctionContext) -> Result<Self::FFIType> {
|
||||
let vec = instance.encode();
|
||||
let ptr = context.allocate_memory(vec.len() as u32)?;
|
||||
context.write_memory(ptr, &vec)?;
|
||||
@@ -231,14 +225,10 @@ impl<T: codec::Codec> PassByImpl<T> for Codec<T> {
|
||||
Ok(pack_ptr_and_len(ptr.into(), vec.len() as u32))
|
||||
}
|
||||
|
||||
fn from_ffi_value(
|
||||
context: &mut dyn FunctionContext,
|
||||
arg: Self::FFIType,
|
||||
) -> Result<T> {
|
||||
fn from_ffi_value(context: &mut dyn FunctionContext, arg: Self::FFIType) -> Result<T> {
|
||||
let (ptr, len) = unpack_ptr_and_len(arg);
|
||||
let vec = context.read_memory(Pointer::new(ptr), len)?;
|
||||
T::decode(&mut &vec[..])
|
||||
.map_err(|e| format!("Could not decode value from wasm: {}", e))
|
||||
T::decode(&mut &vec[..]).map_err(|e| format!("Could not decode value from wasm: {}", e))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,35 +320,31 @@ pub struct Inner<T: PassByInner<Inner = I>, I: RIType>(PhantomData<(T, I)>);
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<T: PassByInner<Inner = I>, I: RIType> PassByImpl<T> for Inner<T, I>
|
||||
where I: IntoFFIValue + FromFFIValue<SelfInstance=I>
|
||||
where
|
||||
I: IntoFFIValue + FromFFIValue<SelfInstance = I>,
|
||||
{
|
||||
fn into_ffi_value(
|
||||
instance: T,
|
||||
context: &mut dyn FunctionContext,
|
||||
) -> Result<Self::FFIType> {
|
||||
fn into_ffi_value(instance: T, context: &mut dyn FunctionContext) -> Result<Self::FFIType> {
|
||||
instance.into_inner().into_ffi_value(context)
|
||||
}
|
||||
|
||||
fn from_ffi_value(
|
||||
context: &mut dyn FunctionContext,
|
||||
arg: Self::FFIType,
|
||||
) -> Result<T> {
|
||||
fn from_ffi_value(context: &mut dyn FunctionContext, arg: Self::FFIType) -> Result<T> {
|
||||
I::from_ffi_value(context, arg).map(T::from_inner)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
impl<T: PassByInner<Inner = I>, I: RIType> PassByImpl<T> for Inner<T, I>
|
||||
where I: IntoFFIValue + FromFFIValue
|
||||
where
|
||||
I: IntoFFIValue + FromFFIValue,
|
||||
{
|
||||
type Owned = I::Owned;
|
||||
|
||||
fn into_ffi_value(instance: &T) -> WrappedFFIValue<Self::FFIType, Self::Owned> {
|
||||
instance.inner().into_ffi_value()
|
||||
instance.inner().into_ffi_value()
|
||||
}
|
||||
|
||||
fn from_ffi_value(arg: Self::FFIType) -> T {
|
||||
T::from_inner(I::from_ffi_value(arg))
|
||||
T::from_inner(I::from_ffi_value(arg))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,17 +401,11 @@ pub struct Enum<T: Copy + Into<u8> + TryFrom<u8>>(PhantomData<T>);
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<T: Copy + Into<u8> + TryFrom<u8>> PassByImpl<T> for Enum<T> {
|
||||
fn into_ffi_value(
|
||||
instance: T,
|
||||
_: &mut dyn FunctionContext,
|
||||
) -> Result<Self::FFIType> {
|
||||
fn into_ffi_value(instance: T, _: &mut dyn FunctionContext) -> Result<Self::FFIType> {
|
||||
Ok(instance.into())
|
||||
}
|
||||
|
||||
fn from_ffi_value(
|
||||
_: &mut dyn FunctionContext,
|
||||
arg: Self::FFIType,
|
||||
) -> Result<T> {
|
||||
fn from_ffi_value(_: &mut dyn FunctionContext, arg: Self::FFIType) -> Result<T> {
|
||||
T::try_from(arg).map_err(|_| format!("Invalid enum discriminant: {}", arg))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ impl<T: Copy> ExchangeableFunction<T> {
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns the original implementation wrapped in [`RestoreImplementation`].
|
||||
pub fn replace_implementation(&'static self, new_impl: T) -> RestoreImplementation<T> {
|
||||
pub fn replace_implementation(&'static self, new_impl: T) -> RestoreImplementation<T> {
|
||||
if let ExchangeableFunctionState::Replaced = self.0.get().1 {
|
||||
panic!("Trying to replace an already replaced implementation!")
|
||||
}
|
||||
@@ -139,6 +139,7 @@ pub struct RestoreImplementation<T: 'static + Copy>(&'static ExchangeableFunctio
|
||||
|
||||
impl<T: Copy> Drop for RestoreImplementation<T> {
|
||||
fn drop(&mut self) {
|
||||
self.0.restore_orig_implementation(self.1.take().expect("Value is only taken on drop; qed"));
|
||||
self.0
|
||||
.restore_orig_implementation(self.1.take().expect("Value is only taken on drop; qed"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,8 +29,10 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
|
||||
/// Wasm binary unwrapped. If built with `SKIP_WASM_BUILD`, the function panics.
|
||||
#[cfg(feature = "std")]
|
||||
pub fn wasm_binary_unwrap() -> &'static [u8] {
|
||||
WASM_BINARY.expect("Development wasm binary is not available. Testing is only \
|
||||
supported with the flag disabled.")
|
||||
WASM_BINARY.expect(
|
||||
"Development wasm binary is not available. Testing is only \
|
||||
supported with the flag disabled.",
|
||||
)
|
||||
}
|
||||
|
||||
/// This function is not used, but we require it for the compiler to include `sp-io`.
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
use sp_runtime_interface::runtime_interface;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
use sp_std::{prelude::*, mem, convert::TryFrom};
|
||||
use sp_std::{convert::TryFrom, mem, prelude::*};
|
||||
|
||||
use sp_core::{sr25519::Public, wasm_export_functions};
|
||||
|
||||
@@ -33,8 +33,10 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
|
||||
/// Wasm binary unwrapped. If built with `SKIP_WASM_BUILD`, the function panics.
|
||||
#[cfg(feature = "std")]
|
||||
pub fn wasm_binary_unwrap() -> &'static [u8] {
|
||||
WASM_BINARY.expect("Development wasm binary is not available. Testing is only \
|
||||
supported with the flag disabled.")
|
||||
WASM_BINARY.expect(
|
||||
"Development wasm binary is not available. Testing is only \
|
||||
supported with the flag disabled.",
|
||||
)
|
||||
}
|
||||
|
||||
/// Used in the `test_array_as_mutable_reference` test.
|
||||
|
||||
@@ -20,13 +20,16 @@
|
||||
|
||||
use sp_runtime_interface::*;
|
||||
|
||||
use sp_runtime_interface_test_wasm::{wasm_binary_unwrap, test_api::HostFunctions};
|
||||
use sp_runtime_interface_test_wasm::{test_api::HostFunctions, wasm_binary_unwrap};
|
||||
use sp_runtime_interface_test_wasm_deprecated::wasm_binary_unwrap as wasm_binary_deprecated_unwrap;
|
||||
|
||||
use sp_wasm_interface::HostFunctions as HostFunctionsT;
|
||||
use sc_executor_common::runtime_blob::RuntimeBlob;
|
||||
use sp_wasm_interface::HostFunctions as HostFunctionsT;
|
||||
|
||||
use std::{collections::HashSet, sync::{Arc, Mutex}};
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
type TestExternalities = sp_state_machine::TestExternalities<sp_runtime::traits::BlakeTwo256, u64>;
|
||||
|
||||
@@ -82,7 +85,10 @@ fn test_set_storage() {
|
||||
|
||||
#[test]
|
||||
fn test_return_value_into_mutable_reference() {
|
||||
call_wasm_method::<HostFunctions>(&wasm_binary_unwrap()[..], "test_return_value_into_mutable_reference");
|
||||
call_wasm_method::<HostFunctions>(
|
||||
&wasm_binary_unwrap()[..],
|
||||
"test_return_value_into_mutable_reference",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -102,7 +108,8 @@ fn test_return_input_public_key() {
|
||||
|
||||
#[test]
|
||||
fn host_function_not_found() {
|
||||
let err = call_wasm_method_with_result::<()>(&wasm_binary_unwrap()[..], "test_return_data").unwrap_err();
|
||||
let err = call_wasm_method_with_result::<()>(&wasm_binary_unwrap()[..], "test_return_data")
|
||||
.unwrap_err();
|
||||
|
||||
assert!(err.contains("Instantiation: Export "));
|
||||
assert!(err.contains(" not found"));
|
||||
@@ -111,41 +118,56 @@ fn host_function_not_found() {
|
||||
#[test]
|
||||
#[should_panic(expected = "Invalid utf8 data provided")]
|
||||
fn test_invalid_utf8_data_should_return_an_error() {
|
||||
call_wasm_method::<HostFunctions>(&wasm_binary_unwrap()[..], "test_invalid_utf8_data_should_return_an_error");
|
||||
call_wasm_method::<HostFunctions>(
|
||||
&wasm_binary_unwrap()[..],
|
||||
"test_invalid_utf8_data_should_return_an_error",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_overwrite_native_function_implementation() {
|
||||
call_wasm_method::<HostFunctions>(&wasm_binary_unwrap()[..], "test_overwrite_native_function_implementation");
|
||||
call_wasm_method::<HostFunctions>(
|
||||
&wasm_binary_unwrap()[..],
|
||||
"test_overwrite_native_function_implementation",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_u128_i128_as_parameter_and_return_value() {
|
||||
call_wasm_method::<HostFunctions>(&wasm_binary_unwrap()[..], "test_u128_i128_as_parameter_and_return_value");
|
||||
call_wasm_method::<HostFunctions>(
|
||||
&wasm_binary_unwrap()[..],
|
||||
"test_u128_i128_as_parameter_and_return_value",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_return_value_memory_is_freed() {
|
||||
call_wasm_method::<HostFunctions>(&wasm_binary_unwrap()[..], "test_vec_return_value_memory_is_freed");
|
||||
call_wasm_method::<HostFunctions>(
|
||||
&wasm_binary_unwrap()[..],
|
||||
"test_vec_return_value_memory_is_freed",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encoded_return_value_memory_is_freed() {
|
||||
call_wasm_method::<HostFunctions>(&wasm_binary_unwrap()[..], "test_encoded_return_value_memory_is_freed");
|
||||
call_wasm_method::<HostFunctions>(
|
||||
&wasm_binary_unwrap()[..],
|
||||
"test_encoded_return_value_memory_is_freed",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_array_return_value_memory_is_freed() {
|
||||
call_wasm_method::<HostFunctions>(&wasm_binary_unwrap()[..], "test_array_return_value_memory_is_freed");
|
||||
call_wasm_method::<HostFunctions>(
|
||||
&wasm_binary_unwrap()[..],
|
||||
"test_array_return_value_memory_is_freed",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_versionining_with_new_host_works() {
|
||||
// We call to the new wasm binary with new host function.
|
||||
call_wasm_method::<HostFunctions>(
|
||||
&wasm_binary_unwrap()[..],
|
||||
"test_versionning_works",
|
||||
);
|
||||
call_wasm_method::<HostFunctions>(&wasm_binary_unwrap()[..], "test_versionning_works");
|
||||
|
||||
// we call to the old wasm binary with a new host functions
|
||||
// old versions of host functions should be called and test should be ok!
|
||||
@@ -158,7 +180,7 @@ fn test_versionining_with_new_host_works() {
|
||||
#[test]
|
||||
fn test_tracing() {
|
||||
use std::fmt;
|
||||
use tracing::{span::Id as SpanId};
|
||||
use tracing::span::Id as SpanId;
|
||||
use tracing_core::field::{Field, Visit};
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -166,9 +188,8 @@ fn test_tracing() {
|
||||
|
||||
struct FieldConsumer(&'static str, Option<String>);
|
||||
impl Visit for FieldConsumer {
|
||||
|
||||
fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
|
||||
if field.name() == self.0 {
|
||||
if field.name() == self.0 {
|
||||
self.1 = Some(format!("{:?}", value))
|
||||
}
|
||||
}
|
||||
@@ -180,14 +201,16 @@ fn test_tracing() {
|
||||
}
|
||||
|
||||
impl tracing::subscriber::Subscriber for TracingSubscriber {
|
||||
fn enabled(&self, _: &tracing::Metadata) -> bool { true }
|
||||
fn enabled(&self, _: &tracing::Metadata) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn new_span(&self, span: &tracing::span::Attributes) -> tracing::Id {
|
||||
let mut inner = self.0.lock().unwrap();
|
||||
let id = SpanId::from_u64((inner.spans.len() + 1) as _);
|
||||
let mut f = FieldConsumer("name", None);
|
||||
span.record(&mut f);
|
||||
inner.spans.insert(f.1.unwrap_or_else(||span.metadata().name().to_owned()));
|
||||
inner.spans.insert(f.1.unwrap_or_else(|| span.metadata().name().to_owned()));
|
||||
id
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user