Root cause: sx_browser.ml registered all HTML tags (a, b, i, p, s, u, g, etc.)
as custom special forms. The evaluator's step_eval_list checked custom special
forms BEFORE checking local env bindings. So (let ((a (fn () 42))) (a))
matched the HTML tag <a> instead of calling the local function a.
Fix: skip custom special forms AND render-check when the symbol is bound in
the local env. Added (not (env-has? env name)) guard to both checks in
step-eval-list (spec/evaluator.sx and transpiled sx_ref.ml).
This was the root cause of "[sx] resume: Not callable: nil" — after hs-wait
resumed, calling letrec-bound functions like wait-boot (which is not an HTML
tag) worked, but any function whose name collided with an HTML tag failed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bytecode compiler now emits OP_PERFORM for (import ...) and compiles
(define-library ...) bodies. The VM stores the import request in
globals["__io_request"] and stops the run loop — no exceptions needed.
vm-execute-module returns a suspension dict, vm-resume-module continues.
Browser: sx_browser.ml detects suspension dicts from execute_module and
returns JS {suspended, op, request, resume} objects. The sx-platform.js
while loop handles cascading suspensions via handleImportSuspension.
13 modules load via .sxbc bytecode in 226ms (manifest-driven), both
islands hydrate, all handlers wired. 2650/2650 tests pass including
6 new vm-import-suspension tests.
Also: consolidated sx-platform-2.js → sx-platform.js, fixed
vm-execute-module missing code-from-value call, fixed bootstrap.py
protocol registry transpiler issues.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
cssx.sx was deleted in the CSSX → ~tw migration. The test scripts
(test_wasm.sh, test_wasm_native.js, bisect_sxbc.sh) still referenced
it, causing ENOENT during WASM build step 5.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three root causes for reactive attribute updates not propagating in WASM:
1. `context` CEK special form only searched kont provide frames, missing
`scope-push!` entries in the native scope_stacks hashtable. Unified by
adding scope_stacks fallback to step_sf_context.
2. `flush-subscribers` used bare `(sub)` call which failed to invoke
complex closures in for-each HO callbacks. Changed to `(cek-call sub nil)`.
3. Test eagerly evaluated `(deref s)` before render-to-dom saw it.
Fixed tests to use quoted expressions matching real browser boot.
WASM native: 10/10, WASM shell: 26/26.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>