From a5ca21ddbaa58f277af3d6a6a17a3b2690aafd73 Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Sun, 24 May 2026 09:00:36 +0900 Subject: [PATCH] cgen: str index-stride via type table, not literal 1 (both stages) Phase 2 step 2. The N_INDEX element-stride for str hardcoded esz=1; route it through the type table (cstage ty_u8->size, wwstage primtypesize("u8")) so str's element width tracks the u8 SSoT. When the TY_STR collapse (Phase 2 step 5) folds str onto the slice-of-u8 path, these sites need no second edit. Byte-id-neutral: u8 size is 1, so emitted stride is unchanged; full test (incl 990-997 byte-id gates) green. --- cmd/w6c/cgen.c | 9 +++++++-- selfhost/cmd/w6c/main.combined.ww | 5 ++++- selfhost/cmd/wcc/cgenutil.ww | 5 ++++- selfhost/cmd/wwdump/main.combined.ww | 5 ++++- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/cmd/w6c/cgen.c b/cmd/w6c/cgen.c index 420c41a0..266b660e 100644 --- a/cmd/w6c/cgen.c +++ b/cmd/w6c/cgen.c @@ -2113,7 +2113,10 @@ cgexpr(Cg *c, Node *n, Local *locals) ? bt->under : bt; int esz = (bu && bu->sub) ? (int)bu->sub->size : 1; - if (bu && bu->kind == TY_STR) esz = 1; + /* str element is u8 — size via the type table + * so #1's TY_STR collapse needs no second edit. */ + if (bu && bu->kind == TY_STR) + esz = (int)ty_u8->size; cgexpr(c, idx, locals); /* idx → AX */ if (esz > 1) { ins2(c, A_MOVQ, aimm(esz), @@ -6234,7 +6237,9 @@ cgexpr(Cg *c, Node *n, Local *locals) Type *eff = idx_eff(bt); int esz = 1; if (eff && eff->sub) esz = (int)eff->sub->size; - if (u && u->kind == TY_STR) esz = 1; + /* str element is u8 — size via the type table so #1's + * TY_STR collapse needs no second edit. */ + if (u && u->kind == TY_STR) esz = (int)ty_u8->size; Type *esub = eff ? eff->sub : NULL; Type *esubu = (esub && esub->kind == TY_NAMED) ? esub->under : esub; diff --git a/selfhost/cmd/w6c/main.combined.ww b/selfhost/cmd/w6c/main.combined.ww index b98aeca4..8cb708d6 100644 --- a/selfhost/cmd/w6c/main.combined.ww +++ b/selfhost/cmd/w6c/main.combined.ww @@ -11432,7 +11432,10 @@ fn elemsizeof(t: *node) i32 = { if (k == nkind.N_TARRAY) { elem = t.lhs; }; if (k == nkind.N_TNAME) { let nm: str = t.str; - if (streq(nm, "str")) { return 1; }; + // str element is u8 — size via the type table so #1's + // TY_STR collapse needs no second edit. Cite cstage cgen.c + // N_INDEX `esz = ty_u8->size`. + if (streq(nm, "str")) { return primtypesize("u8"): i32; }; // Indexing a primitive name (rare): element size = the prim. let ps: i32 = primsize(nm); if (ps > 0) { return ps; }; diff --git a/selfhost/cmd/wcc/cgenutil.ww b/selfhost/cmd/wcc/cgenutil.ww index bd068c89..c1270f66 100644 --- a/selfhost/cmd/wcc/cgenutil.ww +++ b/selfhost/cmd/wcc/cgenutil.ww @@ -872,7 +872,10 @@ fn elemsizeof(t: *node) i32 = { if (k == nkind.N_TARRAY) { elem = t.lhs; }; if (k == nkind.N_TNAME) { let nm: str = t.str; - if (streq(nm, "str")) { return 1; }; + // str element is u8 — size via the type table so #1's + // TY_STR collapse needs no second edit. Cite cstage cgen.c + // N_INDEX `esz = ty_u8->size`. + if (streq(nm, "str")) { return primtypesize("u8"): i32; }; // Indexing a primitive name (rare): element size = the prim. let ps: i32 = primsize(nm); if (ps > 0) { return ps; }; diff --git a/selfhost/cmd/wwdump/main.combined.ww b/selfhost/cmd/wwdump/main.combined.ww index 82aedd43..18dfd561 100644 --- a/selfhost/cmd/wwdump/main.combined.ww +++ b/selfhost/cmd/wwdump/main.combined.ww @@ -11432,7 +11432,10 @@ fn elemsizeof(t: *node) i32 = { if (k == nkind.N_TARRAY) { elem = t.lhs; }; if (k == nkind.N_TNAME) { let nm: str = t.str; - if (streq(nm, "str")) { return 1; }; + // str element is u8 — size via the type table so #1's + // TY_STR collapse needs no second edit. Cite cstage cgen.c + // N_INDEX `esz = ty_u8->size`. + if (streq(nm, "str")) { return primtypesize("u8"): i32; }; // Indexing a primitive name (rare): element size = the prim. let ps: i32 = primsize(nm); if (ps > 0) { return ps; };