JIT allowlist + integration tests + --test mode + clean up debug logging
JIT allowlist (sx_server.ml): - Replace try-every-lambda strategy with StringSet allowlist. Only functions in the list get JIT compiled (compiler, parser, pure transforms). Render functions that need dynamic scope skip JIT entirely — no retry overhead, no silent fallbacks. - Add (jit-allow name) command for dynamic expansion from Python bridge. - JIT failures log once with "[jit] DISABLED fn — reason" then go silent. Standalone --test mode (sx_server.ml): - New --test flag loads full env (spec + adapters + compiler + signals), supports --eval and --load flags. Quick kernel testing without Docker. Example: dune exec bin/sx_server.exe -- --test --eval '(len HTML_TAGS)' Integration tests (integration_tests.ml): - New binary exercising the full rendering pipeline: loads spec + adapters into a server-like env, renders HTML via both native and SX adapter paths. - 26 tests: HTML tags, special forms (when/if/let), letrec with side effects, component rendering, eval-expr with HTML tag functions. - Would have caught the "Undefined symbol: div/lake/init" issues from the previous commit immediately without Docker. VM cleanup (sx_vm.ml): - Remove temporary debug logging (insn counter, call_closure counter, VmClosure depth tracking) added during debugging. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -568,3 +568,43 @@
|
||||
(assert-equal 3 (len r))
|
||||
(assert-equal (list "a" (list "b") (list "c")) r))))
|
||||
)
|
||||
|
||||
(defsuite "define-as-local"
|
||||
(deftest "define inside fn creates local, not global"
|
||||
;; When define is inside a fn body, recursive calls must each
|
||||
;; get their own copy. If define writes to global, recursive
|
||||
;; calls overwrite each other.
|
||||
(let ((result
|
||||
(let ((counter 0))
|
||||
(letrec
|
||||
((make-counter (fn ()
|
||||
(define my-val counter)
|
||||
(set! counter (inc counter))
|
||||
my-val)))
|
||||
(list (make-counter) (make-counter) (make-counter))))))
|
||||
(assert-equal (list 0 1 2) result)))
|
||||
|
||||
(deftest "define inside fn with self-recursion via define"
|
||||
;; read-list-loop pattern: define a function that calls itself
|
||||
(let ((result
|
||||
(let ((items (list)))
|
||||
(define go (fn (n)
|
||||
(when (< n 3)
|
||||
(append! items n)
|
||||
(go (inc n)))))
|
||||
(go 0)
|
||||
items)))
|
||||
(assert-equal (list 0 1 2) result)))
|
||||
|
||||
(deftest "recursive define inside letrec fn doesn't overwrite"
|
||||
;; Each call to make-list creates its own 'loop' local
|
||||
(let ((make-list (fn (items)
|
||||
(let ((result (list)))
|
||||
(define loop (fn (i)
|
||||
(when (< i (len items))
|
||||
(append! result (nth items i))
|
||||
(loop (inc i)))))
|
||||
(loop 0)
|
||||
result))))
|
||||
(assert-equal (list "a" "b") (make-list (list "a" "b")))
|
||||
(assert-equal (list 1 2 3) (make-list (list 1 2 3))))))
|
||||
|
||||
Reference in New Issue
Block a user