Browse the docs

silk.mem.output.

Owned storage for one Copy value that a foreign function writes through a pointer.

When to use#

Use this module to call a foreign function that returns its result through an output pointer, such as int get(T* out). Make an Uninitialized value, pass Uninitialized.address to the function, and then call Uninitialized.assumeInitialized and Initialized.into.

Details#

Each state owns one allocation. The type tells you if the value is initialized. Uninitialized.initialize and Uninitialized.assumeInitialized consume the uninitialized state. Initialized.into consumes the initialized state, returns the value, and releases the allocation. A state that is dropped releases its allocation and does not read the value.

Gotchas#

The address does not keep the storage alive. The foreign function must not keep the address after it returns. Uninitialized.assumeInitialized is unsafe, because only the caller knows that the foreign function wrote a complete, valid value.

Examples#

Let a function write the result through a pointer#

silk
import silk.mem.allocator { Allocator, OutOfMemoryError }
import silk.core.effect { Effect }
import silk.mem.output { Initialized, Uninitialized }
import silk.mem.pointer { Pointer }

// This function stands in for a foreign function such as `void answer(int32_t* out)`.
fn answer(out: *mut i32) -> () {
  unsafe {
    Pointer.write<i32>(out, 42)
  }
}

pub effect fn main() -> i32
  ! OutOfMemoryError {
  let mut allocator = Allocator.systemAllocatorProvider()
  let mut storage = run Uninitialized<i32>.make() |> Effect.provideMut<Allocator>(&mut allocator)
  answer(Uninitialized<i32>.address(&mut storage))
  let filled = unsafe Uninitialized<i32>.assumeInitialized(move storage)
  if Initialized<i32>.into(move filled) != 42 {
    return 1
  }
  return 0
}

Import as Uninitialized with import silk.mem.output { Uninitialized }.

Public declarations: 2.

Uninitialized#

silk
pub struct Uninitialized<T: Copy>

Owned storage for one T that does not hold a valid value yet.

When to use#

Use it to call a foreign function that returns its result through an output pointer, such as int get(T* out). Pass Uninitialized.address to the function, and then call Uninitialized.assumeInitialized and Initialized.into.

Details#

It owns one allocation. Dropping it releases the allocation and does not read the value.

Initialized#

silk
pub struct Initialized<T: Copy>

Owned storage that holds one valid T. Initialized.into returns it.

Implementation Uninitialized<T>#

silk
impl<T> Uninitialized<T>

Associated function make#

silk
pub effect fn make<T: Copy>() -> Uninitialized<T> ! OutOfMemoryError ? &mut Allocator

Allocates storage for one T. It does not write a value.

Errors#

  • OutOfMemoryError if the Allocator cannot supply the storage.

Method address#

silk
pub fn address<T: Copy>(self: &mut Self) -> *mut T

Returns the address of the storage, to pass to a foreign function. It does not read or write the storage.

Gotchas#

The address does not keep the storage alive. The foreign function must finish with it before self is consumed or dropped.

Method initialize#

silk
pub fn initialize<T: Copy>(self: Self, value: T) -> Initialized<T>

Writes value into the storage and returns the initialized state.

Method assumeInitialized#

silk
pub unsafe fn assumeInitialized<T: Copy>(self: Self) -> Initialized<T>

Returns the initialized state after foreign code wrote the value.

Gotchas#

The caller must prove that the storage holds a complete, valid T. A partial write, bytes that were not written, or a value that is not valid for T, such as a bool other than 0 or 1, gives undefined behavior.

Implementation Initialized<T>#

silk
impl<T> Initialized<T>

Method into#

silk
pub fn into<T: Copy>(self: Self) -> T

Returns the value and releases the storage.

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