← board

Cross-target language-feature parity (Intel + ARM)

Target scope (decided 2026-06-17)

In scope now — the four Linux targets, in two families:

Deferred until Intel + ARM parity is done and tested: the embedded targets — Xtensa and RISC-V (RV32) / ESP32. They already self-host codegen, but the language-feature port (classes, async I/O, external symbols, …) is not chased on them in this arc. Reopen the ESP/embedded path (feature-esp32-*) once x86-64/i386/aarch64/arm32 are at full parity. Rationale: keep the audit bounded to the four hosted targets where QEMU oracles are cheap and the byte-identical fixedpoint is already proven; embedded RAM/ABI constraints are a separate concern, best handled after the feature set is settled.

Motivation

The four Linux targets (x86-64 / i386 / aarch64 / arm32) all self-host byte-identical, but feature coverage is uneven — a pile of capabilities only work on x86-64. The cross suites quietly skip them, so the gaps are easy to overlook. This ticket is the audit + close-out: enumerate every x86-64-only feature, build a parity matrix, and bring the cross backends up to it — proving, by making the cross suites run the same feature set, that nothing major was missed.

Known gaps (original audit 2026-06-16 — most now RESOLVED; see Log)

Historical enumeration. Classes-on-cross (#1), external/dynamic symbols (#3), method-pointer fixups (#4), the async-I/O reactor and interfaces are done on all four targets (see Log 2026-06-17 / 2026-06-19). For the authoritative current per-target residue (e.g. SetLength on a var-array param, RTTI/LFM on cross) consult devdocs/developer/feature-matrix.md, not this list. Kept below as the original scope record.

  1. Classes / objects — the big one. i386/aarch64/arm32 codegen errors with "class instantiation not yet supported". Blocks: T.Create, fields/methods on instances, virtual dispatch (VMT), constructors/destructors, the object reference type (feature-object-reference-type), interfaces (feature-interfaces), method pointers (of object, already cross-ready in codegen — see feature-procedural-types), and all of LCL/GTK. This is the gating item for real OOP on cross.
  2. Async reactor / sockets / timers — x86-64-only. The scheduler + CoSwitch
    • channels already run on all 4 targets; the epoll reactor, asyncnet, and CoSleep are gated on x86-64 syscall numbers. Cross needs per-arch numbers (note: aarch64/arm32 have epoll_pwait, not epoll_wait; socket syscall numbers differ; i386 may use socketcall) + the cross test wiring.
  3. External (dynamic) symbols — the i386/arm32 ELF writer blocks them ("external (dynamic) symbols not yet supported"). C-library imports (libc, GTK, libm) are x86-64-only → networking-via-libc and the GUI are x86-64-only.
  4. Method-pointer data fixups (MethodFixups) — i386/arm32 ELF writer blocks them; needed for class VMTs / streaming on cross.

Async sub-track (folded in from feature-async-language-surface)

The async language surface is already shipped byte-identical on all four targets: ; async; directive + await marker, the stackful default, the stackless state-machine backend (; async; stackless;), configurable small coroutine stacks + overflow canary, scheduler/channels. So async is not a cross gap at the language-surface level. What remains (open items inherited from that ticket, now tracked here):

See feature-async-language-surface for the locked spelling and transform detail.

Plan

  1. Audit pass: extend devdocs/developer/feature-matrix.md into a real per-target matrix (✓ / ✗ / partial for each feature × {x86-64, i386, aarch64, arm32}); each ✗ becomes a checklist item here. Grep the four backends for not yet supported / not supported to seed it.
  2. Classes on cross targets (largest sub-arc — may split into its own ticket): instantiation (VMT init + ctor call), field/method access, virtual dispatch, constructors, the MethodFixups ELF path. Unblocks method pointers
    • objects + interfaces cross.
  3. Reactor/sockets/timers cross: per-arch syscall numbers; run reactor/asyncecho/timer suites on i386/aarch64/arm32 under QEMU.
  4. Re-run the whole suite per target; every feature that exists on x86-64 either runs identically on the cross targets or has an explicit, recorded reason it cannot.

Acceptance

A committed per-target feature matrix with no unexplained ✗; classes + method pointers + the async I/O stack run on i386/aarch64/arm32 (or carry a documented structural reason); the cross test suites exercise the same feature set as test-core; bootstrap + cross-bootstrap stay byte-identical.

Log