JIT: closure env merge + bytecode locals scan for closure functions

- jit_compile_lambda: merge closure bindings into effective_globals so
  GLOBAL_GET resolves variables from let/define blocks (emit-on, etc.)
- code_from_value: scan bytecode for max LOCAL_GET/SET slot to compute
  vc_locals (fixes LOCAL_GET overflow in large functions like hs-parse)

3127/3127 no-JIT, 3116/3127 JIT (11 hyperscript on-event: specific
bytecode correctness issue in recursive parser — wrong branch taken
strips on/event-name from result).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-08 11:24:50 +00:00
parent 3155ba47f9
commit d715d8c4ac

View File

@@ -881,7 +881,23 @@ let jit_compile_lambda (l : lambda) globals =
Sx_ref.eval_expr (List [Symbol "compile"; quoted]) (Env compile_env)
in
_jit_compiling := false;
let effective_globals = globals in
(* Merge closure bindings into effective_globals so GLOBAL_GET resolves
variables from let/define blocks. The compiler emits GLOBAL_GET for
free variables; the VM resolves them from vm_env_ref. *)
let effective_globals =
if Hashtbl.length l.l_closure.Sx_types.bindings > 0 then begin
let merged = Hashtbl.copy globals in
let rec merge_env env =
Hashtbl.iter (fun id v ->
let name = Sx_types.unintern id in
if not (Hashtbl.mem merged name) then
Hashtbl.replace merged name v) env.Sx_types.bindings;
match env.Sx_types.parent with Some p -> merge_env p | None -> ()
in
merge_env l.l_closure;
merged
end else globals
in
(match result with
| Dict d when Hashtbl.mem d "bytecode" || Hashtbl.mem d "vc-bytecode" ->
let outer_code = code_from_value result in