cgen: address module-global str/slice pseudo-field stores via the symbol

A module-global base has no frame slot; treating its local-lookup miss
as offset zero wrote .ptr/.len/.cap at the caller return address. LEAQ
the symbol like the struct-field global arms do. Both stages.
This commit is contained in:
2026-08-07 23:00:08 +09:00
parent 7dc3150b65
commit 5ddada94e5
3 changed files with 67 additions and 3 deletions

View File

@@ -5378,10 +5378,19 @@ cgexpr(Cg *c, Node *n, Local *locals)
else if (strcmp(fld, "cap") == 0) delta = 16;
if (delta < 0) goto after_dot_assign;
int boff = localfind(locals, base->str);
/* A global has no frame slot; treating its lookup miss as
* offset zero writes .len at the caller return address. */
int is_global = boff == 0 && !via_ptr
&& let_islet(base->str);
if (n->op != TK_ASSIGN) {
if (via_ptr) {
ins2(c, A_MOVQ, amem(D_BP, boff), areg(D_BX));
ins2(c, A_MOVQ, amem(D_BX, delta), areg(D_BX));
} else if (is_global) {
ins2(c, A_LEAQ, masym(c, base->str),
areg(D_BX));
ins2(c, A_MOVQ, amem(D_BX, delta),
areg(D_BX));
} else {
ins2(c, A_MOVQ, amem(D_BP, boff + delta), areg(D_BX));
}
@@ -5395,6 +5404,11 @@ cgexpr(Cg *c, Node *n, Local *locals)
if (via_ptr) {
ins2(c, A_MOVQ, amem(D_BP, boff), areg(D_BX));
ins2(c, A_MOVQ, areg(D_AX), amem(D_BX, delta));
} else if (is_global) {
ins2(c, A_LEAQ, masym(c, base->str),
areg(D_BX));
ins2(c, A_MOVQ, areg(D_AX),
amem(D_BX, delta));
} else {
ins2(c, A_MOVQ, areg(D_AX), amem(D_BP, boff + delta));
}