Phase 7k: bytes(n) / words(n) allocators (retire mem_alloc)

Allocation reads as intent, not malloc:

  mem_alloc(64)          -> bytes(64)              (64 bytes -> a byte buffer)
  mem_alloc(w * h * 4)   -> words(w * h)           (w*h 32-bit words)

bytes(n) mallocs n bytes and returns a plain pointer (byte-indexed); words(n)
mallocs n*4 bytes and returns a `words` pointer (int-indexed). Since words(X) and
mem_alloc(X*4) allocate the identical number of bytes, the migration cannot change
any allocation size — the `* 4` factor just moves from the argument into the
allocator name, pairing naturally with the Phase-7j `words` retyping
(`var fb: words = words(w * h)`).

Migrated 102 sites (mem_alloc(E*4) -> words(E), else bytes(E)); deleted the
mem_alloc intrinsic. mem_realloc/free/copy/set stay as the low-level
reallocation/free family. Reseeded (22565 lines); C-free fixpoint holds; goldens
byte-identical; 18/18; vocab + doc-fences clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-08-28 02:26:15 +03:00
parent 5cab68ea2e
commit 86948d2b19
22 changed files with 3118 additions and 3069 deletions

View file

@ -34,12 +34,12 @@ fn rt_font() -> str {
}
fn rt_init() -> void {
rt_fb = mem_alloc(320 * 240 * 4)
rt_regs = mem_alloc(64 * 4)
rt_fb = words(320 * 240)
rt_regs = words(64)
mem_set(rt_regs, 0, 64 * 4)
rt_map = mem_alloc(96 * 64)
rt_map = bytes(96 * 64)
mem_set(rt_map, 32, 96 * 64)
rt_statusbuf = mem_alloc(96)
rt_statusbuf = bytes(96)
rt_statusbuf[0] = 0
rt_image_init()
rt_tt_init()
@ -279,7 +279,7 @@ fn rt_dump_ppm(path: str) -> void {
let f = file_open(path, "wb")
if (f == null) { return }
let hdr = mem_alloc(64)
let hdr = bytes(64)
var n = rt_put_str(hdr, 0, "P6\n")
n = rt_put_int(hdr, n, rt_fbw)
n = rt_put_str(hdr, n, " ")
@ -288,7 +288,7 @@ fn rt_dump_ppm(path: str) -> void {
file_write(f, hdr, n)
let px = rt_fbw * rt_fbh
let buf = mem_alloc(px * 3)
let buf = bytes(px * 3)
for i in 0 .. px {
let c = rt_fb[i]
buf[i * 3] = (c / 65536) % 256
@ -369,7 +369,7 @@ fn rt_status_text() -> ptr {
# only it knows their shape. Everything below belongs to the runtime, so the
# runtime writes it — same order both ways.
fn rt_save_state(f: ptr) -> void {
let w: words = mem_alloc(16)
let w: words = bytes(16)
w[0] = rt_rng
w[1] = rt_mapw
w[2] = rt_maph
@ -382,7 +382,7 @@ fn rt_save_state(f: ptr) -> void {
}
fn rt_load_state(f: ptr) -> void {
let w: words = mem_alloc(16)
let w: words = bytes(16)
file_read(f, w, 16)
rt_rng = w[0]
rt_mapw = w[1]

View file

@ -22,10 +22,10 @@ var spr_px: words = null # SPR_MAX * 16 * 16 RGBA pixels, one block
var spr_n: int = 0
fn rt_image_init() -> void {
img_px = mem_alloc(IMG_MAX * 8)
img_w = mem_alloc(IMG_MAX * 4)
img_h = mem_alloc(IMG_MAX * 4)
spr_px = mem_alloc(SPR_MAX * SPR_SZ * SPR_SZ * 4)
img_px = bytes(IMG_MAX * 8)
img_w = words(IMG_MAX)
img_h = words(IMG_MAX)
spr_px = words(SPR_MAX * SPR_SZ * SPR_SZ)
mem_set(spr_px, 0, SPR_MAX * SPR_SZ * SPR_SZ * 4)
}
@ -49,7 +49,7 @@ fn rt_read_file(path: str) -> ptr {
let n = file_tell(f)
file_seek(f, 0, 0)
if n <= 0 { file_close(f); return null }
let buf = mem_alloc(n + 8)
let buf = bytes(n + 8)
file_read(f, buf, n)
file_close(f)
rt_file_len = n
@ -77,10 +77,10 @@ fn rt_decode_png(path: str) -> bool {
var h = 0
var bd = 0
var ct = 0
let plte = mem_alloc(768)
let trns = mem_alloc(256)
let plte = bytes(768)
let trns = bytes(256)
var ntrns = 0
let idat = mem_alloc(size)
let idat = bytes(size)
var idlen = 0
var i = 8
var done = 0
@ -130,7 +130,7 @@ fn rt_decode_png(path: str) -> bool {
if fbpp < 1 { fbpp = 1 }
let stride = (w * bppbits + 7) / 8
let rawlen = h * (stride + 1)
let raw = mem_alloc(rawlen + 8)
let raw = bytes(rawlen + 8)
if z_uncompress(idat, idlen, raw, rawlen) < 0 {
mem_free(d); mem_free(raw); mem_free(idat)
return false
@ -168,7 +168,7 @@ fn rt_decode_png(path: str) -> bool {
}
# expand to 0xAARRGGBB
let out: words = mem_alloc(w * h * 4)
let out: words = words(w * h)
let maxv = (1 << bd) - 1
for y in 0 .. h {
let row = y * (stride + 1) + 1
@ -379,7 +379,7 @@ fn rt_sprites_load(path: str) -> void {
let d = rt_read_file(path)
if (d == null) { spr_n = 0; return }
let size = rt_file_len
let pal: words = mem_alloc(128 * 4)
let pal: words = words(128)
mem_set(pal, 0, 128 * 4)
var cur = 0 - 1
var row = 0

View file

@ -49,7 +49,7 @@ fn z_bits(need: int) -> int {
# A table is a single buffer: 16 length-counts followed by the symbols in
# canonical order. One allocation, no structs.
fn z_table_new(nsym: int) -> ptr {
return mem_alloc((16 + nsym) * 4)
return words((16 + nsym))
}
# lengths[i] = code length of symbol i (0 = symbol unused)
@ -63,7 +63,7 @@ fn z_table_build(table: words, lengths: words, n: int) -> void {
}
table[0] = 0 # length 0 means "not present"
# offset of each length's first symbol
let offs: words = mem_alloc(16 * 4)
let offs: words = words(16)
offs[1] = 0
for l in 1 .. 15 {
offs[l + 1] = offs[l] + table[l]
@ -173,7 +173,7 @@ fn z_codes(out: ptr, at: int, cap: int, lit: ptr, dist: ptr) -> int {
}
fn z_fixed_tables(lit: ptr, dist: ptr) -> void {
let lengths: words = mem_alloc(288 * 4)
let lengths: words = words(288)
for i in 0 .. 144 { lengths[i] = 8 }
for i in 144 .. 256 { lengths[i] = 9 }
for i in 256 .. 280 { lengths[i] = 7 }
@ -191,7 +191,7 @@ fn z_dynamic_tables(lit: ptr, dist: ptr) -> int {
if nlen > 286 { return 0 }
if ndist > 30 { return 0 }
let lengths: words = mem_alloc(320 * 4)
let lengths: words = words(320)
for i in 0 .. 19 { lengths[i] = 0 }
# the code-length alphabet is transmitted in this fixed permutation
# 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 — biased by '0' so it is one literal
@ -230,7 +230,7 @@ fn z_dynamic_tables(lit: ptr, dist: ptr) -> int {
}
z_table_build(lit, lengths, nlen)
# the distance lengths follow the literal ones in the same buffer
let dl: words = mem_alloc(32 * 4)
let dl: words = words(32)
for i in 0 .. ndist { dl[i] = lengths[nlen + i] }
z_table_build(dist, dl, ndist)
mem_free(dl)

View file

@ -64,43 +64,43 @@ var gc_adv: words = null
var gc_bmp: ptr = null
fn rt_tt_init() -> void {
tt_data = mem_alloc(TT_MAX * 8)
tt_size = mem_alloc(TT_MAX * 4)
tt_upem = mem_alloc(TT_MAX * 4)
tt_nglyf = mem_alloc(TT_MAX * 4)
tt_locfm = mem_alloc(TT_MAX * 4)
tt_nhm = mem_alloc(TT_MAX * 4)
tt_asc = mem_alloc(TT_MAX * 4)
tt_desc = mem_alloc(TT_MAX * 4)
tt_gap = mem_alloc(TT_MAX * 4)
tt_glyf = mem_alloc(TT_MAX * 4)
tt_loca = mem_alloc(TT_MAX * 4)
tt_hmtx = mem_alloc(TT_MAX * 4)
tt_cmap = mem_alloc(TT_MAX * 4)
tt_cfmt = mem_alloc(TT_MAX * 4)
tt_data = bytes(TT_MAX * 8)
tt_size = words(TT_MAX)
tt_upem = words(TT_MAX)
tt_nglyf = words(TT_MAX)
tt_locfm = words(TT_MAX)
tt_nhm = words(TT_MAX)
tt_asc = words(TT_MAX)
tt_desc = words(TT_MAX)
tt_gap = words(TT_MAX)
tt_glyf = words(TT_MAX)
tt_loca = words(TT_MAX)
tt_hmtx = words(TT_MAX)
tt_cmap = words(TT_MAX)
tt_cfmt = words(TT_MAX)
ol_x = mem_alloc(TT_PTS * 4)
ol_y = mem_alloc(TT_PTS * 4)
ol_on = mem_alloc(TT_PTS * 4)
ol_ends = mem_alloc(256 * 4)
ol_x = words(TT_PTS)
ol_y = words(TT_PTS)
ol_on = words(TT_PTS)
ol_ends = words(256)
ed_x0 = mem_alloc(TT_EDGES * 4)
ed_y0 = mem_alloc(TT_EDGES * 4)
ed_x1 = mem_alloc(TT_EDGES * 4)
ed_y1 = mem_alloc(TT_EDGES * 4)
sc_x = mem_alloc(TT_EDGES * 4)
sc_d = mem_alloc(TT_EDGES * 4)
ed_x0 = words(TT_EDGES)
ed_y0 = words(TT_EDGES)
ed_x1 = words(TT_EDGES)
ed_y1 = words(TT_EDGES)
sc_x = words(TT_EDGES)
sc_d = words(TT_EDGES)
gc_used = mem_alloc(TT_GC * 4)
gc_font = mem_alloc(TT_GC * 4)
gc_cp = mem_alloc(TT_GC * 4)
gc_px = mem_alloc(TT_GC * 4)
gc_w = mem_alloc(TT_GC * 4)
gc_h = mem_alloc(TT_GC * 4)
gc_ox = mem_alloc(TT_GC * 4)
gc_oy = mem_alloc(TT_GC * 4)
gc_adv = mem_alloc(TT_GC * 4)
gc_bmp = mem_alloc(TT_GC * 8)
gc_used = words(TT_GC)
gc_font = words(TT_GC)
gc_cp = words(TT_GC)
gc_px = words(TT_GC)
gc_w = words(TT_GC)
gc_h = words(TT_GC)
gc_ox = words(TT_GC)
gc_oy = words(TT_GC)
gc_adv = words(TT_GC)
gc_bmp = bytes(TT_GC * 8)
mem_set(gc_used, 0, TT_GC * 4)
}
@ -310,7 +310,7 @@ fn tt_load_outline(id: int, gid: int, a: fixed, b: fixed, c: fixed, e: fixed, dx
var p = endpts + nc * 2
p = p + 2 + tt_u16(d, p) # skip instructions
let flags = mem_alloc(npts + 8)
let flags = bytes(npts + 8)
var i = 0
while i < npts {
let fl = d[p]
@ -327,8 +327,8 @@ fn tt_load_outline(id: int, gid: int, a: fixed, b: fixed, c: fixed, e: fixed, dx
}
}
let xs: words = mem_alloc((npts + 1) * 4)
let ys: words = mem_alloc((npts + 1) * 4)
let xs: words = words((npts + 1))
let ys: words = words((npts + 1))
var xv = 0
for k in 0 .. npts {
let fl = flags[k]

View file

@ -151,7 +151,7 @@ fn tt_raster(id: int, gid: int, px: int) -> ptr {
let SW = W * TT_SS
let SH = H * TT_SS
let cover = mem_alloc(W * H)
let cover = bytes(W * H)
mem_set(cover, 0, W * H)
let unit = 255 / (TT_SS * TT_SS)

View file

@ -80,35 +80,35 @@ var ui_active: int = -1
var ui_focus: int = -1
fn rt_ui_init() -> void {
ui_type = mem_alloc(UI_MAX * 4)
ui_parent = mem_alloc(UI_MAX * 4)
ui_w = mem_alloc(UI_MAX * 4)
ui_h = mem_alloc(UI_MAX * 4)
ui_x = mem_alloc(UI_MAX * 4)
ui_y = mem_alloc(UI_MAX * 4)
ui_haspos = mem_alloc(UI_MAX * 4)
ui_pad = mem_alloc(UI_MAX * 4)
ui_gap = mem_alloc(UI_MAX * 4)
ui_bg = mem_alloc(UI_MAX * 4)
ui_fg = mem_alloc(UI_MAX * 4)
ui_border = mem_alloc(UI_MAX * 4)
ui_align = mem_alloc(UI_MAX * 4)
ui_grow = mem_alloc(UI_MAX * 4)
ui_font = mem_alloc(UI_MAX * 4)
ui_size = mem_alloc(UI_MAX * 4)
ui_skin = mem_alloc(UI_MAX * 4)
ui_inset = mem_alloc(UI_MAX * 4)
ui_img = mem_alloc(UI_MAX * 4)
ui_focusable = mem_alloc(UI_MAX * 4)
ui_rx = mem_alloc(UI_MAX * 4)
ui_ry = mem_alloc(UI_MAX * 4)
ui_rw = mem_alloc(UI_MAX * 4)
ui_rh = mem_alloc(UI_MAX * 4)
ui_visible = mem_alloc(UI_MAX * 4)
ui_fired = mem_alloc(UI_MAX * 4)
ui_hasdyn = mem_alloc(UI_MAX * 4)
ui_dyn = mem_alloc(UI_MAX * 96)
ui_text = mem_alloc(UI_MAX * 8)
ui_type = words(UI_MAX)
ui_parent = words(UI_MAX)
ui_w = words(UI_MAX)
ui_h = words(UI_MAX)
ui_x = words(UI_MAX)
ui_y = words(UI_MAX)
ui_haspos = words(UI_MAX)
ui_pad = words(UI_MAX)
ui_gap = words(UI_MAX)
ui_bg = words(UI_MAX)
ui_fg = words(UI_MAX)
ui_border = words(UI_MAX)
ui_align = words(UI_MAX)
ui_grow = words(UI_MAX)
ui_font = words(UI_MAX)
ui_size = words(UI_MAX)
ui_skin = words(UI_MAX)
ui_inset = words(UI_MAX)
ui_img = words(UI_MAX)
ui_focusable = words(UI_MAX)
ui_rx = words(UI_MAX)
ui_ry = words(UI_MAX)
ui_rw = words(UI_MAX)
ui_rh = words(UI_MAX)
ui_visible = words(UI_MAX)
ui_fired = words(UI_MAX)
ui_hasdyn = words(UI_MAX)
ui_dyn = bytes(UI_MAX * 96)
ui_text = bytes(UI_MAX * 8)
}
# ---- build-time interface (called by compiler-emitted code) ---------------

View file

@ -149,7 +149,7 @@ fn ui_draw_node(i: int) -> void {
var ui_fl: words = null
fn ui_focusables() -> int {
if (ui_fl == null) { ui_fl = mem_alloc(UI_MAX * 4) }
if (ui_fl == null) { ui_fl = words(UI_MAX) }
var n = 0
for i in 0 .. ui_n {
if ui_focusable[i] == 1 {