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}