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:
@@ -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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user