cgen: loop/yield/defer fixed-max buffers raw-ptr → []T (#9)
Phase 0 #9. cgen struct fields loopendbuf/loopcontbuf/yieldbuf/ deferbuf change from `*str`/`**node` over-allocated arena chunks to `[]str`/`[]*node` slices. The 4 alloc sites in cgeninit drop the byte-count form (`LOOP_MAX*24u64`, `DEFER_MAX*8u64`) for element-count (`LOOP_MAX: u64`, `DEFER_MAX: u64`). 10 caller sites in cgenstmt.ww/cgenexpr.ww use `[i]` indexing which works identically for slice-shaped struct fields. Two-line let-then-assign idiom for the 4 inits is a real checker limitation: alloc's element-deferred `[]u8` → `[]T` retype only fires in let-init (checkletassign N_TSLICE LHS), and cglet's alloc-slice writeback shortcut (cgenstmt.ww:577) only fires in let-init too. Direct `c.field = alloc([], N)!` would silently emit a scalar alloc with a junk slice header. Filed #49 for the checker enhancement; the let-then-assign is Hare-idiomatic in the meantime. Verified 132/132 + 995_self_rebuild byte-identity.
This commit is contained in:
@@ -21544,12 +21544,12 @@ type cgen = struct {
|
||||
// before walking the body.
|
||||
fnret: *node, // declared return type of current fn (or nil)
|
||||
looptop: i32,
|
||||
loopendbuf: *str, // stack of end labels for break
|
||||
loopcontbuf: *str, // stack of cont labels for continue
|
||||
loopendbuf: []str, // stack of end labels for break
|
||||
loopcontbuf: []str, // stack of cont labels for continue
|
||||
yieldtop: i32,
|
||||
yieldbuf: *str, // stack of match end labels for yield
|
||||
yieldbuf: []str, // stack of match end labels for yield
|
||||
defertop: i32,
|
||||
deferbuf: **node, // stack of deferred exprs (LIFO at return)
|
||||
deferbuf: []*node, // stack of deferred exprs (LIFO at return)
|
||||
// Variadic-call gather state. cgcall bumps this on each gather
|
||||
// emit and uses it to mint `@vararg_d_N` / `@vararg_sl_N` per
|
||||
// callsite; mirrors cstage's mklabel("vararg_d/sl") freshness
|
||||
@@ -21609,16 +21609,16 @@ fn cgeninit(c: *cgen, a: *arena) void = {
|
||||
// persist across cgfn calls within one file. cgfile resets them
|
||||
// at the start of each compilation unit.
|
||||
c.looptop = 0;
|
||||
// #35: per-slot stride is sizeof(str); the bare 16 is the str=16
|
||||
// width and undershoots under str=24, so indices past (LOOP_MAX*16)/24
|
||||
// = 10 would spill into the next amalloc. Bumped to 24/slot; +8/slot
|
||||
// over-alloc under str=16 is harmless under the bump arena.
|
||||
c.loopendbuf = amalloc(a, (LOOP_MAX: u64) * 24u64): *str;
|
||||
c.loopcontbuf = amalloc(a, (LOOP_MAX: u64) * 24u64): *str;
|
||||
let loopendbuf: []str = alloc([], LOOP_MAX: u64)!;
|
||||
c.loopendbuf = loopendbuf;
|
||||
let loopcontbuf: []str = alloc([], LOOP_MAX: u64)!;
|
||||
c.loopcontbuf = loopcontbuf;
|
||||
c.yieldtop = 0;
|
||||
c.yieldbuf = amalloc(a, (LOOP_MAX: u64) * 24u64): *str;
|
||||
let yieldbuf: []str = alloc([], LOOP_MAX: u64)!;
|
||||
c.yieldbuf = yieldbuf;
|
||||
c.defertop = 0;
|
||||
c.deferbuf = amalloc(a, (DEFER_MAX: u64) * 8u64): **node;
|
||||
let deferbuf: []*node = alloc([], DEFER_MAX: u64)!;
|
||||
c.deferbuf = deferbuf;
|
||||
};
|
||||
|
||||
// localalloc — append a slot for `name` without dedup. Used for
|
||||
|
||||
@@ -469,12 +469,12 @@ type cgen = struct {
|
||||
// before walking the body.
|
||||
fnret: *node, // declared return type of current fn (or nil)
|
||||
looptop: i32,
|
||||
loopendbuf: *str, // stack of end labels for break
|
||||
loopcontbuf: *str, // stack of cont labels for continue
|
||||
loopendbuf: []str, // stack of end labels for break
|
||||
loopcontbuf: []str, // stack of cont labels for continue
|
||||
yieldtop: i32,
|
||||
yieldbuf: *str, // stack of match end labels for yield
|
||||
yieldbuf: []str, // stack of match end labels for yield
|
||||
defertop: i32,
|
||||
deferbuf: **node, // stack of deferred exprs (LIFO at return)
|
||||
deferbuf: []*node, // stack of deferred exprs (LIFO at return)
|
||||
// Variadic-call gather state. cgcall bumps this on each gather
|
||||
// emit and uses it to mint `@vararg_d_N` / `@vararg_sl_N` per
|
||||
// callsite; mirrors cstage's mklabel("vararg_d/sl") freshness
|
||||
@@ -534,16 +534,16 @@ fn cgeninit(c: *cgen, a: *arena) void = {
|
||||
// persist across cgfn calls within one file. cgfile resets them
|
||||
// at the start of each compilation unit.
|
||||
c.looptop = 0;
|
||||
// #35: per-slot stride is sizeof(str); the bare 16 is the str=16
|
||||
// width and undershoots under str=24, so indices past (LOOP_MAX*16)/24
|
||||
// = 10 would spill into the next amalloc. Bumped to 24/slot; +8/slot
|
||||
// over-alloc under str=16 is harmless under the bump arena.
|
||||
c.loopendbuf = amalloc(a, (LOOP_MAX: u64) * 24u64): *str;
|
||||
c.loopcontbuf = amalloc(a, (LOOP_MAX: u64) * 24u64): *str;
|
||||
let loopendbuf: []str = alloc([], LOOP_MAX: u64)!;
|
||||
c.loopendbuf = loopendbuf;
|
||||
let loopcontbuf: []str = alloc([], LOOP_MAX: u64)!;
|
||||
c.loopcontbuf = loopcontbuf;
|
||||
c.yieldtop = 0;
|
||||
c.yieldbuf = amalloc(a, (LOOP_MAX: u64) * 24u64): *str;
|
||||
let yieldbuf: []str = alloc([], LOOP_MAX: u64)!;
|
||||
c.yieldbuf = yieldbuf;
|
||||
c.defertop = 0;
|
||||
c.deferbuf = amalloc(a, (DEFER_MAX: u64) * 8u64): **node;
|
||||
let deferbuf: []*node = alloc([], DEFER_MAX: u64)!;
|
||||
c.deferbuf = deferbuf;
|
||||
};
|
||||
|
||||
// localalloc — append a slot for `name` without dedup. Used for
|
||||
|
||||
@@ -21544,12 +21544,12 @@ type cgen = struct {
|
||||
// before walking the body.
|
||||
fnret: *node, // declared return type of current fn (or nil)
|
||||
looptop: i32,
|
||||
loopendbuf: *str, // stack of end labels for break
|
||||
loopcontbuf: *str, // stack of cont labels for continue
|
||||
loopendbuf: []str, // stack of end labels for break
|
||||
loopcontbuf: []str, // stack of cont labels for continue
|
||||
yieldtop: i32,
|
||||
yieldbuf: *str, // stack of match end labels for yield
|
||||
yieldbuf: []str, // stack of match end labels for yield
|
||||
defertop: i32,
|
||||
deferbuf: **node, // stack of deferred exprs (LIFO at return)
|
||||
deferbuf: []*node, // stack of deferred exprs (LIFO at return)
|
||||
// Variadic-call gather state. cgcall bumps this on each gather
|
||||
// emit and uses it to mint `@vararg_d_N` / `@vararg_sl_N` per
|
||||
// callsite; mirrors cstage's mklabel("vararg_d/sl") freshness
|
||||
@@ -21609,16 +21609,16 @@ fn cgeninit(c: *cgen, a: *arena) void = {
|
||||
// persist across cgfn calls within one file. cgfile resets them
|
||||
// at the start of each compilation unit.
|
||||
c.looptop = 0;
|
||||
// #35: per-slot stride is sizeof(str); the bare 16 is the str=16
|
||||
// width and undershoots under str=24, so indices past (LOOP_MAX*16)/24
|
||||
// = 10 would spill into the next amalloc. Bumped to 24/slot; +8/slot
|
||||
// over-alloc under str=16 is harmless under the bump arena.
|
||||
c.loopendbuf = amalloc(a, (LOOP_MAX: u64) * 24u64): *str;
|
||||
c.loopcontbuf = amalloc(a, (LOOP_MAX: u64) * 24u64): *str;
|
||||
let loopendbuf: []str = alloc([], LOOP_MAX: u64)!;
|
||||
c.loopendbuf = loopendbuf;
|
||||
let loopcontbuf: []str = alloc([], LOOP_MAX: u64)!;
|
||||
c.loopcontbuf = loopcontbuf;
|
||||
c.yieldtop = 0;
|
||||
c.yieldbuf = amalloc(a, (LOOP_MAX: u64) * 24u64): *str;
|
||||
let yieldbuf: []str = alloc([], LOOP_MAX: u64)!;
|
||||
c.yieldbuf = yieldbuf;
|
||||
c.defertop = 0;
|
||||
c.deferbuf = amalloc(a, (DEFER_MAX: u64) * 8u64): **node;
|
||||
let deferbuf: []*node = alloc([], DEFER_MAX: u64)!;
|
||||
c.deferbuf = deferbuf;
|
||||
};
|
||||
|
||||
// localalloc — append a slot for `name` without dedup. Used for
|
||||
|
||||
Reference in New Issue
Block a user