w6c+wwstage: emit global str/slice len via .len field load (#231)
len(str-or-slice-global) was wrong in both stages, differently. cstage's len() arm did a BP-relative slot load; localfind returns 0 for a global, so it emitted `MOVQ 8(BP),AX` — a bogus stack slot. wwstage's arm only handled locals; a global fell through to cgexpr, which loads the whole header and leaves AX=.ptr, not .len. Both stages now emit the global .len load — LEAQ name(SB),CX; MOVQ 8(CX),AX (.len field; header is ptr@0/len@8/cap@16). The LEAQ symbol routes through the post-#1 value mangle (cstage mahint c->cur_mod, wwstage emitsymnamehint c.curmod), not a raw name, so a private same-module same-leaf str global can't re-open the #1 collision. The local-str case is unchanged (control). Slice-global rows wait on #233 (cstage rejects `let g: []u8 = [...]` init); the str global proves the path. Byte-id-blind, so a committed runtime + cs==ww test (797) is the net.
This commit is contained in:
@@ -22452,6 +22452,22 @@ fn cgcall(c: *cgen, n: *node) void = {
|
||||
emitline("(BP), AX\n");
|
||||
return;
|
||||
};
|
||||
// #231: str/slice GLOBAL — the
|
||||
// local-only path above lacked it,
|
||||
// so cgexpr fell through and left
|
||||
// AX=.ptr (not .len). The .len word
|
||||
// lives at the global's address+8;
|
||||
// route the LEAQ through the post-#1
|
||||
// value mangle (c.curmod) so a
|
||||
// private same-leaf global isn't
|
||||
// mis-resolved.
|
||||
if (isletvar(c, a.str)) {
|
||||
emitline("\tLEAQ\t");
|
||||
emitsymnamehint(c, a.str, c.curmod);
|
||||
emitline("(SB), CX\n");
|
||||
emitline("\tMOVQ\t8(CX), AX\n");
|
||||
return;
|
||||
};
|
||||
};
|
||||
if (u.kind == tykind.TY_ARRAY) {
|
||||
emitline("\tMOVQ\t$");
|
||||
|
||||
@@ -3792,6 +3792,22 @@ fn cgcall(c: *cgen, n: *node) void = {
|
||||
emitline("(BP), AX\n");
|
||||
return;
|
||||
};
|
||||
// #231: str/slice GLOBAL — the
|
||||
// local-only path above lacked it,
|
||||
// so cgexpr fell through and left
|
||||
// AX=.ptr (not .len). The .len word
|
||||
// lives at the global's address+8;
|
||||
// route the LEAQ through the post-#1
|
||||
// value mangle (c.curmod) so a
|
||||
// private same-leaf global isn't
|
||||
// mis-resolved.
|
||||
if (isletvar(c, a.str)) {
|
||||
emitline("\tLEAQ\t");
|
||||
emitsymnamehint(c, a.str, c.curmod);
|
||||
emitline("(SB), CX\n");
|
||||
emitline("\tMOVQ\t8(CX), AX\n");
|
||||
return;
|
||||
};
|
||||
};
|
||||
if (u.kind == tykind.TY_ARRAY) {
|
||||
emitline("\tMOVQ\t$");
|
||||
|
||||
@@ -22452,6 +22452,22 @@ fn cgcall(c: *cgen, n: *node) void = {
|
||||
emitline("(BP), AX\n");
|
||||
return;
|
||||
};
|
||||
// #231: str/slice GLOBAL — the
|
||||
// local-only path above lacked it,
|
||||
// so cgexpr fell through and left
|
||||
// AX=.ptr (not .len). The .len word
|
||||
// lives at the global's address+8;
|
||||
// route the LEAQ through the post-#1
|
||||
// value mangle (c.curmod) so a
|
||||
// private same-leaf global isn't
|
||||
// mis-resolved.
|
||||
if (isletvar(c, a.str)) {
|
||||
emitline("\tLEAQ\t");
|
||||
emitsymnamehint(c, a.str, c.curmod);
|
||||
emitline("(SB), CX\n");
|
||||
emitline("\tMOVQ\t8(CX), AX\n");
|
||||
return;
|
||||
};
|
||||
};
|
||||
if (u.kind == tykind.TY_ARRAY) {
|
||||
emitline("\tMOVQ\t$");
|
||||
|
||||
Reference in New Issue
Block a user