From bf09055c4ef9f9e61fd4be16b3fd0a17f7191298 Mon Sep 17 00:00:00 2001 From: giles Date: Fri, 24 Apr 2026 11:59:47 +0000 Subject: [PATCH] js-on-sx: new Number/String/Array link to ctor.prototype (+5 Number) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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). --- lib/js/runtime.sx | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/js/runtime.sx b/lib/js/runtime.sx index 080f937a..b8bbf7b8 100644 --- a/lib/js/runtime.sx +++ b/lib/js/runtime.sx @@ -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