wcc_ww/cgen: W2 #102 indexed-elem field store + &-field gates chase the alias chain

The two ww-side gates from ken's B6-c3 STOP re-attribution
(.ai/ken-b6-oracle.md addendum): WWSTAGE was the alias-blind side at
exactly two cgenexpr.ww sites, both keyed on a bare name-keyed
structlookup that only holds struct-decl names, so an alias-NAMED
spelling missed and fell to the generic-but-runtime-correct route —
byte-divergent from the canonical dedicated shape cs pins post-B6-c3:

  (1) `arr[i].f = v` indexed-elem struct-field STORE arm (the write
      twin of the task-#8 READ arm, which already chases via tichase);
  (2) `&p.f` ptr-field fallback in the TK_AMP N_DOT single-dot leg.

REVIEW AMENDMENT (reviewer-W2, rob's close-by-construction
obligation): the proof-sweep of the two arms found ONE same-class
survivor — (3) the value-struct `&x.f` leg, one leg below (2) in the
same single-DOT arm, same alias-blind bare structlookup. Probe
rW2_ampv reproduced the identical bit-proven mechanism (ww_alias !=
ww_plain; cs_alias == ww_plain) at both base and the frozen tip; the
other in-arm routes are clean (letvar* global helpers chase, str/len
pseudo-field alias legs are filed-loud #96, chained depth>=2 resolves
via tinfo). Same chase applied; arm survivor count is now zero by
the same grep+probe construction.

All three now resolve through structlookupchain (#22) — the name
layer's own alias-chain accessor (the cstage transitive-peel mirror),
already consumed by the sibling `p.f = v` assign arm and cgdot's
pointer-to-struct read. Plain rows short-circuit at its structlookup
head, so non-alias emission is byte-identical by construction; alias
rows land on the same structinfo as their plain twins, so the
dedicated emission converges bit-exactly. esz stays sound:
elemsizeofc reads the chased stamped tinfo (#8 leg).

Convergence proven with ken's pre-staged W2 instrument: ww_alias ==
ww_plain bit-IDENTICAL for kb6_idxf and kb6_ampf (cmp exit 0), which
also lands cs==ww byte-id on both rows; plain controls byte-id held
and their ww asm unchanged base->tip. Full ken-corpus matrix vs the
B6-tip baseline: movers are exactly {kb6_idxf, kb6_ampf} NO->YES;
detectors unmoved (kw1_101 cs0/ww1, fill2 both-loud, tuparg_c
cs0/ww1, fsarg2/fsarg0/try pinned texts verbatim, B5/B6 graduations
all byte-id). Zero behavioral change on any accepted program, zero
acceptance change in either direction.

ww-only: zero C-source bytes; cs binaries (w6c/ww/w6a/w6l) md5
bit-identical base->tip; w6c_ww + wwdump main.combined.ww regen'd via
make, idempotent. 989 lib ratchet: zero flips (31 byte-identical /
9 pinned-divergent #59 / 3 pinned-wwreject #59 across 43 units).

944_alias_cgen_b6_run: idxf_2lvl + ampf_2lvl graduate K_RUN_NOID ->
K_RUN (the two restored byte-id cells) — B6-c3's mutation teeth
restored (reviewer-B6 N-a closes); + amendment rows ampv_2lvl /
ampv_plain_ctl pin the third gate (checks 61 -> 69). All 9 944-family
suites green; sizelint 0; make test-unit "all 292 tests passed".
This commit is contained in:
2026-06-06 04:57:03 +09:00
parent 0077b115fb
commit 05f7af76d1
4 changed files with 145 additions and 45 deletions

View File

@@ -25470,6 +25470,16 @@ fn cgun(c: *cgen, n: *node) void = {
let lkind: nkind = nkind.N_NONE; let lkind: nkind = nkind.N_NONE;
if (tn != nil) { lkind = tn.kind; }; if (tn != nil) { lkind = tn.kind; };
// Pointer-field: &p.f where p:*T. // Pointer-field: &p.f where p:*T.
// #102 (ken B6-c3 re-attribution): an
// alias-NAMED pointee misses the bare
// name-keyed lookup, so &p.f fell to the
// generic cgplaceaddr route — runtime-
// correct but byte-divergent from the
// dedicated shape cs pins post-B6-c3.
// structlookupchain (#22) chases the alias
// chain; plain rows short-circuit at its
// structlookup head, byte-id by
// construction.
if (lkind == nkind.N_TPTR) { if (lkind == nkind.N_TPTR) {
let inner: *node = tn.lhs; let inner: *node = tn.lhs;
let sname: str; let sname: str;
@@ -25478,7 +25488,7 @@ fn cgun(c: *cgen, n: *node) void = {
if (inner.kind == nkind.N_TNAME) { sname = inner.str; }; if (inner.kind == nkind.N_TNAME) { sname = inner.str; };
}; };
if (sname.len > 0) { if (sname.len > 0) {
let si: *structinfo = structlookup(c, sname); let si: *structinfo = structlookupchain(c, inner);
if (si != nil) { if (si != nil) {
let fi: *fieldinfo = si.fields; let fi: *fieldinfo = si.fields;
for (fi != nil) { for (fi != nil) {
@@ -25497,9 +25507,13 @@ fn cgun(c: *cgen, n: *node) void = {
}; };
}; };
// Value-struct local: &o.f. // Value-struct local: &o.f.
// #102 review-found sibling: same
// alias-blind miss one leg below the
// &p.f gate — an alias-NAMED value
// struct fell to the generic route.
// Same chase, same construction.
if (lkind == nkind.N_TNAME) { if (lkind == nkind.N_TNAME) {
let sname: str = tn.str; let si: *structinfo = structlookupchain(c, tn);
let si: *structinfo = structlookup(c, sname);
if (si != nil) { if (si != nil) {
let fi: *fieldinfo = si.fields; let fi: *fieldinfo = si.fields;
for (fi != nil) { for (fi != nil) {
@@ -29555,22 +29569,31 @@ fn cgassign(c: *cgen, n: *node) void = {
// array's element (#61). // array's element (#61).
let elemt: *node = idxelemtn(tn); let elemt: *node = idxelemtn(tn);
let baseisarray: bool = tn.kind == nkind.N_TARRAY; let baseisarray: bool = tn.kind == nkind.N_TARRAY;
let sname: str; let snode: *node = nil;
sname.ptr = nil; sname.len = 0;
let viaptr: bool = false; let viaptr: bool = false;
if (elemt != nil) { if (elemt != nil) {
if (elemt.kind == nkind.N_TPTR) { if (elemt.kind == nkind.N_TPTR) {
let inner: *node = elemt.lhs; let inner: *node = elemt.lhs;
if (inner != nil) { if (inner.kind == nkind.N_TNAME) { if (inner != nil) { if (inner.kind == nkind.N_TNAME) {
sname = inner.str; snode = inner;
viaptr = true; viaptr = true;
};}; };};
} else { if (elemt.kind == nkind.N_TNAME) { } else { if (elemt.kind == nkind.N_TNAME) {
sname = elemt.str; snode = elemt;
};}; };};
}; };
if (sname.len > 0) { // #102 (ken B6-c3 re-attribution): an alias-NAMED
let si: *structinfo = structlookup(c, sname); // element misses the bare name-keyed lookup, so
// `arr[i].f = v` fell to the generic place route —
// runtime-correct but byte-divergent from the
// dedicated shape cs pins post-B6-c3 (the READ twin
// above already chases via tichase, task #8).
// structlookupchain (#22) chases the alias chain;
// plain rows short-circuit at its structlookup
// head, byte-id by construction. esz stays sound:
// elemsizeofc reads the chased stamped tinfo (#8).
if (snode != nil) {
let si: *structinfo = structlookupchain(c, snode);
if (si != nil) { if (si != nil) {
let fi: *fieldinfo = si.fields; let fi: *fieldinfo = si.fields;
for (fi != nil) { for (fi != nil) {

View File

@@ -4454,6 +4454,16 @@ fn cgun(c: *cgen, n: *node) void = {
let lkind: nkind = nkind.N_NONE; let lkind: nkind = nkind.N_NONE;
if (tn != nil) { lkind = tn.kind; }; if (tn != nil) { lkind = tn.kind; };
// Pointer-field: &p.f where p:*T. // Pointer-field: &p.f where p:*T.
// #102 (ken B6-c3 re-attribution): an
// alias-NAMED pointee misses the bare
// name-keyed lookup, so &p.f fell to the
// generic cgplaceaddr route — runtime-
// correct but byte-divergent from the
// dedicated shape cs pins post-B6-c3.
// structlookupchain (#22) chases the alias
// chain; plain rows short-circuit at its
// structlookup head, byte-id by
// construction.
if (lkind == nkind.N_TPTR) { if (lkind == nkind.N_TPTR) {
let inner: *node = tn.lhs; let inner: *node = tn.lhs;
let sname: str; let sname: str;
@@ -4462,7 +4472,7 @@ fn cgun(c: *cgen, n: *node) void = {
if (inner.kind == nkind.N_TNAME) { sname = inner.str; }; if (inner.kind == nkind.N_TNAME) { sname = inner.str; };
}; };
if (sname.len > 0) { if (sname.len > 0) {
let si: *structinfo = structlookup(c, sname); let si: *structinfo = structlookupchain(c, inner);
if (si != nil) { if (si != nil) {
let fi: *fieldinfo = si.fields; let fi: *fieldinfo = si.fields;
for (fi != nil) { for (fi != nil) {
@@ -4481,9 +4491,13 @@ fn cgun(c: *cgen, n: *node) void = {
}; };
}; };
// Value-struct local: &o.f. // Value-struct local: &o.f.
// #102 review-found sibling: same
// alias-blind miss one leg below the
// &p.f gate — an alias-NAMED value
// struct fell to the generic route.
// Same chase, same construction.
if (lkind == nkind.N_TNAME) { if (lkind == nkind.N_TNAME) {
let sname: str = tn.str; let si: *structinfo = structlookupchain(c, tn);
let si: *structinfo = structlookup(c, sname);
if (si != nil) { if (si != nil) {
let fi: *fieldinfo = si.fields; let fi: *fieldinfo = si.fields;
for (fi != nil) { for (fi != nil) {
@@ -8539,22 +8553,31 @@ fn cgassign(c: *cgen, n: *node) void = {
// array's element (#61). // array's element (#61).
let elemt: *node = idxelemtn(tn); let elemt: *node = idxelemtn(tn);
let baseisarray: bool = tn.kind == nkind.N_TARRAY; let baseisarray: bool = tn.kind == nkind.N_TARRAY;
let sname: str; let snode: *node = nil;
sname.ptr = nil; sname.len = 0;
let viaptr: bool = false; let viaptr: bool = false;
if (elemt != nil) { if (elemt != nil) {
if (elemt.kind == nkind.N_TPTR) { if (elemt.kind == nkind.N_TPTR) {
let inner: *node = elemt.lhs; let inner: *node = elemt.lhs;
if (inner != nil) { if (inner.kind == nkind.N_TNAME) { if (inner != nil) { if (inner.kind == nkind.N_TNAME) {
sname = inner.str; snode = inner;
viaptr = true; viaptr = true;
};}; };};
} else { if (elemt.kind == nkind.N_TNAME) { } else { if (elemt.kind == nkind.N_TNAME) {
sname = elemt.str; snode = elemt;
};}; };};
}; };
if (sname.len > 0) { // #102 (ken B6-c3 re-attribution): an alias-NAMED
let si: *structinfo = structlookup(c, sname); // element misses the bare name-keyed lookup, so
// `arr[i].f = v` fell to the generic place route —
// runtime-correct but byte-divergent from the
// dedicated shape cs pins post-B6-c3 (the READ twin
// above already chases via tichase, task #8).
// structlookupchain (#22) chases the alias chain;
// plain rows short-circuit at its structlookup
// head, byte-id by construction. esz stays sound:
// elemsizeofc reads the chased stamped tinfo (#8).
if (snode != nil) {
let si: *structinfo = structlookupchain(c, snode);
if (si != nil) { if (si != nil) {
let fi: *fieldinfo = si.fields; let fi: *fieldinfo = si.fields;
for (fi != nil) { for (fi != nil) {

View File

@@ -25470,6 +25470,16 @@ fn cgun(c: *cgen, n: *node) void = {
let lkind: nkind = nkind.N_NONE; let lkind: nkind = nkind.N_NONE;
if (tn != nil) { lkind = tn.kind; }; if (tn != nil) { lkind = tn.kind; };
// Pointer-field: &p.f where p:*T. // Pointer-field: &p.f where p:*T.
// #102 (ken B6-c3 re-attribution): an
// alias-NAMED pointee misses the bare
// name-keyed lookup, so &p.f fell to the
// generic cgplaceaddr route — runtime-
// correct but byte-divergent from the
// dedicated shape cs pins post-B6-c3.
// structlookupchain (#22) chases the alias
// chain; plain rows short-circuit at its
// structlookup head, byte-id by
// construction.
if (lkind == nkind.N_TPTR) { if (lkind == nkind.N_TPTR) {
let inner: *node = tn.lhs; let inner: *node = tn.lhs;
let sname: str; let sname: str;
@@ -25478,7 +25488,7 @@ fn cgun(c: *cgen, n: *node) void = {
if (inner.kind == nkind.N_TNAME) { sname = inner.str; }; if (inner.kind == nkind.N_TNAME) { sname = inner.str; };
}; };
if (sname.len > 0) { if (sname.len > 0) {
let si: *structinfo = structlookup(c, sname); let si: *structinfo = structlookupchain(c, inner);
if (si != nil) { if (si != nil) {
let fi: *fieldinfo = si.fields; let fi: *fieldinfo = si.fields;
for (fi != nil) { for (fi != nil) {
@@ -25497,9 +25507,13 @@ fn cgun(c: *cgen, n: *node) void = {
}; };
}; };
// Value-struct local: &o.f. // Value-struct local: &o.f.
// #102 review-found sibling: same
// alias-blind miss one leg below the
// &p.f gate — an alias-NAMED value
// struct fell to the generic route.
// Same chase, same construction.
if (lkind == nkind.N_TNAME) { if (lkind == nkind.N_TNAME) {
let sname: str = tn.str; let si: *structinfo = structlookupchain(c, tn);
let si: *structinfo = structlookup(c, sname);
if (si != nil) { if (si != nil) {
let fi: *fieldinfo = si.fields; let fi: *fieldinfo = si.fields;
for (fi != nil) { for (fi != nil) {
@@ -29555,22 +29569,31 @@ fn cgassign(c: *cgen, n: *node) void = {
// array's element (#61). // array's element (#61).
let elemt: *node = idxelemtn(tn); let elemt: *node = idxelemtn(tn);
let baseisarray: bool = tn.kind == nkind.N_TARRAY; let baseisarray: bool = tn.kind == nkind.N_TARRAY;
let sname: str; let snode: *node = nil;
sname.ptr = nil; sname.len = 0;
let viaptr: bool = false; let viaptr: bool = false;
if (elemt != nil) { if (elemt != nil) {
if (elemt.kind == nkind.N_TPTR) { if (elemt.kind == nkind.N_TPTR) {
let inner: *node = elemt.lhs; let inner: *node = elemt.lhs;
if (inner != nil) { if (inner.kind == nkind.N_TNAME) { if (inner != nil) { if (inner.kind == nkind.N_TNAME) {
sname = inner.str; snode = inner;
viaptr = true; viaptr = true;
};}; };};
} else { if (elemt.kind == nkind.N_TNAME) { } else { if (elemt.kind == nkind.N_TNAME) {
sname = elemt.str; snode = elemt;
};}; };};
}; };
if (sname.len > 0) { // #102 (ken B6-c3 re-attribution): an alias-NAMED
let si: *structinfo = structlookup(c, sname); // element misses the bare name-keyed lookup, so
// `arr[i].f = v` fell to the generic place route —
// runtime-correct but byte-divergent from the
// dedicated shape cs pins post-B6-c3 (the READ twin
// above already chases via tichase, task #8).
// structlookupchain (#22) chases the alias chain;
// plain rows short-circuit at its structlookup
// head, byte-id by construction. esz stays sound:
// elemsizeofc reads the chased stamped tinfo (#8).
if (snode != nil) {
let si: *structinfo = structlookupchain(c, snode);
if (si != nil) { if (si != nil) {
let fi: *fieldinfo = si.fields; let fi: *fieldinfo = si.fields;
for (fi != nil) { for (fi != nil) {

View File

@@ -63,22 +63,27 @@
* | alias ptr): the c3 chase moved cs | * | alias ptr): the c3 chase moved cs |
* | onto the PLAIN-canonical dedicated | * | onto the PLAIN-canonical dedicated |
* | shape (cs_alias == ww_PLAIN, bit- | * | shape (cs_alias == ww_PLAIN, bit- |
* | proven, ken c3-STOP addendum) — but | * | proven, ken c3-STOP addendum) — and |
* | WWSTAGE is the alias-blind side at | * | WWSTAGE was the alias-blind side at |
* | these two sites (ww_alias != | * | these two sites (generic-but-correct |
* | ww_plain, generic-but-correct | * | routes). GRADUATED to full byte-id |
* | routes). Two-cell NOID pins; byte-id | * | by the W2 ww fold, task #102 (the |
* | graduates with the filed ww-side W2 | * | two gates now chase the alias chain |
* | fold, task #102 (ww indexed-elem | * | via structlookupchain). ampf's |
* | field gates + &p.f fallback don't | * | pre-c3 byte-id was both-on-generic |
* | fire on alias bases). ampf's pre-c3 |
* | byte-id was both-on-generic |
* | identity, not latency (oracle | * | identity, not latency (oracle |
* | self-correction) | 0/0 * | self-correction) | 0/0
* idxf_plain_ctl / | plain no-alias twins — pin the | * idxf_plain_ctl / | plain no-alias twins — pin the |
* ampf_plain_ctl | canonical dedicated shape byte-id | * ampf_plain_ctl | canonical dedicated shape byte-id |
* | BOTH stages (the convergence target | * | BOTH stages (the convergence target |
* | the NOID rows graduate onto) | 0/0 * | the NOID rows graduate onto) | 0/0
* ampv_2lvl / | W2-review-found #102 sibling: &x.f |
* ampv_plain_ctl | over an alias-NAMED VALUE struct — |
* | the leg one below the &p.f gate had |
* | the same alias-blind bare lookup |
* | (ww_alias != ww_plain; cs_alias == |
* | ww_plain, same bit-proven mechanism).|
* | Chased in the W2 review amendment | 0/0
* chdot_2lvl | kb6_chdot: chained dot over alias | * chdot_2lvl | kb6_chdot: chained dot over alias |
* | hops — latent control | 0/0 * | hops — latent control | 0/0
* esub_2lvl | kb6_esub: [3]my32b narrow-elem index | * esub_2lvl | kb6_esub: [3]my32b narrow-elem index |
@@ -296,11 +301,11 @@ static const struct row rows[] = {
/* ---- c3: addr-of/field-walk/index spine */ /* ---- c3: addr-of/field-walk/index spine */
/* The c3 chase put cs on the PLAIN-canonical dedicated shape /* The c3 chase put cs on the PLAIN-canonical dedicated shape
* (cs_alias == ww_PLAIN, bit-proven — ken c3-STOP addendum); * (cs_alias == ww_PLAIN, bit-proven — ken c3-STOP addendum);
* WWSTAGE is the alias-blind side here: its indexed-elem * WWSTAGE was the alias-blind side here: its indexed-elem
* struct-field store/read gates don't fire on alias bases and * struct-field store gate fell to a generic-but-correct route
* fall to a generic-but-correct route. Byte-id waived until the * on alias bases. GRADUATED: the W2 ww fold (task #102) chases
* filed ww-side W2 fold (task #102) lands; idxf_plain_ctl pins the * the alias chain (structlookupchain), restoring full byte-id —
* convergence target. */ * idxf_plain_ctl pins the canonical shape both rows now share. */
{ "idxf_2lvl", { "idxf_2lvl",
"package main;\n" "package main;\n"
"type el0 = struct { a: i64, b: i64 };\n" "type el0 = struct { a: i64, b: i64 };\n"
@@ -311,7 +316,7 @@ static const struct row rows[] = {
" xs[1].a = 3; xs[1].b = 4;\n" " xs[1].a = 3; xs[1].b = 4;\n"
" if (xs[1].b != 4 || xs[0].b != 2) { return 1; };\n" " if (xs[1].b != 4 || xs[0].b != 2) { return 1; };\n"
" return 0;\n" " return 0;\n"
"};\n", 0, 0, K_RUN_NOID, NULL, NULL }, /* byte-id: task #102 */ "};\n", 0, 0, K_RUN, NULL, NULL }, /* graduated: #102 (W2) */
{ "idxf_plain_ctl", { "idxf_plain_ctl",
"package main;\n" "package main;\n"
"type el0 = struct { a: i64, b: i64 };\n" "type el0 = struct { a: i64, b: i64 };\n"
@@ -325,7 +330,7 @@ static const struct row rows[] = {
/* &p.b ptr-field fallback twin of the same re-attribution: the /* &p.b ptr-field fallback twin of the same re-attribution: the
* pre-c3 byte-id here was BOTH stages on the generic spine * pre-c3 byte-id here was BOTH stages on the generic spine
* (gate-blind identity, not M5 latency — oracle self-correction * (gate-blind identity, not M5 latency — oracle self-correction
* banked in ken's c3-STOP addendum). */ * banked in ken's c3-STOP addendum). GRADUATED with #102 (W2). */
{ "ampf_2lvl", { "ampf_2lvl",
"package main;\n" "package main;\n"
"type st0 = struct { a: i64, b: i64 };\n" "type st0 = struct { a: i64, b: i64 };\n"
@@ -337,7 +342,7 @@ static const struct row rows[] = {
" *q = 9;\n" " *q = 9;\n"
" if (x.b != 9) { return 1; };\n" " if (x.b != 9) { return 1; };\n"
" return 0;\n" " return 0;\n"
"};\n", 0, 0, K_RUN_NOID, NULL, NULL }, /* byte-id: task #102 */ "};\n", 0, 0, K_RUN, NULL, NULL }, /* graduated: #102 (W2) */
{ "ampf_plain_ctl", { "ampf_plain_ctl",
"package main;\n" "package main;\n"
"type st0 = struct { a: i64, b: i64 };\n" "type st0 = struct { a: i64, b: i64 };\n"
@@ -349,6 +354,32 @@ static const struct row rows[] = {
" if (x.b != 9) { return 1; };\n" " if (x.b != 9) { return 1; };\n"
" return 0;\n" " return 0;\n"
"};\n", 0, 0, K_RUN, NULL, NULL }, "};\n", 0, 0, K_RUN, NULL, NULL },
/* W2-review-found #102 sibling: the value-struct &x.f leg sits
* one leg below the &p.f gate in the same cgun single-DOT arm
* and had the same alias-blind bare structlookup (ww_alias !=
* ww_plain, cs_alias == ww_plain — the c3-STOP bit-test
* mechanism verbatim). Chased in the W2 review amendment. */
{ "ampv_2lvl",
"package main;\n"
"type st0 = struct { a: i64, b: i64 };\n"
"type st = st0;\n"
"export fn main() i32 = {\n"
" let x: st; x.a = 1; x.b = 2;\n"
" let q: *i64 = &x.b;\n"
" *q = 9;\n"
" if (x.b != 9) { return 1; };\n"
" return 0;\n"
"};\n", 0, 0, K_RUN, NULL, NULL }, /* amendment: #102 (W2) */
{ "ampv_plain_ctl",
"package main;\n"
"type st0 = struct { a: i64, b: i64 };\n"
"export fn main() i32 = {\n"
" let x: st0; x.a = 1; x.b = 2;\n"
" let q: *i64 = &x.b;\n"
" *q = 9;\n"
" if (x.b != 9) { return 1; };\n"
" return 0;\n"
"};\n", 0, 0, K_RUN, NULL, NULL },
{ "chdot_2lvl", { "chdot_2lvl",
"package main;\n" "package main;\n"
"type in0 = struct { v: i64 };\n" "type in0 = struct { v: i64 };\n"