Native bytecode compilation in MCP: 108s → 1.9s (57x faster)

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>
This commit is contained in:
2026-03-30 10:45:38 +00:00
parent a24efc1a00
commit 951b3a6586
61 changed files with 162 additions and 8202 deletions

View File

@@ -600,16 +600,90 @@ let rec handle_tool name args =
let spec_dir = try Sys.getenv "SX_SPEC_DIR" with Not_found -> "spec" in
Filename.dirname spec_dir
in
(* Use compile-modules.js which now delegates to native OCaml *)
let cmd = Printf.sprintf "cd %s && node --input-type=commonjs hosts/ocaml/browser/compile-modules.js shared/static/wasm 2>&1" project_dir in
let ic = Unix.open_process_in cmd in
let lines = ref [] in
(try while true do lines := input_line ic :: !lines done with End_of_file -> ());
let status = Unix.close_process_in ic in
let output = String.concat "\n" (List.rev !lines) in
(match status with
| Unix.WEXITED 0 -> text_result (Printf.sprintf "OK — bytecode compilation succeeded\n%s" (String.trim output))
| _ -> error_result (Printf.sprintf "Bytecode compilation failed:\n%s" output))
let sx_dir = project_dir ^ "/shared/static/wasm/sx" in
let files = [
"render.sx"; "core-signals.sx"; "signals.sx"; "deps.sx"; "router.sx";
"page-helpers.sx"; "freeze.sx"; "bytecode.sx"; "compiler.sx"; "vm.sx";
"dom.sx"; "browser.sx"; "adapter-html.sx"; "adapter-sx.sx"; "adapter-dom.sx";
"boot-helpers.sx"; "hypersx.sx"; "harness.sx"; "harness-reactive.sx";
"harness-web.sx"; "engine.sx"; "orchestration.sx"; "boot.sx";
] in
let t0 = Unix.gettimeofday () in
(* JSON serialization for bytecode constants *)
let rec const_to_json = function
| Number n ->
if Float.is_integer n then Printf.sprintf "{\"t\":\"n\",\"v\":%d}" (int_of_float n)
else Printf.sprintf "{\"t\":\"n\",\"v\":%g}" n
| String s -> Printf.sprintf "{\"t\":\"s\",\"v\":%s}" (json_escape s)
| Symbol s -> Printf.sprintf "{\"t\":\"sym\",\"v\":%s}" (json_escape s)
| Keyword k -> Printf.sprintf "{\"t\":\"kw\",\"v\":%s}" (json_escape k)
| Bool true -> "{\"t\":\"b\",\"v\":true}"
| Bool false -> "{\"t\":\"b\",\"v\":false}"
| Nil -> "{\"t\":\"nil\"}"
| Dict d when Hashtbl.mem d "bytecode" -> code_to_json (Dict d)
| List items -> Printf.sprintf "{\"t\":\"list\",\"v\":[%s]}"
(String.concat "," (List.map const_to_json items))
| ListRef { contents = items } -> Printf.sprintf "{\"t\":\"list\",\"v\":[%s]}"
(String.concat "," (List.map const_to_json items))
| _ -> "{\"t\":\"nil\"}"
and code_to_json code =
let bc = match Sx_runtime.get code (String "bytecode") with
| List l | ListRef { contents = l } ->
String.concat "," (List.map (fun v -> match v with Number n -> string_of_int (int_of_float n) | _ -> "0") l)
| _ -> "" in
let consts = match Sx_runtime.get code (String "constants") with
| List l | ListRef { contents = l } -> String.concat "," (List.map const_to_json l)
| _ -> "" in
Printf.sprintf "{\"t\":\"code\",\"v\":{\"bytecode\":[%s],\"constants\":[%s]}}" bc consts
and json_escape s =
let buf = Buffer.create (String.length s + 2) in
Buffer.add_char buf '"';
String.iter (fun c -> match c with
| '"' -> Buffer.add_string buf "\\\"" | '\\' -> Buffer.add_string buf "\\\\"
| '\n' -> Buffer.add_string buf "\\n" | '\r' -> Buffer.add_string buf "\\r"
| '\t' -> Buffer.add_string buf "\\t"
| c -> Buffer.add_char buf c) s;
Buffer.add_char buf '"';
Buffer.contents buf
in
let compiled = ref 0 in
let skipped = ref 0 in
let log = Buffer.create 1024 in
List.iter (fun file ->
let src_path = sx_dir ^ "/" ^ file in
if Sys.file_exists src_path then begin
try
let src = In_channel.with_open_text src_path In_channel.input_all in
let exprs = Sx_parser.parse_all src in
let hash = Digest.string src |> Digest.to_hex |> fun s -> String.sub s 0 16 in
let code = Sx_compiler.compile_module (List exprs) in
(* Serialize to JSON *)
let bc = match Sx_runtime.get code (String "bytecode") with
| List l | ListRef { contents = l } ->
String.concat "," (List.map (fun v -> match v with Number n -> string_of_int (int_of_float n) | _ -> "0") l)
| _ -> "" in
let consts = match Sx_runtime.get code (String "constants") with
| List l | ListRef { contents = l } -> String.concat "," (List.map const_to_json l)
| _ -> "" in
let json = Printf.sprintf "{\"magic\":\"SXBC\",\"version\":1,\"hash\":\"%s\",\"module\":{\"bytecode\":[%s],\"constants\":[%s]}}"
hash bc consts in
let json_path = (String.sub src_path 0 (String.length src_path - 3)) ^ ".sxbc.json" in
Out_channel.with_open_text json_path (fun oc -> output_string oc json);
let kb = String.length json / 1024 in
Buffer.add_string log (Printf.sprintf " ok %s → %dK\n" file kb);
incr compiled
with e ->
Buffer.add_string log (Printf.sprintf " SKIP %s — %s\n" file (Printexc.to_string e));
incr skipped
end
) files;
let dt = Unix.gettimeofday () -. t0 in
let summary = Printf.sprintf "Done: %d compiled, %d skipped in %.1fs\n%s"
!compiled !skipped dt (Buffer.contents log) in
if !skipped = 0 then
text_result (Printf.sprintf "OK — bytecode compilation succeeded\n%s" summary)
else
text_result (Printf.sprintf "Bytecode compilation partial\n%s" summary)
| "sx_test" ->
let host = args |> member "host" |> to_string_option |> Option.value ~default:"js" in