Transpiler detects dict literals with a "type" string field and emits CekFrame records instead of Dict(Hashtbl). Maps frame-specific fields to generic record slots: cf_type, cf_env, cf_name, cf_body, cf_remaining, cf_f, cf_args (also evaled), cf_results (also raw-args), cf_extra (ho-type/scheme/indexed/match-val/current-item/...), cf_extra2 (emitted/effect-list/first-render) Runtime get_val handles CekFrame with direct field match — O(1) field access vs Hashtbl.find. Bootstrapper: skip stdlib.sx entirely (already OCaml primitives). Result: 29 CekFrame + 2 CekState = 31 record types, only 8 Hashtbl.create remaining (effect-annotations, empty dicts). Benchmark (200 divs): 2.94s → 1.71s (1.7x speedup from baseline). Real pages: ~same as CekState-only (frames are <20% of allocations; states dominate at 199K/page). Foundation for JIT: record-based value representation enables typed compilation — JIT can emit direct field access instead of hash table lookups. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
15 KiB
15 KiB