w6c/cgen: #71 chained-dot walks chase alias-typed hops — direct offsets, byte-id graduation
rob probe-ruled F1 enrollment (fold-or-file decided by the dispatch
test): the chained-dot STORE walk, its READ twin, and the addr-of
sibling each single-peeled every hop's type, so an alias-typed field
(type fa = inner; outer{x: fa}) aborted the offset-folding fast arm and
fell to the generic address spine — store via cgplaceaddr
(PUSHQ/LEAQ/ADDQ/POPQ), read via ADDQ-per-hop. Runtime-correct BOTH
stages; byte-id NO vs wwstage's folded direct MOVQ offsets
(reviewer-62r diamond find). Chasing the walk hops (+ the read arm's
leaf gate and the two ptr-root sub peels) flips cs onto the fast arm =
wwstage's asm exactly.
Blast radius measured per rob's caution: bootstrap asm cmp-identical
vs the pristine 738d7f4 scratch on all five main.combined.ww, 989
lib_byteid pins unchanged (31/9/3), every control row byte-id — the
flip moves ONLY the #71 shapes.
test: 944_alias_accept_run +2 rows, both decl orders: nested store +
last-field readback; the fwd row adds the &v.y.b addr-of + deref-write
leg. Mutation-checked at the 738d7f4 scratch: both rows byte-id-diff
there; 70/70 green here.
Also graduates the reviewer-F1 slicefield rows: their `.len` readbacks
ride this walk, so the 7 K_RUN_CS rows from commit 1 flip to K_RUN
(byte-id) here.
This commit is contained in:
@@ -4053,8 +4053,9 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
int abort = 0;
|
||||
while (cur && cur->kind == N_DOT && cur->lhs) {
|
||||
Type *pt = cur->lhs->type;
|
||||
Type *pu = (pt && pt->kind == TY_NAMED)
|
||||
? pt->under : pt;
|
||||
/* Transitive chase (#71) — addr-of sibling of the
|
||||
* chained-dot walks. */
|
||||
Type *pu = type_chase_named(pt);
|
||||
if (!pu) { abort = 1; break; }
|
||||
if (cur == opnd && (pu->kind == TY_SLICE
|
||||
|| pu->kind == TY_STR)) {
|
||||
@@ -5517,8 +5518,12 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
int abort = 0;
|
||||
while (cur && cur->kind == N_DOT && cur->lhs) {
|
||||
Type *pt = cur->lhs->type;
|
||||
Type *pu = (pt && pt->kind == TY_NAMED)
|
||||
? pt->under : pt;
|
||||
/* Transitive chase (#71): an alias-typed hop left pu
|
||||
* TY_NAMED -> abort -> the generic cgplaceaddr spine
|
||||
* (PUSHQ/LEAQ/ADDQ/POPQ) while wwstage emits the direct
|
||||
* offset store. Runtime-correct both; chasing converges
|
||||
* cs onto the fast direct arm = wwstage's asm. */
|
||||
Type *pu = type_chase_named(pt);
|
||||
if (!pu) { abort = 1; break; }
|
||||
if (cur == n->lhs && (pu->kind == TY_SLICE
|
||||
|| pu->kind == TY_STR)) {
|
||||
@@ -5530,8 +5535,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
/* `*T` root: dereference at emit time;
|
||||
* walk through pointee struct fields.
|
||||
* Last-hop only (root is a bare ident). */
|
||||
Type *sub = (pu->sub->kind == TY_NAMED)
|
||||
? pu->sub->under : pu->sub;
|
||||
Type *sub = type_chase_named(pu->sub);
|
||||
if (sub && sub->kind == TY_STRUCT) {
|
||||
pu = sub;
|
||||
ptr_root = 1;
|
||||
@@ -10298,7 +10302,10 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
* stale. Sibling of the pointer-chain branch further down. */
|
||||
if (n->lhs && n->lhs->kind == N_DOT) {
|
||||
Type *lt0 = n->lhs->type;
|
||||
Type *lu0 = (lt0 && lt0->kind == TY_NAMED) ? lt0->under : lt0;
|
||||
/* Transitive chase (#71) — the READ twin of the chained-dot
|
||||
* store walk; an alias-typed hop skipped this arm onto the
|
||||
* ADDQ-per-hop address spine while wwstage folds the offsets. */
|
||||
Type *lu0 = type_chase_named(lt0);
|
||||
int leaf_is_pseudo = lu0 && n->str
|
||||
&& (lu0->kind == TY_SLICE || lu0->kind == TY_STR)
|
||||
&& (strcmp(n->str, "ptr") == 0
|
||||
@@ -10313,8 +10320,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
int abort = 0;
|
||||
while (cur && cur->kind == N_DOT && cur->lhs) {
|
||||
Type *pt = cur->lhs->type;
|
||||
Type *pu = (pt && pt->kind == TY_NAMED)
|
||||
? pt->under : pt;
|
||||
Type *pu = type_chase_named(pt);
|
||||
if (!pu) { abort = 1; break; }
|
||||
if (cur == n && (pu->kind == TY_SLICE
|
||||
|| pu->kind == TY_STR)) {
|
||||
@@ -10329,8 +10335,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
* is a bare ident) — `*T`-field mid-
|
||||
* chain keeps its cgexpr-based pointer-
|
||||
* field branch further down. */
|
||||
Type *sub = (pu->sub->kind == TY_NAMED)
|
||||
? pu->sub->under : pu->sub;
|
||||
Type *sub = type_chase_named(pu->sub);
|
||||
if (sub && sub->kind == TY_STRUCT) {
|
||||
pu = sub;
|
||||
ptr_root = 1;
|
||||
|
||||
@@ -50,6 +50,10 @@
|
||||
* | store/push word0-only; CS-ONLY until |
|
||||
* | F2 lands the wwstage half; base ctl |
|
||||
* | + the #54-bound `as` row pinned loud | 0(cs)
|
||||
* nested_alias_field_* | task #71: alias-typed nested-field |
|
||||
* | store/read/addr-of walks fold to |
|
||||
* | direct offsets (byte-id graduation, |
|
||||
* | both decl orders) | 0
|
||||
*
|
||||
* K_RUN rows also assert cstage/wwstage asm byte-id (acceptance
|
||||
* graduations land byte-identical — F0's accept side was wwstage).
|
||||
@@ -275,10 +279,9 @@ static const struct row rows[] = {
|
||||
* noise() call clobbers BX/CX so stale-register luck can't pass a
|
||||
* word0-only header. Unprobed sibling gates are LOUD-tripwired,
|
||||
* pinned by the #73 row at the end of this block. Rows whose
|
||||
* `.len` readback rides the chained-dot READ walk are K_RUN_CS
|
||||
* here (runtime-correct both stages; cs takes the generic spine
|
||||
* pre-#71) and flip to K_RUN at the #71 walk-chase commit, which
|
||||
* graduates their byte-id. */
|
||||
* `.len` readback rides the chained-dot READ walk entered as
|
||||
* K_RUN_CS (runtime-correct both stages; cs took the generic
|
||||
* spine) and graduated to K_RUN with the #71 walk chase. */
|
||||
{ "slicefield_store_2lvl",
|
||||
"package main;\n"
|
||||
"type sl = []int;\n"
|
||||
@@ -294,7 +297,7 @@ static const struct row rows[] = {
|
||||
" if (b.s[2] != 900) { return 2; };\n"
|
||||
" if (b.s.len != 3) { return 3; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN_CS, NULL }, /* ->K_RUN at the #71 walk-chase commit */
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
{ "slicefield_range_2lvl",
|
||||
"package main;\n"
|
||||
"type sl = []int;\n"
|
||||
@@ -311,7 +314,7 @@ static const struct row rows[] = {
|
||||
" if (x < 700) { return 3; };\n"
|
||||
" };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN_CS, NULL }, /* ->K_RUN at the #71 walk-chase commit */
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
{ "strfield_store_2lvl",
|
||||
"package main;\n"
|
||||
"type s1t = str;\n"
|
||||
@@ -323,7 +326,7 @@ static const struct row rows[] = {
|
||||
" b.n = 5;\n"
|
||||
" if (b.s.len != 5) { return 1; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN_CS, NULL }, /* ->K_RUN at the #71 walk-chase commit */
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
{ "slicefield_structlit_2lvl",
|
||||
"package main;\n"
|
||||
"type sl = []int;\n"
|
||||
@@ -336,7 +339,7 @@ static const struct row rows[] = {
|
||||
" if (b.s.len != 3) { return 2; };\n"
|
||||
" if (b.s[2] != 900) { return 3; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN_CS, NULL }, /* ->K_RUN at the #71 walk-chase commit */
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
{ "slicefield_viaptr_2lvl",
|
||||
"package main;\n"
|
||||
"type sl = []int;\n"
|
||||
@@ -350,7 +353,7 @@ static const struct row rows[] = {
|
||||
" if (p.s.len != 3) { return 1; };\n"
|
||||
" if (p.s[2] != 900) { return 2; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN_CS, NULL }, /* ->K_RUN at the #71 walk-chase commit */
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
{ "slicefield_chainstore_2lvl",
|
||||
"package main;\n"
|
||||
"type sl = []int;\n"
|
||||
@@ -364,7 +367,7 @@ static const struct row rows[] = {
|
||||
" if (v.i.s.len != 3) { return 1; };\n"
|
||||
" if (v.i.s[2] != 900) { return 2; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN_CS, NULL }, /* ->K_RUN at the #71 walk-chase commit */
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
{ "slicefield_ptrchain_2lvl",
|
||||
"package main;\n"
|
||||
"type sl = []int;\n"
|
||||
@@ -381,7 +384,7 @@ static const struct row rows[] = {
|
||||
" if (i.s.len != 3) { return 1; };\n"
|
||||
" if (i.s[2] != 900) { return 2; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN_CS, NULL }, /* ->K_RUN at the #71 walk-chase commit */
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
{ "slicefield_chainread_2lvl",
|
||||
"package main;\n"
|
||||
"type sl = []int;\n"
|
||||
@@ -749,6 +752,42 @@ static const struct row rows[] = {
|
||||
" };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
/* ---- task #71 (rob probe-ruled F1 enrollment): nested fields
|
||||
* whose TYPES are aliases. The chained-dot store/read/addr-of
|
||||
* walks single-peeled each hop, aborted on the alias, and fell
|
||||
* to the generic PUSHQ/LEAQ/ADDQ/POPQ address spine — runtime-
|
||||
* correct but byte-id NO vs wwstage's folded direct offsets.
|
||||
* Chasing the walks converges cs onto the direct arm = ww's asm.
|
||||
* Distinct values; the LAST field of the SECOND member checked. */
|
||||
{ "nested_alias_field_norm",
|
||||
"package main;\n"
|
||||
"type fa = inner;\n"
|
||||
"type inner = struct { a: size, b: size };\n"
|
||||
"type outer = struct { x: fa, y: fa };\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let v: outer;\n"
|
||||
" v.x.a = 4; v.x.b = 9;\n"
|
||||
" v.y.a = 7; v.y.b = 3;\n"
|
||||
" if (v.x.b != 9) { return 1; };\n"
|
||||
" if (v.y.b != 3) { return 2; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
{ "nested_alias_field_fwd",
|
||||
"package main;\n"
|
||||
"type outer = struct { x: fa, y: fa };\n"
|
||||
"type fa = inner;\n"
|
||||
"type inner = struct { a: size, b: size };\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let v: outer;\n"
|
||||
" v.x.a = 4; v.x.b = 9;\n"
|
||||
" v.y.a = 7; v.y.b = 3;\n"
|
||||
" if (v.x.b != 9) { return 1; };\n"
|
||||
" if (v.y.b != 3) { return 2; };\n"
|
||||
" let pa = &v.y.b;\n"
|
||||
" *pa = 11;\n"
|
||||
" if (v.y.b != 11) { return 3; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
/* banked row L2-3 (`v as ali` readback) trips task #54's as-binding
|
||||
* aggregate-init bound — LOUD both stages today; fold the row into
|
||||
* #54's pin set on its fold (do not drop). Pinned here as the
|
||||
|
||||
Reference in New Issue
Block a user