import "all.hff"; def ARENA_SIZE = 16 * 1024; 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 = xmalloc(sizeof ArenaRegion); *rp = a.r; let r = ArenaRegion { .prev: rp }; return allocf(a, n); } } } struct Mallocator { fn allocf(*void, n usize) *void { return xmalloc(n); } fn freef(*void, ptr *void) void { free(ptr); } } struct Allocator { a *void, allocf *fn(a *void, n usize) *void, freef *fn(a *void, ptr *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); } } }