Three interacting JIT bugs caused infinite loops and server hangs: 1. _jit_compiling cascade: the re-entrancy flag was local to each binary's hook. When vm_call triggered JIT compilation internally, compiler functions got JIT-compiled during compilation, creating infinite cascades. Fix: shared _jit_compiling flag in sx_vm.ml, set in jit_compile_lambda itself. 2. call_closure always created new VMs: every HO primitive callback (for-each, map, filter) allocated a fresh VM. With 43K+ calls during compilation, this was the direct cause of hangs. Fix: call_closure_reuse reuses the active VM by isolating frames and running re-entrantly. VmSuspended is handled by merging frames for proper IO resumption. 3. vm_call for compiled Lambdas: OP_CALL dispatching to a Lambda with cached bytecode created a new VM instead of pushing a frame on the current one. Fix: push_closure_frame directly. Additional MCP server fixes: - Hot-reload: auto-execv when binary on disk is newer (no restart needed) - Robust JSON: to_int_safe/to_int_or handle null, string, int params - sx_summarise depth now optional (default 2) - Per-request error handling (malformed JSON doesn't crash server) - sx_test uses pre-built binary (skips dune rebuild overhead) - Timed module loading for startup diagnostics sx_server.ml fixes: - Uses shared _jit_compiling flag - Marks lambdas as jit_failed_sentinel on compile failure (no retry spam) - call_closure_reuse with VmSuspended frame merging for IO support Compiled compiler bytecode bug: deeply nested cond/case/let forms (e.g. tw-resolve-style) cause the compiled compiler to loop. Workaround: _jit_compiling guard prevents compiled function execution during compilation. Compilation uses CEK (slower but correct). Test suite: 3127/3127 passed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
144 KiB
144 KiB