Revert JIT VmClosure optimization — was producing wrong bytecode

The optimization to call the compiler through VM directly (instead
of CEK) when it's JIT-compiled was producing incorrect bytecode for
all subsequently compiled functions, causing "Expected number, got
symbol" errors across render-to-html, parse-loop, etc.

Revert to always using CEK for compilation. The compiler runs via
CEK which is slower but produces correct bytecode. JIT-compiled
USER functions still run at VM speed.

1166 passed, 0 failed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-29 21:37:06 +00:00
parent 85f72af74b
commit 3e1727004c

View File

@@ -575,13 +575,7 @@ let jit_compile_lambda (l : lambda) globals =
let param_syms = List (List.map (fun s -> Symbol s) l.l_params) in let param_syms = List (List.map (fun s -> Symbol s) l.l_params) in
let fn_expr = List [Symbol "fn"; param_syms; l.l_body] in let fn_expr = List [Symbol "fn"; param_syms; l.l_body] in
let quoted = List [Symbol "quote"; fn_expr] in let quoted = List [Symbol "quote"; fn_expr] in
let result = match compile_fn with let result = Sx_ref.eval_expr (List [compile_fn; quoted]) (Env (make_env ())) in
| VmClosure cl ->
(* Compiler loaded as bytecode — call through VM directly *)
call_closure cl [quoted] globals
| _ ->
(* Compiler loaded from source — call through CEK *)
Sx_ref.eval_expr (List [compile_fn; quoted]) (Env (make_env ())) in
(* Inject closure bindings into globals so GLOBAL_GET can find them. (* Inject closure bindings into globals so GLOBAL_GET can find them.
Only injects values not already present in globals (preserves Only injects values not already present in globals (preserves
existing defines). Mutable closure vars get stale snapshots here existing defines). Mutable closure vars get stale snapshots here