Fix core-signals bytecode: letrec for self-ref, explicit get for dict destructuring
Two issues prevented core-signals.sx from working as bytecode:
1. computed/effect used (let) for self-referencing bindings (recompute,
run-effect). Changed to (letrec) so the VM pre-allocates slots before
compiling the lambda bodies — required for self-reference in bytecode.
2. deref used dict destructuring (let {:notify n :deps d} ctx ...) which
the transpiled OCaml compiler doesn't support. Rewrote to explicit
(get ctx "notify") / (get ctx "deps") calls.
Also fixed compile-let dict destructuring opcodes (OP_CONST=1 not 2,
OP_CALL_PRIM=52 not 10) for future use when compiler is retranspiled.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -614,13 +614,10 @@
|
||||
(str k))))
|
||||
(emit-op em 16)
|
||||
(emit-byte em temp-slot)
|
||||
(let
|
||||
((key-idx (pool-add (get em "pool") key-str)))
|
||||
(emit-op em 2)
|
||||
(emit-u16 em key-idx))
|
||||
(emit-const em key-str)
|
||||
(let
|
||||
((get-idx (pool-add (get em "pool") "get")))
|
||||
(emit-op em 10)
|
||||
(emit-op em 52)
|
||||
(emit-u16 em get-idx)
|
||||
(emit-byte em 2))
|
||||
(let
|
||||
|
||||
@@ -614,13 +614,10 @@
|
||||
(str k))))
|
||||
(emit-op em 16)
|
||||
(emit-byte em temp-slot)
|
||||
(let
|
||||
((key-idx (pool-add (get em "pool") key-str)))
|
||||
(emit-op em 2)
|
||||
(emit-u16 em key-idx))
|
||||
(emit-const em key-str)
|
||||
(let
|
||||
((get-idx (pool-add (get em "pool") "get")))
|
||||
(emit-op em 10)
|
||||
(emit-op em 52)
|
||||
(emit-u16 em get-idx)
|
||||
(emit-byte em 2))
|
||||
(let
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -83,8 +83,8 @@
|
||||
(when
|
||||
ctx
|
||||
(let
|
||||
{:notify notify-fn :deps dep-list}
|
||||
ctx
|
||||
((notify-fn (get ctx "notify"))
|
||||
(dep-list (get ctx "deps")))
|
||||
(when
|
||||
(not (contains? dep-list s))
|
||||
(append! dep-list s)
|
||||
@@ -124,7 +124,7 @@
|
||||
((compute-fn :as lambda))
|
||||
(let
|
||||
((s (make-signal nil)) (deps (list)) (compute-ctx nil))
|
||||
(let
|
||||
(letrec
|
||||
((recompute (fn () (for-each (fn ((dep :as signal)) (signal-remove-sub! dep recompute)) (signal-deps s)) (signal-set-deps! s (list)) (let ((ctx (dict "deps" (list) "notify" recompute))) (scope-push! "sx-reactive" ctx) (let ((new-val (cek-call compute-fn nil))) (scope-pop! "sx-reactive") (signal-set-deps! s (get ctx "deps")) (let ((old (signal-value s))) (signal-set-value! s new-val) (when (not (identical? old new-val)) (notify-subscribers s))))))))
|
||||
(recompute)
|
||||
(register-in-scope (fn () (dispose-computed s)))
|
||||
@@ -136,7 +136,7 @@
|
||||
((effect-fn :as lambda))
|
||||
(let
|
||||
((deps (list)) (disposed false) (cleanup-fn nil))
|
||||
(let
|
||||
(letrec
|
||||
((run-effect (fn () (when (not disposed) (when cleanup-fn (cek-call cleanup-fn nil)) (for-each (fn ((dep :as signal)) (signal-remove-sub! dep run-effect)) deps) (set! deps (list)) (let ((ctx (dict "deps" (list) "notify" run-effect))) (scope-push! "sx-reactive" ctx) (let ((result (cek-call effect-fn nil))) (scope-pop! "sx-reactive") (set! deps (get ctx "deps")) (when (callable? result) (set! cleanup-fn result))))))))
|
||||
(run-effect)
|
||||
(let
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -83,8 +83,8 @@
|
||||
(when
|
||||
ctx
|
||||
(let
|
||||
{:notify notify-fn :deps dep-list}
|
||||
ctx
|
||||
((notify-fn (get ctx "notify"))
|
||||
(dep-list (get ctx "deps")))
|
||||
(when
|
||||
(not (contains? dep-list s))
|
||||
(append! dep-list s)
|
||||
@@ -124,7 +124,7 @@
|
||||
((compute-fn :as lambda))
|
||||
(let
|
||||
((s (make-signal nil)) (deps (list)) (compute-ctx nil))
|
||||
(let
|
||||
(letrec
|
||||
((recompute (fn () (for-each (fn ((dep :as signal)) (signal-remove-sub! dep recompute)) (signal-deps s)) (signal-set-deps! s (list)) (let ((ctx (dict "deps" (list) "notify" recompute))) (scope-push! "sx-reactive" ctx) (let ((new-val (cek-call compute-fn nil))) (scope-pop! "sx-reactive") (signal-set-deps! s (get ctx "deps")) (let ((old (signal-value s))) (signal-set-value! s new-val) (when (not (identical? old new-val)) (notify-subscribers s))))))))
|
||||
(recompute)
|
||||
(register-in-scope (fn () (dispose-computed s)))
|
||||
@@ -136,7 +136,7 @@
|
||||
((effect-fn :as lambda))
|
||||
(let
|
||||
((deps (list)) (disposed false) (cleanup-fn nil))
|
||||
(let
|
||||
(letrec
|
||||
((run-effect (fn () (when (not disposed) (when cleanup-fn (cek-call cleanup-fn nil)) (for-each (fn ((dep :as signal)) (signal-remove-sub! dep run-effect)) deps) (set! deps (list)) (let ((ctx (dict "deps" (list) "notify" run-effect))) (scope-push! "sx-reactive" ctx) (let ((result (cek-call effect-fn nil))) (scope-pop! "sx-reactive") (set! deps (get ctx "deps")) (when (callable? result) (set! cleanup-fn result))))))))
|
||||
(run-effect)
|
||||
(let
|
||||
|
||||
Reference in New Issue
Block a user