lib/ww/typ + selfhost/cmd/wcc/check: tinfo-on-node infrastructure (Phase A.1)
Foundation for audit §1.8 — wwstage cgen recomputes type sizes at every
site instead of reading n.type_ like cstage does (cmd/wcc/check.c sets
n->type via cexpr; cgen reads n->type->size). The scattered literals
this session has been chasing (#43, #60, etc.) are the symptom; this
chain is the cure.
A.1 is infrastructure only — no cgen-site graduation yet. Subsequent
A.2+ sub-commits collapse each walker family (slotsize, elemsize,
fieldsize, isstrtype, istaggedtype, ...) onto n.type_ reads.
lib/ww/typ.ww:
- tinfocacheent struct (key, val, cnext) — sea-of-stars per rule 12.
- tinfocache: *tinfocacheent field on tctx (now 25 fields).
- tinfocachelookup / tinfocachebind — head-prepend linked-list ops.
selfhost/cmd/wcc/check.ww:
- tinfofornode(c, n) *tinfo — covers N_TNAME primitive (singleton
lookup), N_TNAME alias (recurse via resolvealias), N_TBANG
(unwrap+recurse, iserror dropped — graduate alongside the first
cgen reader that needs it), N_TPTR/N_TSLICE/N_TCHAN (recurse on
sub, call typeptr/typeslice/typechan).
- exprtype N_INTLIT arm now sets e.type_ = tinfofornode(c, tn). Only
population site in this commit; every other arm unchanged.
Empirically verified via temp probe that tinfofornode is reached and
returns non-nil on `let x: i32 = 42;`. Strict scope: zero cgen reads
of n.type_; primtypesize/slotsize/etc. still drive size queries.
131/131 + 994 + 995 byte-identical to caa72f2.
This commit is contained in:
@@ -89,6 +89,17 @@ type tinfo = struct {
|
||||
under: *tinfo,
|
||||
};
|
||||
|
||||
// #61 audit §1.8 / Rob+Drew convergence 2026-05-20: memoizes
|
||||
// tinfofornode lookups keyed by AST pointer. Linked-list shape mirrors
|
||||
// other wwstage-side caches (cgen.aliases, cgen.structs) — sea-of-stars
|
||||
// over hash-table cleverness, and Sym/Scope already pay the FNV cost
|
||||
// for the resolver pass.
|
||||
type tinfocacheent = struct {
|
||||
key: *node,
|
||||
val: *tinfo,
|
||||
cnext: *tinfocacheent,
|
||||
};
|
||||
|
||||
// ---- tctx — the box of primitive types -------------------------------
|
||||
|
||||
type tctx = struct {
|
||||
@@ -118,6 +129,7 @@ type tctx = struct {
|
||||
tyuntypedrune: *tinfo,
|
||||
tyuntypedbool: *tinfo,
|
||||
tyuntypednil: *tinfo,
|
||||
tinfocache: *tinfocacheent,
|
||||
};
|
||||
|
||||
// ---- constructors -----------------------------------------------------
|
||||
@@ -214,6 +226,28 @@ export fn typenamed(a: *arena, name: str, under: *tinfo) *tinfo = {
|
||||
return t;
|
||||
};
|
||||
|
||||
// #61 audit §1.8 — A.1 infrastructure: tinfocache lookup/bind. Keyed
|
||||
// by AST node-pointer so two different N_TNAME("i32") nodes get
|
||||
// independent entries that both resolve to c.tyi32. Used by
|
||||
// tinfofornode in check.ww; cgen still reads sizes via primtypesize
|
||||
// until A.2+ graduates each walker family.
|
||||
export fn tinfocachelookup(c: *tctx, key: *node) *tinfo = {
|
||||
let e: *tinfocacheent = c.tinfocache;
|
||||
for (e != nil) {
|
||||
if (e.key == key) { return e.val; };
|
||||
e = e.cnext;
|
||||
};
|
||||
return nil;
|
||||
};
|
||||
|
||||
export fn tinfocachebind(c: *tctx, key: *node, val: *tinfo) void = {
|
||||
let e: *tinfocacheent = amalloc(c.a, 32u64): *tinfocacheent;
|
||||
e.key = key;
|
||||
e.val = val;
|
||||
e.cnext = c.tinfocache;
|
||||
c.tinfocache = e;
|
||||
};
|
||||
|
||||
// ---- predicates -------------------------------------------------------
|
||||
|
||||
export fn typeisint(t: *tinfo) bool = {
|
||||
|
||||
Reference in New Issue
Block a user