selfhost/cmd/wcc: route remaining wwstage size dispatch through SSoT

Followup to 8e93b31 (#43).  Audit caught dispatch-gate sites the
sweep missed:

  - cgen.ww letpreintern's `sz == 16` str-let detector — would
    desync from emitletdataw's matching `sz == primtypesize("str"):
    i32` strlit-init branch under #1.
  - cgenstmt.ww cglet str-init MOVQ-BX gate and slice-init MOVQ-BX/CX
    gate (and the belt-and-suspenders N_TSLICE shape check at l.607).
  - cgenexpr.ww cgindex str-element loads (3 sites: globalarr,
    baselocal, generic fallback) and the matching cgassign N_INDEX
    str-element write pair (BX spill + post-index store).

All gates now read `primtypesize("str"): i32` / `tyslicesize(): i32`,
so #1's ty_str.size bump propagates through the same two-place edit
the original commit advertised.  Combined files (w6c/wwdump) updated
in lockstep.

131/131 + 994 + 995 byte-identity green; smoke.combined.ww (lib-only
consumer) emits the same asm pre vs post, confirming the change is
SSoT routing only (no behaviour shift).
This commit is contained in:
2026-05-20 09:06:50 +09:00
parent 8e93b31088
commit 087c85c3cf
5 changed files with 108 additions and 30 deletions

View File

@@ -603,8 +603,13 @@ fn cglet(c: *cgen, n: *node) void = {
};
}; };
let shapeok: bool = false;
// #43: route the slice-shape size guard through SSoT.
// The N_TSLICE kind gate already discriminates here, so
// this is belt-and-suspenders, but the literal would
// silently miss after #1 if check.ww's astsize ever
// drifted from this dispatch.
if (scall != nil && tn != nil
&& tn.kind == nkind.N_TSLICE && sz == 24) {
&& tn.kind == nkind.N_TSLICE && sz == tyslicesize(): i32) {
let callee: *node = scall.lhs;
let a0: *node = scall.list;
let a1: *node = nil;
@@ -1019,13 +1024,20 @@ fn cglet(c: *cgen, n: *node) void = {
emitoff(off: i64);
emitline("(BP)\n");
// str init: cgexpr also leaves len in BX; store both.
if (sz == 16) {
// #43: route through primtypesize so #1's str-size bump
// surfaces this site (today sz==16 picks str; once str=24,
// the in-flight str ABI (#34) must propagate cap and the
// dispatch needs reshaping by kind, not raw size).
if (sz == primtypesize("str"): i32) {
emitline("\tMOVQ\tBX, ");
emitoff((off + 8): i64);
emitline("(BP)\n");
};
// slice init: ptr/len/cap in AX/BX/CX.
if (sz == 24) {
// #43: same routing — bare `sz == 24` would collide with a
// 24B str slot under #1; the kind disambiguation lives at
// the caller (cglet's tn.kind == N_TSLICE shape check).
if (sz == tyslicesize(): i32) {
emitline("\tMOVQ\tBX, ");
emitoff((off + 8): i64);
emitline("(BP)\n");