swap_to_static

Function swap_to_static 

Source
pub unsafe fn swap_to_static<T>(
    callout: fn(&mut T),
    arg: Option<&mut T>,
    stack: &'static mut [u8],
) -> Result<(), Error>
Expand description

Swaps to a static stack, executes a function, then returns to the original stack.

This function switches to a pre-allocated static stack buffer, executes the provided callout function, and then restores the original stack. Unlike swap_to_heap, this doesn’t perform any allocation and works in no_std environments.

§Type Parameters

  • T - The type of the argument passed to the callout function. Can be any type.

§Parameters

  • callout - The function to execute on the new stack. It receives a mutable reference to the argument.
  • arg - An optional mutable reference to pass to the callout function. Use None if no argument is needed.
  • stack - A mutable reference to a static byte array to use as the stack. The array must have a 'static lifetime and be large enough for the callout function’s needs.

§Returns

  • Ok(()) - The stack swap completed successfully.
  • Err(Error::StackPtrNotAligned) - The calculated stack pointer is not properly aligned.
  • Err(Error::StackSwapInProgress) - Another stack swap is already in progress.

§Safety

This function is highly unsafe for several reasons:

  • The callout function must not attempt to use stack references from before the swap
  • The static buffer must be large enough for the callout function’s needs, including all recursive calls and stack allocations
  • Nested stack swaps are not supported and will return an error
  • The callout function must not unwind (panic) past the swap point
  • With the tls feature, this is thread-safe but only one swap per thread is allowed
  • Without the tls feature, only one swap can be active globally
  • The static buffer must not be used concurrently by multiple threads

§Examples

use stackaroo::swap_to_static;

static mut MY_STACK: [u8; 1 << 26] = [0; 1 << 26]; // 64MB

fn compute(value: &mut u32) {
    *value = *value * 2 + 1;
}

unsafe {
    let mut x = 100;
    swap_to_static(compute, Some(&mut x), &mut MY_STACK).unwrap();
    assert_eq!(x, 201);
}

§Notes

  • Stack grows downward, so the function uses the end of the buffer as the stack top
  • The buffer is not initialized or cleared between uses
  • This function works in both std and no_std environments