wcc: chained-dot str leaf loads the cap word, both stages
A str field reached through a chained dot (o.i.s) emitted two loads (ptr, len) and stored a stale CX as the cap — both stages, at any non-zero chain depth. Emit the full header at the chained-dot leaf. Review item #29. 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:
@@ -11099,25 +11099,20 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
areg(D_CX));
|
||||
goto dot_done;
|
||||
}
|
||||
if (fu && fu->kind == TY_STR) {
|
||||
ins2(c, A_MOVQ,
|
||||
amem(base_reg,
|
||||
base_disp + total_off + 0),
|
||||
areg(D_AX));
|
||||
ins2(c, A_MOVQ,
|
||||
amem(base_reg,
|
||||
base_disp + total_off + 8),
|
||||
areg(D_BX));
|
||||
goto dot_done;
|
||||
}
|
||||
if (fu && fu->kind == TY_SLICE) {
|
||||
/* Slice leaf: load all three header
|
||||
if (fu && (fu->kind == TY_STR
|
||||
|| fu->kind == TY_SLICE)) {
|
||||
/* str/slice leaf: load all three header
|
||||
* words into (AX=ptr, BX=len, CX=cap)
|
||||
* so the value follows the canonical
|
||||
* slice-rhs convention. base_reg may
|
||||
* be CX (global / `*T` root); load
|
||||
* .cap LAST so the base survives the
|
||||
* earlier reads. */
|
||||
* slice-rhs convention. str IS []u8 —
|
||||
* the same 24B {ptr,len,cap} header. #29:
|
||||
* the str arm here used to load only
|
||||
* ptr+len (cap dropped → a junk strlit
|
||||
* before the chain left CX stale); merged
|
||||
* so both load all three, both stages
|
||||
* (#263). base_reg may be CX (global /
|
||||
* `*T` root); load .cap LAST so the base
|
||||
* survives the earlier reads. */
|
||||
ins2(c, A_MOVQ,
|
||||
amem(base_reg,
|
||||
base_disp + total_off + 0),
|
||||
|
||||
Reference in New Issue
Block a user