selfhost/cmd/wcc: index-base esz from n.type_.size + delete indexbaseesz (#72, A.6.3k)

The N_INDEX node carries the checker-stamped element tinfo (#60 arc); cgindex,
cgun TK_AMP, and cgassign now read the element stride off that .type_.size
instead of indexbaseesz's manual N_DOT-pseudo-field + structlookup walk,
retiring the helper (0 callers, ~96 LOC). Aligns down to cstage's
idx_eff(base->type)->sub->size (cmd/w6c/cgen.c:3517-18, natural element size) --
strictly more cstage-faithful than indexbaseesz's totsize/slotsize derivation
(byte-id held only because firing shapes have totsize==natural; cstage reads
natural and ww-old==cstage, so the flip is structural). Each site keeps its
nil->default-8 fallback; cgindex stays esz-only (signed_elem unset for the
N_DOT base, as before).

Closes the A.6.3 cgenutil-collapse arc: every type/size/offset query in cgen
now reads the checker-stamped tinfo, and the AST-walker / structinfo-walk
helpers it replaced (dotfieldtnode, indexvaluetnode, rhstargetname,
dotinnerstructptr, indexbaseesz) are retired. make test 134/134, byte-id
990-997 hold. Coverage: 713/741/755 + self-rebuild.
This commit is contained in:
2026-05-24 03:16:14 +09:00
parent 0763377806
commit f45caf1cd9
5 changed files with 78 additions and 354 deletions

View File

@@ -720,7 +720,14 @@ fn cgindex(c: *cgen, n: *node) void = {
};
};
} else { if (base.kind == nkind.N_DOT) {
esz = indexbaseesz(c, base);
// `s.ptr[i]` / struct-field index: stride is the
// checker-stamped element tinfo's natural size, the
// same idiom as the N_INDEX-base arm below (#60/#72).
// cstage idx_eff(base->type)->sub->size (cmd/w6c/
// cgen.c:3517-18). esz-only — N_DOT-base signedness
// stays unset, as before.
let dt: *tinfo = n.type_: *tinfo;
if (dt != nil) { esz = dt.size: i32; };
} else { if (base.kind == nkind.N_INDEX) {
// #60: chained `names[i][k]` — n.type_ is the checker-
// stamped outer element tinfo (indexresult over the inner
@@ -2503,11 +2510,13 @@ fn cgun(c: *cgen, n: *node) void = {
};
};
} else { if (base.kind == nkind.N_DOT) {
// `&p.ptr[i]` shape: stride is the element
// of the slice/struct-pointer field, not
// the default 8. Mirrors cgindex's N_DOT
// arm so &p.ptr[i] and p.ptr[i] agree.
esz = indexbaseesz(c, base);
// `&p.ptr[i]`: stride is the checker-stamped
// element tinfo's natural size, mirroring
// cgindex's N_DOT arm so &p.ptr[i] and
// p.ptr[i] agree. cstage idx_eff(base->type)
// ->sub->size (cmd/w6c/cgen.c:3517-18). #72.
let dt: *tinfo = opnd.type_: *tinfo;
if (dt != nil) { esz = dt.size: i32; };
};};
};
cgexpr(c, idx);
@@ -3744,18 +3753,14 @@ fn cgassign(c: *cgen, n: *node) void = {
};
};
} else { if (base.kind == nkind.N_DOT) {
esz = indexbaseesz(c, base);
// Tagged-element gate (below) keys on the store
// target's element type. lhs.type_ is the
// checker-stamped element tinfo of the N_INDEX,
// so carry lhs and let the gate read it via
// lhs.type_ is the checker-stamped element tinfo
// of the N_INDEX: esz is its natural size and the
// tagged-element gate (below) reads the same
// .type_ — same idiom as cgindex's n.type_ read
// (#60). Drops the indexvaluetnode walk for the
// N_DOT base (#69/#61d, was #30). cstage reads
// idx_eff(base->type)->sub (cmd/w6c/cgen.c:3517-
// 3523).
// (#60/#72). cstage idx_eff(base->type)->sub->size
// (cmd/w6c/cgen.c:3517-18).
let dt: *tinfo = lhs.type_: *tinfo;
if (dt != nil) { elemtn = lhs; };
if (dt != nil) { esz = dt.size: i32; elemtn = lhs; };
} else { if (base.kind == nkind.N_INDEX) {
// Chained-write write-side parallel of the
// cgindex N_INDEX-base arm (#24): `names[i][k]