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;
|
||||
|
||||
Reference in New Issue
Block a user