Fix server import suspension, dist sync, JIT errors

- cek_run patched to handle import suspensions via _import_hook.
  define-library (import ...) now resolves cleanly on the server.
  IO suspension errors: 190 → 0. JIT failures: ~50 → 0.
- _import_hook wired in sx_server.ml to load .sx files on demand.
- compile-modules.js syncs source .sx files to dist/sx/ before
  compiling — eliminates stale bytecode from out-of-date copies.
- WASM binary rebuilt with all fixes.
- 2658/2658 tests pass (8 new — previously failing import tests).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-04 22:52:41 +00:00
parent b0a4be0f22
commit 5ac1ca9756
11 changed files with 480 additions and 408 deletions

View File

@@ -79,35 +79,35 @@
(fn
(vm value)
(let
((sp (get vm "sp")) (stack (get vm "stack")))
((sp (vm-sp vm)) (stack (vm-stack vm)))
(when
(>= sp (vm-stack-length stack))
(let
((new-stack (make-vm-stack (* sp 2))))
((new-stack (vm-stack-grow stack sp)))
(vm-stack-copy! stack new-stack sp)
(dict-set! vm "stack" new-stack)
(vm-set-stack! vm new-stack)
(set! stack new-stack)))
(vm-stack-set! stack sp value)
(dict-set! vm "sp" (+ sp 1)))))
(vm-set-sp! vm (+ sp 1)))))
(define
vm-pop
(fn
(vm)
(let
((sp (- (get vm "sp") 1)))
(dict-set! vm "sp" sp)
(vm-stack-get (get vm "stack") sp))))
((sp (- (vm-sp vm) 1)))
(vm-set-sp! vm sp)
(vm-stack-get (vm-stack vm) sp))))
(define
vm-peek
(fn (vm) (vm-stack-get (get vm "stack") (- (get vm "sp") 1))))
(fn (vm) (vm-stack-get (vm-stack vm) (- (vm-sp vm) 1))))
(define
frame-read-u8
(fn
(frame)
(let
((ip (get frame "ip"))
(bc (get (get (get frame "closure") "vm-code") "vc-bytecode")))
(let ((v (nth bc ip))) (dict-set! frame "ip" (+ ip 1)) v))))
((ip (frame-ip frame))
(bc (-> frame frame-closure closure-code code-bytecode)))
(let ((v (nth bc ip))) (frame-set-ip! frame (+ ip 1)) v))))
(define
frame-read-u16
(fn
@@ -206,31 +206,28 @@
(if
(has-key? cells key)
(uv-get (get cells key))
(vm-stack-get (get vm "stack") (+ (get frame "base") slot))))))
(vm-stack-get (vm-stack vm) (+ (frame-base frame) slot))))))
(define
frame-local-set
(fn
(vm frame slot value)
"Write a local variable — to shared cell if captured, else to stack."
"Write a local variable — to shared cell or stack."
(let
((cells (get frame "local-cells")) (key (str slot)))
(if
(has-key? cells key)
(uv-set! (get cells key) value)
(vm-stack-set!
(get vm "stack")
(+ (get frame "base") slot)
value)))))
(vm-stack-set! (vm-stack vm) (+ (frame-base frame) slot) value)))))
(define
frame-upvalue-get
(fn
(frame idx)
(uv-get (nth (get (get frame "closure") "vm-upvalues") idx))))
(uv-get (nth (-> frame frame-closure closure-upvalues) idx))))
(define
frame-upvalue-set
(fn
(frame idx value)
(uv-set! (nth (get (get frame "closure") "vm-upvalues") idx) value)))
(uv-set! (nth (-> frame frame-closure closure-upvalues) idx) value)))
(define frame-ip (fn (frame) (get frame "ip")))
(define frame-set-ip! (fn (frame val) (dict-set! frame "ip" val)))
(define frame-base (fn (frame) (get frame "base")))
@@ -302,12 +299,12 @@
(vm frame name)
"Look up a global: globals table → closure env → primitives → HO wrappers"
(let
((globals (get vm "globals")))
((globals (vm-globals-ref vm)))
(if
(has-key? globals name)
(get globals name)
(let
((closure-env (get (get frame "closure") "closure-env")))
((closure-env (-> frame frame-closure closure-env)))
(if
(nil? closure-env)
(cek-try
@@ -325,41 +322,42 @@
vm-resolve-ho-form
(fn
(vm name)
(cond
(= name "for-each")
(fn
(f coll)
(for-each (fn (x) (vm-call-external vm f (list x))) coll))
(= name "map")
(fn
(f coll)
(map (fn (x) (vm-call-external vm f (list x))) coll))
(= name "map-indexed")
(fn
(f coll)
(map-indexed
(fn (i x) (vm-call-external vm f (list i x)))
coll))
(= name "filter")
(fn
(f coll)
(filter (fn (x) (vm-call-external vm f (list x))) coll))
(= name "reduce")
(fn
(f init coll)
(reduce
(fn (acc x) (vm-call-external vm f (list acc x)))
init
coll))
(= name "some")
(fn
(f coll)
(some (fn (x) (vm-call-external vm f (list x))) coll))
(= name "every?")
(fn
(f coll)
(every? (fn (x) (vm-call-external vm f (list x))) coll))
:else (error (str "VM undefined: " name)))))
(match
name
("for-each"
(fn
(f coll)
(for-each (fn (x) (vm-call-external vm f (list x))) coll)))
("map"
(fn
(f coll)
(map (fn (x) (vm-call-external vm f (list x))) coll)))
("map-indexed"
(fn
(f coll)
(map-indexed
(fn (i x) (vm-call-external vm f (list i x)))
coll)))
("filter"
(fn
(f coll)
(filter (fn (x) (vm-call-external vm f (list x))) coll)))
("reduce"
(fn
(f init coll)
(reduce
(fn (acc x) (vm-call-external vm f (list acc x)))
init
coll)))
("some"
(fn
(f coll)
(some (fn (x) (vm-call-external vm f (list x))) coll)))
("every?"
(fn
(f coll)
(every? (fn (x) (vm-call-external vm f (list x))) coll)))
(_ (error (str "VM undefined: " name))))))
(define
vm-call-external
(fn
@@ -372,14 +370,14 @@
vm-global-set
(fn
(vm frame name value)
"Set a global: write to closure env if name exists there, else globals."
"Set a global: write to closure env if found, else globals table."
(let
((closure-env (get (get frame "closure") "vm-closure-env"))
((closure-env (get (frame-closure frame) "vm-closure-env"))
(written false))
(when
(not (nil? closure-env))
(set! written (env-walk-set! closure-env name value)))
(when (not written) (dict-set! (get vm "globals") name value)))))
(when (not written) (dict-set! (vm-globals-ref vm) name value)))))
(define
env-walk
(fn
@@ -414,20 +412,15 @@
(let
((code (code-from-value code-val))
(uv-count
(if
(dict? code-val)
(let
((n (get code-val "upvalue-count")))
(if (nil? n) 0 n))
0)))
(if (dict? code-val) (or (get code-val "upvalue-count") 0) 0)))
(let
((upvalues (let ((result (list)) (i 0)) (define capture-loop (fn () (when (< i uv-count) (let ((is-local (frame-read-u8 frame)) (index (frame-read-u8 frame))) (let ((cell (if (= is-local 1) (let ((cells (get frame "local-cells")) (key (str index))) (if (has-key? cells key) (get cells key) (let ((c (make-upvalue-cell (vm-stack-get (get vm "stack") (+ (get frame "base") index))))) (dict-set! cells key c) c))) (nth (get (get frame "closure") "vm-upvalues") index)))) (append! result cell) (set! i (+ i 1)) (capture-loop)))))) (capture-loop) result)))
(make-vm-closure code upvalues nil (get vm "globals") nil)))))
((upvalues (let ((result (list)) (i 0)) (define capture-loop (fn () (when (< i uv-count) (let ((is-local (frame-read-u8 frame)) (index (frame-read-u8 frame))) (let ((cell (if (= is-local 1) (let ((cells (get frame "local-cells")) (key (str index))) (if (has-key? cells key) (get cells key) (let ((c (make-upvalue-cell (vm-stack-get (vm-stack vm) (+ (frame-base frame) index))))) (dict-set! cells key c) c))) (nth (-> frame frame-closure closure-upvalues) index)))) (append! result cell) (set! i (+ i 1)) (capture-loop)))))) (capture-loop) result)))
(make-vm-closure code upvalues nil (vm-globals-ref vm) nil)))))
(define
vm-run
(fn
(vm)
"Execute bytecode until all frames are consumed."
"Execute bytecode until all frames are done or IO suspension."
(define
loop
(fn
@@ -438,9 +431,9 @@
((frame (first (vm-frames vm)))
(rest-frames (rest (vm-frames vm))))
(let
((bc (code-bytecode (closure-code (frame-closure frame))))
((bc (-> frame frame-closure closure-code code-bytecode))
(consts
(code-constants (closure-code (frame-closure frame)))))
(-> frame frame-closure closure-code code-constants)))
(if
(>= (frame-ip frame) (len bc))
(vm-set-frames! vm (list))