Replace Node.js compile-modules.js with direct Sx_compiler.compile_module
calls in mcp_tree.ml. No subprocess, no JIT warm-up, no Node.js.
23 files compile in 1.9 seconds.
Also includes rebuilt WASM kernel (iterative cek_run) and all 23
bytecode modules recompiled with native compiler.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reverse hook syncs VM GLOBAL_SET mutations back to global_env so CEK reads
see JIT-written values. Isomorphic nav: store primitives, event-bridge,
client? predicate. Browser JS and bytecode rebuilt.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
List.find returns the element that matched, but SX some should return
the callback's truthy return value. This caused get-verb-info to return
"get" (the verb string) instead of the {method, url} dict.
Also added _active_vm tracking to VM for future HO primitive optimization,
and reverted get-verb-info to use some (no longer needs for-each workaround).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The some HO form passes callbacks through call_sx_fn which creates a new
VM that can't see the enclosing closure's captured variables (el). Replaced
with for-each + mutation which keeps everything in the same VM scope.
Also fixed destructuring param ((verb ...)) → plain param (verb).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The sx-get links were doing full page refreshes because click handlers
never attached. Root causes: VM frame management bug, missing primitives,
CEK/VM type dispatch mismatch, and silent error swallowing.
Fixes:
- VM frame exhaustion: frames <- [] now properly pops to rest_frames
- length primitive: add alias for len in OCaml primitives
- call_sx_fn: use sx_call directly instead of eval_expr (CEK checks
for type "lambda" but VmClosure reports "function")
- Boot error surfacing: Sx.init() now has try/catch + failure summary
- Callback error surfacing: catch-all handler for non-Eval_error exceptions
- Silent JIT failures: log before CEK fallback instead of swallowing
- vm→env sync: loadModule now calls sync_vm_to_env()
- sx_build_bytecode MCP tool added for bytecode compilation
Tests: 50 new tests across test-vm.sx and test-vm-primitives.sx covering
nested VM calls, frame integrity, CEK bridge, primitive availability,
cross-module symbol resolution, and callback dispatch.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- compile-modules.js: Node.js build tool, all 23 .sx files compile to .sxbc.json
- api_load_module with shared globals (beginModuleLoad/endModuleLoad batch API)
- api_compile_module for runtime compilation
- sx-platform.js: bytecode-first loader with source fallback, JSON deserializer
- Deferred JIT enable (setTimeout after boot)
Known issues:
- WASM browser: loadModule loads but functions not accessible (env writeback
issue with interned keys)
- WASM browser: compileModule fails ("Not callable: nil" — compile-module
function from bytecode not working correctly in WASM context)
- Node.js js_of_ocaml: full roundtrip works (compile → load → call)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>