/
githubmirror
/
sway
Обзор
Документация
Войти
/
githubmirror
/
sway
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
sway-lib-std/src/call_frames.sw
201 строка
5 KB
Daniel Frederico Lins Leite
Better `Debug` tests and impls for primitives and std lib types (#7119)
02 май 2025, 12:40
Не верифицирован
02 май 2025, 12:40
324f04f
Код
Авторство
О чём код?
//! Helper functions for accessing data from call frames. //! [Call frames](https://fuellabs.github.io/fuel-specs/master/vm#call-frames) store metadata across untrusted inter-contract calls. library; use ::asset_id::AssetId; use ::contract_id::ContractId; use ::intrinsics::is_reference_type; use ::registers::frame_ptr; use ::raw_ptr::*; use ::codec::*; use ::debug::*; // Note that everything when serialized is padded to word length. // // Call Frame : saved registers offset = 8 // Reserved Registers: previous frame pointer offset = 6 const SAVED_REGISTERS_OFFSET: u64 = 8; const PREV_FRAME_POINTER_OFFSET: u64 = 6; /// Where 73 is the current offset in words from the start of the call frame. const FIRST_PARAMETER_OFFSET: u64 = 73; /// Where 74 (73 + 1) is the current offset in words from the start of the call frame. const SECOND_PARAMETER_OFFSET: u64 = 74; /// Get the `asset_id` of coins being sent from the current call frame. /// /// # Returns /// /// * [AssetId] - The asset included in the current call frame. /// /// # Examples /// /// ```sway /// use std::call_frames::msg_asset_id; /// /// fn foo() { /// let asset = msg_asset_id(); /// assert(asset == AssetId::base()); /// } /// ``` pub fn msg_asset_id() -> AssetId { AssetId::from(asm(asset_id) { addi asset_id fp i32; asset_id: b256 }) } /// Get the code size in bytes (padded to word alignment) from the current call frame. /// /// # Additional Information /// /// More information on data from call frames can be found in the Fuel Specs. /// https://docs.fuel.network/docs/specs/fuel-vm/#call-frames /// /// # Returns /// /// * [u64] - The code size of the current call frame. /// /// # Examples /// /// ```sway /// use std::call_frames::code_size; /// /// fn foo() { /// let size = code_size(); /// assert(size != 0); /// } /// ``` pub fn code_size() -> u64 { let ptr = asm(size, ptr, offset: 576) { add size fp offset; size: raw_ptr }; ptr.read::<u64>() } /// Get the first parameter from the current call frame. /// /// # Additional Information /// /// More information on data from call frames can be found in the Fuel Specs. /// https://docs.fuel.network/docs/specs/fuel-vm/#call-frames /// /// # Returns /// /// * [u64] - The first parameter of the current call frame. /// /// # Examples /// /// ```sway /// use std::call_frames::first_param; /// /// fn foo() { /// let param = first_param(); /// assert(param != 0); /// } /// ``` pub fn first_param() -> u64 { frame_ptr().add::<u64>(FIRST_PARAMETER_OFFSET).read() } /// Get the second parameter from the current call frame. /// /// # Additional Information /// /// More information on data from call frames can be found in the Fuel Specs. /// https://docs.fuel.network/docs/specs/fuel-vm/#call-frames /// /// # Returns /// /// * [u64] - The second parameter of the current call frame. /// /// # Examples /// /// ```sway /// use std::call_frames::second_param; /// /// fn foo() { /// let param: u64 = second_param(); /// assert(param != 0); /// } /// ``` pub fn second_param() -> u64 { frame_ptr().add::<u64>(SECOND_PARAMETER_OFFSET).read() } /// Get the called method name from the current call frame. pub fn called_method() -> str { use ::codec::decode_first_param; decode_first_param::<str>() } /// Get the called arguments from the current call frame. pub fn called_args<T>() -> T where T: AbiDecode, { use ::codec::decode_second_param; decode_second_param::<T>() } // Accessing arbitrary call frames by pointer // /// Get a pointer to the previous (relative to the `frame_pointer` parameter) call frame using offsets from a pointer. /// /// # Additional Information /// /// More information on data from call frames can be found in the Fuel Specs. /// https://docs.fuel.network/docs/specs/fuel-vm/#call-frames /// /// # Arguments /// /// * `frame_pointer`: [raw_ptr] - The call frame reference directly before the returned call frame pointer. /// /// # Returns /// /// * [raw_ptr] - The memory location of the previous call frame data. /// /// # Examples /// /// ```sway /// use std::{call_frames::get_previous_frame_pointer, registers::frame_ptr}; /// /// fn foo() { /// let current_call_frame = frame_ptr(); /// let previous_call_frame = get_previous_frame_pointer(current_call_frame); /// assert(!previous_call_frame.is_null()); /// } /// ``` pub fn get_previous_frame_pointer(frame_pointer: raw_ptr) -> raw_ptr { let offset = frame_pointer.add::<u64>(SAVED_REGISTERS_OFFSET + PREV_FRAME_POINTER_OFFSET); asm(res, ptr: offset) { lw res ptr i0; res: raw_ptr } } /// Get the value of `ContractId` from any call frame on the stack. /// /// # Arguments /// /// * `frame_pointer`: [raw_ptr] - The call frame for which the Contract Id is to be returned. /// /// # Returns /// /// * [ContractId] - The Contract Id of for the call frame. /// /// # Examples /// /// ```sway /// use std::{call_frames::get_contract_id_from_call_frame, registers::frame_ptr}; /// /// fn foo() { /// let current_call_frame = frame_ptr(); /// let contract_id = get_contract_id_from_call_frame(current_call_frame); /// } /// ``` pub fn get_contract_id_from_call_frame(frame_pointer: raw_ptr) -> ContractId { ContractId::from(asm(res, ptr: frame_pointer) { ptr: b256 }) }