selfhost: retire dotchain bundle workaround (closes #17)

dotchain struct + bundle pre-declares retired. dotchainresolve now
takes 6 direct out-params; per-iter locals declared inline. Bootstrap
ww2==ww3==ww4 byte-identical — end-to-end validation of session's
N_DOT / N_INDEX / TK_AMP / fldloadop fixes.

i64 widths retained on out-params via task #19 workaround (i32 deref-
stores leave caller slot upper 4B stale, MOVQ reads zero-extend to
garbage). Documented in selfhost/CLAUDE.md active-workarounds.
This commit is contained in:
2026-05-14 01:11:07 +09:00
parent f26c86f5b7
commit 5f87c60e6c
6 changed files with 383 additions and 417 deletions

View File

@@ -8,6 +8,8 @@ The C bootstrap's cgen has known silent-miscompilation traps. They produce wrong
1. **`amalloc(n)` with n < struct size silently corrupts neighbours.** No error — the bump arena hands out n bytes and field writes overflow into the next record. When introducing or growing a struct, audit every `amalloc(_, n)` call site and over-size (we routinely pass 48 for a 40-byte struct). Symptom: linked-list prepends lose all but the most recent entry.
2. **Out-param `*p: *i32` deref-stores leave caller slot's upper 4 bytes stale.** `*p = v` lowers to MOVL (4B), but the caller's 8B slot was zero-init via MOVQ; a later i64-widening read emits MOVQ (8B raw) and zero-extends, so a negative i32 round-trips as a 4G-rooted positive i64. Default to `*i64` out-params for offsets / signed indices until task #19 lands. Symptom: garbage frame offsets like `MOVL AX, 4294967280(BP)` in stage-2 asm.
Fixed (no workaround needed):
- `def NAME: str = "..."` field access. `.len`/`.ptr` on an Sdef ident