wcc_ww/cgen: #77 alias-NAMED global ARRAY emit — tichase at the dispatch entry (g-fold G2)
ww half of the #77+#78 fused g-fold train; completes the family. cs
half landed as the previous commit (G1) — the two ship together, one
gated train, per the fuse ruling on both tasks.
Root: the global DATA emit walk dispatched on the UNCHASED decl tnode —
a NO-PEEL consumer (zero `.under` tokens on the path; it never learned
aliases exist). An alias-typed global array's N_TNAME matched no arm
and the documented skip-policy ate the decl: w6c_ww referenced
main.g(SB) but emitted zero DATAW → loud `w6l: undefined reference to
main.g` on every direct alias-global array row (ken NEW-1, all k_gidx*
shapes). Every other kind was already chased (letvarisstr/isslice/
isfloat/isstruct walk aliaslookup chains; the tuple gate walks tnodes;
emitarraydata/emitslicedata chase tinfo internally; letemitsize walks —
registration was never the gap), probe-confirmed: only array rows
failed ww-side.
Fix: ONE tichase at the dispatch entry, per the spec's entry-point rule
— not per-arm. Dispatch arms touched (enumerated):
emitletdataw (cgen.ww): hoisted `dti = tichase(d.lhs.type_)` at the
per-decl entry; the isarr8 scalar-shortcut gate and the array arm
now key on dti.kind == TY_ARRAY (were d.lhs.kind == N_TARRAY) and
emitarraydata receives dti; the struct zero-fill arm's inline
TY_NAMED loop collapses into the same dti (ef93b16 precedent,
byte-neutral). str/float/struct/slice/tuple gates unchanged.
letpreintern (cgen.ww): the #18 [N]str array-leg gate keyed on the
N_TARRAY tnode while its body already chased the tinfo — gate now
keys on the chased kind, so alias-typed [N]str globals pre-intern
their _S_ labels in decl order (label-order parity with cstage;
the inner elem chase collapses into tichase).
For non-alias decls tichase is identity (same tinfo pointer) — the
emitted bytes are unchanged by construction; full byte-id invariant
holds (test-unit 288/288 incl. the new table).
main.combined.ww (w6c + wwdump) regenerated by `make` — diff verified
content-identical to the cgen.ww hunks, nothing else.
Graduation table committed as test/wcc/944_alias_global_decl_run.c —
23 rows x {cs run, ww run, byte-id} = 69 checks green. This table IS
the permanent guard: the path is lint-invisible (NO-PEEL — nothing for
the future peellint to see), so only a runtime+byte-id row pins it.
Rows: plain control; alias array 1-lvl read/write/decl-order; 2-lvl
read + order-permuted write (the #78 silent saved-BP rows); [4]u32
narrow-esz; scalar/str/f64/f32 2-lvl; alias-of-named-struct field w/r
(the cs SEGV-at-one-user-level row) + 3-layer + STRUCTLIT init; slice
2-lvl literal; [2]str 1-lvl/2-lvl (letpreintern label leg); def-side
2-lvl array/struct/float; no-regression holds (alias global SLICE,
alias ELEMENT [2]row). Values >255, LAST element asserted.
Probe-OUT rows documented in the test header, filed not pinned: #86
(named-tuple global init: cs checker loud-reject vs ww accept), #87
(plain tagged global: cs silent-wrong vs ww loud-reject, non-alias).
This commit is contained in:
@@ -38257,23 +38257,15 @@ export fn letpreintern(c: *cgen, file: *node) void = {
|
||||
// so emitstrarraydata's DATAR rows find an _S_ rodata
|
||||
// row. Must match that helper's interning order exactly
|
||||
// to keep labels stable.
|
||||
// g-fold #77: gate on the CHASED tinfo kind — the
|
||||
// N_TARRAY tnode test missed alias-typed [N]str
|
||||
// globals, desyncing label order vs cstage.
|
||||
let handled: bool = false;
|
||||
if (d.lhs != nil && r != nil) {
|
||||
if (d.lhs.kind == nkind.N_TARRAY
|
||||
let au: *tinfo = tichase(d.lhs.type_: *tinfo);
|
||||
if (au != nil && au.kind == tykind.TY_ARRAY
|
||||
&& r.kind == nkind.N_ARRLIT) {
|
||||
let au: *tinfo = d.lhs.type_: *tinfo;
|
||||
for (au != nil && au.kind == tykind.TY_NAMED) {
|
||||
au = au.under;
|
||||
};
|
||||
let eu: *tinfo = nil;
|
||||
if (au != nil) {
|
||||
if (au.kind == tykind.TY_ARRAY) {
|
||||
eu = au.sub;
|
||||
for (eu != nil && eu.kind == tykind.TY_NAMED) {
|
||||
eu = eu.under;
|
||||
};
|
||||
};
|
||||
};
|
||||
let eu: *tinfo = tichase(au.sub);
|
||||
if (eu != nil && eu.kind == tykind.TY_STR) {
|
||||
handled = true;
|
||||
let alen: i32 = au.alen: i32;
|
||||
@@ -39302,6 +39294,15 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
||||
let sz: i32 = letemitsize(c, d);
|
||||
let issg: bool = letvarisstruct(c, nm);
|
||||
let fsz: i32 = letvarisfloat(c, nm);
|
||||
// g-fold #77: ONE chase at the dispatch entry. The
|
||||
// array gates below keyed on the N_TARRAY tnode —
|
||||
// an alias-typed global's N_TNAME matched no arm
|
||||
// and the skip-policy ate the decl: no DATAW,
|
||||
// undefined reference at link. The str/float/
|
||||
// struct/slice/tuple gates already alias-walk
|
||||
// (letvaris* / the tlt tnode walk) and stay put.
|
||||
let dti: *tinfo = nil;
|
||||
if (d.lhs != nil) { dti = tichase(d.lhs.type_: *tinfo); };
|
||||
// C-t3 (#48): tuple global — slot-laid DATAW
|
||||
// row (+ DATAR ptr patches for str elements)
|
||||
// via emittupledata. Unsupported element
|
||||
@@ -39363,8 +39364,8 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
||||
// below handles it and the duplicate DATAW would
|
||||
// otherwise differ across stages on user code.
|
||||
let isarr8: bool = false;
|
||||
if (d.lhs != nil) {
|
||||
if (d.lhs.kind == nkind.N_TARRAY) { isarr8 = true; };
|
||||
if (dti != nil) {
|
||||
if (dti.kind == tykind.TY_ARRAY) { isarr8 = true; };
|
||||
};
|
||||
if (sz == 8 && !issg && fsz == 0 && !isarr8 && !istup) {
|
||||
let v: u64 = 0u64;
|
||||
@@ -39516,13 +39517,7 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
||||
if (issg) {
|
||||
if (d.rhs == nil) {
|
||||
let zsz: i32 = sz;
|
||||
if (d.lhs != nil) {
|
||||
let ti: *tinfo = d.lhs.type_: *tinfo;
|
||||
for (ti != nil && ti.kind == tykind.TY_NAMED) {
|
||||
ti = ti.under;
|
||||
};
|
||||
if (ti != nil) { zsz = ti.size: i32; };
|
||||
};
|
||||
if (dti != nil) { zsz = dti.size: i32; };
|
||||
emitline("DATAW ");
|
||||
emitsymnamehint(c, nm, d.nmod);
|
||||
emitline("(SB),\"");
|
||||
@@ -39544,8 +39539,8 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
||||
// fold-failures don't corrupt the DATA literal.
|
||||
// No-rhs arrays (e.g. `let buf: [N]u8;`) go through
|
||||
// the same helper with rhs=nil → zero-fill branch.
|
||||
if (d.lhs != nil) {
|
||||
if (d.lhs.kind == nkind.N_TARRAY) {
|
||||
if (dti != nil) {
|
||||
if (dti.kind == tykind.TY_ARRAY) {
|
||||
let rh: *node = d.rhs;
|
||||
let route: bool = false;
|
||||
if (rh == nil) { route = true; };
|
||||
@@ -39555,9 +39550,8 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
||||
};
|
||||
};
|
||||
if (route) {
|
||||
let at: *tinfo = d.lhs.type_: *tinfo;
|
||||
emitarraydata(c, "DATAW", nm,
|
||||
d.nmod, at, rh);
|
||||
d.nmod, dti, rh);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1296,23 +1296,15 @@ export fn letpreintern(c: *cgen, file: *node) void = {
|
||||
// so emitstrarraydata's DATAR rows find an _S_ rodata
|
||||
// row. Must match that helper's interning order exactly
|
||||
// to keep labels stable.
|
||||
// g-fold #77: gate on the CHASED tinfo kind — the
|
||||
// N_TARRAY tnode test missed alias-typed [N]str
|
||||
// globals, desyncing label order vs cstage.
|
||||
let handled: bool = false;
|
||||
if (d.lhs != nil && r != nil) {
|
||||
if (d.lhs.kind == nkind.N_TARRAY
|
||||
let au: *tinfo = tichase(d.lhs.type_: *tinfo);
|
||||
if (au != nil && au.kind == tykind.TY_ARRAY
|
||||
&& r.kind == nkind.N_ARRLIT) {
|
||||
let au: *tinfo = d.lhs.type_: *tinfo;
|
||||
for (au != nil && au.kind == tykind.TY_NAMED) {
|
||||
au = au.under;
|
||||
};
|
||||
let eu: *tinfo = nil;
|
||||
if (au != nil) {
|
||||
if (au.kind == tykind.TY_ARRAY) {
|
||||
eu = au.sub;
|
||||
for (eu != nil && eu.kind == tykind.TY_NAMED) {
|
||||
eu = eu.under;
|
||||
};
|
||||
};
|
||||
};
|
||||
let eu: *tinfo = tichase(au.sub);
|
||||
if (eu != nil && eu.kind == tykind.TY_STR) {
|
||||
handled = true;
|
||||
let alen: i32 = au.alen: i32;
|
||||
@@ -2341,6 +2333,15 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
||||
let sz: i32 = letemitsize(c, d);
|
||||
let issg: bool = letvarisstruct(c, nm);
|
||||
let fsz: i32 = letvarisfloat(c, nm);
|
||||
// g-fold #77: ONE chase at the dispatch entry. The
|
||||
// array gates below keyed on the N_TARRAY tnode —
|
||||
// an alias-typed global's N_TNAME matched no arm
|
||||
// and the skip-policy ate the decl: no DATAW,
|
||||
// undefined reference at link. The str/float/
|
||||
// struct/slice/tuple gates already alias-walk
|
||||
// (letvaris* / the tlt tnode walk) and stay put.
|
||||
let dti: *tinfo = nil;
|
||||
if (d.lhs != nil) { dti = tichase(d.lhs.type_: *tinfo); };
|
||||
// C-t3 (#48): tuple global — slot-laid DATAW
|
||||
// row (+ DATAR ptr patches for str elements)
|
||||
// via emittupledata. Unsupported element
|
||||
@@ -2402,8 +2403,8 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
||||
// below handles it and the duplicate DATAW would
|
||||
// otherwise differ across stages on user code.
|
||||
let isarr8: bool = false;
|
||||
if (d.lhs != nil) {
|
||||
if (d.lhs.kind == nkind.N_TARRAY) { isarr8 = true; };
|
||||
if (dti != nil) {
|
||||
if (dti.kind == tykind.TY_ARRAY) { isarr8 = true; };
|
||||
};
|
||||
if (sz == 8 && !issg && fsz == 0 && !isarr8 && !istup) {
|
||||
let v: u64 = 0u64;
|
||||
@@ -2555,13 +2556,7 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
||||
if (issg) {
|
||||
if (d.rhs == nil) {
|
||||
let zsz: i32 = sz;
|
||||
if (d.lhs != nil) {
|
||||
let ti: *tinfo = d.lhs.type_: *tinfo;
|
||||
for (ti != nil && ti.kind == tykind.TY_NAMED) {
|
||||
ti = ti.under;
|
||||
};
|
||||
if (ti != nil) { zsz = ti.size: i32; };
|
||||
};
|
||||
if (dti != nil) { zsz = dti.size: i32; };
|
||||
emitline("DATAW ");
|
||||
emitsymnamehint(c, nm, d.nmod);
|
||||
emitline("(SB),\"");
|
||||
@@ -2583,8 +2578,8 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
||||
// fold-failures don't corrupt the DATA literal.
|
||||
// No-rhs arrays (e.g. `let buf: [N]u8;`) go through
|
||||
// the same helper with rhs=nil → zero-fill branch.
|
||||
if (d.lhs != nil) {
|
||||
if (d.lhs.kind == nkind.N_TARRAY) {
|
||||
if (dti != nil) {
|
||||
if (dti.kind == tykind.TY_ARRAY) {
|
||||
let rh: *node = d.rhs;
|
||||
let route: bool = false;
|
||||
if (rh == nil) { route = true; };
|
||||
@@ -2594,9 +2589,8 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
||||
};
|
||||
};
|
||||
if (route) {
|
||||
let at: *tinfo = d.lhs.type_: *tinfo;
|
||||
emitarraydata(c, "DATAW", nm,
|
||||
d.nmod, at, rh);
|
||||
d.nmod, dti, rh);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -38257,23 +38257,15 @@ export fn letpreintern(c: *cgen, file: *node) void = {
|
||||
// so emitstrarraydata's DATAR rows find an _S_ rodata
|
||||
// row. Must match that helper's interning order exactly
|
||||
// to keep labels stable.
|
||||
// g-fold #77: gate on the CHASED tinfo kind — the
|
||||
// N_TARRAY tnode test missed alias-typed [N]str
|
||||
// globals, desyncing label order vs cstage.
|
||||
let handled: bool = false;
|
||||
if (d.lhs != nil && r != nil) {
|
||||
if (d.lhs.kind == nkind.N_TARRAY
|
||||
let au: *tinfo = tichase(d.lhs.type_: *tinfo);
|
||||
if (au != nil && au.kind == tykind.TY_ARRAY
|
||||
&& r.kind == nkind.N_ARRLIT) {
|
||||
let au: *tinfo = d.lhs.type_: *tinfo;
|
||||
for (au != nil && au.kind == tykind.TY_NAMED) {
|
||||
au = au.under;
|
||||
};
|
||||
let eu: *tinfo = nil;
|
||||
if (au != nil) {
|
||||
if (au.kind == tykind.TY_ARRAY) {
|
||||
eu = au.sub;
|
||||
for (eu != nil && eu.kind == tykind.TY_NAMED) {
|
||||
eu = eu.under;
|
||||
};
|
||||
};
|
||||
};
|
||||
let eu: *tinfo = tichase(au.sub);
|
||||
if (eu != nil && eu.kind == tykind.TY_STR) {
|
||||
handled = true;
|
||||
let alen: i32 = au.alen: i32;
|
||||
@@ -39302,6 +39294,15 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
||||
let sz: i32 = letemitsize(c, d);
|
||||
let issg: bool = letvarisstruct(c, nm);
|
||||
let fsz: i32 = letvarisfloat(c, nm);
|
||||
// g-fold #77: ONE chase at the dispatch entry. The
|
||||
// array gates below keyed on the N_TARRAY tnode —
|
||||
// an alias-typed global's N_TNAME matched no arm
|
||||
// and the skip-policy ate the decl: no DATAW,
|
||||
// undefined reference at link. The str/float/
|
||||
// struct/slice/tuple gates already alias-walk
|
||||
// (letvaris* / the tlt tnode walk) and stay put.
|
||||
let dti: *tinfo = nil;
|
||||
if (d.lhs != nil) { dti = tichase(d.lhs.type_: *tinfo); };
|
||||
// C-t3 (#48): tuple global — slot-laid DATAW
|
||||
// row (+ DATAR ptr patches for str elements)
|
||||
// via emittupledata. Unsupported element
|
||||
@@ -39363,8 +39364,8 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
||||
// below handles it and the duplicate DATAW would
|
||||
// otherwise differ across stages on user code.
|
||||
let isarr8: bool = false;
|
||||
if (d.lhs != nil) {
|
||||
if (d.lhs.kind == nkind.N_TARRAY) { isarr8 = true; };
|
||||
if (dti != nil) {
|
||||
if (dti.kind == tykind.TY_ARRAY) { isarr8 = true; };
|
||||
};
|
||||
if (sz == 8 && !issg && fsz == 0 && !isarr8 && !istup) {
|
||||
let v: u64 = 0u64;
|
||||
@@ -39516,13 +39517,7 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
||||
if (issg) {
|
||||
if (d.rhs == nil) {
|
||||
let zsz: i32 = sz;
|
||||
if (d.lhs != nil) {
|
||||
let ti: *tinfo = d.lhs.type_: *tinfo;
|
||||
for (ti != nil && ti.kind == tykind.TY_NAMED) {
|
||||
ti = ti.under;
|
||||
};
|
||||
if (ti != nil) { zsz = ti.size: i32; };
|
||||
};
|
||||
if (dti != nil) { zsz = dti.size: i32; };
|
||||
emitline("DATAW ");
|
||||
emitsymnamehint(c, nm, d.nmod);
|
||||
emitline("(SB),\"");
|
||||
@@ -39544,8 +39539,8 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
||||
// fold-failures don't corrupt the DATA literal.
|
||||
// No-rhs arrays (e.g. `let buf: [N]u8;`) go through
|
||||
// the same helper with rhs=nil → zero-fill branch.
|
||||
if (d.lhs != nil) {
|
||||
if (d.lhs.kind == nkind.N_TARRAY) {
|
||||
if (dti != nil) {
|
||||
if (dti.kind == tykind.TY_ARRAY) {
|
||||
let rh: *node = d.rhs;
|
||||
let route: bool = false;
|
||||
if (rh == nil) { route = true; };
|
||||
@@ -39555,9 +39550,8 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
||||
};
|
||||
};
|
||||
if (route) {
|
||||
let at: *tinfo = d.lhs.type_: *tinfo;
|
||||
emitarraydata(c, "DATAW", nm,
|
||||
d.nmod, at, rh);
|
||||
d.nmod, dti, rh);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user