w6c+w6c_ww: size-keyed @tagscr — one tagged scratch per slot size (fix #44)

A fn mixing two tagged slot sizes smaller-first (regex compile(): 56B
append-element widen then 64B sret return) hit the #15/#26c rule-7
grow-fatal — the single shared per-fn @tagscr is first-use-sized and
its pinned offset can't grow. Key the scratch by slot size instead:
@tagscr<sz>, one first-use-allocated slot per distinct size, all three
sites (widen-store via_outer, widen-push, N_INDEX tagged-element
assign) funnelled through cg_tagscr_slot / tagscradd in both stages.
Single-size fns emit byte-identical asm to pre-fix (control row pinned
+ hand-cmp'd vs master w6c). 736's tagscr_size_grow_fatal fixture
pinned the now-unreachable fatal; converted to a byte-id succ row.
Runtime rows live in 926_tagscr_sizes_run.
This commit is contained in:
2026-06-04 04:34:54 +09:00
parent 8999b59ab0
commit c2308a11c7
9 changed files with 483 additions and 176 deletions

View File

@@ -206,7 +206,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node) i32 = {
let pname: str = rhsstructpayload(c, arg);
if (pname.len > 0) {
let ptype: *node = param.lhs;
let scroff: i32 = localadd(c, "@tagscr", widensz, nil);
let scroff: i32 = tagscradd(c, widensz);
emitline("\tXORQ\tAX, AX\n");
let zz: i32 = 0;
for (zz < widensz) {
@@ -2831,11 +2831,10 @@ fn cgwidentaggedstore(c: *cgen, dst: *tinfo, src: *node,
emitline(", ");
emitoff(bspill: i64);
emitline("(BP)\n");
// Shared scratch sized at first use per #15/#26c. A sibling
// site (cgreturn, pushargsrev, cgindex) hitting @tagscr later
// with a larger size fatals (rule 7) — pinned offset can't
// grow in place.
let scr: i32 = localadd(c, "@tagscr", slot_sz, nil);
// Shared per-size scratch sized at first use (#15/#26c, size-keyed
// by #44): sibling sites (cgreturn, pushargsrev, cgindex) hitting
// the same slot size reuse the slot; a different size pins its own.
let scr: i32 = tagscradd(c, slot_sz);
emitline("\tXORQ\tAX, AX\n");
let z: i32 = 0;
for (z < slot_sz) {