wcc: tuple slice-element read loads the full 24B header, both stages
Reading a slice-typed tuple element (t.0) loaded only the pointer word; len and cap took whatever was left in BX/CX — silent garbage in BOTH stages once anything clobbered the registers between build and read. Load all three header words at the tuple-element arm. Review item #28. 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:
@@ -11319,15 +11319,16 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
areg(D_X0));
|
||||
break;
|
||||
}
|
||||
/* str IS []u8 — load (ptr, len, cap) into
|
||||
* (AX, BX, CX), the canonical slice-header ABI,
|
||||
* so chains like `t.1.len` propagate through the
|
||||
* slice-rhs convention (#1/Phase 3 collapse).
|
||||
* UNLIKE the field arms there is no slice-element
|
||||
* sibling here, so the triple is hand-authored;
|
||||
* base is BP (frame) or CX (global base — CX is
|
||||
* written LAST so it survives the +0/+8 reads). */
|
||||
if (fu && fu->kind == TY_STR) {
|
||||
/* str IS []u8, and a slice is the same 24B
|
||||
* {ptr,len,cap} header — load all three words into
|
||||
* (AX, BX, CX), the canonical slice-header ABI, so
|
||||
* chains like `t.1.len` propagate through the
|
||||
* slice-rhs convention (#1/Phase 3 collapse). #28:
|
||||
* pre-fix the gate was str-only, so a SLICE tuple
|
||||
* element fell to the fldloadop tail (one ptr word;
|
||||
* len/cap stale). base is BP (frame) or CX (global
|
||||
* base — CX written LAST so it survives the +0/+8). */
|
||||
if (fu && (fu->kind == TY_STR || fu->kind == TY_SLICE)) {
|
||||
ins2(c, A_MOVQ,
|
||||
amem(base_reg, base_disp + foff + 0),
|
||||
areg(D_AX));
|
||||
|
||||
Reference in New Issue
Block a user