Fix JIT compile-let shadow binding: evaluate init before defining local
compile-let called scope-define-local eagerly as part of the let binding, adding the new local to the scope before compile-expr ran for the init expression. When nested lets rebound the same variable (e.g. the hyperscript parser's 4 chained `parts` bindings), the init expression resolved the name to the new uninitialized slot instead of the outer one — producing nil where it should have read the previous value. Move scope-define-local after compile-expr so init expressions see the outer scope's binding. Fixes all 11 JIT hyperscript parser failures. 3127/3127 JIT + non-JIT, 25/25 standalone hyperscript tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -599,11 +599,12 @@
|
||||
(binding)
|
||||
(let
|
||||
((name (if (= (type-of (first binding)) "symbol") (symbol-name (first binding)) (first binding)))
|
||||
(value (nth binding 1))
|
||||
(slot (scope-define-local let-scope name)))
|
||||
(value (nth binding 1)))
|
||||
(compile-expr em value let-scope false)
|
||||
(emit-op em 17)
|
||||
(emit-byte em slot)))
|
||||
(let
|
||||
((slot (scope-define-local let-scope name)))
|
||||
(emit-op em 17)
|
||||
(emit-byte em slot))))
|
||||
bindings)
|
||||
(compile-begin em body let-scope tail?)))))
|
||||
(define
|
||||
|
||||
Reference in New Issue
Block a user