wcc/cgen: GAP-A.len def-global array .len — def-twin cgdot arm (#7 lineage, wwstage align-up)
wwstage .len on a def-global array fell to the cgdot SB-fallback (w6l: undefined reference to 'len') — the #7 let-array arm gates on letvartnode (c.lets only), so def-globals (c.defs) missed it. Add a def .len-only arm in cgdot using the existing defvartnode (the def-side mirror of letvartnode), emitting the length immediate from the #11-stamped N_TARRAY length child. cstage cgen.c was already correct, so this is a wwstage-only source change: w6c unchanged, w6c_ww + wwdump regen'd (they embed the wcc cgen). .ptr (cstage itself buggy — emits LEAQ (BP), filed GAP-A.ptr) and .cap (wwstage silent garbage; arrays have no cap, filed GAP-A.cap) are NOT folded (rule-11, separate concerns). Pin: table-driven test/wcc/816_def_arr_len (def [3] + [_] inferred + 1-elem + u8 stride .len, both stages + byte-id), teeth-proven.
This commit is contained in:
@@ -24962,6 +24962,37 @@ fn cgdot(c: *cgen, n: *node) void = {
|
||||
};
|
||||
};
|
||||
};
|
||||
// GAP-A (#7 def-twin): `def NAME: [N]T = arrlit;` `.len` = static
|
||||
// elem count. The let-global arm above resolves via letvartnode
|
||||
// (c.lets only); a def lives in c.defs, misses it, and falls to the
|
||||
// SB fallback → MOVQ len(SB) (w6l: undefined 'len'). cstage cgen.c
|
||||
// emits MOVQ $alen here. defvartnode is the def-side mirror of
|
||||
// letvartnode (returns dtnode = the N_TARRAY whose .rhs length child
|
||||
// is #11-stamped). `.ptr`/`.cap` are NOT mirrored: cstage's def .ptr
|
||||
// is itself buggy (LEAQ (BP), task GAP-A.ptr) and arrays have no
|
||||
// .cap (cstage rejects, task GAP-A.cap).
|
||||
if (lhs != nil) {
|
||||
if (lhs.kind == nkind.N_IDENT) {
|
||||
if (streq(fld, "len")) {
|
||||
let dtn: *node = defvartnode(c, lhs.str);
|
||||
if (dtn != nil) {
|
||||
if (dtn.kind == nkind.N_TARRAY) {
|
||||
let lenn: *node = dtn.rhs;
|
||||
let alen: i64 = 0i64;
|
||||
if (lenn != nil) {
|
||||
if (lenn.kind == nkind.N_INTLIT) {
|
||||
alen = lenn.uval: i64;
|
||||
};
|
||||
};
|
||||
emitline("\tMOVQ\t$");
|
||||
emitint(alen);
|
||||
emitline(", AX\n");
|
||||
return;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
// Top-level TUPLE global positional read (C-t3, #48): `g.N` —
|
||||
// LEAQ name(SB) into CX, then load at the element's SLOT offset
|
||||
// (C-t0 layout), the element's natural width. Mirrors the local
|
||||
|
||||
Reference in New Issue
Block a user