gear_core_backend_codegen/
lib.rs

1// This file is part of Gear.
2//
3// Copyright (C) 2021-2023 Gear Technologies Inc.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5//
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10//
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19use host::{HostFn, HostFnMeta};
20use proc_macro::TokenStream;
21use syn::ItemFn;
22
23mod host;
24
25/// Apply host state wrapper to host functions.
26///
27/// Supported meta attributes:
28/// * `fallible`             - if the host function executes fallible call.
29/// * `wgas`                 - if the host function supports with-gas version.
30/// * `cost`                 - RuntimeCosts definition, for example `#[host(cost = RuntimeCosts::Null)]`
31/// * `err`                  - Structure definition with error code, for example `#[host(err = ErrorWithHash)]`
32///
33/// # Example
34///
35/// ```ignore
36/// #[host(fallible, wgas, cost = RuntimeCosts::Reply(len))]
37/// pub fn reply(
38///     ctx: &mut R,
39///     payload_ptr: u32,
40///     len: u32,
41///     value_ptr: u32,
42///     delay: u32,
43/// ) -> Result<(), R::Error> {
44///     let read_payload = ctx.register_read(payload_ptr, len);
45///     let value = ctx.register_and_read_value(value_ptr)?;
46///     let payload = ctx.read(read_payload)?.try_into()?;
47///
48///     let state = ctx.host_state_mut();
49///     state.ext.reply(ReplyPacket::new(payload, value), delay)
50///         .map_err(Into::into)
51/// }
52/// ```
53///
54/// will generate
55///
56/// ```ignore
57/// pub fn reply(ctx: &mut R,
58///     payload_ptr: u32,
59///     len: u32,
60///     value_ptr: u32,
61///     delay: u32
62/// ) -> Result<(), R::Error> {
63///     syscall_trace!("reply", payload_ptr, len, value_ptr, delay, err_mid_ptr);
64///
65///     ctx.run_fallible::<_, _, ErrorWithHash>(err_mid_ptr, RuntimeCosts::Reply(len), |ctx| {
66///         // ...
67///     })
68/// }
69///
70/// pub fn reply_wgas(
71///     ctx: &mut R,
72///     payload_ptr: u32,
73///     len: u32,
74///     gas_limit: u64,
75///     value_ptr: u32,
76///     delay: u32
77/// ) -> Result<(), R::Error> {
78///     syscall_trace!("reply_wgas", payload_ptr, len, gas_limit, value_ptr, delay, err_mid_ptr);
79///
80///     ctx.run_fallible::<_, _, ErrorWithHash>(err_mid_ptr, RuntimeCosts::ReplyWGas(len), |ctx| {
81///         // ...
82///     })
83/// }
84/// ```
85#[proc_macro_attribute]
86pub fn host(meta: TokenStream, item: TokenStream) -> TokenStream {
87    let meta: HostFnMeta = syn::parse_macro_input!(meta);
88    let item: ItemFn = syn::parse_macro_input!(item);
89
90    HostFn::new(meta, item).into()
91}