solana-program-library/examples/rust/custom-heap/src/entrypoint.rs

55 lines
1.7 KiB
Rust

//! Program entrypoint
#![cfg(not(feature = "no-entrypoint"))]
use solana_program::{
account_info::AccountInfo,
entrypoint,
entrypoint::{ProgramResult, HEAP_LENGTH, HEAP_START_ADDRESS},
pubkey::Pubkey,
};
use std::{alloc::Layout, mem::size_of, ptr::null_mut, usize};
/// Developers can implement their own heap by defining their own
/// `#[global_allocator]`. The following implements a dummy for test purposes
/// but can be flushed out with whatever the developer sees fit.
struct BumpAllocator;
unsafe impl std::alloc::GlobalAlloc for BumpAllocator {
#[inline]
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
const POS_PTR: *mut usize = HEAP_START_ADDRESS as *mut usize;
const TOP_ADDRESS: usize = HEAP_START_ADDRESS + HEAP_LENGTH;
const BOTTOM_ADDRESS: usize = HEAP_START_ADDRESS + size_of::<*mut u8>();
let mut pos = *POS_PTR;
if pos == 0 {
// First time, set starting position
pos = TOP_ADDRESS;
}
pos = pos.saturating_sub(layout.size());
pos &= !(layout.align().saturating_sub(1));
if pos < BOTTOM_ADDRESS {
return null_mut();
}
*POS_PTR = pos;
pos as *mut u8
}
#[inline]
unsafe fn dealloc(&self, _: *mut u8, _: Layout) {
// I'm a bump allocator, I don't free
}
}
#[cfg(target_arch = "bpf")]
#[global_allocator]
static A: BumpAllocator = BumpAllocator;
entrypoint!(process_instruction);
fn process_instruction(
program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
crate::processor::process_instruction(program_id, accounts, instruction_data)
}