WASM rebuild: VM reuse_stack fix + boot.sxbc hydration + island preload

Recompiled WASM kernel (wasm_of_ocaml) to include the VM reuse_stack
fix from sx_vm.ml. Recompiled boot.sxbc with the clear-and-replace
hydration (replaceChildren + nil hydrating scope + dom-append).

sx-platform.js deployed with island preload, isMultiDefine fix, and
K.load error checking.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-16 15:21:11 +00:00
parent 87fdb1db71
commit 6f374fabce
4 changed files with 249 additions and 202 deletions

View File

@@ -846,7 +846,11 @@
// already contain named (define name ...) forms.
var name = _hashToName[hash];
if (name) {
var isMultiDefine = /\(define\s+[a-zA-Z]/.test(rewritten);
// Check if this is a multi-define file (client lib with top-level defines).
// Only top-level (define ...) forms count — nested ones inside defisland/defcomp
// bodies should NOT suppress name insertion.
var startsWithDef = /^\((defcomp|defisland|defmacro)\s/.test(rewritten);
var isMultiDefine = !startsWithDef && /\(define\s+[a-zA-Z]/.test(rewritten);
if (!isMultiDefine) {
rewritten = rewritten.replace(
/^\((defcomp|defisland|defmacro|define)\s/,
@@ -856,7 +860,12 @@
}
try {
K.load(rewritten);
var loadRv = K.load(rewritten);
if (typeof loadRv === "string" && loadRv.indexOf("Error") >= 0) {
console.warn("[sx] K.load error for", (_hashToName[hash] || hash) + ":", loadRv);
delete _loadedHashes[hash];
return false;
}
_loadedHashes[hash] = true;
return true;
} catch(e) {
@@ -865,11 +874,28 @@
}
}
// Eagerly pre-load island definitions from the manifest.
// Called from boot.sx before hydration. Scans the DOM for data-sx-island
// attributes and loads definitions via the content-addressed manifest.
// Unlike __resolve-symbol (called from inside env_get), this runs at the
// top level so K.load can register bindings without reentrancy issues.
K.registerNative("preload-island-defs", function() {
var manifest = loadPageManifest();
if (!manifest || !manifest.defs) return null;
var els = document.querySelectorAll('[data-sx-island]');
for (var i = 0; i < els.length; i++) {
var name = "~" + els[i].getAttribute("data-sx-island");
if (manifest.defs[name] && !_loadedHashes[manifest.defs[name]]) {
loadDefinitionByHash(manifest.defs[name]);
}
}
return null;
});
// Register the resolve hook — called by the VM when GLOBAL_GET fails
K.registerNative("__resolve-symbol", function(args) {
var name = args[0];
if (!name) return null;
// Content-addressed resolution — components, libraries, macros
var manifest = loadPageManifest();
if (manifest && manifest.defs && manifest.defs[name]) {
@@ -918,6 +944,20 @@
K.eval("(process-sx-scripts nil)");
console.log("[sx] sx-hydrate-elements...");
K.eval("(sx-hydrate-elements nil)");
// Pre-load island definitions from manifest before hydration.
// Must happen at JS level (not from inside SX eval) to avoid
// K.load reentrancy issues with the symbol resolve hook.
var manifest = loadPageManifest();
if (manifest && manifest.defs) {
var islandEls = document.querySelectorAll("[data-sx-island]");
for (var ii = 0; ii < islandEls.length; ii++) {
var iname = "~" + islandEls[ii].getAttribute("data-sx-island");
var ihash = manifest.defs[iname];
if (ihash && !_loadedHashes[ihash]) {
loadDefinitionByHash(ihash);
}
}
}
console.log("[sx] sx-hydrate-islands...");
K.eval("(sx-hydrate-islands nil)");
console.log("[sx] process-elements...");

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1792,7 +1792,7 @@
blake2_js_for_wasm_create: blake2_js_for_wasm_create};
}
(globalThis))
({"link":[["runtime-0db9b496",0],["prelude-d7e4b000",0],["stdlib-23ce0836",[]],["re-9a0de245",[2]],["sx-faa4f9b6",[2,3]],["jsoo_runtime-f96b44a8",[2]],["js_of_ocaml-651f6707",[2,5]],["dune__exe__Sx_browser-efe9c27c",[2,4,6]],["std_exit-10fb8830",[2]],["start-f808dbe1",0]],"generated":(b=>{var
({"link":[["runtime-0db9b496",0],["prelude-d7e4b000",0],["stdlib-23ce0836",[]],["re-9a0de245",[2]],["sx-3eef5187",[2,3]],["jsoo_runtime-f96b44a8",[2]],["js_of_ocaml-651f6707",[2,5]],["dune__exe__Sx_browser-d641d5ea",[2,4,6]],["std_exit-10fb8830",[2]],["start-f808dbe1",0]],"generated":(b=>{var
c=b,a=b?.module?.export||b;return{"env":{"caml_ba_kind_of_typed_array":()=>{throw new
Error("caml_ba_kind_of_typed_array not implemented")},"caml_exn_with_js_backtrace":()=>{throw new
Error("caml_exn_with_js_backtrace not implemented")},"caml_int64_create_lo_mi_hi":()=>{throw new