System Primitives and Runtime

This page describes the operational clean LLVM compiler. Low-level operations are part of seed itself, not an addon language, but ordinary applications should consume narrow audited safe wrappers.

Runtime profiles

Profile Meaning
hosted platform runtime services selected by the target
freestanding libc-free image with explicitly selected services
kernel kernel ABI/service restrictions and no hosted assumptions
none no runtime services beyond target/compiler primitives

Effects (alloc, blocking, panic, I/O) are checked against the selected profile/service set. Profiles do not change ownership/type semantics.

Linux-native hosted execution has no mandatory libc. linux-libc is an explicit interoperability runtime choice. Freestanding/kernel targets remain libc-free.

Typed raw memory

unsafe fn use_buffer() -> result<i64, alloc_error> {
    let pointer = raw_try_alloc<i64>(4)?
    raw_write<i64>(pointer, 0, 42)
    let value = raw_read<i64>(pointer, 0)
    raw_free<i64>(pointer)
    result.ok(value)
}

An extern ABI that returns process/static-lifetime view storage may declare @static_view. This is a trusted provenance assertion restricted to extern; the call remains unsafe and an ordinary safe library wrapper must audit the foreign lifetime guarantee.

The clean unsafe substrate is raw_try_alloc<t>, raw_null<t>, raw_is_null<t>, raw_read<t>, raw_write<t>, raw_free<t>, and raw_slice<t>. Allocation rejects negative counts, multiplication overflow, and allocator failure with alloc_error. Unsafe callers remain responsible for extent, alignment, initialization, provenance, aliasing, and exact-once element release.

raw_null<t>() produces the internal null sentinel used by audited unsafe owners, and raw_is_null<t>(pointer) tests it. The standard box<t> confines those operations behind its constructor, consuming extraction, and destructor.

Linux-native allocations whose payload plus header fits 8 KiB and whose alignment is at most 16 bytes use precise slab classes (16 bytes through 8 KiB). Empty 1 MiB slabs share a process-wide 32-entry cache; excess empty slabs are unmapped. Larger or more strictly aligned allocations remain page-rounded direct mappings and are unmapped immediately.

The native runtime also supplies optimizer-introduced memcpy, memmove, and memset entry points without libc. Its sqrt(f64) runtime symbol lowers to the LLVM square-root intrinsic, allowing strict floating-point workloads to remain libc-free.

Legacy alloc(type,n), integer-address read/write, and free examples belong to archived backends and are not the clean compiler API.

Address spaces and devices

Raw pointer types may identify user, kernel, physical, mmio, or dma address spaces. They remain distinct through .sdi and LLVM lowering. Typed volatile operations and explicit unsafe mapping/cast transitions are used for device memory. compiler/llvm/libs/system builds safe nominal wrappers for MMIO, pages, pin/DMA, initialization, and CPU-local mechanisms.

Atomics

The compiler validates acquire/release helpers and explicit ordered load, store, fetch-add, exchange, compare-exchange, and fence operations. Invalid load/store/CAS ordering combinations are rejected. Atomics are distinct from volatile device access. A safe wrapper must establish allocation lifetime, alignment, shared access, and a consistent atomic protocol.

FFI and ABI

The target/ABI layer assigns explicit internal seed, public seed, platform-C, compiler-builtin, entry, interrupt, and naked ABI classes. .sdi includes target, ABI, build-profile, runtime-profile, and runtime-feature identity; known seed artifact mismatches fail closed with a rebuild diagnostic. Foreign C/assembly objects have no seed profile metadata and remain explicitly linkable.

Covered FFI boundaries include scalars, raw pointers, non-capturing callbacks, opaque handles, and pointer-based scalar C-struct wrappers. By-value C structs and richer platform ABI modeling remain limited. Foreign calls are unsafe until wrapped by a checked safe API.

Panic and cleanup

Safe check failure invokes the target panic/trap policy. Panic, trap, and abort never unwind across seed, FFI, dynamic-library, interrupt, kernel/user, or task boundaries. No lexical cleanup or user destructor runs on those edges.

Separate runtime and libraries

Compiler-builtins use stable runtime symbol IDs rather than source-name string inspection. Hosted executable runtime services include allocation/resource operations, process entry/args/environment, output/files, time/randomness, network descriptors, scheduler hooks, regions, panic, and abort at the level implemented by each target row.

seed_runtime_format_write consumes the stable immediate format_args descriptor and writes each {pointer, byte_length} piece without building a contiguous buffer. format_args.to_string() instead uses the selected allocator and reports failure as alloc_error; neither path requires libc.

Dynamic libraries declare required runtime symbols and resolve against the executable/runtime domain. Installed libraries are target/ABI qualified; dynamic linkage is default and --static selects static seed archives. Process libraries use the public seed_runtime_process_* boundary. Native entry-vector primitives such as seed_process_argc remain hidden inside the executable and are reached only through exported runtime wrappers.

Target levels

The declarative target matrix separates LLVM/object emission from static link, dynamic link, executable, and run levels.

See seed/compiler/llvm/tests/GATE14_TARGET_MATRIX.tsv rather than inferring capabilities from the presence of an LLVM triple.

Boot meaning

For Gate 7, “boot” means the compiler emits a target image, QEMU system emulation loads it through the declared firmware/machine path, target entry code executes, writes the expected success evidence through the target mechanism, and exits or reaches the expected terminal state. It does not mean that a full operating system, driver stack, userspace, or libc is present.

Release profiles

--release and --release-small preserve safe checks. LLVM may remove checks only when proved redundant. ThinLTO, PGO, static linkage, code/relocation model, red-zone policy, entry, linker script, target, runtime profile, and sysroot are explicit independent controls.