pub struct Frame<'a> { /* private fields */ }Expand description
Execution frame holding the instruction’s accounts and data.
Frame is the entry point for Hopper’s phased execution model.
It tracks which accounts have been borrowed (mutably or immutably)
to prevent aliasing violations at runtime.
Implementations§
Source§impl<'a> Frame<'a>
impl<'a> Frame<'a>
Sourcepub fn new(
program_id: &'a Address,
accounts: &'a [AccountView],
instruction_data: &'a [u8],
) -> Result<Self, ProgramError>
pub fn new( program_id: &'a Address, accounts: &'a [AccountView], instruction_data: &'a [u8], ) -> Result<Self, ProgramError>
Create a new execution frame.
Sourcepub fn program_id(&self) -> &Address
pub fn program_id(&self) -> &Address
Program ID.
Sourcepub fn account_count(&self) -> usize
pub fn account_count(&self) -> usize
Number of accounts in this frame.
Sourcepub fn account_view(&self, index: usize) -> Result<&AccountView, ProgramError>
pub fn account_view(&self, index: usize) -> Result<&AccountView, ProgramError>
Get raw account view by index.
Sourcepub fn ix_data(&mut self) -> &mut SliceCursor<'a>
pub fn ix_data(&mut self) -> &mut SliceCursor<'a>
Get instruction data cursor.
Sourcepub fn ix_data_raw(&self) -> &[u8]
pub fn ix_data_raw(&self) -> &[u8]
Get raw instruction data.
Sourcepub fn account(&self, index: usize) -> Result<FrameAccount<'_>, ProgramError>
pub fn account(&self, index: usize) -> Result<FrameAccount<'_>, ProgramError>
Get an immutable account view (no borrow tracking needed for reads).
Sourcepub fn account_mut(
&mut self,
index: usize,
) -> Result<FrameAccountMut<'_>, ProgramError>
pub fn account_mut( &mut self, index: usize, ) -> Result<FrameAccountMut<'_>, ProgramError>
Get a mutable account view with runtime borrow checking.
Returns an error if this account is already borrowed mutably. This prevents the most dangerous aliasing pattern in Solana programs.
Sourcepub fn segment_borrows(&self) -> &SegmentBorrowRegistry
pub fn segment_borrows(&self) -> &SegmentBorrowRegistry
Get the segment borrow registry for direct manipulation.
Sourcepub fn segment_borrows_mut(&mut self) -> &mut SegmentBorrowRegistry
pub fn segment_borrows_mut(&mut self) -> &mut SegmentBorrowRegistry
Get the mutable segment borrow registry.
Sourcepub fn segment_ref<'f, T: Pod + FixedLayout>(
&'f mut self,
index: usize,
offset: u32,
) -> Result<SegRef<'f, T>, ProgramError>
pub fn segment_ref<'f, T: Pod + FixedLayout>( &'f mut self, index: usize, offset: u32, ) -> Result<SegRef<'f, T>, ProgramError>
Read a typed value from a segment of an account’s data region.
Registers a read borrow for the given byte range, then projects
the pointer through the live byte-borrow guard into a Ref<'_, T>.
Returns an error if the range conflicts with an existing write
borrow on the same account.
offset is relative to the layout body (after the 16-byte header).
§Preferred path
Most programs don’t need to construct a Frame at all, the
hopper_runtime::Context handler signature gives you
ctx.segment_ref::<T>(index, abs_offset) with the same tightened
Pod contract, the same RAII guard, and none of the phased
execution bookkeeping. Reach for Frame::segment_ref only when
you’re inside the advanced frame-gated execution model.
§Safety Contract
- T must be
Pod + FixedLayout(safe to interpret from any bit pattern, alignment-1, no padding). - Bounds are checked at runtime.
- Borrow conflicts are checked at runtime.
- The returned
SegRef<T>owns both the byte-slice borrow and a RAII lease on the segment registry entry. Dropping it releases both, no sticky-ledger residue from post-audit.
Sourcepub fn segment_mut<'f, T: Pod + FixedLayout>(
&'f mut self,
index: usize,
offset: u32,
) -> Result<SegRefMut<'f, T>, ProgramError>
pub fn segment_mut<'f, T: Pod + FixedLayout>( &'f mut self, index: usize, offset: u32, ) -> Result<SegRefMut<'f, T>, ProgramError>
Get a mutable typed reference to a segment of an account’s data.
Registers a write borrow for the given byte range, then projects
the pointer through the live byte-borrow guard into a RefMut<'_, T>.
Returns an error if the range overlaps any existing borrow (read or
write) on the same account.
This is the core primitive that makes Hopper strictly better than raw Pinocchio: you get the same pointer arithmetic, but with segment-level conflict detection that prevents aliasing bugs.
offset is relative to the layout body (after the 16-byte header).
§Safety Contract
- T must be
Pod + FixedLayout. - Bounds are checked at runtime.
- Borrow conflicts are checked at runtime.
- The returned
SegRefMut<T>carries both the account-level exclusive byte guard and a RAII registry lease, dropping it releases the full borrow cleanly, so sequential patterns on the same segment compose like ordinary Rust borrows.
§Example
// Only borrows the "balance" region [32..40), not the entire account.
{
let mut balance = frame.segment_mut::<WireU64>(0, 32)?;
balance.set(balance.get() + amount);
} // SegRefMut drops here, releasing both guards.
// Now we can re-borrow the same (or a different) segment safely.
let mut balance_again = frame.segment_mut::<WireU64>(0, 32)?;Sourcepub unsafe fn segment_mut_unchecked<T: Pod + FixedLayout>(
&self,
index: usize,
offset: u32,
) -> Result<RefMut<'_, T>, ProgramError>
pub unsafe fn segment_mut_unchecked<T: Pod + FixedLayout>( &self, index: usize, offset: u32, ) -> Result<RefMut<'_, T>, ProgramError>
Unsafe escape hatch for performance-critical paths.
Skips borrow tracking entirely. The caller takes full responsibility
for aliasing safety. Returns a RefMut<T> so the borrow guard is
still tied to the returned value’s lifetime, the “unchecked” part
is only the conflict-detection skip, not the lifetime tying.
§Safety
The caller must guarantee no other mutable reference to the same byte range exists for the duration of the returned reference, and that no overlapping segment borrow has been registered.
Sourcepub fn require_signer(&self, index: usize) -> ProgramResult
pub fn require_signer(&self, index: usize) -> ProgramResult
Validate that account at index is a signer.
Sourcepub fn require_writable(&self, index: usize) -> ProgramResult
pub fn require_writable(&self, index: usize) -> ProgramResult
Validate that account at index is writable.
Sourcepub fn require_owned(&self, index: usize) -> ProgramResult
pub fn require_owned(&self, index: usize) -> ProgramResult
Validate that account at index is owned by this program.
Validate signer + writable (common pattern for authority accounts).
Sourcepub fn require_unique(&self, a: usize, b: usize) -> ProgramResult
pub fn require_unique(&self, a: usize, b: usize) -> ProgramResult
Validate two accounts are unique.
Sourcepub fn require_program(&self, index: usize, program: &Address) -> ProgramResult
pub fn require_program(&self, index: usize, program: &Address) -> ProgramResult
Require an account matches a specific program address.