wcc: for-range destructure copies the full str/slice binding, both stages
The per-binding copy loop moved ONE word of a 24B str/slice binding — .len and .cap read zero/garbage in BOTH stages (byte-identical, the deepest both-wrong-identical of the drain: the F7-era stride fix asserted convergence without re-measuring the absolute). Copy the full extent for an sz>8 str/slice binding; the rewritten 989_tupfieldsize pins all three header words with sliced caps so cap!=len has teeth. The tagged-binding arm remains open as task #53 (wwstage paramfieldsize). Review-era task #40, recategorized #263 fused. Both stages move in one commit: one emission contract; splitting would leave the byte-id gates red between the halves.
This commit is contained in:
@@ -14344,6 +14344,50 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
|
||||
}
|
||||
} else {
|
||||
for (int b = 0; b < nbinds; b++) {
|
||||
/* #40 (#263): a str/slice/struct destructure
|
||||
* binding (24B header / aggregate, sz>8) copies
|
||||
* its FULL extent — the single fldloadop word
|
||||
* truncated a slice binding to its .ptr, dropping
|
||||
* .len/.cap (both stages identically, byte-id-
|
||||
* WRONG; F7-c4 fixed only the STRIDE). Same
|
||||
* word-run + sized-tail idiom as the non-
|
||||
* destructure aggregate copy above. */
|
||||
int bsz = binds[b].sz;
|
||||
if (bsz > 8) {
|
||||
int k = 0;
|
||||
for (; k + 8 <= bsz; k += 8) {
|
||||
ins2(c, A_MOVQ,
|
||||
amem(D_BX, binds[b].foff + k),
|
||||
areg(D_AX));
|
||||
ins2(c, A_MOVQ, areg(D_AX),
|
||||
amem(D_BP, binds[b].off + k));
|
||||
}
|
||||
if (k + 4 <= bsz) {
|
||||
ins2(c, A_MOVL,
|
||||
amem(D_BX, binds[b].foff + k),
|
||||
areg(D_AX));
|
||||
ins2(c, A_MOVL, areg(D_AX),
|
||||
amem(D_BP, binds[b].off + k));
|
||||
k += 4;
|
||||
}
|
||||
if (k + 2 <= bsz) {
|
||||
ins2(c, A_MOVW,
|
||||
amem(D_BX, binds[b].foff + k),
|
||||
areg(D_AX));
|
||||
ins2(c, A_MOVW, areg(D_AX),
|
||||
amem(D_BP, binds[b].off + k));
|
||||
k += 2;
|
||||
}
|
||||
if (k + 1 <= bsz) {
|
||||
ins2(c, A_MOVB,
|
||||
amem(D_BX, binds[b].foff + k),
|
||||
areg(D_AX));
|
||||
ins2(c, A_MOVB, areg(D_AX),
|
||||
amem(D_BP, binds[b].off + k));
|
||||
k += 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
int op = fldloadop(binds[b].ftype, binds[b].sz);
|
||||
ins2(c, op, amem(D_BX, binds[b].foff),
|
||||
areg(D_AX));
|
||||
|
||||
Reference in New Issue
Block a user