diff --git a/NEXT.md b/NEXT.md index 2fdff00..e151fd9 100644 --- a/NEXT.md +++ b/NEXT.md @@ -1,3 +1,58 @@ +# Where this is — 2026-09-14, end of session + +**Branch `dev-loop` at `e7bb643`, tree clean, no branches but `dev-loop` and `master`, nothing running.** +`dune test` is 232 checks and 0 failures in about 47 seconds; `dune build @checks` runs `@page`, `@x86` and +`@cells` and is the thing to run deliberately. The survey is 103 MATCH / 0 DIFFER / 0 refused. + +## The core thesis is done + +`flan dev --x86` works. The hand-written backend now serves the editor, which is the only thing it was ever +for, and it is roughly twice as fast as the LLVM path: + +| | LLVM | `--x86` | +|---|---|---| +| `C-c C-c` at the socket | 62–66ms | **27–30ms** | +| `C-x C-e` | 60–61ms | **24–25ms** | +| codegen | `llc` 42–48ms | `as` **8.0–8.4ms** | +| link | `ld` 9.7–11.4ms | `ld` 8.9–9.3ms | + +Both rows were measured on this machine, because its `llc` is slower than the one `docs/BUILT.md` recorded. +What the headline hides is where the remaining time now sits: `ld` did not move and is half the x86 build, and +about 9ms of the round trip is the frontend re-checking the program — 14% of the LLVM loop but a third of this +one. The next millisecond is in the linker, not the code generator. + +## The one thing that does not work, and it is not small + +**`flan dev --x86` requires `--two-process` and refuses the merged daemon.** A merged host is `-rdynamic`, so +it exports every `flan.*` body, and those interpose the prelude bodies of the LLVM-built macro module the +compiler loads into itself. An LLVM caller lands in an x86 body and takes SIGSEGV inside `flan.[clamp]` during +the first macro expansion, before the program has started. `flan.abi.x86` does not guard this and was never +meant to — a macro module deliberately carries no marker. `-Bsymbolic` is the wrong fix. The honest one is +hidden visibility on a macro module's Flan bodies, and it wants its own lane. `start_merged`'s `--x86` +plumbing is written and correct, just unreachable. See `docs/handoffs/HANDOFF-x86-devloop.md`. + +## Still open, unchanged + +**`ArithError` established no restarts**, for the mechanical reason in `docs/handoffs/HANDOFF-arith.md`: the +runtime cannot push a restart frame on a program's behalf. The question is whether signal-and-die-with-a-location +is enough, or whether `saturate` belongs on the cast arm alone. + +**Frame descriptions are gated on `--debug`.** Correct in every build, free at runtime, and a release build is +where a crash would most want them. One `if` in three places. + +**The 2MB OFL font** `examples/text-codepoints-loading.flan` would like vendored. It runs without it and says so +on screen. + +## Settled this session, so nobody reopens it + +`dune test` stays fast and slow checks stay opt-in. `@page`, `@x86` and `@cells` are aliases, `@checks` is the +umbrella, and none of them is attached to `@runtest`. The reason is not cost in the abstract: the suite is run +constantly, including by every lane, so a second added to the default run is paid hundreds of times. Quick +tests for the inner loop, the full suite on purpose. + +`tools/` is empty. Both sweep scripts were deleted — they existed only to convert lanes that branched before a +rename, every such branch has merged, and both had stopped being able to tell a real hit from a false one. + # Where this is — 2026-09-14 morning, wrap-up **Branch `dev-loop` at `0661e60`, working tree clean, every lane merged, nothing running.**