Fix isomorphic SSR: revert inline opcodes, add named let compilation, fix cookie decode
Three bugs broke island SSR rendering of the home stepper widget: 1. Inline VM opcodes (OP_ADD..OP_DEC) broke JIT-compiled functions. The compiler emitted single-byte opcodes for first/rest/len/= etc. that produced wrong results in complex recursive code (sx-parse returned nil, split-tag produced 1 step instead of 16). Reverted compiler to use CALL_PRIM for all primitives. VM opcode handlers kept for future use. 2. Named let (let loop ((x init)) body) had no compiler support — silently produced broken bytecode. Added desugaring to letrec. 3. URL-encoded cookie values not decoded server-side. Client set-cookie uses encodeURIComponent but Werkzeug doesn't decode cookie values. Added unquote() in bridge cookie injection. Also: call-lambda used eval_expr which copies Dict values (signals), breaking mutations through aser lambda calls. Switched to cek_call. Also: stepper preview now includes ~cssx/tw spreads for SSR styling. Tests: 1317 JS, 1114 OCaml, 26 integration (2 pre-existing failures) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -432,3 +432,37 @@
|
||||
(render-sx
|
||||
"(do (defcomp ~page (&key x) (div x))
|
||||
(case \"miss\" \"hit\" (~page :x \"found\") :else \"index\"))"))))
|
||||
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Dict mutation through lambda calls in aser body
|
||||
;; --------------------------------------------------------------------------
|
||||
;;
|
||||
;; Regression: aser's :else branch used call-lambda which re-evaluated
|
||||
;; args through eval_expr. The CEK evaluator copies Dict values during
|
||||
;; evaluation (treating them as dict literals), so mutations inside the
|
||||
;; lambda operated on a copy, not the original. This broke signal
|
||||
;; reset!/swap! in island SSR where aser processes multi-body let forms.
|
||||
|
||||
(defsuite "aser-dict-mutation"
|
||||
(deftest "lambda mutating dict arg in multi-body let"
|
||||
(assert-equal "99"
|
||||
(render-sx
|
||||
"(let ((mutate! (fn (d k v) (dict-set! d k v)))
|
||||
(d (dict \"x\" 1)))
|
||||
(mutate! d \"x\" 99)
|
||||
(get d \"x\"))")))
|
||||
|
||||
(deftest "signal reset! in multi-body let"
|
||||
(assert-equal "99"
|
||||
(render-sx
|
||||
"(let ((s (signal 42)))
|
||||
(reset! s 99)
|
||||
(deref s))")))
|
||||
|
||||
(deftest "signal reset! then len of deref in multi-body let"
|
||||
(assert-equal "3"
|
||||
(render-sx
|
||||
"(let ((s (signal (list))))
|
||||
(reset! s (list 1 2 3))
|
||||
(len (deref s)))"))))
|
||||
|
||||
Reference in New Issue
Block a user