diff --git a/selfhost/cmd/w6c/main.combined.ww b/selfhost/cmd/w6c/main.combined.ww index 9c698388..571601cd 100644 --- a/selfhost/cmd/w6c/main.combined.ww +++ b/selfhost/cmd/w6c/main.combined.ww @@ -25470,6 +25470,16 @@ fn cgun(c: *cgen, n: *node) void = { let lkind: nkind = nkind.N_NONE; if (tn != nil) { lkind = tn.kind; }; // 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) { let inner: *node = tn.lhs; let sname: str; @@ -25478,7 +25488,7 @@ fn cgun(c: *cgen, n: *node) void = { if (inner.kind == nkind.N_TNAME) { sname = inner.str; }; }; if (sname.len > 0) { - let si: *structinfo = structlookup(c, sname); + let si: *structinfo = structlookupchain(c, inner); if (si != nil) { let fi: *fieldinfo = si.fields; for (fi != nil) { @@ -25497,9 +25507,13 @@ fn cgun(c: *cgen, n: *node) void = { }; }; // 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) { - let sname: str = tn.str; - let si: *structinfo = structlookup(c, sname); + let si: *structinfo = structlookupchain(c, tn); if (si != nil) { let fi: *fieldinfo = si.fields; for (fi != nil) { @@ -29555,22 +29569,31 @@ fn cgassign(c: *cgen, n: *node) void = { // array's element (#61). let elemt: *node = idxelemtn(tn); let baseisarray: bool = tn.kind == nkind.N_TARRAY; - let sname: str; - sname.ptr = nil; sname.len = 0; + let snode: *node = nil; let viaptr: bool = false; if (elemt != nil) { if (elemt.kind == nkind.N_TPTR) { let inner: *node = elemt.lhs; if (inner != nil) { if (inner.kind == nkind.N_TNAME) { - sname = inner.str; + snode = inner; viaptr = true; };}; } else { if (elemt.kind == nkind.N_TNAME) { - sname = elemt.str; + snode = elemt; };}; }; - if (sname.len > 0) { - let si: *structinfo = structlookup(c, sname); + // #102 (ken B6-c3 re-attribution): an alias-NAMED + // 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) { let fi: *fieldinfo = si.fields; for (fi != nil) { diff --git a/selfhost/cmd/wcc/cgenexpr.ww b/selfhost/cmd/wcc/cgenexpr.ww index ce6c13a9..74369d59 100644 --- a/selfhost/cmd/wcc/cgenexpr.ww +++ b/selfhost/cmd/wcc/cgenexpr.ww @@ -4454,6 +4454,16 @@ fn cgun(c: *cgen, n: *node) void = { let lkind: nkind = nkind.N_NONE; if (tn != nil) { lkind = tn.kind; }; // 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) { let inner: *node = tn.lhs; let sname: str; @@ -4462,7 +4472,7 @@ fn cgun(c: *cgen, n: *node) void = { if (inner.kind == nkind.N_TNAME) { sname = inner.str; }; }; if (sname.len > 0) { - let si: *structinfo = structlookup(c, sname); + let si: *structinfo = structlookupchain(c, inner); if (si != nil) { let fi: *fieldinfo = si.fields; for (fi != nil) { @@ -4481,9 +4491,13 @@ fn cgun(c: *cgen, n: *node) void = { }; }; // 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) { - let sname: str = tn.str; - let si: *structinfo = structlookup(c, sname); + let si: *structinfo = structlookupchain(c, tn); if (si != nil) { let fi: *fieldinfo = si.fields; for (fi != nil) { @@ -8539,22 +8553,31 @@ fn cgassign(c: *cgen, n: *node) void = { // array's element (#61). let elemt: *node = idxelemtn(tn); let baseisarray: bool = tn.kind == nkind.N_TARRAY; - let sname: str; - sname.ptr = nil; sname.len = 0; + let snode: *node = nil; let viaptr: bool = false; if (elemt != nil) { if (elemt.kind == nkind.N_TPTR) { let inner: *node = elemt.lhs; if (inner != nil) { if (inner.kind == nkind.N_TNAME) { - sname = inner.str; + snode = inner; viaptr = true; };}; } else { if (elemt.kind == nkind.N_TNAME) { - sname = elemt.str; + snode = elemt; };}; }; - if (sname.len > 0) { - let si: *structinfo = structlookup(c, sname); + // #102 (ken B6-c3 re-attribution): an alias-NAMED + // 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) { let fi: *fieldinfo = si.fields; for (fi != nil) { diff --git a/selfhost/cmd/wwdump/main.combined.ww b/selfhost/cmd/wwdump/main.combined.ww index 4dfe08c2..0e3989b1 100644 --- a/selfhost/cmd/wwdump/main.combined.ww +++ b/selfhost/cmd/wwdump/main.combined.ww @@ -25470,6 +25470,16 @@ fn cgun(c: *cgen, n: *node) void = { let lkind: nkind = nkind.N_NONE; if (tn != nil) { lkind = tn.kind; }; // 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) { let inner: *node = tn.lhs; let sname: str; @@ -25478,7 +25488,7 @@ fn cgun(c: *cgen, n: *node) void = { if (inner.kind == nkind.N_TNAME) { sname = inner.str; }; }; if (sname.len > 0) { - let si: *structinfo = structlookup(c, sname); + let si: *structinfo = structlookupchain(c, inner); if (si != nil) { let fi: *fieldinfo = si.fields; for (fi != nil) { @@ -25497,9 +25507,13 @@ fn cgun(c: *cgen, n: *node) void = { }; }; // 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) { - let sname: str = tn.str; - let si: *structinfo = structlookup(c, sname); + let si: *structinfo = structlookupchain(c, tn); if (si != nil) { let fi: *fieldinfo = si.fields; for (fi != nil) { @@ -29555,22 +29569,31 @@ fn cgassign(c: *cgen, n: *node) void = { // array's element (#61). let elemt: *node = idxelemtn(tn); let baseisarray: bool = tn.kind == nkind.N_TARRAY; - let sname: str; - sname.ptr = nil; sname.len = 0; + let snode: *node = nil; let viaptr: bool = false; if (elemt != nil) { if (elemt.kind == nkind.N_TPTR) { let inner: *node = elemt.lhs; if (inner != nil) { if (inner.kind == nkind.N_TNAME) { - sname = inner.str; + snode = inner; viaptr = true; };}; } else { if (elemt.kind == nkind.N_TNAME) { - sname = elemt.str; + snode = elemt; };}; }; - if (sname.len > 0) { - let si: *structinfo = structlookup(c, sname); + // #102 (ken B6-c3 re-attribution): an alias-NAMED + // 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) { let fi: *fieldinfo = si.fields; for (fi != nil) { diff --git a/test/wcc/944_alias_cgen_b6_run.c b/test/wcc/944_alias_cgen_b6_run.c index 0a166db5..50eeecf8 100644 --- a/test/wcc/944_alias_cgen_b6_run.c +++ b/test/wcc/944_alias_cgen_b6_run.c @@ -63,22 +63,27 @@ * | alias ptr): the c3 chase moved cs | * | onto the PLAIN-canonical dedicated | * | shape (cs_alias == ww_PLAIN, bit- | - * | proven, ken c3-STOP addendum) — but | - * | WWSTAGE is the alias-blind side at | - * | these two sites (ww_alias != | - * | ww_plain, generic-but-correct | - * | routes). Two-cell NOID pins; byte-id | - * | graduates with the filed ww-side W2 | - * | fold, task #102 (ww indexed-elem | - * | field gates + &p.f fallback don't | - * | fire on alias bases). ampf's pre-c3 | - * | byte-id was both-on-generic | + * | proven, ken c3-STOP addendum) — and | + * | WWSTAGE was the alias-blind side at | + * | these two sites (generic-but-correct | + * | routes). GRADUATED to full byte-id | + * | by the W2 ww fold, task #102 (the | + * | two gates now chase the alias chain | + * | via structlookupchain). ampf's | + * | pre-c3 byte-id was both-on-generic | * | identity, not latency (oracle | * | self-correction) | 0/0 * idxf_plain_ctl / | plain no-alias twins — pin the | * ampf_plain_ctl | canonical dedicated shape byte-id | * | BOTH stages (the convergence target | * | 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 | * | hops — latent control | 0/0 * 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 */ /* The c3 chase put cs on the PLAIN-canonical dedicated shape * (cs_alias == ww_PLAIN, bit-proven — ken c3-STOP addendum); - * WWSTAGE is the alias-blind side here: its indexed-elem - * struct-field store/read gates don't fire on alias bases and - * fall to a generic-but-correct route. Byte-id waived until the - * filed ww-side W2 fold (task #102) lands; idxf_plain_ctl pins the - * convergence target. */ + * WWSTAGE was the alias-blind side here: its indexed-elem + * struct-field store gate fell to a generic-but-correct route + * on alias bases. GRADUATED: the W2 ww fold (task #102) chases + * the alias chain (structlookupchain), restoring full byte-id — + * idxf_plain_ctl pins the canonical shape both rows now share. */ { "idxf_2lvl", "package main;\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" " if (xs[1].b != 4 || xs[0].b != 2) { return 1; };\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", "package main;\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 * pre-c3 byte-id here was BOTH stages on the generic spine * (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", "package main;\n" "type st0 = struct { a: i64, b: i64 };\n" @@ -337,7 +342,7 @@ static const struct row rows[] = { " *q = 9;\n" " if (x.b != 9) { return 1; };\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", "package main;\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" " return 0;\n" "};\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", "package main;\n" "type in0 = struct { v: i64 };\n"