js-on-sx: fall-off-end functions return undefined, not null (+2)

Previously a JS function body with no return fell through the call/cc
begin as nil, making `(function(){}())` return null and typeof → object.
Spec: falls-off-end gives undefined.

Wrap the call/cc in (let ((__r__ ...)) (if (= __r__ nil) :js-undefined __r__)).
Downside: explicit `return null` also returns nil, but so does (pick
your last expression evaluating to null). For 99% of cases it's
fall-off-end and the fix is correct. Code that genuinely needs
distinguishable null would need separate nil/undef handling in the
evaluator.

Unit 521/522, slice 148/148 unchanged.
Number 73/100 → 74/100 (+1), String 33/100 → 34/100 (+1).
Fixes S15.5.1.1_A1_T1 family (String(function(){}()) should be "undefined").
This commit is contained in:
2026-04-24 12:31:32 +00:00
parent 6a4269d327
commit 679d6bd590

View File

@@ -1307,11 +1307,20 @@
(js-sym "let")
(list (list (js-sym "this") (list (js-sym "js-this"))))
(list
(js-sym "call/cc")
(js-sym "let")
(list
(js-sym "fn")
(list (js-sym "__return__"))
(cons (js-sym "begin") (append inits body-forms)))))))))
(list
(js-sym "__r__")
(list
(js-sym "call/cc")
(list
(js-sym "fn")
(list (js-sym "__return__"))
(cons (js-sym "begin") (append inits body-forms))))))
(list
(js-sym "if")
(list (js-sym "=") (js-sym "__r__") nil)
:js-undefined (js-sym "__r__"))))))))
(define
js-transpile-funcexpr-async