zena:memory

zena
import {…} from 'zena:memory';

Low-level access to WebAssembly linear memory and memory allocators.

Provides Memory for reading and writing typed values at raw byte addresses, and allocator implementations (Allocator, FreeListAllocator, BumpAllocator) for managing linear memory buffers.

Examples ​

zena
import { Memory, defaultAllocator } from 'zena:memory';

if (let (true, ptr) = defaultAllocator.alloc(64)) {
  let mem = Memory.default;
  mem.setI32(ptr, 42);
  let val = mem.getI32(ptr);
  defaultAllocator.free(ptr);
}

Classes

Memory

zena
final class Memory

Represents the WASM linear memory as an array-like object. Provides typed access to memory via operator overloading.

Properties
zena
static default: Memory
#

The default memory instance (memory index 0).

zena
byteLength: i32 { get; }
#

The current size in bytes.

Methods
zena
size(): i32
#

Get the current size of linear memory in 64KB pages.

zena
grow(pages: i32): i32
#

Grow linear memory by the specified number of pages. Returns the previous size in pages, or -1 on failure.

zena
getU8(ptr: i32): i32
#

Load an unsigned byte from the given address.

zena
setU8(ptr: i32, value: i32): void
#

Store a byte at the given address.

zena
getI32(ptr: i32): i32
#

Load a 32-bit signed integer from the given address.

zena
setI32(ptr: i32, value: i32): void
#

Store a 32-bit integer at the given address.

zena
getI64(ptr: i32): i64
#

Load a 64-bit signed integer from the given address.

zena
setI64(ptr: i32, value: i64): void
#

Store a 64-bit integer at the given address.

zena
getF32(ptr: i32): f32
#

Load a 32-bit float from the given address.

zena
setF32(ptr: i32, value: f32): void
#

Store a 32-bit float at the given address.

zena
getF64(ptr: i32): f64
#

Load a 64-bit float from the given address.

zena
setF64(ptr: i32, value: f64): void
#

Store a 64-bit float at the given address.

Operators
zena
operator [](index: i32): i32
#

Read a byte at the given index.

zena
operator []=(index: i32, value: i32): void
#

Write a byte at the given index.

FreeListAllocator

zena
final class FreeListAllocator implements Allocator
Implements Allocator

A free-list allocator that supports both alloc() and free().

Uses a simple first-fit free list. Each block has an 8-byte header: [size: i32, next: i32] (next is only used when block is free)

This is the recommended allocator for general use where memory needs to be reclaimed.

Constructors
zena
new(startPtr: i32)
#
Properties
zena
static default: FreeListAllocator
#

The default allocator, starting at byte 65536 (page 1) to avoid WASI console buffer overlap.

zena
allocated: i32 { get; }
#

Get approximate bytes currently allocated (not including freed).

Methods
zena
alloc(bytes: i32): inline (true, i32) | inline (false, _)
#

Allocate bytes bytes of linear memory.

zena
allocAligned(bytes: i32, align: i32): inline (true, i32) | inline (false, _)
#

Allocate with alignment.

zena
free(ptr: i32): void
#

Free a previously allocated pointer.

BumpAllocator

zena
final class BumpAllocator implements Allocator
Implements Allocator

A bump-pointer allocator for arena-style memory management.

Fast allocation (just increment a pointer), but free() is a no-op. Use reset() to free all allocations at once.

To create a BumpAllocator, first allocate a region from the root allocator:

zena
if (let (true, region) = defaultAllocator.alloc(4096)) {
  let arena = new BumpAllocator(region, 4096);
  if (let (true, ptr) = arena.alloc(64)) {
    // use ptr
  }
  arena.reset();  // Reuse the arena
  defaultAllocator.free(region);
}

Best for: temporary allocations with known lifetime, scratch buffers.

Constructors
zena
new(startPtr: i32, size: i32)
#

Create a BumpAllocator over a pre-allocated memory region.

startPtr

Start of the region (from another allocator)

size

Size of the region in bytes

Properties
zena
allocated: i32 { get; }
#

The number of bytes currently allocated.

zena
remaining: i32 { get; }
#

The number of bytes remaining in the arena.

Methods
zena
alloc(bytes: i32): inline (true, i32) | inline (false, _)
#

Allocate bytes bytes. Returns (true, ptr) on success, (false, _) if exhausted.

zena
allocAligned(bytes: i32, align: i32): inline (true, i32) | inline (false, _)
#

Allocate with alignment. Returns (true, ptr) on success, (false, _) if exhausted.

zena
free(ptr: i32): void
#

Free is a no-op for bump allocators. Use reset() instead.

zena
reset(): void
#

Reset the allocator to its initial state, allowing reuse. WARNING: This invalidates ALL previously allocated pointers!

Interfaces

Allocator

zena
interface Allocator

Interface for linear memory allocators. Libraries should accept Allocator to allow flexible memory strategies.

Allocation methods return (true, ptr) | (false, _) to force callers to handle allocation failures. Use pattern matching:

zena
if (let (true, ptr) = alloc.alloc(size)) {
  // use ptr
} else {
  // handle out of memory
}
Methods
zena
alloc(bytes: i32): inline (true, i32) | inline (false, _)
#

Allocate bytes bytes. Returns (true, ptr) on success, (false, _) on failure.

zena
allocAligned(bytes: i32, align: i32): inline (true, i32) | inline (false, _)
#

Allocate bytes bytes aligned to align (must be power of 2).

zena
free(ptr: i32): void
#

Free a previously allocated pointer. May be a no-op for some allocators.

Variables

defaultAllocator

zena
let defaultAllocator: FreeListAllocator

The default allocator for general use. Supports alloc() and free(). This is the FreeListAllocator.default instance.