w6c: 'as' on a module-global tagged ident loads the full box

cstage's N_TYPEASSERT assumed cgexpr filled the registers and spilled
an uninitialized payload (cs=0 for any stored value); mirror the
landed wwstage emission (tag/payload/cap from g(SB)). Flips the
residual row to cs==ww==correct. Task #46.
This commit is contained in:
2026-06-12 22:45:10 +09:00
parent fc47c3d0f2
commit e09a8c1775
2 changed files with 35 additions and 23 deletions

View File

@@ -10716,7 +10716,22 @@ cgexpr(Cg *c, Node *n, Local *locals)
if (sl_off == 0) {
sl_off = localoff(c, &locals, "@asrt_spill",
slot_size, cg_frame);
if (cg_tagged_memread(s)) {
if (s && s->kind == N_IDENT && let_islet(s->str)) {
/* #46 (#263): a module-global tagged ident —
* cgexpr loads only the tag word (MOVQ g(SB),AX),
* so the DX/CX spill below would write
* uninitialized payload. Copy the whole box from
* g(SB)+0/+8[/+16] into the spill so the
* tag-check + payload load index off memory like
* a local. ww half landed F8-c3. */
ins2(c, A_LEAQ, masym(c, s->str), areg(D_AX));
for (int k = 0; k < slot_size; k += 8) {
ins2(c, A_MOVQ, amem(D_AX, k),
areg(D_DX));
ins2(c, A_MOVQ, areg(D_DX),
amem(D_BP, sl_off + k));
}
} else if (cg_tagged_memread(s)) {
/* #37: >32B box read — ADDRESS in AX; copy
* the whole box from memory. */
cgexpr(c, s, locals);