wcc/ww: tagged GLOBAL reassign stores tag and payload

Reassigning a module-global tagged union stored the payload into the
tag word; emit the full tag+payload store to g(SB). Both-wrong pair:
cstage silently DROPS the store entirely (filed task #41) — rows pin
ww-runtime-correct and the documented cstage residual. Review item #32.
This commit is contained in:
2026-06-12 09:10:16 +09:00
parent 94bfca761c
commit b3a355744f
5 changed files with 247 additions and 0 deletions

View File

@@ -30976,6 +30976,25 @@ fn cgassign(c: *cgen, n: *node) void = {
};
};
};
// #32 (#263 ww-runtime-correct): tagged-union GLOBAL reassign
// `g = expr`. No BP slot — LEAQ g(SB),BX then the shared widener
// stores tag+payload off BX (mirror the local arm above + the
// global-struct-field tagged arm at :10220). Pre-fix the generic
// scalar store below clobbered the tag word. cstage drops the
// store entirely — cs!=ww residual until the cstage half (#41).
if (lc == nil) {
let gtn: *node = letvartnode(c, lhs.str);
if (gtn != nil) {
if (istaggedtype(c, gtn)) {
let gsz: i32 = slotsize(c, gtn);
emitline("\tLEAQ\t");
emitsymname(c, lhs.str);
emitline("(SB), BX\n");
cgwidentaggedstore(c, gtn.type_: *tinfo, n.rhs, "BX", 0, gsz);
return;
};
};
};
};
};
};

View File

@@ -8205,6 +8205,25 @@ fn cgassign(c: *cgen, n: *node) void = {
};
};
};
// #32 (#263 ww-runtime-correct): tagged-union GLOBAL reassign
// `g = expr`. No BP slot — LEAQ g(SB),BX then the shared widener
// stores tag+payload off BX (mirror the local arm above + the
// global-struct-field tagged arm at :10220). Pre-fix the generic
// scalar store below clobbered the tag word. cstage drops the
// store entirely — cs!=ww residual until the cstage half (#41).
if (lc == nil) {
let gtn: *node = letvartnode(c, lhs.str);
if (gtn != nil) {
if (istaggedtype(c, gtn)) {
let gsz: i32 = slotsize(c, gtn);
emitline("\tLEAQ\t");
emitsymname(c, lhs.str);
emitline("(SB), BX\n");
cgwidentaggedstore(c, gtn.type_: *tinfo, n.rhs, "BX", 0, gsz);
return;
};
};
};
};
};
};

View File

@@ -30976,6 +30976,25 @@ fn cgassign(c: *cgen, n: *node) void = {
};
};
};
// #32 (#263 ww-runtime-correct): tagged-union GLOBAL reassign
// `g = expr`. No BP slot — LEAQ g(SB),BX then the shared widener
// stores tag+payload off BX (mirror the local arm above + the
// global-struct-field tagged arm at :10220). Pre-fix the generic
// scalar store below clobbered the tag word. cstage drops the
// store entirely — cs!=ww residual until the cstage half (#41).
if (lc == nil) {
let gtn: *node = letvartnode(c, lhs.str);
if (gtn != nil) {
if (istaggedtype(c, gtn)) {
let gsz: i32 = slotsize(c, gtn);
emitline("\tLEAQ\t");
emitsymname(c, lhs.str);
emitline("(SB), BX\n");
cgwidentaggedstore(c, gtn.type_: *tinfo, n.rhs, "BX", 0, gsz);
return;
};
};
};
};
};
};