checkpoint: MEM record-keeping — facade completion, phase ground truth, 2.2 state
Brings the MEM checkpoint up to the 2026-06-11 sessions: the std.sx pure-re-export facade arc (49a36bb/c75cd9c + issues 0120-0122), the allocator primitive rename (88bae3c), opt-in UFCS (a47ea14), Phase 2.2 typed helpers (84e0fb0), BufAlloc by-value init (51194a2); next step Phase 2.3 diagnostic wrappers. Older 2026-05-25-era records fold into collapsed details blocks.
This commit is contained in:
@@ -5,6 +5,39 @@ Tracking checkpoint for the mem.sx Zig-aligned implementation
|
||||
|
||||
## Last completed step
|
||||
|
||||
**Allocator primitive rename — `alloc`→`alloc_bytes`,
|
||||
`dealloc`→`dealloc_bytes` (`88bae3c`, 2026-06-11).** Phase 4's naming
|
||||
piece pulled forward per Agra's call (Option A in the 2.2 naming fork):
|
||||
the bare names free up NOW so the Phase 2.2 helpers land under their
|
||||
FINAL Appendix-A names (`alloc(T,n)` / `free(s)` / `create` / `destroy`
|
||||
/ `clone` / `resize` / `mem_realloc`) with zero later churn. Phase 4
|
||||
shrinks to signature expansion (size/align params + resize/remap +
|
||||
deinit) only.
|
||||
|
||||
What changed (signatures unchanged — 2-method era continues):
|
||||
- `std.sx` protocol decl; `std/mem.sx` 6 impls + internals; library
|
||||
call sites (glyph_cache/json/state/renderer); 13 example .sx files
|
||||
(incl. the two custom `Tracer` impls in 0306/0808 — caught broken
|
||||
mid-step by stdout-diff review BEFORE pinning; the first `--update`
|
||||
had captured their broken output, restored + fixed + re-pinned).
|
||||
- Compiler: `interp.zig` thunk-name lookups
|
||||
(`__thunk_CAllocator_Allocator_alloc_bytes`/`_dealloc_bytes`) — the
|
||||
ONE hard name coupling; `allocViaContext` + default-context emission
|
||||
are slot-positional (rename-safe); ffi.zig's `"alloc"` check is the
|
||||
Obj-C `Cls.alloc()` intercept (unrelated, untouched).
|
||||
- 37 `.ir` snapshots re-pinned (thunk symbols + reflection
|
||||
field-name strings); all 37 verified stdout-clean before update;
|
||||
path-noise churn reverted.
|
||||
- External repos migrated + gated: game (`main.sx`, SxChess.app
|
||||
builds + bundles) and m3te (`board_fx.sx`, `main.sx`,
|
||||
`tools/key_particle.sx`; tools/run_tests.sh 23/23). Obj-C zero-arg
|
||||
`.alloc()` calls are NOT protocol calls — excluded by pattern.
|
||||
|
||||
Gates: zig build 0, zig build test 0, suite 582/582, m3te 23/23,
|
||||
game rebuilt.
|
||||
|
||||
<details><summary>Prior steps (2026-05-25 era)</summary>
|
||||
|
||||
- **`resolveType(null) → .s64` silent fallback removed.** `resolveType`
|
||||
now takes a non-optional `*const Node`; the `null → .s64` branch is
|
||||
gone. Callers that legitimately had no annotation handle it
|
||||
@@ -140,8 +173,66 @@ Tracking checkpoint for the mem.sx Zig-aligned implementation
|
||||
of zeros, on both interp and codegen paths. 156/156 example tests
|
||||
+ chess clean.
|
||||
|
||||
</details>
|
||||
|
||||
## Current state
|
||||
|
||||
**std.sx-as-pure-re-exports plan COMPLETE** (2026-06-11,
|
||||
Agra-directed end-to-end). std.sx is now a facade of alias
|
||||
declarations only (`49a36bb`): implementations live in std/core.sx
|
||||
(builtins, libc escape hatch, Context/Allocator/Into/Source_Location/
|
||||
`string` — the reserved name needs and permits no alias), std/fmt.sx
|
||||
(print/format/any_to_string/string ops), std/list.sx (List); the
|
||||
namespace tail is unchanged and `core`/`fmt`/`list` carry alongside
|
||||
it. Consumer surface byte-identical; 37 .ir snapshots re-pinned
|
||||
(pure renumbering, digit-normalized diff empty).
|
||||
|
||||
Issues filed AND resolved along the way (all same-day,
|
||||
Agra-authorized): 0120 generic-struct head aliases (`f2db8ec`,
|
||||
example 0211), 0121 fn aliases of every kind incl. comptime-pack
|
||||
(`721369a`, example 0546), 0122 whole-program passes pinning the
|
||||
source context per decl (`340be40` — latent on master, exposed by
|
||||
the facade; coverage 0129/1047/1049/1052/1053/1056). Protocol
|
||||
aliases (plain + Into's xx path) and #builtin/#foreign aliases
|
||||
probe-verified working; param-protocol impl dot-calls are a designed
|
||||
opt-in gap, not a bug.
|
||||
|
||||
Gates at completion: zig build test 426/426, suite 588/588,
|
||||
m3te 23/23, game SxChess builds + bundles. Suite baseline 588.
|
||||
|
||||
**(2026-06-11) Phase-by-phase ground truth** (verified against the
|
||||
tree; the sections below this one are the 2026-05-25 era record):
|
||||
- Phase 1 DONE (xx heap-copy via context.allocator; serializer; the
|
||||
whole implicit-Context refactor).
|
||||
- Phase 2.1 DONE-equivalent: allocators.sx became `std/mem.sx` via the
|
||||
STDLIB restructure (`59f0aa7`).
|
||||
- **Primitive rename DONE (`88bae3c`)** — see "Last completed step".
|
||||
Protocol is `alloc_bytes(size)` / `dealloc_bytes(ptr)` (2-method
|
||||
era signatures).
|
||||
- Phase 2.2 helpers: NOT YET — next step. Final names per Appendix A:
|
||||
`create(a,$T)->*T`, `alloc(a,$T,n)->[]T`, `destroy(a,ptr)`,
|
||||
`free(a,slice)`, `clone(src,a)`, `resize(slice,a,n)`,
|
||||
`mem_realloc(a,ptr,old,new,align)`. The `free` helper requires
|
||||
REMOVING std.sx's bare `malloc`/`free` foreign decls (lines ~13-16;
|
||||
`libc_malloc`/`libc_free` aliases already exist) and migrating ~30
|
||||
bare uses (mostly examples) — fold into the helpers step.
|
||||
- Phase 2.3: TrackingAllocator exists; FailingAllocator +
|
||||
LoggingAllocator missing.
|
||||
- Phase 3 (caller migration to helpers): not started.
|
||||
- Phase 4: now signature-expansion only (alloc_bytes gains alignment;
|
||||
dealloc_bytes gains size+align; + resize/remap/deinit) — naming
|
||||
piece already landed.
|
||||
- Phase 5 (--leak-check + specs Memory chapter): not started.
|
||||
- NOTE: plan's "init returns Allocator via xx heap-copy" section is
|
||||
SUPERSEDED by the by-value convention (CLAUDE.md "Allocator
|
||||
construction"); BufAlloc.init still returns *BufAlloc (state lives
|
||||
in the caller's buffer — review at Phase 4 whether to align).
|
||||
- Suite baseline 582; gates now: zig build && zig build test &&
|
||||
bash tests/run_examples.sh (+ m3te 23/23 + game build for
|
||||
std-touching steps). The old 148-159 counts below are historical.
|
||||
|
||||
<details><summary>2026-05-25 era state (historical)</summary>
|
||||
|
||||
Phase 0.0c shipped (allocator API on one-line `init` returning `*T`;
|
||||
TrackingAllocator added). 148/148 tests pass.
|
||||
|
||||
@@ -270,8 +361,77 @@ bypass) is FULLY CLOSED. User-typed `context.allocator.X` flows
|
||||
through the real protocol vtable at codegen *and* runs the same
|
||||
chain at comptime in the interp. No remaining shortcut.
|
||||
|
||||
</details>
|
||||
|
||||
## Current state
|
||||
|
||||
**Opt-in UFCS landed (`a47ea14`, 2026-06-11)** — the canonical dot
|
||||
surface now works: `context.allocator.create(Session)`,
|
||||
`slice.clone(a)`. Agra specified the model in-session (three
|
||||
clarifying rulings): free-fn dot-calls are OPT-IN via
|
||||
`name :: ufcs (params) { body }` (NEW declaration form) or
|
||||
`name :: ufcs target;` (alias); plain fns are direct/`|>`-only with a
|
||||
tailored rejection. Implementation inverted TWO pre-existing gaps:
|
||||
unannotated fns used to dot-dispatch (removed; 6 example files
|
||||
audited + migrated, ZERO reliance in m3te/game) and aliases did NOT
|
||||
dot-dispatch at all (0036 only ever pinned direct+pipe). Generic ufcs
|
||||
fns bind `$T` from the receiver; protocol receivers dispatch own
|
||||
methods first, fall through to ufcs fns for non-members
|
||||
(protocolHasMethod gate in lower/call.zig). Root-cause bonus:
|
||||
`inferGenericReturnType` now delegates to `buildTypeBindings` (ONE
|
||||
binding builder) — structured generic params (`[]$T`) no longer type
|
||||
direct calls as `T{}` stubs. mem.sx helpers marked `ufcs`; specs.md
|
||||
§UFCS rewritten around the opt-in matrix. Tests: 0053 (matrix), 1166
|
||||
(rejection), 0838 re-pinned (dot+pipe+direct). Gates: 585/585, zbt 0,
|
||||
m3te 23/23, game builds. 0119 RESOLVED (final banner).
|
||||
|
||||
**Phase 2.2 DONE (`84e0fb0`, 2026-06-11).** The 0119 block resolved as
|
||||
a LANGUAGE RULING, not a compiler fix (Agra, in-session): dot-form UFCS
|
||||
on generic free functions is not the contract — UFCS free-fn
|
||||
dot-dispatch is the annotated `ufcs` alias mechanism (concrete
|
||||
targets), and the FLUENT spelling for free functions is the pipe:
|
||||
`context.allocator |> create(Session)` desugars at parse time to the
|
||||
direct call, which dispatches generics through normal monomorphization
|
||||
(verified for protocol + slice receivers). specs.md §UFCS corrected
|
||||
(it overstated "generic functions" for the dot form). Issue 0119
|
||||
carries the RESOLVED banner; residual unfiled corner: a `ufcs` alias
|
||||
naming a generic target doesn't dot-dispatch either.
|
||||
|
||||
Landed:
|
||||
- `std/mem.sx` typed helpers, era-complete bodies, final names:
|
||||
`create(a,$T)->*T`, `destroy(a,*$T)`, `alloc(a,$T,n)->[]T`,
|
||||
`free(a,[]$T)`, `clone(src,a)`, `resize(slice,a,n)` (fresh storage +
|
||||
copy + free-old; old slice dangles), `mem_realloc(a,ptr,old,new,
|
||||
align)` (alloc+copy+dealloc; align unhonored until the protocol
|
||||
carries alignment — documented inline). NO zero-init (Zig-aligned).
|
||||
- std.sx bare `malloc`/`free` decls REMOVED (libc_malloc/libc_free
|
||||
stay as the raw escape hatch); users migrated: examples
|
||||
0205/0604/0804/0806/0808/1610 + game/chess/pieces.sx.
|
||||
- Regression: examples/0838-memory-helpers.sx (whole surface, direct +
|
||||
`|>` spellings, TrackingAllocator balances 8/8). 37 .ir re-pins
|
||||
(constant-pool renumbering from the removed decls — the
|
||||
ISSUE-MEM-004 cascade; all verified stdout-clean pre-update).
|
||||
- KNOWN GAP: `string` does NOT bind a `[]$T` param (probe: "unknown
|
||||
type 'T'") — string-clone story deferred (sx string is [:0]u8-shaped;
|
||||
decide at Phase 4/5).
|
||||
|
||||
Gates: zig build 0, zbt 0, suite 583/583, m3te 23/23, game SxChess.app
|
||||
builds.
|
||||
|
||||
## Next step
|
||||
|
||||
**Phase 2.3 — diagnostic wrappers**: `FailingAllocator` (delegates to
|
||||
parent while budget remains, then alloc returns null) and
|
||||
`LoggingAllocator` (tag-prefixed prints, delegates) in `std/mem.sx`,
|
||||
2-method-era bodies, by-value `init` per the CLAUDE.md convention.
|
||||
Then Phase 3 (migrate std.sx/library/example callers to the helpers —
|
||||
NOTE std.sx itself cannot import mem.sx (circular); its internals keep
|
||||
alloc_bytes), Phase 4 (protocol signature expansion: alignment + size
|
||||
on the primitives, resize/remap/deinit — naming already landed),
|
||||
Phase 5 (--leak-check + specs Memory chapter).
|
||||
|
||||
<details><summary>2026-05-25 era next-step record (historical)</summary>
|
||||
|
||||
Phase 1.3 (closure env allocation through context) shipped in commit
|
||||
`8e21cc5`. Phase 1.4 (codegen serializer for all interp Value
|
||||
variants) shipped this session. Phase 1.2 (free / malloc through
|
||||
@@ -300,6 +460,8 @@ Open follow-ups, in roughly the order they make sense:
|
||||
the canonical buffer/string case is already handled by `[]T` /
|
||||
`string`.
|
||||
|
||||
</details>
|
||||
|
||||
## Phase 0.3 audit findings — chess allocator usage (closed)
|
||||
|
||||
After Step 5 / matchContextAllocCall removal, every consumer call
|
||||
@@ -324,6 +486,83 @@ Allocator value naturally.
|
||||
|
||||
## Log
|
||||
|
||||
- **2026-06-11 (latest)** — Redundant flat `#import "modules/std/mem.sx"`
|
||||
dropped from the facade (`c75cd9c`, Agra spotted it): the tail's
|
||||
`mem ::` import already covers the graph needs (ufcs helpers +
|
||||
CAllocator); the double import was duplicating lowered IR (~2.5k
|
||||
lines across 37 re-pinned .ir snapshots, output byte-identical).
|
||||
Gates: suite 588/588, zbt 0, m3te 23/23, game builds.
|
||||
- **2026-06-11 (prior)** — std.sx restructured to a pure re-export
|
||||
facade (`49a36bb`): all implementations moved to std/core.sx /
|
||||
std/fmt.sx / std/list.sx; std.sx = alias decls + namespace tail.
|
||||
En route, two more issues filed AND resolved: 0121 fn aliases
|
||||
(`721369a` — renamed aliases were broken for EVERY fn kind, not
|
||||
just packs; scan-time fn_ast_map registration via the shared
|
||||
alias-chain walk; example 0546) and 0122 ambient source-context
|
||||
bugs in convergeClosureShapeSets / checkErrorFlow / unknown-type
|
||||
loop (`340be40` — latent on master, exposed by the facade).
|
||||
Probe-verified before executing: protocols (plain + Into xx path),
|
||||
#builtin / #foreign aliases, reserved `string` (no alias needed or
|
||||
possible). 37 .ir re-pins (pure renumbering). Gates: zbt 426/426,
|
||||
suite 588/588, m3te 23/23, game builds + bundles.
|
||||
- **2026-06-11 (prior)** — Issue 0120 filed AND resolved (Agra-directed
|
||||
same-session fix). Found probing the std.sx-as-pure-re-exports
|
||||
restructure: generic-struct head alias (`BoxAlias :: Box;`) lowered
|
||||
silently to `.unresolved` → LLVM backend panic; cross-module
|
||||
`Box :: r.Box;` re-export invisible. Fix: `selectGenericStructHead`
|
||||
follows const-alias decls hop-by-hop from each ALIAS AUTHOR's source
|
||||
(`aliasedStructTemplate`, nominal.zig; `namespaceAliasVerdictFrom`
|
||||
for `ns.X` RHS), checked before the template map so a facade's
|
||||
same-name re-export beats an invisible global template; plus the
|
||||
missing "unknown type" diagnostic on the `.call` type-head tail
|
||||
(resolveTypeCallWithBindings). Also fixed PRE-EXISTING stale unit
|
||||
test (calls.test.zig UFCS plan — predated a47ea14's opt-in model;
|
||||
master was 425/426). specs.md Type Aliases + readme re-export
|
||||
section + Decisions Log updated. Regression: examples/0211 (+rich/
|
||||
+facade companions). Gates: zbt 426/426, suite 587/587.
|
||||
- **2026-06-11 (prior)** — BufAlloc.init by-value (`51194a2`, Agra
|
||||
request): init no longer carves its state struct off the buffer's
|
||||
head (`-> BufAlloc`, plain literal; the old `-> *BufAlloc` cost 24
|
||||
bytes of every buffer and returned null under min-size). The
|
||||
CLAUDE.md by-value convention now holds for ALL allocators.
|
||||
Regression: examples/0839 (full-capacity 64+64 on a 128 buffer —
|
||||
failed pre-fix; exact-fit, overflow, reset). 0129's pinned output
|
||||
unchanged. .ir churn: init's signature (sret) + renumbering.
|
||||
Gates: 586/586, zbt 0, m3te 23/23, game builds.
|
||||
- **2026-06-11 (earlier)** — Opt-in UFCS (`a47ea14`). Agra's model:
|
||||
dot-calls opt-in via `:: ufcs (...)` marker or `:: ufcs target;`
|
||||
alias; plain fns direct/`|>`-only. Parser (ufcs-fn form,
|
||||
FnDecl.is_ufcs), call-plan + lowering gates (calls.zig,
|
||||
lower/call.zig), protocol-receiver fall-through, generic dispatch
|
||||
with receiver-bound `$T`, inferGenericReturnType → buildTypeBindings
|
||||
(fixes pre-existing `T{}` mis-typing of structured-param generics).
|
||||
6 reliant examples migrated; mem helpers marked ufcs; specs §UFCS
|
||||
rewritten; tests 0053+1166+0838. 585/585, zbt 0, m3te 23/23, game
|
||||
builds. 0119 closed with the full arc in its banner.
|
||||
- **2026-06-11 (later)** — Phase 2.2 shipped (`84e0fb0`). Typed helpers
|
||||
in std/mem.sx (create/destroy/alloc/free/clone/resize/mem_realloc,
|
||||
era-complete bodies, no zero-init); bare malloc/free dropped from
|
||||
std.sx (6 example files + game pieces.sx migrated to libc_*). The
|
||||
0119 "blocker" resolved as Agra's language ruling: generic free fns
|
||||
are NOT dot-rewritten — fluent spelling is `|>` (parse-time desugar
|
||||
→ direct call → normal monomorphization; verified on protocol +
|
||||
slice receivers). specs.md §UFCS corrected; 0119 RESOLVED banner.
|
||||
Regression examples/0838 (direct + |> spellings; tracker 8/8).
|
||||
37 .ir re-pins (const-pool renumbering). Gates: 583/583, zbt 0,
|
||||
m3te 23/23, game builds. String-clone deferred (string doesn't bind
|
||||
[]$T — known gap noted).
|
||||
- **2026-06-11** — Allocator primitive rename (`88bae3c`): protocol
|
||||
`alloc`→`alloc_bytes`, `dealloc`→`dealloc_bytes` (2-method-era
|
||||
signatures unchanged). Phase 4's naming piece pulled forward (Agra
|
||||
Option A) so Phase 2.2 helpers land final-named once. Touched:
|
||||
std.sx decl, mem.sx 6 impls, 4 library files, 13 examples (incl.
|
||||
two custom Tracer impls — initially missed, caught by pre-pin
|
||||
stdout review after the first --update captured their broken
|
||||
output; restored, fixed, re-pinned), interp.zig thunk-name strings,
|
||||
37 .ir snapshots. Externals migrated + gated: game (SxChess.app
|
||||
builds) + m3te (23/23). Suite 582/582, zbt 0. Discriminator note:
|
||||
Obj-C `.alloc()` is zero-arg; Allocator `.alloc(size)` has an arg —
|
||||
the sed keyed on `\.alloc\((?!\))`.
|
||||
- **2026-05-25 (latest)** — `resolveType(null) → .s64` removed.
|
||||
Signature changed to non-optional `*const Node`; 12 callers
|
||||
surveyed and classified. The three unguarded ones — top-level
|
||||
|
||||
Reference in New Issue
Block a user