VM import suspension for browser lazy loading
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>
This commit is contained in:
1636
lib/compiler.sx
1636
lib/compiler.sx
File diff suppressed because it is too large
Load Diff
37
lib/vm.sx
37
lib/vm.sx
@@ -62,7 +62,8 @@
|
||||
vm-run
|
||||
vm-step
|
||||
vm-call-closure
|
||||
vm-execute-module)
|
||||
vm-execute-module
|
||||
vm-resume-module)
|
||||
(begin
|
||||
(define make-upvalue-cell (fn (value) {:uv-value value}))
|
||||
(define uv-get (fn (cell) (get cell "uv-value")))
|
||||
@@ -443,7 +444,11 @@
|
||||
(if
|
||||
(>= (frame-ip frame) (len bc))
|
||||
(vm-set-frames! vm (list))
|
||||
(do (vm-step vm frame rest-frames bc consts) (loop))))))))
|
||||
(do
|
||||
(vm-step vm frame rest-frames bc consts)
|
||||
(when
|
||||
(nil? (get (vm-globals-ref vm) "__io_request"))
|
||||
(loop)))))))))
|
||||
(loop)))
|
||||
(define
|
||||
vm-step
|
||||
@@ -595,8 +600,7 @@
|
||||
(= op 112)
|
||||
(let
|
||||
((request (vm-pop vm)))
|
||||
(error
|
||||
(str "VM: IO suspension (OP_PERFORM) — request: " request)))
|
||||
(dict-set! (vm-globals-ref vm) "__io_request" request))
|
||||
:else (error (str "VM: unknown opcode " op))))))
|
||||
(define
|
||||
vm-call-closure
|
||||
@@ -614,14 +618,29 @@
|
||||
(fn
|
||||
(code globals)
|
||||
(let
|
||||
((closure (make-vm-closure code (list) "module" globals nil))
|
||||
(vm (make-vm globals)))
|
||||
((vm-code (code-from-value code)) (vm (make-vm globals)))
|
||||
(let
|
||||
((frame (make-vm-frame closure 0)))
|
||||
(pad-n-nils vm (code-locals code))
|
||||
((closure (make-vm-closure vm-code (list) "module" globals nil))
|
||||
(frame (make-vm-frame closure 0)))
|
||||
(pad-n-nils vm (code-locals vm-code))
|
||||
(vm-set-frames! vm (list frame))
|
||||
(vm-run vm)
|
||||
(vm-pop vm))))))) ;; end define-library
|
||||
(let
|
||||
((io-req (get (vm-globals-ref vm) "__io_request")))
|
||||
(if (nil? io-req) (vm-pop vm) {:vm vm :suspended true :op "import" :request io-req}))))))
|
||||
(define
|
||||
vm-resume-module
|
||||
(fn
|
||||
(suspended-result)
|
||||
"Resume a suspended VM after IO (import) has been resolved.\n Clears __io_request in globals, pushes nil (import result), re-runs."
|
||||
(let
|
||||
((vm (get suspended-result :vm)))
|
||||
(dict-set! (vm-globals-ref vm) "__io_request" nil)
|
||||
(vm-push vm nil)
|
||||
(vm-run vm)
|
||||
(let
|
||||
((io-req (get (vm-globals-ref vm) "__io_request")))
|
||||
(if (nil? io-req) (vm-pop vm) {:vm vm :suspended true :op "import" :request io-req}))))))) ;; end define-library
|
||||
|
||||
;; Re-export to global namespace for backward compatibility
|
||||
(import (sx vm))
|
||||
|
||||
Reference in New Issue
Block a user