Open Manual

Changelog

Nytrix uses dated milestones. Use ny --version for snapshots.

[0.10] - 2026-08-22 to 2026-09-11

Reliability, build portability, and dynamic ABI correctness

Fixed

ASCII and UTF-8 code-point slices, including open-ended bounds.

their declared field layouts and lowers scalar member reads with the field's

ABI (f32/f64/integer), covering user-defined records without type-name

hardcoding.

the managed-dictionary layout. The typed-dict assertion in type.ny passes;

that fixture remains open on nested-list indexing. Fresh uncached runs of

errors.ny, iter.ny, and collections.ny pass.

callback crash; the minimal regression now passes with caches disabled.

the builtin as an unknown raw extern call. Raw allocations now carry

explicit pointer provenance, so get rejects their contents as sequences

even when zeroed memory resembles a C string. The nil and raw-pointer

fallback reproducers pass with caches off.

destructuring pattern should unpack it into a scalar.

slot accessor before appending, avoiding a second integer tag. Native

string .get with a string fallback keeps its string result ABI. Clean

iter.ny and collections.ny fixture runs pass with result caching off.

(mod 4) branch. Bigint-to-int boundaries return raw scalar values, and

bigint clz/ctz calls use the raw runtime ABI.

element lists retain tagged decoding; odd byte values such as 3 no longer

become a second tag (7).

1-, 2-, 3-, and 4-byte sequences without losing the module-qualified call's

string value.

joins normalize raw scalar arm results before returning through an any

function boundary.

through rt_any_to_i64 a second time when an integer fallback is present;

values such as 7 remain 7 across an any receiver.

frame instead of being emitted as undeclared global symbols. This restores

loop-shaped dictionary construction and lookup, including 10,000 distinct

to_str(i) keys.

them, preventing one extra integer tag per recursion level in inline

flattening helpers.

from_int(...)) with the integer slot tag instead of classifying odd raw

payloads as already-tagged values. This fixes nested list reads.

their machine-form scalar representation through early-return and callback

lowering; iter.ny and the nested collection filter coverage pass.

sequence-element decoder in find_if and partition, preserving odd

integer payloads and nested handles across native any boundaries.

encoded byte width from the leading octet, so multibyte characters advance

by bytes even when string length metadata reports codepoints.

module-level list/dict values, eliminating the E1010 callable-resolution

storm; remaining strict diagnostics are reported at their actual dynamic

operation sites.

ok(v)/err(v) guards that previously double-tagged scalar payloads in the

LLVM/JIT path.

runs; the prior _char_list_to_str/swap_items rooting failure is closed.

boxing, untyped returns box raw scalar producers exactly once

(return_any), and raw consumers decode at their store boundary

(globals, locals, comma names). Fixed the foo(x){x*x} halving family

plus the parser, use, use/core, and sugar fixtures.

*_len_raw, builder handles, load64): untyped calls returning raw

machine words no longer classify as any, so odd raw words stop being

halved.

want_dynamic as a real constant register (raw integer arguments

previously arrived doubled, 21 as 43), rt_tbuf_dyn_elem selects

tagged/raw per argument, and dict literals keep proven-dynamic values

in their canonical word so integer zero no longer reads back as nil.

thread.ny passes in full.

untyped declaration triggered any-boundary boxing, so mapcat's first

list read saw tagged zero (1) and panicked with "index_read out of

range". Removes the crash class from sha256 and the mapcat flatten

family.

rt_dynamic_callable_base misread plain code addresses whose low

three bits equal the native tag as encoded values and pre-decoded

them, and rt_call_any1/rt_call_any2 decoded a second time after

the dynamic-callable decode. Callbacks in fnptr parameters jumped

into address/8 or /64; every mapcat-family fixture now reaches its

assertions instead of crashing.

integer tag instead of rt_value_tag (odd literals such as 17 were

mislabeled as tagged and read back halved), and elements unboxed

through rt_any_to_i64 get tags from the new rt_raw_word_tag.

dynamic values (container handles are no longer re-tagged on read),

and rt_tbuf_append_i64_raw re-registers its buffer after realloc

moves it.

arms once and int-returning functions decode tagged tails by the

tail's semantic. case.ny passes in full.

seeding callees with a constant-zero length; only proven RAW_INT

arguments keep the constant zero.

_match_at bound hoist, and _list_push_reserved handle rebinding;

nil, gc, struct, and the collections container and index

sections pass.

their tags. ownership.ny passes.

table.ny passes including the -7 fallback case.

attr, prolog, rewrite, and set-idx-filled.

cstr concatenation resolves semantically to str, so it escaped the

rt_any_* exclusion in return normalization and was tagged a second

time ("map string" turned every mapped char into a decimal address).

String-producing binary expressions are no longer re-tagged.

raw scalars". The inline-lambda marker guessed from the callee name

(strstr("filter")), unboxing integers for every filter/any/all

callback; the marker is chosen from the lambda body instead (bool tail

expression, parameter semantics), and a new tagged-args callable

encoding (bit 61, rt_mark_dynamic_bool_callable_tagged_args) keeps

the raw 0/1 result ABI while delivering canonical tagged arguments to

dynamic-parameter bodies. (v % 2) == 0 predicates compute again.

dynamic word, so callback arguments no longer shift-tag them a second

time (find_if handed its predicate tagged(tagged(x)) and compared

21 > 15), and their length slots seed rt_len instead of a constant

zero (_char_list_to_str measured slen=0 and returned empty strings;

swapped("abcd", 0, 3) returned "").

println(f(9)) printed the list handle as a decimal address and

f(9)[0] read the tagged encoding, because a conservative non-dynamic

semantic rep on an untyped declaration suppressed the any ABI.

descriptor lists, so is_str probes see a real string header and

_iter_is_seq/flatten split them; the is_str lowering also

accepts both TAG_STR (120) and TAG_STR_CONST (121) in the tag slot.

(ny_value_box_i64 handed back tagged 3 where the program compared

raw 1); shift-promotion.ny passes in full.

(rt_trace_func_raw, rt_trace_loc_raw, rt_trace_enter_raw,

rt_trace_ret_void_raw, rt_trace_exit_raw, rt_trace_dump_raw,

rt_print_flush_raw) and the identity rt_trace_ret_i64/u64/ptr

/f64_bits decode their tagged scalar argument once. trace.ny and

io.ny pass in full.

string keys (the string variants copy/intern; the i64 variants hashed

the key's pointer word). dict.nshape still mismatches on a

loop-shaped reproducer recorded in the TODO; the symbol selection is

a prerequisite for the remaining fix.

Changed

operands in the raw i64 domain, preventing tagged interpreter encoding

from corrupting Vulkan feature masks; dynamic operands retain the

tagged path.

before consulting process-wide leaf-name tables, preventing same-named

imported constants from changing a module's flag arithmetic.

module mutable values, removing another source of cross-module leaf

collisions.

lowering and LLVM/JIT registration; rt_native_tbuf_get remains as

the compatibility implementation and alias.

float tags when they cross dynamic list reads; the benchmark matrix

remains green.

accumulation across any boundaries; the native regression passes.

LLVM backends, including fannkuch, havlak, intops, sha256, and thread-

ring; the benchmark-correctness TODO is therefore closed.

rt_native_f64_round as a compatibility alias for generated code.

bridges; native floating-power lowering now uses rt_f64_pow.

it while the former bridge name remains available for compatibility.

creation, including spaced arguments and clean child reaping on the

native path.

integer arithmetic, and direct-Unicode X11 keysyms no longer use the

dynamic bitwise bridge. Added a focused cold regression probe for both

contracts.

descriptor reads and uses a fixed integer tag for statically scalar

locals; the cold correctness gate passes with sub-10µs native and LLVM

runtime.

source, and explicit-alignment metadata, with an explicit

array_len_known discriminator for symbolic extents.

rt_gettimeofday runtime bridge names; compatibility exports preserve

cached objects using the former rt_native_* spellings.

fixture process groups in one scheduler pass and retain timeout status

per worker, avoiding cumulative timeout/reap delays in compile-heavy

sweeps.

canonical raw SIMD bridges instead of emitting stale rt_native_*

symbols.

prefixes instead of depending on one fixed formula version.

remains a separate explicit gate.

whose current type-analysis implementation still depends on LLVM

types.

[0.9] - 2026-07-21 to 2026-08-21

Native tooling, and runtime reliability

Added

preserved as initial reaching definitions instead of uninitialized

zero rewrites, and added safe rollback on failure.

parameters are not overwritten with zero.

offset calculation in f64buf_new/i64buf_new and

f64buf_load/f64buf_store.

core/*.inc) to .h header format for syntax highlighting and

standard C toolchain support.

arrays, unions, packed structs, bitfields, extended numeric types,

function pointers, typedefs, macros, and variadics.

limits, bounded tables, and parser cleanup.

executable-memory remapping through mprotect, clone, fork, and

vfork.

runtime assertions with source expressions and file:line:col

diagnostics.

and source underlines.

managed heap initialization.

roots, modular operations, conversion, and number-theory helpers.

constraint solving, and string analysis.

Changed

command helpers live in src/base, the ny REPL in

src/cmd/ny/repl, parsing, runtime, and build wiring under

src/code, and frontend analysis, typing, canonical NYIR, native

emission, and LLVM integration now have dedicated directories. Build

manifests, cache dependency lists, tests, tooling, and documentation

use the canonical paths.

backend; src/code/native/llvm now owns LLVM terminals, and the

remaining direct AST-to-LLVM implementation is explicitly quarantined

pending its semantic parity gate.

instead of auto-selecting mold. NYTRIX_LINKER=lld|mold remains an

explicit optional acceleration, linker capability checks are re-

evaluated when selection changes, and duplicate native data symbols

are eliminated for strict GNU ld.

assert_compile, and compile-time range obligations before erasing

them; known-false proofs preserve their source diagnostic instead of

compiling as successful no-ops.

runtime/static counters, and enforceable benchmark budgets.

sampling with --bench-runtime-counters; the report artifact is

sampled outside timed runs and the counts are exported to console,

CSV, JSON, and Markdown.

unresolved calls, reports alias-uncertain raw-memory/unknown-call

sites, and the canonical bench runner can enforce zero-capable

allocation/helper/bounds/indirect/effect/alias/ spill/reload limits.

Linux benchmark reports can optionally collect perf stat

cycles/instructions/branch/cache counters outside timed samples.

function count, and largest specialized function, with benchmark

metadata budgets for both module-wide and per-specialization code

size. Bounds-check elimination also removes identical checks when an

earlier identical SSA check dominates the later one.

row with dynamic/tag/boxing/allocation/helper/bounds/effect/vectorizat

ion/regalloc counters, per-function emitted code bytes, explicit

monomorphized specialization byte attribution, and matching per-

function/hot-loop regalloc telemetry on x86-64 and AArch64.

formals into caller-local slots when safe, applies immediate

SCCP/CFG/DCE cleanup, gives bounded static loop-depth benefit credit,

and traces detailed accept/reject profitability reasons.

Monomorphization tracing now also explains recursion, unsupported-

shape, body-cost, cap, keyword/list-only, and missing-fact rejections.

bytes and compiler peak RSS using a report-only compile outside timed

samples. Bench fixtures can enforce compile-time, code-size, peak-RSS,

native/C, and native/LLVM budgets; CSV/JSON/Markdown preserve the

measured diagnostics and budget state.

loop counts, compare eligible vector widths, use retained range bounds

in profitability, and emit deterministic rejection reasons for

retained scalar loops.

repeated measurements, capture host/toolchain/revision metadata,

enforce optional per-fixture native/C and native/LLVM ratio budgets,

and highlight the largest backend gaps while keeping correctness smoke

runs separate from performance samples.

detected cycles instead of relying on instruction count plus an

arbitrary pass count.

setup cost, a guarded variable-trip vector bound, and scalar cleanup

tails; the x86 backend already folds encodable constants into

immediate forms instead of materializing them when the consumer

permits it.

pressure for GPR, FPR, and vector classes separately; x86-64 tier

reports attach those metrics to individual functions, and verifier

diagnostics include CFG block identifiers when available.

checksum; git lock entries continue to retain resolved commits.

TODO checkboxes into the performance guide.

modules before publication and invalidate prior cache protocols,

preventing repeated Invalid record failures after a cache hit.

as ny-test fixtures: etc/tests/errors/args/ asserts invalid flag

values fail with their diagnostic, and etc/tests/runtime/args/

asserts valid performance/runtime flag combinations compile and run.

Both run under ./make test.

provably-safe shifts (<<, >> with the shift count known in [0,

64)), and ordered comparisons, in addition to add/sub/mul/div/mod.

Proven-operand expressions emit inline raw-int IR with no tag-check

guard or BigInt fallback PHI (verified: 28 bin.runtime.slow blocks

to 0 for a mixed operator function under --profile=peak).

paths as peak (NYTRIX_RAW_INT_EXPR_FAST and the

NYTRIX_RAW_INT_EXPR_FAST_OPS operator list, whose default now covers

every supported operator kind).

of being staged through the previous FFI pipeline.

multiple valid Nytrix signatures without LLVM symbol collisions.

retaining the in-memory JIT path.

Fixed

and floating .get fallbacks at the dynamic-value boundary, with cold

coverage for direct reads and values forwarded through any

parameters.

so an early-returning imported call cannot leak its filename into

later module alias resolution.

shared ABI repairs; all native/LLVM checksums pass, including

fannkuch and thread-ring.

64-bit typed stores, including the socket-address construction path.

bytes directly instead of treating the dynamic load16 result as raw

data.

the C accept call, avoiding a dynamic dictionary extraction at the fd

boundary.

argument semantics.

SCEV wrap/CFG edge cases and safe IRCE/LICM preheader motion.

stable CFG labels/PHIs, scalar-IV remapping, and no duplicate exit

labels.

invalid architecture and inline-assembly guards.

exposes no unrestricted unsafe escape hatch, and unsupported C

constructs are rejected.

use std.core consumer.

fixed C11 portability issues in the frontend.

inconsistent native/GMP bigint allocation behavior.

handling, JIT exit-code propagation, and stencil cold/warm cache

detection.

[0.8] - 2026-07-13

Native execution, proof tooling, and platform parity

Added

Wasm with _ny_top_entry, explicit Nytrix env.__MD_ITALIC_2__

namespace. Explicit aliases opt into namespacing, while existing

Nytrix declarations retain precedence.

witnesses; false or dynamic obligations fail compilation, and ordinary

values cannot satisfy proof parameters. std.math.logic adds

evaluation, simplification, certificates, bounded solvers, rewriting,

and Prolog-style unification and backtracking.

Windows change notifications behind std.os.fs.watch, with an mtime

fallback.

time, output, and supported file limits, including suspended Windows

Job Object startup and explicit unsupported-limit reporting.

fixture and suite timeouts, and host-aware concurrency capped at eight

workers with 6 GiB reserved per worker.

Changed

formats, result oracles, JIT loading, and proof analysis now live in

focused modules.

executable without running it, while ordinary files and -c execute

through the selected host-native path.

selects immediate operands, indexes DCE label references once, and

preserves floating types across collapsed equivalence classes.

focused call body and frame-relative accesses in the native encoder.

maintained benchmark and native-oracle fixtures rather than release-

note timing samples.

MCJIT, and cache format updates reject mixed stdlib/user entries and

sanitizer-contaminated native objects.

producing the compiler and standard bundle.

totals.

reducing idle CPU use and edit-to-recompile latency.

provenance sidecar before loading, so interrupted or stale cache

entries return to normal compilation instead of being trusted.

Fixed

--verify-artifact rejects stale or malformed snapshots before reuse.

length; :load rejects corrupted v2 images before rebuilding

persistent state while continuing to accept older source-only

snapshots.

ranges, structural rankings, and duplicate detection. It ignores

strings, comments, multiline macros, control conditions, and call

continuations rather than reporting phantom C functions. ny-fmt

--selftest validates that scanner together with high-confidence

language-pattern checks.

list.append/extend results and set() calls on dictionaries

initialized as frozen {} literals, with stable NYAUD1120 and

NYAUD1119 diagnostics and practical fixes.

relocations per program bundle, so large straight-line call sites no

longer fail at the old 256-relocation transport ceiling.

functions (previously 64) and reject larger requests before lowering.

Portable NYIP bundles retain their separate 4,096-function NYIR VM

boundary.

parameter layouts on demand, without registering anonymous carriers as

builtin scalars. Installed system headers recover useful declarations

from unsupported syntax; project headers remain strict.

callees finalize before entry. Native-only link discovery also matches

JIT behavior and deduplicates source annotations.

preservation, eliminating nondeterministic native ELF results.

UBSan handling.

status, plain output, and valid LLDB diagnostics.

variadic C imports, trace/debug progress suppression, ELF32 return

bounds, watcher lifetime, parser recovery, and dictionary helper

ambiguity.

multi-platform workflow.

[0.7] - 2026-06-30

LLVM-free native backend and C interoperability

Added

format, and

--nyir-run, --nyir-dump-bin, and --nyir-run-bin.

RISC-V,

with debug-scoped WASM, BPF, PowerPC, MIPS, and AVR support.

relocations and

multi-function aggregation.

and

external linkers for supported native fixtures.

memcpy, memmove, memcmp, and memchr - strlen, strcmp, and

strchr

recursion - Register and stack-passed i64/f64 arguments, including mixed

calls - f32 arithmetic, comparisons, register/stack calls, and f64

observation - Narrow ABI returns: bool, u8, i16, and u32 -

Signed division, modulo, comparisons, arithmetic shifts, and high-bit

u32 immediates - __MD_ITALIC_1__p now:

reads to NYIR_LOAD_I64 - Supports __MD_ITALIC_0__p += value

debug VM,

and emits frame-relative lea on x86-64/i386.

later

local reads observe mutations.

layouts

without poisoning fallback.

load_layout.

unsupported field

shapes instead of silently dropping them.

hard aborts.

point to

Nytrix iterator syntax.

[0.6] - 2026-06-30

Fuzzing, crypto/math expansion, renderer polish

Added

string, and checksum workloads.

discovery.

lattice/factorization modules.

Changed

gradient/<use> support, and terminal 256-color output.

default;

proven-nonzero f64 division checks elided.

UCRT/MSYS2.

Fixed

probing.

[0.5] - 2026-06-05

Editor/viewer framework

Added

hierarchy, inspector, gizmos, transform tools, and runtime bootstrap.

Changed

arg) ret.

Fixed

[0.4] - 2026-05-30

Ownership, typed pipeline, CLI unification

Added

lambda/nested-collection inference, and monomorphic specialization.

mode.

time reflection.

pkg, ny new.

Changed

representations.

Fixed

values.

[0.3] - 2026-04-13

Graphics stack and platform expansion

Added

parser stack.

renderer paths.

added.

learning guide.

Changed

std.os.ui.window.

split.

the

code they cover.

graphics workloads.

Fixed

coverage expansion.

std.os.

[0.2] - 2026-03-09

Compiler, runtime, and stdlib foundation

Added

lowering.

bridge.

commands.

reflection

operators, effects, and the #main { ... } entry guard.

backends.

ECC/DLP,

hash/PRNG, and public-key crypto helpers.

baselines.

Changed

modules.

Fixed

issues

found by the initial test suite.

[0.1] - 2025-12-24

Prototype bootstrap

Added

CMakeLists.txt, src/cmd/ny/main.c).

testable tree.