wcc/cgen: #94 def-array indexed &-base leg (both-stage)
`&D[i]` over a module-level DEF array SEGV'd on BOTH stages: the TK_AMP N_INDEX N_IDENT base classify checked only the local and let legs, so a def-array base fell to a wrong else — cstage zero-based the addend (XORQ BX,BX -> wild pointer, cgen.c) while wwstage value-loaded the symbol (MOVQ name(SB) = D[0], not its address, cgenexpr.ww complex-base fallback). Divergent asm, both wild. Add one def-array leg per stage, mirroring the working let leg: - cs: `def_isarraydef(base) -> LEAQ name(SB),BX` alongside let_islet. - ww: the `defvartnode` fallback the read-side cgindex already takes (cgenexpr.ww:1762) -> N_TARRAY classifies isglobalarr -> LEAQ name(SB). The def DATA symbol already exists (plain &D + D[i]-read work), so once the base is the address the existing i*esz scale + ADDQ round-trips. cs and ww now emit BYTE-IDENTICAL LEAQ-SB asm — the both-broken -> both-correct convergence is the point (#263 class). Rows (944_def_amp_idx_run, all 0/0 byte-id): amp_int [3]int, amp_u32 [3]u32 esz=4 (narrow scale), amp_arg &D[2] as a func-arg; controls ctrl_plain (&D), ctrl_read (D[i]), ctrl_2d (&M[1][1]) keep working. *p spelled `let v: T = *p` — `*p: T` parses as `*(p: T)`. OUT (filed #112): &D[..] slicing a def-array is a distinct parse reject needing a Hare-fidelity ruling — not this leg.
This commit is contained in:
@@ -25884,6 +25884,16 @@ fn cgun(c: *cgen, n: *node) void = {
|
||||
// name(SB) (a str/slice's .ptr IS the symbol's
|
||||
// first word). Align UP, mirroring cgindex.
|
||||
let tn: *node = letvartnode(c, base.str);
|
||||
// #94: a def-array base resolves via
|
||||
// defvartnode (the def-side sister), the same
|
||||
// fallback cgindex's read-side already takes
|
||||
// (cgenexpr.ww:1762). Without it &D[i] over a
|
||||
// def array fell to the complex-base value-load
|
||||
// below (MOVQ name(SB) = D[0] not the address),
|
||||
// divergent from cstage's zero-base SEGV — both
|
||||
// wild. The N_TARRAY tnode classifies isglobalarr
|
||||
// → LEAQ name(SB), the cstage-identical base.
|
||||
if (tn == nil) { tn = defvartnode(c, base.str); };
|
||||
if (tn != nil) {
|
||||
globalname = base.str;
|
||||
esz = elemsizeofc(c, tn);
|
||||
|
||||
@@ -4697,6 +4697,16 @@ fn cgun(c: *cgen, n: *node) void = {
|
||||
// name(SB) (a str/slice's .ptr IS the symbol's
|
||||
// first word). Align UP, mirroring cgindex.
|
||||
let tn: *node = letvartnode(c, base.str);
|
||||
// #94: a def-array base resolves via
|
||||
// defvartnode (the def-side sister), the same
|
||||
// fallback cgindex's read-side already takes
|
||||
// (cgenexpr.ww:1762). Without it &D[i] over a
|
||||
// def array fell to the complex-base value-load
|
||||
// below (MOVQ name(SB) = D[0] not the address),
|
||||
// divergent from cstage's zero-base SEGV — both
|
||||
// wild. The N_TARRAY tnode classifies isglobalarr
|
||||
// → LEAQ name(SB), the cstage-identical base.
|
||||
if (tn == nil) { tn = defvartnode(c, base.str); };
|
||||
if (tn != nil) {
|
||||
globalname = base.str;
|
||||
esz = elemsizeofc(c, tn);
|
||||
|
||||
@@ -25884,6 +25884,16 @@ fn cgun(c: *cgen, n: *node) void = {
|
||||
// name(SB) (a str/slice's .ptr IS the symbol's
|
||||
// first word). Align UP, mirroring cgindex.
|
||||
let tn: *node = letvartnode(c, base.str);
|
||||
// #94: a def-array base resolves via
|
||||
// defvartnode (the def-side sister), the same
|
||||
// fallback cgindex's read-side already takes
|
||||
// (cgenexpr.ww:1762). Without it &D[i] over a
|
||||
// def array fell to the complex-base value-load
|
||||
// below (MOVQ name(SB) = D[0] not the address),
|
||||
// divergent from cstage's zero-base SEGV — both
|
||||
// wild. The N_TARRAY tnode classifies isglobalarr
|
||||
// → LEAQ name(SB), the cstage-identical base.
|
||||
if (tn == nil) { tn = defvartnode(c, base.str); };
|
||||
if (tn != nil) {
|
||||
globalname = base.str;
|
||||
esz = elemsizeofc(c, tn);
|
||||
|
||||
Reference in New Issue
Block a user