diff --git a/hosts/ocaml/bin/sx_server.ml b/hosts/ocaml/bin/sx_server.ml index c6ba57e..3ce91d3 100644 --- a/hosts/ocaml/bin/sx_server.ml +++ b/hosts/ocaml/bin/sx_server.ml @@ -1008,6 +1008,18 @@ let rec dispatch env cmd = | Eval_error msg -> send_error msg | exn -> send_error (Printexc.to_string exn)) + | List [Symbol "vm-reset-fn"; String name] -> + (* Reset a function's JIT-compiled bytecode, forcing CEK interpretation. + Used to work around JIT compilation bugs in specific functions. *) + (match Hashtbl.find_opt env.bindings name with + | Some (Lambda l) -> + l.l_compiled <- Some Sx_vm.jit_failed_sentinel; + Printf.eprintf "[jit] reset %s (forced CEK)\n%!" name; + send_ok () + | _ -> + Printf.eprintf "[jit] reset %s: not found or not lambda\n%!" name; + send_ok ()) + | List [Symbol "aser-blob"] -> (* Like aser but reads source as a binary blob. *) let src = read_blob () in diff --git a/shared/sx/ocaml_bridge.py b/shared/sx/ocaml_bridge.py index bbc13d3..679c44e 100644 --- a/shared/sx/ocaml_bridge.py +++ b/shared/sx/ocaml_bridge.py @@ -439,6 +439,16 @@ class OcamlBridge: skipped += 1 _logger.warning("OCaml load skipped %s: %s", filepath, e) + # JIT workaround: reset functions with known compilation bugs. + # cssx-resolve has a complex cond that the JIT miscompiles + # (colour branch skipped even when conditions are true). + # Resetting forces CEK interpretation. + try: + await self._send('(vm-reset-fn "cssx-resolve")') + await self._read_until_ok(ctx=None) + except OcamlBridgeError: + pass + # SSR overrides: effect is a no-op on the server (prevents # reactive loops during island SSR — effects are DOM side-effects) try: