Skip to content

Memory

Janus is built with Zig, but ordinary .jan source does not use Zig expression builtins. Raw memory exists as named library operations with profile boundaries. The rule is simple:

Zig may build Janus. Zig may not speak Janus.

Use std.mem only when the code is actually doing raw address or byte work. Ownership and allocation belong in std.alloc; value conversion belongs in std.conv.

func reinterpret[T](p: *auto) -> *T {.profile: sovereign.}
func realign[T](p: *auto) -> !*T
func pointer_from[T](addr: usize) -> *T {.profile: sovereign.}
func address_of[T](p: *auto) -> usize
func copy_bytes(dst: *u8, src: *const u8, count: usize) -> void

The canonical spelling is std.mem.reinterpret[T](p), std.mem.realign[T](p)?, std.mem.pointer_from[T](addr), std.mem.address_of[T](p), and std.mem.copy_bytes(...). If an implementation phase reaches the functions through a temporary alias or stub, that does not change the documented Janus surface.

reinterpret and pointer_from are dangerous by construction. They require :sovereign because the caller is asserting facts the compiler cannot prove. The current source syntax marks that boundary with an inline function profile pragma before the function body:

func device_register(addr: usize) -> *u32 {.profile: sovereign.} do
return std.mem.pointer_from[u32](addr)
end

realign is checked. It returns MemError.MisalignedPointer when the address does not satisfy the target type alignment.

address_of is observational: it exposes the address of an existing pointer as an integer. That still belongs in raw memory code, not ordinary application logic.

copy_bytes is raw byte movement. The caller owns the overlap and bounds contract.

std.mem no longer re-exports allocator modules. Import ownership APIs from std.alloc:

use std.alloc.arena
use std.alloc.page_allocator

Use std.alloc.arena for caller-owned bump allocation and std.alloc.page_allocator for page-backed system allocation. Older three-method allocator consumers use std.alloc.legacy_allocator until they migrate to the canonical layout-aware std.alloc.trait.Allocator.

Run the doctrine lint before changing standard library boundaries:

Terminal window
janus lint --stdlib-boundaries

The lint rejects allocator APIs in std.mem, raw pointer reinterpretation in std.alloc, and value conversion helpers in std.mem.

Do not write these in user .jan files:

Zig expression builtinJanus surface
@ptrCaststd.mem.reinterpret[T](p)
@alignCaststd.mem.realign[T](p)?
@ptrFromIntstd.mem.pointer_from[T](addr)
@intFromPtrstd.mem.address_of[T](p)
@memcpystd.mem.copy_bytes(dst, src, count)
@importuse module.path or use zig "bridge.zig"

If a foreign library or platform boundary needs Zig syntax, isolate it in an explicit graft or generated bridge. Inline graft zig do ... end bodies are embedded Zig escape hatches; their Zig syntax is not Janus syntax.

use std.conv as conv
func device_register(addr: usize) -> *u32 {.profile: sovereign.} do
return std.mem.pointer_from[u32](addr)
end
func buffer_addr(buf: *u8) -> usize do
return std.mem.address_of[u8](buf)
end
func checked_byte(n: i64) -> !u8 do
return conv.to[u8](n)?
end

pointer_from is for MMIO, boot code, and audited low-level bridges. It is not a value conversion. Use std.conv for value conversions.

Executable authority is not raw data in public Janus APIs. Do not expose func_addr: u64, handler_addr: usize, callback_addr: u64, or any equivalent integer-shaped function entry in user-facing code.

Public APIs should accept typed callables, generated actor or grain starters, opaque handles, executor/task values, or capability-bearing wrapper types. The compiler and runtime may lower a typed callable to an internal RuntimeEntryId, but that integer representation is bridge plumbing, not a Janus surface.

The canonical names are snake_case:

  • pointer_from, not pointerFrom
  • address_of, not addressOf
  • copy_bytes, not copyBytes
  • fill_bytes, not fillBytes
  • move_bytes, not moveBytes

CamelCase raw-memory names are Zig heritage and should not appear in new documentation, lessons, or examples.