lib/ww + wcc + w6c + wwdump: strip *arena cascade (γ-6)
amalloc has 0 callers post-γ-2; the *arena threaded through
newnode/newscope/newtype/prim/typesinit/type{ptr,slice,array,chan,
named}/lexinit/parserinit/joindotted/checkinit/arenau64tos/cgeninit
and the scope.a / tctx.a / lex.a / parser.a / checker.a / cgen.a
fields are vestigial.
Drop `import mem;` from 15 files, remove six struct fields, strip
*arena from 14 signatures, update ~120 call sites across lib/ww +
wcc + w6c + wwdump. selfhost/test/sym_link.ww fixture drops the
newarena/freearena probe; still exits 42 on scopedefine/scopelookup.
Both main.combined.ww auto-regenerated.
Comments retidied: typ.ww "once per arena" → "once per program";
parse.ww drops "arena-build" qualifier on joindotted; sym.ww drops
mem-sibling-imports rationale.
Verified 132/132 incl. 994_w6c_ww + 995_self_rebuild byte-identity
(the primary symmetric-stages gate).
This commit is contained in:
@@ -20,11 +20,9 @@
|
||||
package wcc;
|
||||
|
||||
import os;
|
||||
import mem;
|
||||
import tok;
|
||||
|
||||
type checker = struct {
|
||||
a: *arena,
|
||||
tc: *tctx,
|
||||
top: *scope,
|
||||
cur: *scope,
|
||||
@@ -72,11 +70,11 @@ fn seedprimitives(c: *checker) void = {
|
||||
// separate alias chain — see collectaliases in cgen.ww for the
|
||||
// companion seed.
|
||||
let empty: str;
|
||||
let tnvoid: *node = newnode(c.a, nkind.N_TNAME, empty, 0, 0);
|
||||
let tnvoid: *node = newnode(nkind.N_TNAME, empty, 0, 0);
|
||||
tnvoid.str = "void";
|
||||
let bang: *node = newnode(c.a, nkind.N_TBANG, empty, 0, 0);
|
||||
let bang: *node = newnode(nkind.N_TBANG, empty, 0, 0);
|
||||
bang.lhs = tnvoid;
|
||||
let nomemdecl: *node = newnode(c.a, nkind.N_TYPEDECL, empty, 0, 0);
|
||||
let nomemdecl: *node = newnode(nkind.N_TYPEDECL, empty, 0, 0);
|
||||
nomemdecl.str = "nomem";
|
||||
nomemdecl.lhs = bang;
|
||||
scopedefine(c.top, "nomem", skind.SK_TYPE, nil, nomemdecl);
|
||||
@@ -350,7 +348,7 @@ fn resolvewalk(c: *checker, n: *node) void = {
|
||||
if (k == nkind.N_MCASE) {
|
||||
if (n.lhs != nil) { resolvewalk(c, n.lhs); };
|
||||
let outer: *scope = c.cur;
|
||||
c.cur = newscope(c.a, outer);
|
||||
c.cur = newscope(outer);
|
||||
let nm: str = n.str;
|
||||
if (nm.len > 0) {
|
||||
checkmoduleshadow(c, nm, "binding");
|
||||
@@ -372,7 +370,7 @@ fn resolvewalk(c: *checker, n: *node) void = {
|
||||
// Mirrors cstage cstmt N_BLOCK at cmd/wcc/check.c:1559-1566.
|
||||
if (k == nkind.N_BLOCK) {
|
||||
let outer: *scope = c.cur;
|
||||
c.cur = newscope(c.a, outer);
|
||||
c.cur = newscope(outer);
|
||||
let m: *node = n.list;
|
||||
for (m != nil) {
|
||||
resolvewalk(c, m);
|
||||
@@ -651,7 +649,7 @@ fn scruttype(c: *checker, e: *node) *node = {
|
||||
// exprtype to return primitive type nodes for literal
|
||||
// expressions. The arena keeps them around as long as the checker.
|
||||
fn mktname(c: *checker, nm: str) *node = {
|
||||
let n: *node = newnode(c.a, nkind.N_TNAME, "", 0, 0);
|
||||
let n: *node = newnode(nkind.N_TNAME, "", 0, 0);
|
||||
n.str = nm;
|
||||
return n;
|
||||
};
|
||||
@@ -838,7 +836,7 @@ fn astoffset(c: *checker, dot: *node) i64 = {
|
||||
// wwstage cgen only reads `uval` for N_INTLIT codegen so `str` is
|
||||
// just for the AST printer, but set it for parity with the parser's
|
||||
// own literal-emit shape.
|
||||
fn arenau64tos(a: *arena, v: u64) str = {
|
||||
fn arenau64tos(v: u64) str = {
|
||||
let buf: []u8 = alloc([], 24u64)!;
|
||||
let i: i32 = 23;
|
||||
buf[i] = 0u8;
|
||||
@@ -862,7 +860,7 @@ fn arenau64tos(a: *arena, v: u64) str = {
|
||||
fn foldtointlit(c: *checker, n: *node, v: i64) void = {
|
||||
n.kind = nkind.N_INTLIT;
|
||||
n.uval = v: u64;
|
||||
n.str = arenau64tos(c.a, v: u64);
|
||||
n.str = arenau64tos(v: u64);
|
||||
n.lhs = nil;
|
||||
n.list = nil;
|
||||
let empty: str;
|
||||
@@ -1014,11 +1012,11 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
||||
// site that needs iserror discrimination.
|
||||
r = tinfofornode(c, n.lhs);
|
||||
} else { if (k == nkind.N_TPTR) {
|
||||
r = typeptr(c.a, tinfofornode(c, n.lhs));
|
||||
r = typeptr(tinfofornode(c, n.lhs));
|
||||
} else { if (k == nkind.N_TSLICE) {
|
||||
r = typeslice(c.a, tinfofornode(c, n.lhs));
|
||||
r = typeslice(tinfofornode(c, n.lhs));
|
||||
} else { if (k == nkind.N_TCHAN) {
|
||||
r = typechan(c.a, tinfofornode(c, n.lhs));
|
||||
r = typechan(tinfofornode(c, n.lhs));
|
||||
} else { if (k == nkind.N_TARRAY) {
|
||||
// Cstage cmd/wcc/check.c:314-326: length must be an integer
|
||||
// literal (`[_]T` keeps alen=0 as the inferred-length sentinel
|
||||
@@ -1034,14 +1032,14 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
||||
if (n.rhs.kind == nkind.N_INTLIT) { elen = n.rhs.uval; };
|
||||
};
|
||||
let sub: *tinfo = tinfofornode(c, n.lhs);
|
||||
r = typearray(c.a, sub, elen);
|
||||
r = typearray(sub, elen);
|
||||
} else { if (k == nkind.N_TFN) {
|
||||
// Cstage cmd/wcc/check.c:437-466: function types are 8B / 8B
|
||||
// (call-target pointer shape). Pre-bind before recursing into
|
||||
// the return type so a recursive `type F = fn() F` self-ref
|
||||
// doesn't spin (cycle-break mirror of the TSTRUCT/TTAGGED
|
||||
// pattern below).
|
||||
r = newtype(c.a, tykind.TY_FN);
|
||||
r = newtype(tykind.TY_FN);
|
||||
r.size = 8u64;
|
||||
r.align = 8u64;
|
||||
r.slotsize = 8u64;
|
||||
@@ -1052,7 +1050,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
||||
// (default i32 = 4B/4B). Cgen's slotsize-TENUM fallback pads
|
||||
// to 8B per its stack-slot contract; tinfo.size carries the
|
||||
// raw storage width so size(EnumT) folds to the correct value.
|
||||
r = newtype(c.a, tykind.TY_ENUM);
|
||||
r = newtype(tykind.TY_ENUM);
|
||||
let storage: *tinfo = nil;
|
||||
if (n.lhs != nil) { storage = tinfofornode(c, n.lhs); };
|
||||
if (storage == nil) { storage = c.tc.tyi32; };
|
||||
@@ -1071,7 +1069,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
||||
// slotsize TTUPLE — narrow scalars pad to 8 (cgen spills each
|
||||
// tuple element into its own register / stack-slot eightbyte),
|
||||
// composites contribute their own ti.slotsize.
|
||||
r = newtype(c.a, tykind.TY_TUPLE);
|
||||
r = newtype(tykind.TY_TUPLE);
|
||||
tinfocachebind(c.tc, n, r);
|
||||
let total: u64 = 0u64;
|
||||
let slottotal: u64 = 0u64;
|
||||
@@ -1109,7 +1107,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
||||
// struct; size-derived alignment; final round to 8). That
|
||||
// slot total lands in ti.slotsize so the cgen fast-path can
|
||||
// graduate TY_STRUCT off the AST walker.
|
||||
r = newtype(c.a, tykind.TY_STRUCT);
|
||||
r = newtype(tykind.TY_STRUCT);
|
||||
tinfocachebind(c.tc, n, r);
|
||||
let off: u64 = 0u64;
|
||||
let maxalign: u64 = 1u64;
|
||||
@@ -1151,7 +1149,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
||||
// Cstage cmd/wcc/check.c:347-435: 8B tag + max(variant)
|
||||
// rounded up to 8. Pre-bind for cycle protection (recursive
|
||||
// sum-type shapes through NAMED variants).
|
||||
r = newtype(c.a, tykind.TY_TAGGED);
|
||||
r = newtype(tykind.TY_TAGGED);
|
||||
tinfocachebind(c.tc, n, r);
|
||||
// #61 A.3 nullable fold: `(*T | void)` collapses to a single
|
||||
// 8B pointer slot, null is the void variant. Mirrors
|
||||
@@ -1310,11 +1308,11 @@ fn exprtype(c: *checker, e: *node) *node = {
|
||||
if (e.list.list == nil) {
|
||||
if (e.list.next != nil) {
|
||||
if (e.list.next.next == nil) {
|
||||
let sl: *node = newnode(c.a, nkind.N_TSLICE, "", 0, 0);
|
||||
let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0);
|
||||
sl.lhs = mktname(c, "u8");
|
||||
let nome: *node = mktname(c, "nomem");
|
||||
sl.next = nome;
|
||||
let tt: *node = newnode(c.a, nkind.N_TTAGGED, "", 0, 0);
|
||||
let tt: *node = newnode(nkind.N_TTAGGED, "", 0, 0);
|
||||
tt.list = sl;
|
||||
return tt;
|
||||
};
|
||||
@@ -1324,11 +1322,11 @@ fn exprtype(c: *checker, e: *node) *node = {
|
||||
// Value form: `alloc(value)`.
|
||||
if (e.list.next == nil) {
|
||||
let argt: *node = exprtype(c, e.list);
|
||||
let ptr: *node = newnode(c.a, nkind.N_TPTR, "", 0, 0);
|
||||
let ptr: *node = newnode(nkind.N_TPTR, "", 0, 0);
|
||||
ptr.lhs = argt;
|
||||
let nome: *node = mktname(c, "nomem");
|
||||
ptr.next = nome;
|
||||
let tt: *node = newnode(c.a, nkind.N_TTAGGED, "", 0, 0);
|
||||
let tt: *node = newnode(nkind.N_TTAGGED, "", 0, 0);
|
||||
tt.list = ptr;
|
||||
return tt;
|
||||
};
|
||||
@@ -1845,14 +1843,14 @@ fn checkletassign(c: *checker, n: *node) void = {
|
||||
};
|
||||
};
|
||||
if (!shadowed) {
|
||||
let sl: *node = newnode(c.a, nkind.N_TSLICE, "", 0, 0);
|
||||
let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0);
|
||||
sl.lhs = n.lhs.lhs;
|
||||
if (wrapped) {
|
||||
src = sl;
|
||||
} else {
|
||||
let nome: *node = mktname(c, "nomem");
|
||||
sl.next = nome;
|
||||
let tt: *node = newnode(c.a, nkind.N_TTAGGED, "", 0, 0);
|
||||
let tt: *node = newnode(nkind.N_TTAGGED, "", 0, 0);
|
||||
tt.list = sl;
|
||||
src = tt;
|
||||
};
|
||||
@@ -2043,7 +2041,7 @@ fn installparams(c: *checker, params: *node) void = {
|
||||
// per-statement scopes.
|
||||
fn resolvefnbody(c: *checker, fnnode: *node) void = {
|
||||
let outer: *scope = c.cur;
|
||||
c.cur = newscope(c.a, c.cur);
|
||||
c.cur = newscope(c.cur);
|
||||
installparams(c, fnnode.list);
|
||||
// #61 audit §1.8 — A.2: walk each param's declared type-expr so
|
||||
// tinfofornode stamps n.type_ on it. installparams binds the name
|
||||
@@ -2065,10 +2063,9 @@ fn resolvefnbody(c: *checker, fnnode: *node) void = {
|
||||
c.cur = outer;
|
||||
};
|
||||
|
||||
export fn checkinit(c: *checker, a: *arena, tc: *tctx) void = {
|
||||
c.a = a;
|
||||
export fn checkinit(c: *checker, tc: *tctx) void = {
|
||||
c.tc = tc;
|
||||
c.top = newscope(a, nil);
|
||||
c.top = newscope(nil);
|
||||
c.cur = c.top;
|
||||
c.nresolved = 0;
|
||||
c.nunresolved = 0;
|
||||
|
||||
Reference in New Issue
Block a user