Found in a modularity review of main @ 8e8970a. Tracking issue.
What
The EIGENSCRIPT_EXT_* discipline is genuinely good — one registration seam at builtins.c:7386-7396 behind three #ifs, backed by ext_names.h's X-macro registry. EIGENSCRIPT_FREESTANDING gets no such treatment and is carved inline instead:
| File |
EIGENSCRIPT_FREESTANDING blocks |
approx. lines gated |
src/builtins.c |
52 |
~1578 |
src/lint.c |
6 |
~952 (:638-934, :2041-2459, :2468-2663, :2686-2800) |
Host-only builtins are interleaved with portable ones, so tools/freestanding_check.sh breaking is the only feedback that a newly added builtin leaked a host symbol.
Two clean patterns already in-tree
ext_store.c:8 gates the entire 1193-line TU in one block, leaving a linkable no-op registrar (ext_store.c:12).
jit.c:50-130 stubs a 5-function interface (jit_cache_new/free/alloc/seal/unseal) so jit.h contains zero conditional compilation.
Why the split is cheap here
The host-only statics are already group-local, so the groups are separable without untangling shared state:
g_orig_termios / g_raw_mode (builtins.c:96-97) — terminal
g_stream_file (:2023) — streams
g_argc / g_argv (:2071) — argv
g_proc_sigpipe_once (:3517) — process
A builtins_host.c holding the filesystem/path/process/exec/terminal groups (roughly :2070-2290 and :2800-3770) would replace ~50 #ifdef pairs with one Makefile line, and make "did this new builtin just become host-only?" a link error rather than a gate failure.
Note on the freestanding seam itself — it is good
Worth stating explicitly so this isn't read as broader criticism: src/freestanding/ (1745 lines behind standard libc names via -DEIGS_MINI_STANDARD_NAMES=1) is never #included by any runtime TU, is verified by a two-stage symbol gate plus a byte/ulp differential against glibc (make freestanding-libc-diff), and involves no parallel maintenance of runtime logic — the carve-outs are early-returns and stubs, not forked implementations. The problem is only on the host side of the boundary.
Found in a modularity review of
main@8e8970a. Tracking issue.What
The
EIGENSCRIPT_EXT_*discipline is genuinely good — one registration seam atbuiltins.c:7386-7396behind three#ifs, backed byext_names.h's X-macro registry.EIGENSCRIPT_FREESTANDINGgets no such treatment and is carved inline instead:EIGENSCRIPT_FREESTANDINGblockssrc/builtins.csrc/lint.c:638-934,:2041-2459,:2468-2663,:2686-2800)Host-only builtins are interleaved with portable ones, so
tools/freestanding_check.shbreaking is the only feedback that a newly added builtin leaked a host symbol.Two clean patterns already in-tree
ext_store.c:8gates the entire 1193-line TU in one block, leaving a linkable no-op registrar (ext_store.c:12).jit.c:50-130stubs a 5-function interface (jit_cache_new/free/alloc/seal/unseal) sojit.hcontains zero conditional compilation.Why the split is cheap here
The host-only statics are already group-local, so the groups are separable without untangling shared state:
g_orig_termios/g_raw_mode(builtins.c:96-97) — terminalg_stream_file(:2023) — streamsg_argc/g_argv(:2071) — argvg_proc_sigpipe_once(:3517) — processA
builtins_host.cholding the filesystem/path/process/exec/terminal groups (roughly:2070-2290and:2800-3770) would replace ~50#ifdefpairs with one Makefile line, and make "did this new builtin just become host-only?" a link error rather than a gate failure.Note on the freestanding seam itself — it is good
Worth stating explicitly so this isn't read as broader criticism:
src/freestanding/(1745 lines behind standard libc names via-DEIGS_MINI_STANDARD_NAMES=1) is never#included by any runtime TU, is verified by a two-stage symbol gate plus a byte/ulp differential against glibc (make freestanding-libc-diff), and involves no parallel maintenance of runtime logic — the carve-outs are early-returns and stubs, not forked implementations. The problem is only on the host side of the boundary.