WASM kernel fixes: parse, env sync, iterative CEK, click delegation
Browser kernel: - Add `parse` native fn (matches server: unwrap single, list for multiple) - Restore env==global_env guard on _env_bind_hook (let bindings must not leak to _vm_globals — caused JIT CSSX "Not callable: nil" errors) - Add _env_bind_hook call in env_set_id so set! mutations sync to VM globals - Fire _vm_global_set_hook from OP_DEFINE so VM defines sync back to CEK env CEK evaluator: - Replace recursive cek_run with iterative while loop using sx_truthy (previous attempt used strict Bool true matching, broke in wasm_of_ocaml) - Remove dead cek_run_iterative function Web modules: - Remove find-matching-route and parse-route-pattern stubs from boot-helpers.sx that shadowed real implementations from router.sx - Sync boot-helpers.sx to dist/static dirs for bytecode compilation Platform (sx-platform.js): - Set data-sx-ready attribute after boot completes (was only in boot-init which sx-platform.js doesn't call — it steps through boot manually) - Add document-level click delegation for a[sx-get] links as workaround for bytecoded bind-event not attaching per-element listeners (VM closure issue under investigation — bind-event runs but dom-add-listener calls don't result in addEventListener) Tests: - New test_kernel.js: 24 tests covering env sync, parse, route matching, host FFI/preventDefault, deep recursion - New navigation test: "sx-get link fetches SX not HTML and preserves layout" (currently catches layout breakage after SPA swap — known issue) Known remaining issues: - JIT CSSX failures: closure-captured variables resolve to nil in VM bytecode - SPA content swap via execute-request breaks page layout - Bytecoded bind-event doesn't attach per-element addEventListener (root cause unknown — when listen-target guard appears to block despite element being valid) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -216,8 +216,8 @@ let sync_env_to_vm () =
|
||||
) global_env.bindings
|
||||
|
||||
(* Hook: intercept env_bind on global_env to also update _vm_globals.
|
||||
This ensures VmClosures see new definitions immediately, even during
|
||||
a single boot-init call that loads page scripts and components. *)
|
||||
Only sync bindings on the global env — let bindings in child envs
|
||||
must NOT leak into _vm_globals (they'd overwrite real definitions). *)
|
||||
let () =
|
||||
Sx_types._env_bind_hook := Some (fun env name v ->
|
||||
if env == global_env then
|
||||
@@ -476,6 +476,16 @@ let () =
|
||||
| [String src] -> List (Sx_parser.parse_all src)
|
||||
| _ -> raise (Eval_error "sx-parse: expected string"));
|
||||
|
||||
(* parse: same as server — unwraps single results, returns list for multiple.
|
||||
Used by boot.sx (page scripts, suspense) and engine.sx (marsh update). *)
|
||||
bind "parse" (fun args ->
|
||||
match args with
|
||||
| [String src] | [SxExpr src] ->
|
||||
let exprs = Sx_parser.parse_all src in
|
||||
(match exprs with [e] -> e | _ -> List exprs)
|
||||
| [v] -> v
|
||||
| _ -> raise (Eval_error "parse: expected string"));
|
||||
|
||||
bind "sx-serialize" (fun args ->
|
||||
match args with
|
||||
| [v] -> String (inspect v)
|
||||
|
||||
Reference in New Issue
Block a user