js-on-sx: new Number/String/Array link to ctor.prototype (+5 Number)

js-get-ctor-proto used to always synthesise a per-ctor-id empty dict in
__js_proto_table__, ignoring the :prototype slot that every built-in
constructor dict (Number, String, Array, Boolean, Object, Function)
already carries. So `new Number()` got `{__proto__: {}}` instead of
`{__proto__: Number.prototype}`, breaking every prototype-chain-method
lookup:

  (new Number()).toLocaleString            // undefined → function
  (new Number()).toLocaleString === Number.prototype.toLocaleString

Fix: when the receiver is a dict with a "prototype" key, return that
directly; otherwise fall through to the existing proto-table path.
Declared classes from JS still go through the table because they emit
js-set-ctor-proto! at definition.

Unit 521/522, slice 148/148 unchanged.
Number scoreboard: 53/100 → 58/100 (+5). Sample: S15.7.5_A1_T03..T07
(toLocaleString/toString/toFixed/toExponential prototype identity).
This commit is contained in:
2026-04-24 11:59:47 +00:00
parent f63934b15e
commit bf09055c4e

View File

@@ -739,12 +739,18 @@
js-get-ctor-proto
(fn
(ctor)
(let
((id (js-ctor-id ctor)))
(cond
((dict-has? __js_proto_table__ id) (get __js_proto_table__ id))
(else
(let ((p (dict))) (begin (dict-set! __js_proto_table__ id p) p)))))))
(cond
((and (= (type-of ctor) "dict") (contains? (keys ctor) "prototype"))
(get ctor "prototype"))
(else
(let
((id (js-ctor-id ctor)))
(cond
((dict-has? __js_proto_table__ id) (get __js_proto_table__ id))
(else
(let
((p (dict)))
(begin (dict-set! __js_proto_table__ id p) p)))))))))
(define
js-reset-ctor-proto!
(fn