memory

The memory module provides low-level memory management functions for manual allocation and deallocation.

import "conjure/memory"

Core Allocation Functions

alloc

Allocates a block of memory of the specified size in bytes. Returns a raw pointer to the allocated memory. Panics if allocation fails (out of memory).

var ptr = memory.alloc(1024)  // Allocate 1KB
defer memory.free(ptr)

// Use the memory...

Signature:

func alloc(size usize) rawptr

free

Frees a block of memory previously allocated with alloc(). Passing a null pointer is safe and does nothing.

var ptr = memory.alloc(256)
// Use the memory...
memory.free(ptr)

Signature:

func free(ptr rawptr)

realloc

Reallocates a block of memory to a new size. The contents up to the minimum of the old and new sizes are preserved. Returns a raw pointer to the reallocated memory. Panics if reallocation fails.

var ptr = memory.alloc(100)
// Buffer is too small, grow it
ptr = memory.realloc(ptr, 200)
defer memory.free(ptr)

Signature:

func realloc(ptr rawptr, newSize usize) rawptr

Memory Operations

copy

Copies a specified number of bytes from the source memory area to the destination. The memory areas must not overlap. Returns the destination pointer.

var src = memory.alloc(100)
var dest = memory.alloc(100)
defer memory.free(src)
defer memory.free(dest)

// Copy 100 bytes from src to dest
memory.copy(dest, src, 100)

Signature:

func copy(dest rawptr, src rawptr, size usize) rawptr

set

Sets all bytes in a memory region to a specific value. Commonly used to zero-initialize memory.

var ptr = memory.alloc(256)
memory.set(ptr, 0, 256)  // Zero-initialize all 256 bytes

Signature:

func set(ptr rawptr, value u8, size usize)

Pointer Arithmetic

These functions enable alignment calculations and custom allocator implementations.

ptrToInt

Converts a raw pointer to an unsigned integer for arithmetic operations.

var ptr = memory.alloc(100)
var addr = memory.ptrToInt(ptr)
io.println("Address: #{addr}")

Signature:

func ptrToInt(ptr rawptr) usize

intToPtr

Converts an unsigned integer back to a raw pointer.

var addr usize = 0x1000
var ptr = memory.intToPtr(addr)

Signature:

func intToPtr(addr usize) rawptr

Alignment Utilities

DEFAULT_ALIGNMENT

The default alignment for allocations (8 bytes on 64-bit systems).

var alignment = memory.DEFAULT_ALIGNMENT  // 8

alignPadding

Calculates the padding needed to align an address to a given alignment.

var addr usize = 0x1003
var padding = memory.alignPadding(addr, 8)  // Returns 5 (to reach 0x1008)

Signature:

func alignPadding(addr usize, alignment usize) usize

alignForward

Returns the aligned address (rounded up to the alignment boundary).

var addr usize = 0x1003
var aligned = memory.alignForward(addr, 8)  // Returns 0x1008

Signature:

func alignForward(addr usize, alignment usize) usize

Type-Safe Allocation

new

Allocates memory sized for a specific type.

struct Player { x f32, y f32, health i32 }

var player = *Player(memory.new[Player]())
defer memory.free(player)

player.x = 100
player.y = 200
player.health = 100

Signature:

func new[T]() rawptr

Example: Dynamic Buffer

import "conjure/memory"

struct Buffer {
    data rawptr
    size usize
    capacity usize
}

func newBuffer(initialCapacity usize) Buffer {
    return Buffer{
        data = memory.alloc(initialCapacity),
        size = 0,
        capacity = initialCapacity,
    }
}

func freeBuffer(buf *Buffer) {
    memory.free(buf.data)
    buf.data = null
    buf.size = 0
    buf.capacity = 0
}

func grow(buf *Buffer, newCapacity usize) {
    buf.data = memory.realloc(buf.data, newCapacity)
    buf.capacity = newCapacity
}

Example: Aligned Allocation

import "conjure/memory"

// Allocate 256 bytes with 16-byte alignment (for SIMD)
func allocAligned(size usize, alignment usize) rawptr {
    // Allocate extra space for alignment
    var totalSize = size + alignment - 1
    var raw = memory.alloc(totalSize)

    // Calculate aligned address
    var addr = memory.ptrToInt(raw)
    var aligned = memory.alignForward(addr, alignment)

    return memory.intToPtr(aligned)
}