55 lines
1.7 KiB
Rust
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)
|
|
}
|