silk.mem.slot.
Initialization-state changes for one element slot of raw storage.
When to use#
Use these operations with silk.mem.raw_buffer when you implement a container. Application code
uses an initialized collection such as silk.collections.list.List, which tracks the slot states for you.
Details#
A slot is uninitialized or initialized. Slot.write changes an uninitialized slot to
initialized. Slot.take and Slot.dropValue change an initialized slot to uninitialized.
Slot.copy reads a Copy value and does not change the state. Each operation consumes the
slot selection, so one selection cannot be used two times. The slot does not record its state.
The container must keep its own record of which slots are initialized.
Gotchas#
Slot.take, Slot.copy, and Slot.dropValue are unsafe. The caller must prove that
the slot is initialized. A second Slot.write without a state change overwrites the earlier
value and does not drop it, so that value leaks. A slot index outside the buffer count traps
when you select the slot.
Examples#
Write a value, copy it, then take it#
import silk.mem.allocator { Allocator, OutOfMemoryError }
import silk.core.effect { Effect }
import silk.mem.layout { Layout }
import silk.mem.raw_buffer { RawBuffer }
import silk.mem.slot { Slot }
pub effect fn main() -> i32
! OutOfMemoryError {
let mut allocator = Allocator.systemAllocatorProvider()
let allocation = run Allocator.allocate(Layout.of<i32>())
|> Effect.provideMut<Allocator>(&mut allocator)
unsafe {
let mut buffer = RawBuffer.from<i32>(move allocation, 1)
Slot.write(RawBuffer.slot(&mut buffer, 0), 21)
let copied = Slot.copy(RawBuffer.slot(&mut buffer, 0))
let taken = Slot.take(RawBuffer.slot(&mut buffer, 0))
if copied + taken != 42 {
return 1
}
}
return 0
}Import as Slot with import silk.mem.slot { Slot }.
Public declarations: 1.
Slot#
pub struct SlotThe owner type of the slot operations. It has no fields and is never constructed.
Details#
import silk.mem.slot { Slot } gives access to Slot.write and the other operations. This struct
is not the builtin Slot<'storage, T> place type that silk.mem.raw_buffer.RawBuffer.slot returns.
A slot is uninitialized or initialized, and does not record its state. The container must keep its own record of which slots are initialized. Each operation consumes the slot selection, so one selection cannot be used two times.
Gotchas#
A second Slot.write without a state change overwrites the earlier value and does not drop
it, so that value leaks.
Implementation Slot#
impl SlotAssociated function address#
pub fn address<'storage, T>(slot: Intrinsic.Slot<'storage, T>) -> *mut TReturns the address of the slot as a non-null *mut T. It does not read or initialize the
slot.
Gotchas#
This function consumes the slot selection. The pointer holds no borrow and does not keep the storage alive. Each later access through the pointer must make sure that the storage is alive, that the slot has the necessary initialization state, and that no other access conflicts.
Associated function write#
pub fn write<'storage, T>(slot: Intrinsic.Slot<'storage, T>, value: T) -> ()Moves value into an uninitialized slot. After the call, the slot is initialized.
Gotchas#
The slot must be uninitialized. If it holds a value, write overwrites that value and does
not drop it, so the earlier value leaks. value must have the slot type T, with the same
lifetimes.
Associated function take#
pub unsafe fn take<'storage, T>(slot: Intrinsic.Slot<'storage, T>) -> TMoves the value out of an initialized slot and returns it. After the call, the slot is uninitialized.
Details#
The returned value keeps all lifetimes inside T. It does not keep the borrow of the storage.
Gotchas#
The caller must prove that the slot is initialized. If it is not, the behavior is undefined.
Associated function copy#
pub unsafe fn copy<'storage, T: Copy>(slot: Intrinsic.Slot<'storage, T>) -> TReturns a copy of the Copy value in an initialized slot. The slot stays initialized.
Gotchas#
The caller must prove that the slot is initialized. If it is not, the behavior is undefined.
Associated function dropValue#
pub unsafe fn dropValue<'storage, T>(slot: Intrinsic.Slot<'storage, T>) -> ()Drops the value in an initialized slot. After the call, the slot is uninitialized.
Gotchas#
The caller must prove that the slot is initialized. If it is not, the behavior is undefined.
Category: Memory.
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2.