Fix root cause: skip JIT for closure lambdas in BOTH hook and vm_call

The closure check was only in vm_call (sx_vm.ml) but inner functions
like read-list-loop were also compiled through the JIT hook in
sx_server.ml. The hook compiled them with closure merging, producing
incorrect bytecode (read-list-loop mishandled closing parens).

Added the same closure check to the JIT hook: skip lambdas with
non-empty closures. Now sx-parse works correctly:
  (a (b) (c)) → 3 siblings, not (a (b (c)))

Pre-compiled count increased from 17 to 33 — more top-level
functions compiled (inner ones correctly skipped to CEK).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-23 19:24:14 +00:00
parent 96f50b9dfa
commit a823e59376
2 changed files with 4 additions and 10 deletions

View File

@@ -913,6 +913,10 @@ let register_jit_hook env =
| Some _ -> None (* compile failed — CEK handles *)
| None ->
if !_jit_compiling then None
else if Hashtbl.length l.l_closure.bindings > 0
|| l.l_closure.parent <> None then
(* Skip JIT for lambdas with closure bindings *)
None
else begin
let fn_name = match l.l_name with Some n -> n | None -> "?" in
_jit_compiling := true;