selfhost/cmd/wcc/cgen: size amalloc slots to struct, not sizeof(str)@16
Nine sites used hardcoded byte counts sized for str=16. With str's in-memory size invariant about to grow under #1, the next-pointer or field write would land past the slot and corrupt the next bump allocation — selfhost/CLAUDE.md flags this exact pattern. Over-alloc by 8B is harmless under the bump allocator, so bumping the constants is correct at str=16 too. Sites: fnret, enumtype, modent (×4), ffi, strlit, enummember slot sizes; loopendbuf, loopcontbuf, yieldbuf LOOP_MAX strides. Latent bug found by str-size-hang-debug worker via PC trace on a str=24 probe: fnretlookup spun forever because the frnext write fell into the string heap, forming a cycle. Fix verified at str=16 (130/130 + 994/995) and probed at str=24 (994 still green; further graduation work tracked by #1).
This commit is contained in:
@@ -19854,7 +19854,8 @@ fn collectenums(c: *cgen, file: *node) void = {
|
|||||||
let body: *node = d.lhs;
|
let body: *node = d.lhs;
|
||||||
if (body != nil) {
|
if (body != nil) {
|
||||||
if (body.kind == nkind.N_TENUM) {
|
if (body.kind == nkind.N_TENUM) {
|
||||||
let et: *enumtype = amalloc(c.a, 64u64): *enumtype;
|
// #35: sizeof(enumtype) = 72 under str=24 ({str,str,*node,*enummember,*enumtype}); amalloc < struct corrupts the next slot.
|
||||||
|
let et: *enumtype = amalloc(c.a, 80u64): *enumtype;
|
||||||
et.ename = d.str;
|
et.ename = d.str;
|
||||||
et.emod = d.nmod;
|
et.emod = d.nmod;
|
||||||
et.storage = body.lhs;
|
et.storage = body.lhs;
|
||||||
@@ -19873,7 +19874,8 @@ fn collectenums(c: *cgen, file: *node) void = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
prev = val;
|
prev = val;
|
||||||
let em: *enummember = amalloc(c.a, 32u64): *enummember;
|
// #35: sizeof(enummember) = 40 under str=24 ({str,u64,*enummember}).
|
||||||
|
let em: *enummember = amalloc(c.a, 48u64): *enummember;
|
||||||
em.mname = m.str;
|
em.mname = m.str;
|
||||||
em.mval = val;
|
em.mval = val;
|
||||||
em.emnext = nil;
|
em.emnext = nil;
|
||||||
@@ -20162,10 +20164,14 @@ fn cgeninit(c: *cgen, a: *arena) void = {
|
|||||||
// persist across cgfn calls within one file. cgfile resets them
|
// persist across cgfn calls within one file. cgfile resets them
|
||||||
// at the start of each compilation unit.
|
// at the start of each compilation unit.
|
||||||
c.looptop = 0;
|
c.looptop = 0;
|
||||||
c.loopendbuf = amalloc(a, (LOOP_MAX: u64) * 16u64): *str;
|
// #35: per-slot stride is sizeof(str); the bare 16 is the str=16
|
||||||
c.loopcontbuf = amalloc(a, (LOOP_MAX: u64) * 16u64): *str;
|
// 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;
|
||||||
c.yieldtop = 0;
|
c.yieldtop = 0;
|
||||||
c.yieldbuf = amalloc(a, (LOOP_MAX: u64) * 16u64): *str;
|
c.yieldbuf = amalloc(a, (LOOP_MAX: u64) * 24u64): *str;
|
||||||
c.defertop = 0;
|
c.defertop = 0;
|
||||||
c.deferbuf = amalloc(a, (DEFER_MAX: u64) * 8u64): **node;
|
c.deferbuf = amalloc(a, (DEFER_MAX: u64) * 8u64): **node;
|
||||||
};
|
};
|
||||||
@@ -20521,7 +20527,8 @@ fn internstrlit(c: *cgen, bytes: str) str = {
|
|||||||
let lab: str;
|
let lab: str;
|
||||||
lab.ptr = p;
|
lab.ptr = p;
|
||||||
lab.len = total;
|
lab.len = total;
|
||||||
let nw: *strlit = amalloc(c.a, 48u64): *strlit;
|
// #35: sizeof(strlit) = 56 under str=24 ({str,str,*strlit}).
|
||||||
|
let nw: *strlit = amalloc(c.a, 64u64): *strlit;
|
||||||
nw.label = lab;
|
nw.label = lab;
|
||||||
nw.bytes = bytes;
|
nw.bytes = bytes;
|
||||||
nw.slnext = c.strlits;
|
nw.slnext = c.strlits;
|
||||||
@@ -21250,7 +21257,8 @@ fn collectfnrets(c: *cgen, file: *node) void = {
|
|||||||
let d: *node = file.list;
|
let d: *node = file.list;
|
||||||
for (d != nil) {
|
for (d != nil) {
|
||||||
if (d.kind == nkind.N_FNDECL) {
|
if (d.kind == nkind.N_FNDECL) {
|
||||||
let f: *fnret = amalloc(c.a, 64u64): *fnret;
|
// #35: sizeof(fnret) = 72 under str=24 ({str,str,*node,*node,*fnret}); was the trigger that hung w6c_ww on the hangtest — frnext overflowed into the next amalloc, breaking fnretlookup's chain walk.
|
||||||
|
let f: *fnret = amalloc(c.a, 80u64): *fnret;
|
||||||
f.fname = d.str;
|
f.fname = d.str;
|
||||||
f.fmod = d.nmod;
|
f.fmod = d.nmod;
|
||||||
f.rtype = d.lhs;
|
f.rtype = d.lhs;
|
||||||
@@ -21490,6 +21498,9 @@ type modent = struct {
|
|||||||
mnext: *modent,
|
mnext: *modent,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #35: sizeof(modent) = 56 under str=24 ({str,str,*modent}); each
|
||||||
|
// of the four amallocs below grew from 48 to 64 to keep mnext inside
|
||||||
|
// the slot.
|
||||||
fn collectmods(c: *cgen, file: *node) void = {
|
fn collectmods(c: *cgen, file: *node) void = {
|
||||||
c.mods = nil;
|
c.mods = nil;
|
||||||
if (file == nil) { return; };
|
if (file == nil) { return; };
|
||||||
@@ -21513,7 +21524,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
|||||||
};
|
};
|
||||||
if (!isffi) {
|
if (!isffi) {
|
||||||
if (!streq(d.str, "main")) {
|
if (!streq(d.str, "main")) {
|
||||||
let m: *modent = amalloc(c.a, 48u64): *modent;
|
let m: *modent = amalloc(c.a, 64u64): *modent;
|
||||||
m.mname = d.str;
|
m.mname = d.str;
|
||||||
m.nmod = d.nmod;
|
m.nmod = d.nmod;
|
||||||
m.mnext = c.mods;
|
m.mnext = c.mods;
|
||||||
@@ -21525,7 +21536,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
|||||||
if (d.kind == nkind.N_DEF) {
|
if (d.kind == nkind.N_DEF) {
|
||||||
if (d.exported == 0) {
|
if (d.exported == 0) {
|
||||||
if (d.nmod.len > 0) {
|
if (d.nmod.len > 0) {
|
||||||
let m: *modent = amalloc(c.a, 48u64): *modent;
|
let m: *modent = amalloc(c.a, 64u64): *modent;
|
||||||
m.mname = d.str;
|
m.mname = d.str;
|
||||||
m.nmod = d.nmod;
|
m.nmod = d.nmod;
|
||||||
m.mnext = c.mods;
|
m.mnext = c.mods;
|
||||||
@@ -21536,7 +21547,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
|||||||
if (d.kind == nkind.N_TYPEDECL) {
|
if (d.kind == nkind.N_TYPEDECL) {
|
||||||
if (d.exported == 0) {
|
if (d.exported == 0) {
|
||||||
if (d.nmod.len > 0) {
|
if (d.nmod.len > 0) {
|
||||||
let m: *modent = amalloc(c.a, 48u64): *modent;
|
let m: *modent = amalloc(c.a, 64u64): *modent;
|
||||||
m.mname = d.str;
|
m.mname = d.str;
|
||||||
m.nmod = d.nmod;
|
m.nmod = d.nmod;
|
||||||
m.mnext = c.mods;
|
m.mnext = c.mods;
|
||||||
@@ -21547,7 +21558,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
|||||||
if (d.kind == nkind.N_LET) {
|
if (d.kind == nkind.N_LET) {
|
||||||
if (d.exported == 0) {
|
if (d.exported == 0) {
|
||||||
if (d.nmod.len > 0) {
|
if (d.nmod.len > 0) {
|
||||||
let m: *modent = amalloc(c.a, 48u64): *modent;
|
let m: *modent = amalloc(c.a, 64u64): *modent;
|
||||||
m.mname = d.str;
|
m.mname = d.str;
|
||||||
m.nmod = d.nmod;
|
m.nmod = d.nmod;
|
||||||
m.mnext = c.mods;
|
m.mnext = c.mods;
|
||||||
@@ -21653,7 +21664,8 @@ fn fficollect(c: *cgen, file: *node) void = {
|
|||||||
let symnode: *node = a.list;
|
let symnode: *node = a.list;
|
||||||
if (symnode != nil) {
|
if (symnode != nil) {
|
||||||
if (symnode.kind == nkind.N_STRLIT) {
|
if (symnode.kind == nkind.N_STRLIT) {
|
||||||
let f: *ffi = amalloc(c.a, 48u64): *ffi;
|
// #35: sizeof(ffi) = 56 under str=24 ({str,str,*ffi}).
|
||||||
|
let f: *ffi = amalloc(c.a, 64u64): *ffi;
|
||||||
f.ident = d.str;
|
f.ident = d.str;
|
||||||
f.symbol = symnode.str;
|
f.symbol = symnode.str;
|
||||||
f.fnext = c.ffis;
|
f.fnext = c.ffis;
|
||||||
|
|||||||
@@ -241,7 +241,8 @@ fn collectenums(c: *cgen, file: *node) void = {
|
|||||||
let body: *node = d.lhs;
|
let body: *node = d.lhs;
|
||||||
if (body != nil) {
|
if (body != nil) {
|
||||||
if (body.kind == nkind.N_TENUM) {
|
if (body.kind == nkind.N_TENUM) {
|
||||||
let et: *enumtype = amalloc(c.a, 64u64): *enumtype;
|
// #35: sizeof(enumtype) = 72 under str=24 ({str,str,*node,*enummember,*enumtype}); amalloc < struct corrupts the next slot.
|
||||||
|
let et: *enumtype = amalloc(c.a, 80u64): *enumtype;
|
||||||
et.ename = d.str;
|
et.ename = d.str;
|
||||||
et.emod = d.nmod;
|
et.emod = d.nmod;
|
||||||
et.storage = body.lhs;
|
et.storage = body.lhs;
|
||||||
@@ -260,7 +261,8 @@ fn collectenums(c: *cgen, file: *node) void = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
prev = val;
|
prev = val;
|
||||||
let em: *enummember = amalloc(c.a, 32u64): *enummember;
|
// #35: sizeof(enummember) = 40 under str=24 ({str,u64,*enummember}).
|
||||||
|
let em: *enummember = amalloc(c.a, 48u64): *enummember;
|
||||||
em.mname = m.str;
|
em.mname = m.str;
|
||||||
em.mval = val;
|
em.mval = val;
|
||||||
em.emnext = nil;
|
em.emnext = nil;
|
||||||
@@ -549,10 +551,14 @@ fn cgeninit(c: *cgen, a: *arena) void = {
|
|||||||
// persist across cgfn calls within one file. cgfile resets them
|
// persist across cgfn calls within one file. cgfile resets them
|
||||||
// at the start of each compilation unit.
|
// at the start of each compilation unit.
|
||||||
c.looptop = 0;
|
c.looptop = 0;
|
||||||
c.loopendbuf = amalloc(a, (LOOP_MAX: u64) * 16u64): *str;
|
// #35: per-slot stride is sizeof(str); the bare 16 is the str=16
|
||||||
c.loopcontbuf = amalloc(a, (LOOP_MAX: u64) * 16u64): *str;
|
// 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;
|
||||||
c.yieldtop = 0;
|
c.yieldtop = 0;
|
||||||
c.yieldbuf = amalloc(a, (LOOP_MAX: u64) * 16u64): *str;
|
c.yieldbuf = amalloc(a, (LOOP_MAX: u64) * 24u64): *str;
|
||||||
c.defertop = 0;
|
c.defertop = 0;
|
||||||
c.deferbuf = amalloc(a, (DEFER_MAX: u64) * 8u64): **node;
|
c.deferbuf = amalloc(a, (DEFER_MAX: u64) * 8u64): **node;
|
||||||
};
|
};
|
||||||
@@ -908,7 +914,8 @@ fn internstrlit(c: *cgen, bytes: str) str = {
|
|||||||
let lab: str;
|
let lab: str;
|
||||||
lab.ptr = p;
|
lab.ptr = p;
|
||||||
lab.len = total;
|
lab.len = total;
|
||||||
let nw: *strlit = amalloc(c.a, 48u64): *strlit;
|
// #35: sizeof(strlit) = 56 under str=24 ({str,str,*strlit}).
|
||||||
|
let nw: *strlit = amalloc(c.a, 64u64): *strlit;
|
||||||
nw.label = lab;
|
nw.label = lab;
|
||||||
nw.bytes = bytes;
|
nw.bytes = bytes;
|
||||||
nw.slnext = c.strlits;
|
nw.slnext = c.strlits;
|
||||||
@@ -1637,7 +1644,8 @@ fn collectfnrets(c: *cgen, file: *node) void = {
|
|||||||
let d: *node = file.list;
|
let d: *node = file.list;
|
||||||
for (d != nil) {
|
for (d != nil) {
|
||||||
if (d.kind == nkind.N_FNDECL) {
|
if (d.kind == nkind.N_FNDECL) {
|
||||||
let f: *fnret = amalloc(c.a, 64u64): *fnret;
|
// #35: sizeof(fnret) = 72 under str=24 ({str,str,*node,*node,*fnret}); was the trigger that hung w6c_ww on the hangtest — frnext overflowed into the next amalloc, breaking fnretlookup's chain walk.
|
||||||
|
let f: *fnret = amalloc(c.a, 80u64): *fnret;
|
||||||
f.fname = d.str;
|
f.fname = d.str;
|
||||||
f.fmod = d.nmod;
|
f.fmod = d.nmod;
|
||||||
f.rtype = d.lhs;
|
f.rtype = d.lhs;
|
||||||
@@ -1877,6 +1885,9 @@ type modent = struct {
|
|||||||
mnext: *modent,
|
mnext: *modent,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #35: sizeof(modent) = 56 under str=24 ({str,str,*modent}); each
|
||||||
|
// of the four amallocs below grew from 48 to 64 to keep mnext inside
|
||||||
|
// the slot.
|
||||||
fn collectmods(c: *cgen, file: *node) void = {
|
fn collectmods(c: *cgen, file: *node) void = {
|
||||||
c.mods = nil;
|
c.mods = nil;
|
||||||
if (file == nil) { return; };
|
if (file == nil) { return; };
|
||||||
@@ -1900,7 +1911,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
|||||||
};
|
};
|
||||||
if (!isffi) {
|
if (!isffi) {
|
||||||
if (!streq(d.str, "main")) {
|
if (!streq(d.str, "main")) {
|
||||||
let m: *modent = amalloc(c.a, 48u64): *modent;
|
let m: *modent = amalloc(c.a, 64u64): *modent;
|
||||||
m.mname = d.str;
|
m.mname = d.str;
|
||||||
m.nmod = d.nmod;
|
m.nmod = d.nmod;
|
||||||
m.mnext = c.mods;
|
m.mnext = c.mods;
|
||||||
@@ -1912,7 +1923,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
|||||||
if (d.kind == nkind.N_DEF) {
|
if (d.kind == nkind.N_DEF) {
|
||||||
if (d.exported == 0) {
|
if (d.exported == 0) {
|
||||||
if (d.nmod.len > 0) {
|
if (d.nmod.len > 0) {
|
||||||
let m: *modent = amalloc(c.a, 48u64): *modent;
|
let m: *modent = amalloc(c.a, 64u64): *modent;
|
||||||
m.mname = d.str;
|
m.mname = d.str;
|
||||||
m.nmod = d.nmod;
|
m.nmod = d.nmod;
|
||||||
m.mnext = c.mods;
|
m.mnext = c.mods;
|
||||||
@@ -1923,7 +1934,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
|||||||
if (d.kind == nkind.N_TYPEDECL) {
|
if (d.kind == nkind.N_TYPEDECL) {
|
||||||
if (d.exported == 0) {
|
if (d.exported == 0) {
|
||||||
if (d.nmod.len > 0) {
|
if (d.nmod.len > 0) {
|
||||||
let m: *modent = amalloc(c.a, 48u64): *modent;
|
let m: *modent = amalloc(c.a, 64u64): *modent;
|
||||||
m.mname = d.str;
|
m.mname = d.str;
|
||||||
m.nmod = d.nmod;
|
m.nmod = d.nmod;
|
||||||
m.mnext = c.mods;
|
m.mnext = c.mods;
|
||||||
@@ -1934,7 +1945,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
|||||||
if (d.kind == nkind.N_LET) {
|
if (d.kind == nkind.N_LET) {
|
||||||
if (d.exported == 0) {
|
if (d.exported == 0) {
|
||||||
if (d.nmod.len > 0) {
|
if (d.nmod.len > 0) {
|
||||||
let m: *modent = amalloc(c.a, 48u64): *modent;
|
let m: *modent = amalloc(c.a, 64u64): *modent;
|
||||||
m.mname = d.str;
|
m.mname = d.str;
|
||||||
m.nmod = d.nmod;
|
m.nmod = d.nmod;
|
||||||
m.mnext = c.mods;
|
m.mnext = c.mods;
|
||||||
@@ -2040,7 +2051,8 @@ fn fficollect(c: *cgen, file: *node) void = {
|
|||||||
let symnode: *node = a.list;
|
let symnode: *node = a.list;
|
||||||
if (symnode != nil) {
|
if (symnode != nil) {
|
||||||
if (symnode.kind == nkind.N_STRLIT) {
|
if (symnode.kind == nkind.N_STRLIT) {
|
||||||
let f: *ffi = amalloc(c.a, 48u64): *ffi;
|
// #35: sizeof(ffi) = 56 under str=24 ({str,str,*ffi}).
|
||||||
|
let f: *ffi = amalloc(c.a, 64u64): *ffi;
|
||||||
f.ident = d.str;
|
f.ident = d.str;
|
||||||
f.symbol = symnode.str;
|
f.symbol = symnode.str;
|
||||||
f.fnext = c.ffis;
|
f.fnext = c.ffis;
|
||||||
|
|||||||
@@ -19854,7 +19854,8 @@ fn collectenums(c: *cgen, file: *node) void = {
|
|||||||
let body: *node = d.lhs;
|
let body: *node = d.lhs;
|
||||||
if (body != nil) {
|
if (body != nil) {
|
||||||
if (body.kind == nkind.N_TENUM) {
|
if (body.kind == nkind.N_TENUM) {
|
||||||
let et: *enumtype = amalloc(c.a, 64u64): *enumtype;
|
// #35: sizeof(enumtype) = 72 under str=24 ({str,str,*node,*enummember,*enumtype}); amalloc < struct corrupts the next slot.
|
||||||
|
let et: *enumtype = amalloc(c.a, 80u64): *enumtype;
|
||||||
et.ename = d.str;
|
et.ename = d.str;
|
||||||
et.emod = d.nmod;
|
et.emod = d.nmod;
|
||||||
et.storage = body.lhs;
|
et.storage = body.lhs;
|
||||||
@@ -19873,7 +19874,8 @@ fn collectenums(c: *cgen, file: *node) void = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
prev = val;
|
prev = val;
|
||||||
let em: *enummember = amalloc(c.a, 32u64): *enummember;
|
// #35: sizeof(enummember) = 40 under str=24 ({str,u64,*enummember}).
|
||||||
|
let em: *enummember = amalloc(c.a, 48u64): *enummember;
|
||||||
em.mname = m.str;
|
em.mname = m.str;
|
||||||
em.mval = val;
|
em.mval = val;
|
||||||
em.emnext = nil;
|
em.emnext = nil;
|
||||||
@@ -20162,10 +20164,14 @@ fn cgeninit(c: *cgen, a: *arena) void = {
|
|||||||
// persist across cgfn calls within one file. cgfile resets them
|
// persist across cgfn calls within one file. cgfile resets them
|
||||||
// at the start of each compilation unit.
|
// at the start of each compilation unit.
|
||||||
c.looptop = 0;
|
c.looptop = 0;
|
||||||
c.loopendbuf = amalloc(a, (LOOP_MAX: u64) * 16u64): *str;
|
// #35: per-slot stride is sizeof(str); the bare 16 is the str=16
|
||||||
c.loopcontbuf = amalloc(a, (LOOP_MAX: u64) * 16u64): *str;
|
// 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;
|
||||||
c.yieldtop = 0;
|
c.yieldtop = 0;
|
||||||
c.yieldbuf = amalloc(a, (LOOP_MAX: u64) * 16u64): *str;
|
c.yieldbuf = amalloc(a, (LOOP_MAX: u64) * 24u64): *str;
|
||||||
c.defertop = 0;
|
c.defertop = 0;
|
||||||
c.deferbuf = amalloc(a, (DEFER_MAX: u64) * 8u64): **node;
|
c.deferbuf = amalloc(a, (DEFER_MAX: u64) * 8u64): **node;
|
||||||
};
|
};
|
||||||
@@ -20521,7 +20527,8 @@ fn internstrlit(c: *cgen, bytes: str) str = {
|
|||||||
let lab: str;
|
let lab: str;
|
||||||
lab.ptr = p;
|
lab.ptr = p;
|
||||||
lab.len = total;
|
lab.len = total;
|
||||||
let nw: *strlit = amalloc(c.a, 48u64): *strlit;
|
// #35: sizeof(strlit) = 56 under str=24 ({str,str,*strlit}).
|
||||||
|
let nw: *strlit = amalloc(c.a, 64u64): *strlit;
|
||||||
nw.label = lab;
|
nw.label = lab;
|
||||||
nw.bytes = bytes;
|
nw.bytes = bytes;
|
||||||
nw.slnext = c.strlits;
|
nw.slnext = c.strlits;
|
||||||
@@ -21250,7 +21257,8 @@ fn collectfnrets(c: *cgen, file: *node) void = {
|
|||||||
let d: *node = file.list;
|
let d: *node = file.list;
|
||||||
for (d != nil) {
|
for (d != nil) {
|
||||||
if (d.kind == nkind.N_FNDECL) {
|
if (d.kind == nkind.N_FNDECL) {
|
||||||
let f: *fnret = amalloc(c.a, 64u64): *fnret;
|
// #35: sizeof(fnret) = 72 under str=24 ({str,str,*node,*node,*fnret}); was the trigger that hung w6c_ww on the hangtest — frnext overflowed into the next amalloc, breaking fnretlookup's chain walk.
|
||||||
|
let f: *fnret = amalloc(c.a, 80u64): *fnret;
|
||||||
f.fname = d.str;
|
f.fname = d.str;
|
||||||
f.fmod = d.nmod;
|
f.fmod = d.nmod;
|
||||||
f.rtype = d.lhs;
|
f.rtype = d.lhs;
|
||||||
@@ -21490,6 +21498,9 @@ type modent = struct {
|
|||||||
mnext: *modent,
|
mnext: *modent,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #35: sizeof(modent) = 56 under str=24 ({str,str,*modent}); each
|
||||||
|
// of the four amallocs below grew from 48 to 64 to keep mnext inside
|
||||||
|
// the slot.
|
||||||
fn collectmods(c: *cgen, file: *node) void = {
|
fn collectmods(c: *cgen, file: *node) void = {
|
||||||
c.mods = nil;
|
c.mods = nil;
|
||||||
if (file == nil) { return; };
|
if (file == nil) { return; };
|
||||||
@@ -21513,7 +21524,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
|||||||
};
|
};
|
||||||
if (!isffi) {
|
if (!isffi) {
|
||||||
if (!streq(d.str, "main")) {
|
if (!streq(d.str, "main")) {
|
||||||
let m: *modent = amalloc(c.a, 48u64): *modent;
|
let m: *modent = amalloc(c.a, 64u64): *modent;
|
||||||
m.mname = d.str;
|
m.mname = d.str;
|
||||||
m.nmod = d.nmod;
|
m.nmod = d.nmod;
|
||||||
m.mnext = c.mods;
|
m.mnext = c.mods;
|
||||||
@@ -21525,7 +21536,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
|||||||
if (d.kind == nkind.N_DEF) {
|
if (d.kind == nkind.N_DEF) {
|
||||||
if (d.exported == 0) {
|
if (d.exported == 0) {
|
||||||
if (d.nmod.len > 0) {
|
if (d.nmod.len > 0) {
|
||||||
let m: *modent = amalloc(c.a, 48u64): *modent;
|
let m: *modent = amalloc(c.a, 64u64): *modent;
|
||||||
m.mname = d.str;
|
m.mname = d.str;
|
||||||
m.nmod = d.nmod;
|
m.nmod = d.nmod;
|
||||||
m.mnext = c.mods;
|
m.mnext = c.mods;
|
||||||
@@ -21536,7 +21547,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
|||||||
if (d.kind == nkind.N_TYPEDECL) {
|
if (d.kind == nkind.N_TYPEDECL) {
|
||||||
if (d.exported == 0) {
|
if (d.exported == 0) {
|
||||||
if (d.nmod.len > 0) {
|
if (d.nmod.len > 0) {
|
||||||
let m: *modent = amalloc(c.a, 48u64): *modent;
|
let m: *modent = amalloc(c.a, 64u64): *modent;
|
||||||
m.mname = d.str;
|
m.mname = d.str;
|
||||||
m.nmod = d.nmod;
|
m.nmod = d.nmod;
|
||||||
m.mnext = c.mods;
|
m.mnext = c.mods;
|
||||||
@@ -21547,7 +21558,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
|||||||
if (d.kind == nkind.N_LET) {
|
if (d.kind == nkind.N_LET) {
|
||||||
if (d.exported == 0) {
|
if (d.exported == 0) {
|
||||||
if (d.nmod.len > 0) {
|
if (d.nmod.len > 0) {
|
||||||
let m: *modent = amalloc(c.a, 48u64): *modent;
|
let m: *modent = amalloc(c.a, 64u64): *modent;
|
||||||
m.mname = d.str;
|
m.mname = d.str;
|
||||||
m.nmod = d.nmod;
|
m.nmod = d.nmod;
|
||||||
m.mnext = c.mods;
|
m.mnext = c.mods;
|
||||||
@@ -21653,7 +21664,8 @@ fn fficollect(c: *cgen, file: *node) void = {
|
|||||||
let symnode: *node = a.list;
|
let symnode: *node = a.list;
|
||||||
if (symnode != nil) {
|
if (symnode != nil) {
|
||||||
if (symnode.kind == nkind.N_STRLIT) {
|
if (symnode.kind == nkind.N_STRLIT) {
|
||||||
let f: *ffi = amalloc(c.a, 48u64): *ffi;
|
// #35: sizeof(ffi) = 56 under str=24 ({str,str,*ffi}).
|
||||||
|
let f: *ffi = amalloc(c.a, 64u64): *ffi;
|
||||||
f.ident = d.str;
|
f.ident = d.str;
|
||||||
f.symbol = symnode.str;
|
f.symbol = symnode.str;
|
||||||
f.fnext = c.ffis;
|
f.fnext = c.ffis;
|
||||||
|
|||||||
Reference in New Issue
Block a user