Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,15 @@ This will add `pinocchio` as a dependency to your project.

## Defining the program entrypoint

A Solana program needs to define an entrypoint, which will be called by the runtime to begin the program execution. The `entrypoint!` macro emits the common boilerplate to set up the program entrypoint. The macro will also set up [global allocator](https://doc.rust-lang.org/stable/core/alloc/trait.GlobalAlloc.html) and [panic handler](https://doc.rust-lang.org/nomicon/panic-handler.html) using the [default_allocator!](https://docs.rs/pinocchio/latest/pinocchio/macro.default_allocator.html) and [default_panic_handler!](https://docs.rs/pinocchio/latest/pinocchio/macro.default_panic_handler.html) macros.
A Solana program needs to define an entrypoint, which will be called by the runtime to begin the program execution. The `entrypoint!` macro emits the common boilerplate to set up the program entrypoint. The macro will also set up [global allocator](https://doc.rust-lang.org/stable/core/alloc/trait.GlobalAlloc.html) and [custom panic hook](https://github.com/anza-xyz/rust/blob/2830febbc59d44bdd7ad2c3b81731f1d08b96eba/library/std/src/sys/pal/sbf/mod.rs#L49) using the [default_allocator!](https://docs.rs/pinocchio/latest/pinocchio/macro.default_allocator.html) and [default_panic_handler!](https://docs.rs/pinocchio/latest/pinocchio/macro.default_panic_handler.html) macros.

The [`entrypoint!`](https://docs.rs/pinocchio/latest/pinocchio/macro.entrypoint.html) is a convenience macro that invokes three other macros to set all symbols required for a program execution:

* [`program_entrypoint!`](https://docs.rs/pinocchio/latest/pinocchio/macro.program_entrypoint.html): declares the program entrypoint
* [`default_allocator!`](https://docs.rs/pinocchio/latest/pinocchio/macro.default_allocator.html): declares the default (bump) global allocator
* [`default_panic_hanlder!`](https://docs.rs/pinocchio/latest/pinocchio/macro.default_panic_handler.html): declares the default panic handler
* [`default_panic_handler!`](https://docs.rs/pinocchio/latest/pinocchio/macro.default_panic_handler.html): declares the default panic handler

If all dependencies are `no_std`, you should append [`nostd_panic_handler!`](https://docs.rs/pinocchio/latest/pinocchio/macro.nostd_panic_handler.html) to declare a rust runtime panic handler. There's no need to do this if any dependency is `std` since rust compiler will emit std panic handler.

To use the `entrypoint!` macro, use the following in your entrypoint definition:
```rust
Expand Down
46 changes: 40 additions & 6 deletions sdk/pinocchio/src/entrypoint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,11 @@ pub unsafe fn deserialize<'a, const MAX_ACCOUNTS: usize>(
(program_id, processed, instruction_data)
}

/// Default panic handler.
/// Default panic hook (std).
///
/// This macro sets up a default panic handler that logs the panic message and the file where the
/// panic occurred.
/// This macro sets up a default panic hook that logs the panic message and the file where the
/// panic occurred. Syscall "abort()" will be called after it returns. It acts as a hook after
/// rust runtime panics.
///
/// Note that this requires the `"std"` feature to be enabled.
#[cfg(feature = "std")]
Expand All @@ -240,11 +241,11 @@ macro_rules! default_panic_handler {
};
}

/// Default panic handler.
/// Default panic hook (no std).
///
/// This macro sets up a default panic handler that logs the file where the panic occurred.
/// This macro sets up a default panic hook that logs the file where the panic occurred.
///
/// This is used when the `"std"` feature is disabled.
/// This is used when the `"std"` feature is disabled and program is `std`.
#[cfg(not(feature = "std"))]
#[macro_export]
macro_rules! default_panic_handler {
Expand All @@ -262,6 +263,39 @@ macro_rules! default_panic_handler {
};
}

/// A rust panic handler for `no_std`.
///
/// When all crates are `no_std`, we need to define a global `#[panic_handler]`.
/// It takes over the default rust panic handler.
///
/// This macro is used when the `"std"` feature is disabled.
#[cfg(not(feature = "std"))]
#[macro_export]
macro_rules! nostd_panic_handler {
() => {
/// A panic handler for `no_std`.
#[cfg(target_os = "solana")]
#[no_mangle]
#[panic_handler]
fn handler(info: &core::panic::PanicInfo<'_>) -> ! {
if let Some(location) = info.location() {
unsafe {
$crate::syscalls::sol_panic_(
location.file().as_ptr(),
location.file().len() as u64,
location.line() as u64,
location.column() as u64,
)
}
} else {
// Panic reporting.
$crate::log::sol_log("** PANICKED **");
unsafe { $crate::syscalls::abort() }
}
}
};
}

/// Default global allocator.
///
/// This macro sets up a default global allocator that uses a bump allocator to allocate memory.
Expand Down
2 changes: 2 additions & 0 deletions sdk/pinocchio/src/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ define_syscall!(fn sol_get_epoch_rewards_sysvar(addr: *mut u8) -> u64);
define_syscall!(fn sol_poseidon(parameters: u64, endianness: u64, vals: *const u8, val_len: u64, hash_result: *mut u8) -> u64);
define_syscall!(fn sol_remaining_compute_units() -> u64);
define_syscall!(fn sol_alt_bn128_compression(op: u64, input: *const u8, input_size: u64, result: *mut u8) -> u64);
define_syscall!(fn abort() -> !);
define_syscall!(fn sol_panic_(filename: *const u8, filename_len: u64, line: u64, column: u64) -> !);

#[cfg(target_feature = "static-syscalls")]
pub const fn sys_hash(name: &str) -> usize {
Expand Down