Function psm::replace_stack
source · pub unsafe fn replace_stack<F: FnOnce()>(
base: *mut u8,
size: usize,
callback: F,
) -> !
Expand description
Run the provided non-terminating computation on an entirely new stack.
base
address must be the low address of the stack memory region, regardless of the stack
growth direction. It is not necessary for the whole region [base; base + size]
to be usable
at the time this function called, however it is required that at least the following hold:
- Both
base
andbase + size
are aligned up to the target-specific requirements; - Depending on
StackDirection
value for the platform, the end of the stack memory region, which would end up containing the first frame(s), must have sufficient number of pages allocated to execute code until more pages are commited. The other end should contain a guard page (not writable, readable or executable) to ensure Rust’s soundness guarantees.
Note, that some or all of these considerations are irrelevant to some applications. For example, Rust’s soundness story relies on all stacks having a guard-page, however if the user is able to guarantee that the memory region used for stack cannot be exceeded, a guard page may end up being an expensive unnecessity.
The previous stack is not deallocated and may not be deallocated unless the data on the old
stack is not referenced in any way (by e.g. the callback
closure).
On platforms where multiple stack pointers are available, the “current” stack pointer is replaced.
§Guidelines
Memory regions that are aligned to a single page (usually 4kB) are an extremely portable choice for stacks.
Allocate at least 4kB of stack. Some architectures (such as SPARC) consume stack memory significantly faster compared to the more usual architectures such as x86 or ARM. Allocating less than 4kB of memory may make it impossible to commit more pages without overflowing the stack later on.
§Unsafety
The stack base
address must be aligned as appropriate for the target.
The stack size
must be a multiple of stack alignment required by target.
The size
must not overflow isize
.
callback
must not return (not enforced by typesystem currently because !
is unstable),
unwind or otherwise return control flow to any of the previous frames.