mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 00:37:57 +00:00
[contracts] API host functions: remove seal_ name prefix + enable aliasing (#12126)
* works but ugly * refactored + renamed host fns * fixed tests * fix benchmarks * updated marco docs * Update frame/contracts/proc-macro/src/lib.rs Co-authored-by: Alexander Theißen <alex.theissen@me.com> * fix for the duplicated prefixed alias bug + test * refactored a bit * fix warnings + try to make macro rustdoc compile * fmt after clearing * examples update + nocompile * add seal_ prefixes to unstable host functions * updated after a review Co-authored-by: Alexander Theißen <alex.theissen@me.com>
This commit is contained in:
@@ -174,22 +174,16 @@ impl ToTokens for HostFn {
|
||||
}
|
||||
|
||||
impl HostFn {
|
||||
pub fn try_from(item: syn::Item) -> syn::Result<Self> {
|
||||
pub fn try_from(item: syn::ItemFn) -> syn::Result<Self> {
|
||||
let err = |span, msg| {
|
||||
let msg = format!("Invalid host function definition. {}", msg);
|
||||
syn::Error::new(span, msg)
|
||||
};
|
||||
let msg = "only #[version(<u8>)] or #[unstable] attribute is allowed.";
|
||||
let span = item.span();
|
||||
let item = match item {
|
||||
syn::Item::Fn(i_fn) => Ok(i_fn),
|
||||
_ => Err(err(span, msg)),
|
||||
}?;
|
||||
|
||||
let mut attrs = item.attrs.clone();
|
||||
attrs.retain(|a| !(a.path.is_ident("doc") || a.path.is_ident("prefixed_alias")));
|
||||
let name = item.sig.ident.to_string();
|
||||
let attrs: Vec<&syn::Attribute> =
|
||||
item.attrs.iter().filter(|m| !m.path.is_ident("doc")).collect();
|
||||
|
||||
let module = match attrs.len() {
|
||||
0 => Ok("seal0".to_string()),
|
||||
1 => {
|
||||
@@ -306,6 +300,7 @@ impl HostFn {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EnvDef {
|
||||
pub fn try_from(item: syn::ItemMod) -> syn::Result<Self> {
|
||||
let span = item.span();
|
||||
@@ -316,9 +311,32 @@ impl EnvDef {
|
||||
.ok_or(err("Invalid environment definition, expected `mod` to be inlined."))?
|
||||
.1;
|
||||
|
||||
let extract_fn = |i: &syn::Item| match i {
|
||||
syn::Item::Fn(i_fn) => Some(i_fn.clone()),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let selector = |a: &syn::Attribute| a.path.is_ident("prefixed_alias");
|
||||
|
||||
let aliases = items
|
||||
.iter()
|
||||
.filter_map(extract_fn)
|
||||
.filter(|i| i.attrs.iter().any(selector))
|
||||
.map(|mut i| {
|
||||
i.attrs.retain(|i| !selector(i));
|
||||
i.sig.ident = syn::Ident::new(
|
||||
&format!("seal_{}", &i.sig.ident.to_string()),
|
||||
i.sig.ident.span(),
|
||||
);
|
||||
i
|
||||
})
|
||||
.map(|i| HostFn::try_from(i));
|
||||
|
||||
let host_funcs = items
|
||||
.iter()
|
||||
.map(|i| HostFn::try_from(i.clone()))
|
||||
.filter_map(extract_fn)
|
||||
.map(|i| HostFn::try_from(i))
|
||||
.chain(aliases)
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
Ok(Self { host_funcs })
|
||||
@@ -484,7 +502,7 @@ fn expand_impls(def: &mut EnvDef) -> proc_macro2::TokenStream {
|
||||
/// ```nocompile
|
||||
/// #[define_env]
|
||||
/// pub mod some_env {
|
||||
/// fn some_host_fn(ctx: Runtime<E: Ext>, key_ptr: u32, value_ptr: u32, value_len: u32) -> Result<(), TrapReason> {
|
||||
/// fn some_host_fn(ctx: Runtime<E>, key_ptr: u32, value_ptr: u32, value_len: u32) -> Result<(), TrapReason> {
|
||||
/// ctx.some_host_fn(KeyType::Fix, key_ptr, value_ptr, value_len).map(|_| ())
|
||||
/// }
|
||||
/// }
|
||||
@@ -499,17 +517,45 @@ fn expand_impls(def: &mut EnvDef) -> proc_macro2::TokenStream {
|
||||
/// #[define_env]
|
||||
/// pub mod some_env {
|
||||
/// #[version(1)]
|
||||
/// fn some_host_fn(ctx: Runtime<E: Ext>, key_ptr: u32, value_ptr: u32, value_len: u32) -> Result<ReturnCode, TrapReason> {
|
||||
/// fn some_host_fn(ctx: Runtime<E>, key_ptr: u32, value_ptr: u32, value_len: u32) -> Result<ReturnCode, TrapReason> {
|
||||
/// ctx.some_host_fn(KeyType::Fix, key_ptr, value_ptr, value_len).map(|_| ())
|
||||
/// }
|
||||
///
|
||||
/// #[unstable]
|
||||
/// fn some_host_fn(ctx: Runtime<E: Ext>, key_ptr: u32, value_ptr: u32, value_len: u32) -> Result<u32, TrapReason> {
|
||||
/// fn some_host_fn(ctx: Runtime<E>, key_ptr: u32, value_ptr: u32, value_len: u32) -> Result<u32, TrapReason> {
|
||||
/// ctx.some_host_fn(KeyType::Fix, key_ptr, value_ptr, value_len).map(|_| ())
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// In legacy versions of pallet_contracts, it was a naming convention that all host functions had
|
||||
/// to be named with the `seal_` prefix. For the sake of backwards compatibility, each host function
|
||||
/// now can get a such prefix-named alias function generated by marking it by the
|
||||
/// `#[prefixed_alias]` attribute:
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```nocompile
|
||||
/// #[define_env]
|
||||
/// pub mod some_env {
|
||||
/// #[version(1)]
|
||||
/// #[prefixed_alias]
|
||||
/// fn some_host_fn(ctx: Runtime<E>, key_ptr: u32, value_ptr: u32, value_len: u32) -> Result<ReturnCode, TrapReason> {
|
||||
/// ctx.some_host_fn(KeyType::Fix, key_ptr, value_ptr, value_len).map(|_| ())
|
||||
/// }
|
||||
///
|
||||
/// #[unstable]
|
||||
/// fn some_host_fn(ctx: Runtime<E>, key_ptr: u32, value_ptr: u32, value_len: u32) -> Result<u32, TrapReason> {
|
||||
/// ctx.some_host_fn(KeyType::Fix, key_ptr, value_ptr, value_len).map(|_| ())
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// In this example, the following host functions will be generated by the macro:
|
||||
/// - `some_host_fn()` in module `seal1`,
|
||||
/// - `seal_some_host_fn()` in module `seal1`,
|
||||
/// - `some_host_fn()` in module `__unstable__`.
|
||||
///
|
||||
/// Only following return types are allowed for the host functions defined with the macro:
|
||||
/// - `Result<(), TrapReason>`,
|
||||
/// - `Result<ReturnCode, TrapReason>`,
|
||||
|
||||
Reference in New Issue
Block a user