From 6ff38f52bb8a3d765a99a4eceba3f7413b18289d Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Thu, 21 May 2026 04:18:52 +0900 Subject: [PATCH] lib/ww: migrate 5 typed amalloc sites to alloc(T{...})! (typed-9) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 0 critical lib/ww/ gap (frontend used by BOTH cstage + wwstage, not covered by phase0-mapper's selfhost/cmd/ audit). 5 typed-struct amalloc sites + 1 γ pointer-array + 1 α byte buffer: - lib/ww/ast.ww newnode (node, 20 fields, was 208u64 over-sized) - lib/ww/typ.ww newtype (tinfo, 13 fields, was 112u64 over-sized) - lib/ww/typ.ww tinfocachebind (tinfocacheent, was 32u64 sizelint-ok) - lib/ww/sym.ww newscope (scope, 6 fields, was 64u64) + buckets γ - lib/ww/sym.ww scopedefineinmodule (sym, 10 fields, was 112u64) - lib/ww/parse/parse.ww joindotted (α []u8 + .ptr extract) Retires 4 rule-7 over-sized amalloc workarounds plus a #36 tinfocacheent sizelint-ok. WHY-comments documenting the workarounds are dropped (no longer applicable — alloc(T{...})! sizes from the type table). ast.ww newnode's `fval = 0: f64` carries a 3-line WHY comment naming the 990_selfhost TK_FLOAT-count diff probe (lex.ww:382 precedent for the same cast pattern). Bare `0.0` here would shift the dump-diff token-input scope and break 990's byte-identity probe. β grow loops in lib/ww/lex/lex.ww:570,592 deferred — separate sweep. Verified 132/132 + 995_self_rebuild byte-identity. Net -63 lines. --- lib/ww/ast.ww | 9 +++-- lib/ww/parse/parse.ww | 12 +++---- lib/ww/sym.ww | 16 ++------- lib/ww/typ.ww | 16 ++------- selfhost/cmd/w6c/main.combined.ww | 53 +++++++++------------------- selfhost/cmd/wwdump/main.combined.ww | 53 +++++++++------------------- 6 files changed, 48 insertions(+), 111 deletions(-) diff --git a/lib/ww/ast.ww b/lib/ww/ast.ww index 5a16e0aa..8bbd5302 100644 --- a/lib/ww/ast.ww +++ b/lib/ww/ast.ww @@ -128,11 +128,10 @@ type node = struct { }; export fn newnode(a: *arena, k: nkind, file: str, line: i32, col: i32) *node = { - let n: *node = amalloc(a, 208u64): *node; // ≥ struct size - n.kind = k; - n.file = file; - n.line = line; - n.col = col; + // fval cast-init: 990's wwdump TK_FLOAT diff requires this file + // to tokenise identically through C and ww (lex.ww:382 has the + // same workaround for the cstage %g-formats vs ww-skips divergence). + let n: *node = alloc(node{kind=k, file=file, line=line, col=col, op=tkind.TK_NONE, str="", uval=0u64, fval=0: f64, lhs=nil, rhs=nil, cond=nil, body=nil, els=nil, list=nil, next=nil, attr=nil, exported=0, type_=nil, tsuffix="", nmod=""})!; return n; }; diff --git a/lib/ww/parse/parse.ww b/lib/ww/parse/parse.ww index bed314c8..8b8614e2 100644 --- a/lib/ww/parse/parse.ww +++ b/lib/ww/parse/parse.ww @@ -125,17 +125,17 @@ fn expectbindname(p: *parser, into: *str) bool = { // cross-module dependency. fn joindotted(a: *arena, head: str, tail: str) str = { let n: u64 = head.len: u64 + 1u64 + tail.len: u64; - let p: *u8 = amalloc(a, n + 1u64): *u8; + let buf: []u8 = alloc([], n + 1u64)!; let i: u64 = 0u64; let j: i32 = 0; - for (j < head.len) { p[i] = head[j]; i += 1u64; j += 1; }; - p[i] = 46u8; // '.' + for (j < head.len) { buf[i] = head[j]; i += 1u64; j += 1; }; + buf[i] = 46u8; // '.' i += 1u64; j = 0; - for (j < tail.len) { p[i] = tail[j]; i += 1u64; j += 1; }; - p[i] = 0u8; + for (j < tail.len) { buf[i] = tail[j]; i += 1u64; j += 1; }; + buf[i] = 0u8; let r: str; - r.ptr = p; + r.ptr = buf.ptr; r.len = n: i32; return r; }; diff --git a/lib/ww/sym.ww b/lib/ww/sym.ww index d625bcad..8583f8f6 100644 --- a/lib/ww/sym.ww +++ b/lib/ww/sym.ww @@ -65,11 +65,8 @@ fn hashstr(s: str) u64 = { }; export fn newscope(a: *arena, parent: *scope) *scope = { - let s: *scope = amalloc(a, 64u64): *scope; - s.parent = parent; - s.a = a; - s.nbuckets = NBUCKETS; - s.buckets = amalloc(a, (NBUCKETS: u64) * 8u64): **sym; + let buckets_sl: []*sym = alloc([], NBUCKETS: u64)!; + let s: *scope = alloc(scope{parent=parent, first=nil, last=nil, buckets=buckets_sl.ptr, nbuckets=NBUCKETS, a=a})!; return s; }; @@ -237,14 +234,7 @@ export fn scopedefineinmodule(s: *scope, name: str, mod: str, k: skind, t: *tinf }; b = b.hashnext; }; - let sy: *sym = amalloc(s.a, 112u64): *sym; - sy.name = name; - sy.skind = k; - sy.type_ = t; - sy.decl = decl; - sy.mod = mod; - sy.scope = s; - sy.hashnext = s.buckets[bi]; + let sy: *sym = alloc(sym{name=name, skind=k, type_=t, decl=decl, exported=0, is_const=0, mod=mod, snext=nil, hashnext=s.buckets[bi], scope=s})!; s.buckets[bi] = sy; if (s.first == nil) { s.first = sy; } else { s.last.snext = sy; }; s.last = sy; diff --git a/lib/ww/typ.ww b/lib/ww/typ.ww index 4a8ddef0..388525fc 100644 --- a/lib/ww/typ.ww +++ b/lib/ww/typ.ww @@ -87,9 +87,7 @@ type tinfo = struct { variadic: i32, nullable: i32, // #61 A.3: TY_TAGGED `(*T | void)` fold collapses to // 8B ptr slot (null is the void variant). Mirrors - // cstage Type.nullable (cmd/wcc/ww.h:430-433); - // slot sits in variadic's natural pad so amalloc(96) - // is unchanged. + // cstage Type.nullable (cmd/wcc/ww.h:430-433). name: str, under: *tinfo, slotsize: u64, // #61 A.5: stack-slot SSoT split from `size`. @@ -152,10 +150,7 @@ type tctx = struct { // ---- constructors ----------------------------------------------------- export fn newtype(a: *arena, k: tykind) *tinfo = { - // #61 A.5: grew tinfo by slotsize: u64 (96 → 104). Over-size to 112 - // per the bootstrap amalloc-undersize trap (selfhost/CLAUDE.md §1). - let t: *tinfo = amalloc(a, 112u64): *tinfo; - t.kind = k; + let t: *tinfo = alloc(tinfo{kind=k, size=0u64, align=0u64, sub=nil, alen=0u64, fields=nil, params=nil, ret=nil, variadic=0, nullable=0, name="", under=nil, slotsize=0u64})!; return t; }; @@ -270,12 +265,7 @@ export fn tinfocachelookup(c: *tctx, key: *node) *tinfo = { }; export fn tinfocachebind(c: *tctx, key: *node, val: *tinfo) void = { - // #36 (typed amalloc) — over-size the 24B tinfocacheent struct to - // dodge the cstage amalloc