xrpl_wasm_stdlib/host/
host_bindings_empty.rs

1#[cfg(not(target_arch = "wasm32"))]
2/// Macro to generate stub implementations of host functions for non-WASM builds.
3///
4/// This macro creates empty stub functions that return an empty buffer with the length
5/// of the final parameter value. This allows code to compile and run basic tests in
6/// non-WASM environments without actual host bindings (in particular, doc code).
7///
8/// # How it works
9///
10/// For each function signature, the macro:
11/// 1. Generates a public unsafe function with the same signature
12/// 2. Calls the `@return_value` helper with just the parameter names (no types)
13/// 3. The helper recursively finds the last parameter and returns its value as i32
14///
15/// # Example
16///
17/// Input:
18/// ```ignore
19/// export_host_functions! {
20///     fn account_keylet(_account_ptr: *const u8, _account_len: usize,
21///                       _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
22/// }
23/// ```
24///
25/// Generates:
26/// ```ignore
27/// pub unsafe fn account_keylet(_account_ptr: *const u8, _account_len: usize,
28///                              _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32 {
29///     _out_buff_len as i32  // Returns 32 at runtime
30/// }
31/// ```
32macro_rules! export_host_functions {
33    // Main rule: Generate function definitions
34    // Matches zero or more function signatures and generates stub implementations
35    ($(
36        $(#[$attr:meta])*
37        fn $name:ident($($param:ident: $param_ty:ty),*) -> $ret:ty;
38    )*) => {
39        $(
40            #[allow(clippy::too_many_arguments)]
41            #[allow(clippy::missing_safety_doc)]
42            $(#[$attr])*
43            pub unsafe fn $name($($param: $param_ty),*) -> $ret {
44                // Call helper rule with parameter names only (types stripped)
45                // This will recursively find and return the last parameter value
46                export_host_functions!(@return_value $($param),*)
47            }
48        )*
49    };
50
51    // Helper rule: Find and return the last parameter value
52    //
53    // This uses tail recursion to traverse the parameter list:
54    // - Recursively strips off the first parameter
55    // - Continues until only one parameter remains
56    // - Returns that final parameter value as i32
57    //
58    // Example: @return_value a, b, c, d
59    //   → @return_value b, c, d
60    //   → @return_value c, d
61    //   → @return_value d
62    //   → d as i32
63
64    // Base case 1: No parameters
65    // If the function has no parameters, return 0
66    (@return_value) => {
67        0
68    };
69
70    // Base case 2: One parameter remaining
71    // We've found the last parameter! Return its value cast to i32
72    (@return_value $last_param:ident) => {
73        $last_param as i32
74    };
75
76    // Recursive case: Multiple parameters
77    // Strip off the first parameter ($param) and recurse with the rest ($rest)
78    // This effectively "walks" through the parameter list to find the last one
79    (@return_value $param:ident, $($rest:ident),+) => {
80        export_host_functions!(@return_value $($rest),+)
81    };
82}
83
84// Re-export all host functions as public functions for use by the rest of the codebase
85// For non-WASM targets, _these are stub implementations that panic
86// The actual test implementations using MockHostBindings are in the tests module below
87
88// Generate all the stub functions
89export_host_functions! {
90    // Host Function Category: ledger and transaction info
91    fn get_ledger_sqn() -> i32;
92    fn get_parent_ledger_time() -> i32;
93    fn get_parent_ledger_hash(_out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
94    fn get_base_fee() -> i32;
95    fn amendment_enabled(_amendment_ptr: *const u8, _amendment_len: usize) -> i32;
96    fn cache_ledger_obj(_keylet_ptr: *const u8, _keylet_len: usize, _cache_num: i32) -> i32;
97    fn get_tx_field(_field: i32, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
98    fn get_current_ledger_obj_field(_field: i32, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
99    fn get_ledger_obj_field(_cache_num: i32, _field: i32, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
100    fn get_tx_nested_field(_locator_ptr: *const u8, _locator_len: usize, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
101    fn get_current_ledger_obj_nested_field(_locator_ptr: *const u8, _locator_len: usize, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
102    fn get_ledger_obj_nested_field(_cache_num: i32, _locator_ptr: *const u8, _locator_len: usize, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
103    fn get_tx_array_len(_field: i32) -> i32;
104    fn get_current_ledger_obj_array_len(_field: i32) -> i32;
105    fn get_ledger_obj_array_len(_cache_num: i32, _field: i32) -> i32;
106    fn get_tx_nested_array_len(_locator_ptr: *const u8, _locator_len: usize) -> i32;
107    fn get_current_ledger_obj_nested_array_len(_locator_ptr: *const u8, _locator_len: usize) -> i32;
108    fn get_ledger_obj_nested_array_len(_cache_num: i32, _locator_ptr: *const u8, _locator_len: usize) -> i32;
109
110    // // Host Function Category: update current ledger entry
111    fn update_data(_data_ptr: *const u8, _data_len: usize) -> i32;
112
113    // Host Function Category: hash and keylet computation
114    fn compute_sha512_half(_data_ptr: *const u8, _data_len: usize, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
115    fn check_sig(_message_ptr: *const u8, _message_len: usize, _signature_ptr: *const u8, _signature_len: usize, _pubkey_ptr: *const u8, _pubkey_len: usize) -> i32;
116    fn account_keylet(_account_ptr: *const u8, _account_len: usize, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
117    fn amm_keylet(_issue1_ptr: *const u8, _issue1_len: usize, _issue2_ptr: *const u8, _issue2_len: usize, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
118    fn check_keylet(_account_ptr: *const u8, _account_len: usize, _sequence: i32, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
119    fn credential_keylet(_subject_ptr: *const u8, _subject_len: usize, _issuer_ptr: *const u8, _issuer_len: usize, _cred_type_ptr: *const u8, _cred_type_len: usize, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
120    fn delegate_keylet(_account_ptr: *const u8, _account_len: usize, _authorize_ptr: *const u8, _authorize_len: usize, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
121    fn deposit_preauth_keylet(_account_ptr: *const u8, _account_len: usize, _authorize_ptr: *const u8, _authorize_len: usize, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
122    fn did_keylet(_account_ptr: *const u8, _account_len: usize, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
123    fn escrow_keylet(_account_ptr: *const u8, _account_len: usize, _sequence: i32, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
124    fn line_keylet(_account1_ptr: *const u8, _account1_len: usize, _account2_ptr: *const u8, _account2_len: usize, _currency_ptr: *const u8, _currency_len: usize, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
125    fn mpt_issuance_keylet(_issuer_ptr: *const u8, _issuer_len: usize, _sequence: i32, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
126    fn mptoken_keylet(_mptid_ptr: *const u8, _mptid_len: usize, _holder_ptr: *const u8, _holder_len: usize, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
127    fn nft_offer_keylet(_account_ptr: *const u8, _account_len: usize, _sequence: i32, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
128    fn offer_keylet(_account_ptr: *const u8, _account_len: usize, _sequence: i32, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
129    fn oracle_keylet(_account_ptr: *const u8, _account_len: usize, _document_id: i32, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
130    fn paychan_keylet(_account_ptr: *const u8, _account_len: usize, _destination_ptr: *const u8, _destination_len: usize, _sequence: i32, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
131    fn permissioned_domain_keylet(_account_ptr: *const u8, _account_len: usize, _sequence: i32, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
132    fn signers_keylet(_account_ptr: *const u8, _account_len: usize, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
133    fn ticket_keylet(_account_ptr: *const u8, _account_len: usize, _sequence: i32, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
134    fn vault_keylet(_account_ptr: *const u8, _account_len: usize, _sequence: i32, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
135
136    // Host Function Category: NFT
137    fn get_nft(_account_ptr: *const u8, _account_len: usize, _nft_id_ptr: *const u8, _nft_id_len: usize, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
138    fn get_nft_issuer(_nft_id_ptr: *const u8, _nft_id_len: usize, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
139    fn get_nft_taxon(_nft_id_ptr: *const u8, _nft_id_len: usize, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
140    fn get_nft_flags(_nft_id_ptr: *const u8, _nft_id_len: usize) -> i32;
141    fn get_nft_transfer_fee(_nft_id_ptr: *const u8, _nft_id_len: usize) -> i32;
142    fn get_nft_serial(_nft_id_ptr: *const u8, _nft_id_len: usize, _out_buff_ptr: *mut u8, _out_buff_len: usize) -> i32;
143
144    // Host Function Category: FLOAT
145    fn float_from_int(_in_int: i64, _out_buff: *mut u8, _out_buff_len: usize, _rounding_mode: i32) -> i32;
146    fn float_from_uint(_in_uint_ptr: *const u8, _in_uint_len: usize, _out_buff: *mut u8, _out_buff_len: usize, _rounding_mode: i32) -> i32;
147    fn float_set(_exponent: i32, _mantissa: i64, _out_buff: *mut u8, _out_buff_len: usize, _rounding_mode: i32) -> i32;
148    fn float_compare(_in_buff1: *const u8, _in_buff1_len: usize, _in_buff2: *const u8, _in_buff2_len: usize) -> i32;
149    fn float_add(_in_buff1: *const u8, _in_buff1_len: usize, _in_buff2: *const u8, _in_buff2_len: usize, _out_buff: *mut u8, _out_buff_len: usize, _rounding_mode: i32) -> i32;
150    fn float_subtract(_in_buff1: *const u8, _in_buff1_len: usize, _in_buff2: *const u8, _in_buff2_len: usize, _out_buff: *mut u8, _out_buff_len: usize, _rounding_mode: i32) -> i32;
151    fn float_multiply(_in_buff1: *const u8, _in_buff1_len: usize, _in_buff2: *const u8, _in_buff2_len: usize, _out_buff: *mut u8, _out_buff_len: usize, _rounding_mode: i32) -> i32;
152    fn float_divide(_in_buff1: *const u8, _in_buff1_len: usize, _in_buff2: *const u8, _in_buff2_len: usize, _out_buff: *mut u8, _out_buff_len: usize, _rounding_mode: i32) -> i32;
153    fn float_pow(_in_buff: *const u8, _in_buff_len: usize, _in_int: i32, _out_buff: *mut u8, _out_buff_len: usize, _rounding_mode: i32) -> i32;
154    fn float_root(_in_buff: *const u8, _in_buff_len: usize, _n: i32, _out_buff: *mut u8, _out_buff_len: usize, _rounding_mode: i32) -> i32;
155    fn float_log(_in_buff: *const u8, _in_buff_len: usize, _out_buff: *mut u8, _out_buff_len: usize, _rounding_mode: i32) -> i32;
156
157    // Host Function Category: TRACE
158    fn trace(_msg_read_ptr: *const u8, _msg_read_len: usize, _data_read_ptr: *const u8, _data_read_len: usize, _as_hex: i32) -> i32;
159    fn trace_num(_msg_read_ptr: *const u8, _msg_read_len: usize, _number: i64) -> i32;
160    fn trace_account(_msg_read_ptr: *const u8, _msg_read_len: usize, _account_ptr: *const u8, _account_len: usize) -> i32;
161    fn trace_opaque_float(_msg_read_ptr: *const u8, _msg_read_len: usize, _opaque_float_ptr: *const u8, _opaque_float_len: usize) -> i32;
162    fn trace_amount(_msg_read_ptr: *const u8, _msg_read_len: usize, _amount_ptr: *const u8, _amount_len: usize) -> i32;
163}