From b1cc67b36f5fe4fd724acd6d6bf4d59d3c165178 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Sun, 13 Sep 2026 21:27:03 +0700 Subject: [PATCH] Second handoff: the backend is correct and is not yet the dev backend --- NEXT.md | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/NEXT.md b/NEXT.md index 6428080..7dd115e 100644 --- a/NEXT.md +++ b/NEXT.md @@ -1,3 +1,73 @@ +# Where this is — end of 2026-09-13, second handoff + +**Branch `dev-loop` at `e725a5a`, working tree clean, `dune test` green, every lane merged.** +Nothing is running and nothing is half-built. Read this first. + +## The x86 backend is correct, and is not yet the dev backend + +`spike/x86/survey.sh` builds every program in `test/programs` and every probe in `spike/x86` both +ways and compares **stdout, stderr and exit status**: **97 MATCH, 0 DIFFER, 0 refused by name.** That +is up from 41/1/41 at the start of the day. Conditions, bounds checks, `Fnval`'s indirection cell and +`--x86 --dev` all landed. `DISCUSS.md` items 16, 17 and 18 are the three reports. + +**`HANDOFF-x86-rt.md` at the root has the remaining seven items in order.** Item 1 is the substantial +one and is the reason the backend exists: + +> **A redefinition emitter in `lib/x86.ml`** — the counterpart to `Emit.redefinition`, producing a +> `.so`. Until it exists the backend builds whole programs and cannot serve a single `C-c C-c`, which +> is where `DISCUSS.md` item 13's ~21ms of a 35ms redefinition actually lives. + +**And the constraint the last lane found, which is the thing not to rediscover:** publishing a cell an +LLVM-built module can store into puts an edge on `lib/x86.ml`'s own licence that *"a dev build is +compiled entirely by this backend and a release build entirely by LLVM, and the two never meet in one +process."* The two conventions agree on scalars and **disagree on every aggregate**, so an +`Emit.redefinition` module dlopened into an `--x86` host is correct right up until the first redefined +function takes or returns a struct. The answer is a redefinition emitter in `x86.ml`, not an aggregate +classifier. It is written into both files' headers. + +Items 2, 4 and 5 on that list are small. Item 3 (`f64` → `i64` out of range, `INT64_MIN / -1`) is a +**language decision and not backend work** — the two backends differ there today, deliberately. +Items 6 and 7 are debug information and a size/speed measurement, neither started. + +## Two things that were true this morning and are not now + +Worth stating because the notes elsewhere may still read the old way: + +- **`Rt` with an aggregate return was never a gap.** Every `rt` builder in `check.ml` answers `Unit`, + an `Int`, a `Ptr`, an `Alloc` or a `Handle`, with aggregates leaving through an out-pointer, and + `crossable` refuses an aggregate return from a `declare` outright. The refusal in `call_native` is + unreachable and building sret behind it would have been *wrong* — that path is the C boundary, where + SysV returns a 16-byte slice in `rax:rdx` rather than by hidden pointer. `Vec`, `Map` and `Pool` all + match; item 16's "unexercised" line was stale. +- **The header check is not opt-in.** `vendor/raylib/raylib-5.5.h` is committed and + `vendor/raylib/headers` names it directly. There is no `FLAN_RAYLIB_H`. + +## The dev loop, as it now stands + +Everything below works today on the LLVM path, which is the default and unaffected by any of the +backend work. + +`C-c C-c` a top-level form, `C-x C-e` an expression, `C-u` before either to mark a pause. +`C-c C-m` expands a macro one step and `C-u C-c C-m` to the fixpoint, into `*flan-macroexpansion*` +where `m` expands again in place. `C-c C-b` lists restarts at a break. `M-x flan-inspect-address`, +`M-x flan-allocations`, `M-x flan-leaks`. A watch keeps count, min, max, last and mean per label, +windowed to the editor's last tick. + +Macros come from imported packages, qualified like a `defn`, and a session expands the buffer's own. +`vendor/raylib/modes.flan` has five `with-*` macros over raylib's begin/end pairs, used at 35 call +sites. A failed evaluation no longer kills the session — `lib/dev.ml`'s `serve` guards the whole +request and `Session.eval` commits below the checker. + +## Queued, nothing blocked on a decision + +1. `HANDOFF-x86-rt.md`'s seven items, item 1 first. +2. `text_codepoints_loading` and `textures_image_processing` — ordinary porting now that + `slice-from-ptr` exists. +3. Generic structs and `$n` array lengths — decided, unblocked, sections below. **Stopped once + already because it was started against the author's freeze; do not start it without asking.** +4. `any` and `drop` — **stashed by the author deliberately.** Both designed, neither has a customer. + Do not schedule either. + # Decided by the author, end of 2026-09-13: the backend, then a feature freeze **Priority is finishing the x86 backend and tightening the dev workflow.** After the backend is done,