Browse the docs

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#

silk
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#

silk
pub struct Slot

The 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#

silk
impl Slot

Associated function address#

silk
pub fn address<'storage, T>(slot: Intrinsic.Slot<'storage, T>) -> *mut T

Returns 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#

silk
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#

silk
pub unsafe fn take<'storage, T>(slot: Intrinsic.Slot<'storage, T>) -> T

Moves 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#

silk
pub unsafe fn copy<'storage, T: Copy>(slot: Intrinsic.Slot<'storage, T>) -> T

Returns 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#

silk
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.

View the source of this page