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