VM: fix nested IO suspension frame corruption, island hydration preload

VM frame merging bug: call_closure_reuse now saves caller continuations
on a reuse_stack instead of merging frames. resume_vm restores them in
innermost-first order. Fixes frame count corruption when nested closures
suspend via OP_PERFORM. Zero test regressions (3924/3924).

Island hydration: hydrate-island now looks up components from (global-env)
instead of render-env, triggering the symbol resolve hook. Added JS-level
preload-island-defs that scans DOM for data-sx-island and loads definitions
from the content-addressed manifest BEFORE hydration — avoids K.load
reentrancy when the resolve hook fires inside env_get.

loadDefinitionByHash: fixed isMultiDefine check — defcomp/defisland bodies
containing nested (define ...) forms no longer suppress name insertion.
Added K.load return value checking for silent error string returns.

sx_browser.ml: resolve hook falls back to global_env.bindings when
_vm_globals miss (sync gap). Snapshot reuse_stack alongside pending_cek.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-16 13:23:35 +00:00
parent 684a46297d
commit c9634ba649
5 changed files with 93 additions and 16 deletions

View File

@@ -280,6 +280,7 @@
(root)
(let
((els (dom-query-all (or root (dom-body)) "[data-sx-island]")))
(preload-island-defs)
(log-info
(str
"sx-hydrate-islands: "
@@ -313,7 +314,7 @@
(let
((comp-name (str "~" name)) (env (get-render-env nil)))
(let
((comp (env-get env comp-name)))
((comp (env-get (global-env) comp-name)))
(if
(not (or (component? comp) (island? comp)))
(log-warn (str "hydrate-island: unknown island " comp-name))