Skip to main content

DataStack

Struct DataStack 

Source
pub struct DataStack { /* private fields */ }
Expand description

Type-erased stack of values and registers.

Capacity is fixed at construction and rounded up to a power of two. A push that does not fit fails instead of growing the stack, so a running script cannot make the host reallocate under it. Dropping the stack unwinds everything still on it. See the module docs for the layout.

Implementations§

Source§

impl DataStack

Source

pub fn new(capacity: usize, mode: DataStackMode) -> Self

Allocates a stack of at least capacity bytes, rounded up to a power of two.

Source

pub fn position(&self) -> usize

Returns how many bytes are used.

Source

pub fn size(&self) -> usize

Returns the total capacity in bytes.

Source

pub fn available(&self) -> usize

Returns how many bytes are still free.

Source

pub fn as_bytes(&self) -> &[u8]

Returns the used part of the buffer, tags included.

Source

pub fn visit(&self, f: impl FnMut(DataStackVisitedItem<'_>) -> bool)

Walks the stack from the top down, calling f for every item.

Stops early when f returns false, or when an item cannot be read.

Source

pub fn push<T: Finalize + Sized + 'static>(&mut self, value: T) -> bool

Moves a value onto the stack.

Returns false without touching anything when the mode forbids values or the value does not fit.

Source

pub unsafe fn push_raw( &mut self, layout: Layout, type_hash: TypeHash, finalizer: unsafe fn(*mut ()), data: &[u8], ) -> bool

DataStack::push for a value whose type is only known at runtime.

§Safety

data must be a valid byte image of a value of the type named by type_hash, matching layout, and finalizer must be the drop function of that type. The bytes are moved, so the caller must not drop the source afterwards.

Source

pub fn push_register<T: Finalize + 'static>(&mut self) -> Option<usize>

Reserves an empty register for values of type T and returns its index.

Source

pub fn push_register_value<T: Finalize + 'static>( &mut self, value: T, ) -> Option<usize>

Reserves a register for T and moves value into it, returning its index.

Source

pub unsafe fn push_register_raw( &mut self, type_hash: TypeHash, value_layout: Layout, ) -> Option<usize>

DataStack::push_register for a type only known at runtime.

§Safety

value_layout must be the real layout of the type named by type_hash. A wrong layout makes every later access to that register read or write out of bounds.

Source

pub fn push_stack(&mut self, other: Self) -> Result<(), Self>

Moves the whole content of other on top of this stack.

Gives other back untouched when it does not fit. Used to hand a batch of arguments prepared elsewhere to a call.

Source

pub fn push_from_register( &mut self, register: &mut DataStackRegisterAccess<'_>, ) -> bool

Moves a register value onto the stack, leaving the register empty.

Returns false when the mode forbids values or the value does not fit.

Source

pub fn pop<T: Sized + 'static>(&mut self) -> Option<T>

Moves the top value off the stack.

Returns None, leaving the stack untouched, when the top value is not a T.

Source

pub unsafe fn pop_raw( &mut self, ) -> Option<(Layout, TypeHash, unsafe fn(*mut ()), Vec<u8>)>

DataStack::pop without knowing the type, returning the raw bytes along with the layout, type and drop function.

§Safety

The returned bytes are an owned value that nothing drops for the caller. Losing them leaks, and dropping them twice is undefined. Feed them back to DataStack::push_raw or run the returned finalizer once.

Source

pub fn drop(&mut self) -> bool

Drops the top value in place instead of returning it.

Returns false when the top of the stack is a register.

Source

pub fn drop_register(&mut self) -> bool

Removes the topmost register, dropping its value if it holds one.

Returns false when the top of the stack is not a register.

Source

pub fn pop_stack(&mut self, data_count: usize, capacity: Option<usize>) -> Self

Moves the top data_count values into a new stack of their own.

capacity sizes the new stack, and is raised when the values need more. Used to detach arguments for a call that runs elsewhere, for example on another thread.

Source

pub fn pop_to_register( &mut self, register: &mut DataStackRegisterAccess<'_>, ) -> bool

Moves the top value into a register, dropping whatever the register held.

Returns false when the types do not match or the stack is empty.

Source

pub fn store(&self) -> DataStackToken

Marks the current position, to unwind or reverse back to later.

Source

pub fn restore(&mut self, token: DataStackToken)

Unwinds down to token, dropping every value and register above it.

This is how a scope cleans up after itself.

Source

pub fn reverse(&mut self, token: DataStackToken)

Reverses the order of the items pushed since token.

Callers push arguments in declaration order while callees pop them in the same order, so the block has to be flipped in between. See DataStackPack::stack_push_reversed.

Source

pub fn peek(&self) -> Option<TypeHash>

Returns the type of the top item without moving anything.

A register reports the type tag of its header, not the type it stores.

Source

pub fn registers_count(&self) -> usize

Returns how many registers are alive.

Source

pub fn access_register( &mut self, index: usize, ) -> Option<DataStackRegisterAccess<'_>>

Takes a handle to one register, or None when the index is unused.

Source

pub fn access_registers_pair( &mut self, a: usize, b: usize, ) -> Option<(DataStackRegisterAccess<'_>, DataStackRegisterAccess<'_>)>

Takes handles to two different registers at once, for moving a value between them.

Returns None when the indices are equal or unused.

Source

pub unsafe fn prevent_drop(&mut self)

Stops this stack from unwinding its content when it is dropped.

§Safety

Everything still on the stack leaks unless its ownership was already handed to someone else, which is what DataStack::push_stack does.

Trait Implementations§

Source§

impl Drop for DataStack

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Finalize for T

Source§

unsafe fn finalize_raw(data: *mut ())

Drops the value stored at data in place. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.