From 888915402e8401bb922d30ac4f4debd1f129076a Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Sun, 13 Sep 2026 17:23:05 +0700 Subject: [PATCH] The backend first, then a freeze; any and drop are stashed --- NEXT.md | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/NEXT.md b/NEXT.md index eae5c98..176faad 100644 --- a/NEXT.md +++ b/NEXT.md @@ -1,3 +1,73 @@ +# 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, +**feature freeze for the rest of the day.** Work in flight may finish; nothing new starts. + +**Stashed, explicitly not wanted now:** `any` and `drop`. Both are designed, neither has a customer, +and the author's words are that they feel like extra language features. `any` is plan.org's opt-in +tagged union (two words, a pointer and a typeid, no GC). `drop` is `spec-memory.md`'s hook for owning +something that is not memory. Their old entries stand; do not schedule either. + +## The backend, in the order that finishes it + +`DISCUSS.md` item 16 is the report and its verdict is the sequencing: *"the wiring is done and it was +the easy half. What is left is conditions, and the measurement moved them from 'first obstacle' to +'the only obstacle'."* 40 of 111 programs lower today; the other 40 are refused by name. + +1. **Conditions, entire.** The transfer-channel guard after every call, the landing pad, the transfer + exit, `fdefers` on it, `emit_restart_case` and `emit_with_alloc`. Several hundred lines of + `emit.ml` **reimplemented from `spec-conditions.md` rather than ported**, because `emit.ml` writes + LLVM control flow and this writes bytes. The semantics are settled and the LLVM path is the oracle: + compare program output, never disassembly. + + The mechanism is three pieces. The transfer channel is a pointer passed as the last argument; after + every call, check whether it is set; a set channel jumps to a per-function landing pad that runs + the defers and either handles or re-propagates. + + `check_no_transfer` is what makes today's omission sound rather than hopeful — it walks the linked + program and refuses by name. It is also the measure of progress: the 40 refusals are 27 + `restart-case`, 7 `signal`, 4 `handler-bind`, 1 `with-allocator`, 1 `fdefers`. + +2. **Bounds checks**, which are the same work — `check_at` and `check_slice` cannot exist without the + guard. **Until they do, `--x86` is silently a `--no-bounds-checks` build**, and `bounds.flan` is + the one program that DIFFERs (exit 139 against LLVM's 134). Item 16 says this out loud and calls + deciding what a bounds violation means in a build with no handler one of two cheap things worth + doing first. Do that before item 1, not after. + +3. **`Rt` with an aggregate return**, and with it most of the container runtime. `Vec`, `Map` and + `Pool` have not been exercised through this backend at all. + +4. **`Fnval`'s indirection cell.** `FnAddr (Fnval n)` emits the symbol, which is right for a + whole-program build and wrong the instant anything is redefined into it. There are no cells and no + `--dev` here, deliberately — **but this is the one that decides whether the backend ever serves the + dev loop**, which is the reason it exists. Item 15's question 5, still waiting. + +5. **Size and speed, measured.** Nothing has a number on it. Every value is in memory, every + intermediate is a frame temporary, and a block copy is `rep movsb`. That is the trade the brief + asked for and nobody has checked what it cost. + +6. **Debug information.** None; `--x86` and `--debug` are refused together. + +Two known divergences that are deliberate and should stay written down: `(uninit)` is stable garbage +rather than `poison`, and `unreachable` is `ud2` rather than UB. Item 16 says to take item 15's +question 4 seriously now that there are two backends that can disagree. + +## Tightening the dev workflow — what is already known to want doing + +- **Finish the macro branch** (`worktree-agent-a859480edc827ab73`): `dune test` never ran on it. + `HANDOFF-macros.md` on that branch has six items. Its customer is `with-drawing`/`with-mode-2d`, + which removes a class of unbalanced-pair bug from every raylib program. +- **`slice-from-ptr`** — queued below. Blocks three raylib examples and leaves the hand-written `Font` + surface with no example caller. +- **`merged_serve`'s 10s warning path** (`lib/dev.ml:2322-2326`), the last item in `HANDOFF-f1.md`. +- **The memcheck half of the registry** — `VALGRIND_MAKE_MEM_UNDEFINED` in `flan_arena_proc`. The + registry answer and the memcheck answer are different tools and must not be blurred. + +## Not in the freeze, because it is already decided and unblocked + +**Generic structs and `$n` array lengths** — queued below with the Odin citations. It is a language +feature and the freeze says do not start it. Left here so it is not lost, not so it is picked up. + # Where this is — end of 2026-09-13 **Branch `dev-loop` at `861f591`, working tree clean, `dune test` green.** Read this section first;