import "libc.hff"; import "all.hff"; def ARENA_SIZE = 16 * 1024; defmacro ALIGNUP(x,a) [ (((x) + ((a) - 1)) & -(a)) ] extern fn xmalloc(n usize) *void; extern fn xcalloc(n usize, m usize) *void; extern fn xrealloc(p *void, n usize) *void; struct ArenaRegion { prev *ArenaRegion, idx int, mem [ARENA_SIZE]u8, } struct Arena { r *ArenaRegion, fn allocf(a *void, n usize) *void { let a *Arena = a; n = ALIGNUP(n, 16); if ARENA_SIZE < n { return xmalloc(n); } else if a.r == #null { a.r = xcalloc(1, sizeof ArenaRegion); return allocf(a, n); } else if ARENA_SIZE - a.r.idx >= n { let ptr = &a.r.mem[a.r.idx]; a.r.idx += n; return ptr; } else { let rp *ArenaRegion = xmalloc(sizeof ArenaRegion); *rp = *a.r; let r = ArenaRegion { .prev: rp }; return allocf(a, n); } } } struct Allocator { a *void, allocf *fn(*void, usize) *void, freef *fn(*void, *void) void, fn alloc(self *Allocator, n usize) *void { if self.allocf { return self.allocf(self.a, n); } return #null; } fn free(self *Allocator, ptr *void) void { if self.freef { self.freef(self.a, ptr); } } }