cmd/w6c+selfhost/wcc: route cgparam/MLET/spill sizes through SSoT

#43 (8e93b31 + 087c85c) routed many sizeof(str) / sizeof(slice)
sites through primtypesize / tyslicesize / ty_*->size, but missed
the cgparam regs-fit, cgparam stack-stitch, cgmlet mixed
scalar+str receive, and vararg slice gather paths in both stages.
A bare #1 bump (str→24B) on top of #43 reds ~60 tests because
those paths still hardcoded 16/24.

Cstage:
- cgen.c:7360-7361 cgmlet: sz0/sz1 → (int)u0->size / (int)u1->size.
- cgen.c:7557 cgparam regs-fit: slice|is_str → (int)pu->size.
- cgen.c:7586 cgparam stack-stitch: same.
- cgen.c:4368 cgcall vararg gather: localoff slice descriptor →
  (int)vsu->size (the cstage twin of cgenexpr.ww:3084).

Wwstage:
- cgendecl.ww:225, :243 cgfnparams: 16 → primtypesize("str"): i32.
- cgenexpr.ww:3084 cgcall vararg gather: 24 → tyslicesize(): i32.

Plus a latent-bug fix at cgenstmt.ww cglet :1031 / :1040: the
str-init and slice-init arms dispatched on size only. Under #1's
str→24, both arms would have fired on a str let (duplicate
MOVQ BX,off+8 + bogus MOVQ CX,off+8). Added isstrtype / isslicetype
kind gates mirroring cstage cgen.c:6439's
`type_isstr(lt) && sz == ty_str->size`. Zero asm change today
because the size constants implicitly disambiguate at 16 vs 24.

Probe with temporary #1 bump (str.size=24) confirms 990_selfhost +
994_w6c_ww go green — the cgen-routing slice for #1 is now
closed. Remaining red under bump is lib/ww/typ.ww's parallel SSoT
seed + stringstest cap*16u64 strides + w6l_ww runtime SIGSEGV;
all tracked separately.

EIGHTBYTES register-count sites (cgen.c:7553-7554, cgendecl.ww:224
/:260) intentionally NOT touched — those are str ABI in-flight
3-reg work (task #34), not slot-width SSoT.
This commit is contained in:
2026-05-20 10:08:15 +09:00
parent 087c85c3cf
commit caa72f2365
6 changed files with 77 additions and 46 deletions

View File

@@ -1024,20 +1024,19 @@ fn cglet(c: *cgen, n: *node) void = {
emitoff(off: i64);
emitline("(BP)\n");
// str init: cgexpr also leaves len in BX; store both.
// #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) {
// #60: gate by kind too — under #1's str=24 bump, sizeof(str)
// and sizeof(slice) collide, so a bare `sz ==` check fires
// both branches for one let. Mirrors cstage cgen.c:6439's
// `type_isstr(lt) && sz == ty_str->size` shape.
if (isstrtype(c, tn) && sz == primtypesize("str"): i32) {
emitline("\tMOVQ\tBX, ");
emitoff((off + 8): i64);
emitline("(BP)\n");
};
// slice init: ptr/len/cap in AX/BX/CX.
// #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) {
// slice init: ptr/len/cap in AX/BX/CX. Same kind+size gate as
// the str arm — without the kind check this fires on a str let
// once sz==24 (#60).
if (isslicetype(c, tn) && sz == tyslicesize(): i32) {
emitline("\tMOVQ\tBX, ");
emitoff((off + 8): i64);
emitline("(BP)\n");