diff --git a/NEXT.md b/NEXT.md index ef6cca1..bff3e87 100644 --- a/NEXT.md +++ b/NEXT.md @@ -57,8 +57,9 @@ question 4 seriously now that there are two backends that can disagree. - **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. +- ~~**`slice-from-ptr`**~~ — **built**, see below. `examples/text-rectangle-bounds.flan` is the port it + unblocked, and the first example to call the hand-written `Font` surface. The other two it named — + `text_codepoints_loading` and `textures_image_processing` — are now ordinary porting work. - **`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. @@ -131,10 +132,11 @@ the Emacs side". **Superseded** — the registry lane built that properly. Delet fits in `defvar` globals, nothing is move-only, and generics is off its critical path. Tier 0 and Tier 1 items 4, 5 and 6 are all done. Nothing blocks writing it. -## Landed: a pointer from C gets a length, and `slice-from-ptr` is how it says so +## Landed: a pointer from C needs a length before it can be indexed -> **Built.** `(slice-from-ptr p n)` is in `lib/check.ml`, `Tast.SliceFromPtr` in `lib/tast.ml`, one `insertvalue` -> pair in `lib/emit.ml`. The section below is kept as it was written; what was built and what it refuses is here. +> **Built, 2026-09-13.** `(slice-from-ptr p n)` is in `lib/check.ml`, `Tast.SliceFromPtr` in `lib/tast.ml`, one +> `insertvalue` pair in `lib/emit.ml`. The section is kept as it was written, because the reasoning is the part +> worth having; what was built and what it refuses is in this box. **Option 1, and only option 1.** The reasoning below still holds: option 2 cannot reach `font.recs`, where the count is a sibling *field*, so option 1 was the floor and turned out to be the whole thing. @@ -162,7 +164,7 @@ is the one place raylib's invariant (both arrays hold `glyph-count` entries) is is the port that motivated all of it and it runs; `test/programs/slice-from-ptr.flan` covers the form with no raylib, no window and no C. -## Queued: a pointer from C needs a length before it can be indexed +### The reasoning, as it was written **Sequenced after the generics lane**, which holds `lib/check.ml`. diff --git a/examples/text-rectangle-bounds.flan b/examples/text-rectangle-bounds.flan index f32f8e6..25e4da0 100644 --- a/examples/text-rectangle-bounds.flan +++ b/examples/text-rectangle-bounds.flan @@ -36,10 +36,12 @@ ;;;; ;;;; - `GetCodepoint` wants a pointer into the middle of the text, and Flan has ;;;; the operation the C is spelling by hand: `(string (slice b i n))` is the -;;;; tail from `i` with no copy and no pointer arithmetic. The shim -;;;; NUL-terminates a copy on the way into C, so the call costs a scan of the -;;;; remaining bytes rather than nothing — fine for a 250-byte string drawn -;;;; once a frame, and worth knowing before reaching for it in a hot loop. +;;;; tail from `i` with no copy and no pointer arithmetic. It is not free: +;;;; the shim NUL-terminates a copy on the way into C, into a 256-byte stack +;;;; buffer or a malloc when the tail is longer — and this message is 284 +;;;; bytes, so the first thirty glyphs of each pass do allocate. Fine for one +;;;; string drawn once a frame; worth knowing before reaching for the same +;;;; shape in a hot loop. (import rl "vendor:raylib")