selfhost/cmd/wcc: peel TY_NAMED in 5 structural walkers (#63, Phase-N step 1)
Phase-N prerequisite (additive, byte-id unchanged). slotsize / fieldsize / nullableptrtag (cgenutil) and tupleelemslot / fieldslotsize (check) read size/slot/kind off a tinfo without peeling TY_NAMED. Once Phase-N step 2 (#64) makes tinfofornode build per-decl TY_NAMED wrappers, an unpeeled reader would misbehave (fall through to 8 / take natural size not slot / miss NAMED-of-tagged). Prepend a transitive `for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; }` peel + nil re-guard at each, mirroring cstage's `while (t->kind == TY_NAMED) t = t->under` and the recursive typeis* predicates. Additive no-op today: tinfofornode still collapses aliases, so no NAMED is ever built and the loop never executes. byte-id 990-997 unchanged (133/133). Audit (worker + reviewer, independently, across all selfhost/cmd/wcc/*.ww + lib/ww/*.ww): these 5 are the ONLY non-peeling structural walkers. typeis* recurse on .under; typeeq is nominal by design (ptr-identity, the step-3 goal); typeisuntyped cannot receive a NAMED; check.ww type constructors and localloadop read only .size/.slotsize, which typenamed copies from .under so they stay numerically correct on a NAMED without peeling.
This commit is contained in:
@@ -1671,6 +1671,11 @@ fn slotsize(c: *cgen, typn: *node) i32 = {
|
||||
if (typn == nil) { return 8; };
|
||||
let ti: *tinfo = typn.type_: *tinfo;
|
||||
if (ti == nil) { return 8; };
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query;
|
||||
// wrappers are built in step 2 (#64). No-op today (tinfofornode
|
||||
// still collapses aliases → no TY_NAMED), so byte-id is unchanged.
|
||||
for (ti != nil && ti.kind == tykind.TY_NAMED) { ti = ti.under; };
|
||||
if (ti == nil) { return 8; };
|
||||
let kk: tykind = ti.kind;
|
||||
if (kk == tykind.TY_VOID) { return 0; };
|
||||
if (kk == tykind.TY_PTR || kk == tykind.TY_SLICE ||
|
||||
@@ -1703,6 +1708,11 @@ fn fieldsize(c: *cgen, tnode: *node) i32 = {
|
||||
if (tnode == nil) { return 8; };
|
||||
let ti: *tinfo = tnode.type_: *tinfo;
|
||||
if (ti == nil) { return 8; };
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query;
|
||||
// wrappers are built in step 2 (#64). No-op today (tinfofornode
|
||||
// still collapses aliases → no TY_NAMED), so byte-id is unchanged.
|
||||
for (ti != nil && ti.kind == tykind.TY_NAMED) { ti = ti.under; };
|
||||
if (ti == nil) { return 8; };
|
||||
let k: tykind = ti.kind;
|
||||
if (k == tykind.TY_STRUCT) { return ti.slotsize: i32; };
|
||||
if (k == tykind.TY_ARRAY) { return ti.slotsize: i32; };
|
||||
@@ -2047,6 +2057,11 @@ export fn nullableptrtag(t: *node) i32 = {
|
||||
if (t == nil) { return 0; };
|
||||
let ti: *tinfo = t.type_: *tinfo;
|
||||
if (ti == nil) { return 0; };
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query;
|
||||
// wrappers are built in step 2 (#64). No-op today (tinfofornode
|
||||
// still collapses aliases → no TY_NAMED), so byte-id is unchanged.
|
||||
for (ti != nil && ti.kind == tykind.TY_NAMED) { ti = ti.under; };
|
||||
if (ti == nil) { return 0; };
|
||||
if (ti.kind != tykind.TY_TAGGED) { return 0; };
|
||||
let p: *tparam = ti.params;
|
||||
let i: i32 = 0;
|
||||
|
||||
Reference in New Issue
Block a user