js-on-sx: Object.prototype.toString dispatches by [[Class]]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 23s

Was hardcoded to "[object Object]" for everything; per ES it should
return "[object Array]", "[object Function]", "[object Number]",
etc. by class. Added js-object-tostring-class helper that switches
on type-of and dict-internal markers (__js_*_value__,
__callable__). Prototype-identity checks ensure
Object.prototype.toString.call(Number.prototype) returns
"[object Number]" (similar for String/Boolean/Array).
built-ins/Array: 18/45 → 20/45, built-ins/Number: 43/50 → 44/50.
conformance.sh: 148/148.
This commit is contained in:
2026-05-08 04:26:37 +00:00
parent fb0ca374a3
commit 8d9ce7838d
4 changed files with 72 additions and 19 deletions

View File

@@ -942,6 +942,32 @@
"function")
(else "object"))))
(define
js-object-tostring-class
(fn
(v)
(cond
((js-undefined? v) "[object Undefined]")
((= v nil) "[object Null]")
((= (type-of v) "list") "[object Array]")
((= (type-of v) "string") "[object String]")
((= (type-of v) "number") "[object Number]")
((= (type-of v) "boolean") "[object Boolean]")
((or (= (type-of v) "lambda") (= (type-of v) "function") (= (type-of v) "component"))
"[object Function]")
((= (type-of v) "dict")
(cond
((contains? (keys v) "__callable__") "[object Function]")
((contains? (keys v) "__js_string_value__") "[object String]")
((contains? (keys v) "__js_number_value__") "[object Number]")
((contains? (keys v) "__js_boolean_value__") "[object Boolean]")
((= v (get Number "prototype")) "[object Number]")
((= v (get String "prototype")) "[object String]")
((= v (get Boolean "prototype")) "[object Boolean]")
((= v (get Array "prototype")) "[object Array]")
(else "[object Object]")))
(else "[object Object]"))))
(define
js-to-boolean
(fn
@@ -3444,7 +3470,7 @@
(and (>= idx 0) (< idx (len o)) (integer? idx))))
(else false))))
(define Object {:keys js-object-keys :getPrototypeOf js-object-get-prototype-of :isSealed js-object-is-sealed :seal js-object-seal :create js-object-create :isExtensible js-object-is-extensible :is js-object-is :setPrototypeOf js-object-set-prototype-of :getOwnPropertyNames js-object-get-own-property-names :getOwnPropertyDescriptors js-object-get-own-property-descriptors :defineProperty js-object-define-property :fromEntries js-object-from-entries :getOwnPropertyDescriptor js-object-get-own-property-descriptor :assign js-object-assign :isFrozen js-object-is-frozen :freeze js-object-freeze :values js-object-values :hasOwn js-object-has-own :prototype {:hasOwnProperty (fn (k) (let ((o (js-this))) (js-object-has-own o k))) :toLocaleString (fn () "[object Object]") :isPrototypeOf (fn (o) (let ((this-val (js-this))) (cond ((not (dict? o)) false) (else (let ((proto (if (contains? (keys o) "__proto__") (get o "__proto__") nil))) (cond ((= proto this-val) true) ((= proto nil) false) (else ((get (get Object "prototype") "isPrototypeOf") proto)))))))) :toString (fn () "[object Object]") :propertyIsEnumerable (fn (k) (let ((o (js-this))) (js-object-has-own o k))) :valueOf (fn () (js-this))} :__callable__ (fn (&rest args) (let ((this-val (js-this))) (let ((is-new (and (dict? this-val) (contains? (keys this-val) "__proto__") (= (get this-val "__proto__") (get Object "prototype"))))) (cond ((= (len args) 0) (if is-new this-val (dict))) ((or (= (nth args 0) nil) (js-undefined? (nth args 0))) (if is-new this-val (dict))) ((= (type-of (nth args 0)) "string") (js-new-call String (list (nth args 0)))) ((= (js-typeof (nth args 0)) "number") (js-new-call Number (list (nth args 0)))) ((= (js-typeof (nth args 0)) "boolean") (js-new-call Boolean (list (nth args 0)))) (else (nth args 0)))))) :preventExtensions js-object-prevent-extensions :entries js-object-entries :defineProperties js-object-define-properties})
(define Object {:keys js-object-keys :getPrototypeOf js-object-get-prototype-of :isSealed js-object-is-sealed :seal js-object-seal :create js-object-create :isExtensible js-object-is-extensible :is js-object-is :setPrototypeOf js-object-set-prototype-of :getOwnPropertyNames js-object-get-own-property-names :getOwnPropertyDescriptors js-object-get-own-property-descriptors :defineProperty js-object-define-property :fromEntries js-object-from-entries :getOwnPropertyDescriptor js-object-get-own-property-descriptor :assign js-object-assign :isFrozen js-object-is-frozen :freeze js-object-freeze :values js-object-values :hasOwn js-object-has-own :prototype {:hasOwnProperty (fn (k) (let ((o (js-this))) (js-object-has-own o k))) :toLocaleString (fn () "[object Object]") :isPrototypeOf (fn (o) (let ((this-val (js-this))) (cond ((not (dict? o)) false) (else (let ((proto (if (contains? (keys o) "__proto__") (get o "__proto__") nil))) (cond ((= proto this-val) true) ((= proto nil) false) (else ((get (get Object "prototype") "isPrototypeOf") proto)))))))) :toString (fn () (js-object-tostring-class (js-this))) :propertyIsEnumerable (fn (k) (let ((o (js-this))) (js-object-has-own o k))) :valueOf (fn () (js-this))} :__callable__ (fn (&rest args) (let ((this-val (js-this))) (let ((is-new (and (dict? this-val) (contains? (keys this-val) "__proto__") (= (get this-val "__proto__") (get Object "prototype"))))) (cond ((= (len args) 0) (if is-new this-val (dict))) ((or (= (nth args 0) nil) (js-undefined? (nth args 0))) (if is-new this-val (dict))) ((= (type-of (nth args 0)) "string") (js-new-call String (list (nth args 0)))) ((= (js-typeof (nth args 0)) "number") (js-new-call Number (list (nth args 0)))) ((= (js-typeof (nth args 0)) "boolean") (js-new-call Boolean (list (nth args 0)))) (else (nth args 0)))))) :preventExtensions js-object-prevent-extensions :entries js-object-entries :defineProperties js-object-define-properties})
(dict-set! Object "length" 1)

View File

@@ -1,27 +1,45 @@
{
"totals": {
"pass": 45,
"fail": 0,
"skip": 5,
"timeout": 0,
"pass": 44,
"fail": 3,
"skip": 0,
"timeout": 3,
"total": 50,
"runnable": 45,
"pass_rate": 100.0
"runnable": 50,
"pass_rate": 88.0
},
"categories": [
{
"category": "built-ins/Math",
"category": "built-ins/Number",
"total": 50,
"pass": 45,
"fail": 0,
"skip": 5,
"timeout": 0,
"pass_rate": 100.0,
"top_failures": []
"pass": 44,
"fail": 3,
"skip": 0,
"timeout": 3,
"pass_rate": 88.0,
"top_failures": [
[
"Timeout",
3
],
[
"Test262Error (assertion failed)",
3
]
]
}
],
"top_failure_modes": [],
"top_failure_modes": [
[
"Timeout",
3
],
[
"Test262Error (assertion failed)",
3
]
],
"pinned_commit": "d5e73fc8d2c663554fb72e2380a8c2bc1a318a33",
"elapsed_seconds": 9.0,
"elapsed_seconds": 57.4,
"workers": 1
}

View File

@@ -1,17 +1,24 @@
# test262 scoreboard
Pinned commit: `d5e73fc8d2c663554fb72e2380a8c2bc1a318a33`
Wall time: 9.0s
Wall time: 57.4s
**Total:** 45/45 runnable passed (100.0%). Raw: pass=45 fail=0 skip=5 timeout=0 total=50.
**Total:** 44/50 runnable passed (88.0%). Raw: pass=44 fail=3 skip=0 timeout=3 total=50.
## Top failure modes
- **3x** Timeout
- **3x** Test262Error (assertion failed)
## Categories (worst pass-rate first, min 10 runnable)
| Category | Pass | Fail | Skip | Timeout | Total | Pass % |
|---|---:|---:|---:|---:|---:|---:|
| built-ins/Math | 45 | 0 | 5 | 0 | 50 | 100.0% |
| built-ins/Number | 44 | 3 | 0 | 3 | 50 | 88.0% |
## Per-category top failures (min 10 runnable, worst first)
### built-ins/Number (44/50 — 88.0%)
- **3x** Timeout
- **3x** Test262Error (assertion failed)

View File

@@ -158,6 +158,8 @@ Each item: implement → tests → update progress. Mark `[x]` when tests green.
Append-only record of completed iterations. Loop writes one line per iteration: date, what was done, test count delta.
- 2026-05-08 — **`Object.prototype.toString` dispatches by [[Class]].** Was hardcoded to `"[object Object]"` for everything; per ES it should return `"[object Array]"`, `"[object Function]"`, `"[object Number]"`, etc. based on the receiver's class. Added `js-object-tostring-class` helper that switches on `(type-of v)` and on dict-internal markers (`__js_string_value__`, `__js_number_value__`, `__js_boolean_value__`, `__callable__`). Also added prototype-identity checks so `Object.prototype.toString.call(Number.prototype)` returns `"[object Number]"` (similar for String/Boolean/Array). built-ins/Array: 18/45 → 20/45, built-ins/Number: 43/50 → 44/50. conformance.sh: 148/148.
- 2026-05-08 — **`Math.X.name` returns the JS-style method name.** `Math.acos.name`, `Math.acosh.name`, `Math.asin.name` were returning the SX symbol name (`"js-math-acos"` etc.). `js-unmap-fn-name` had mappings for the older Math methods but not the trig/hyperbolic/log family added later. Added mappings for sin, cos, tan, asin, acos, atan, atan2, sinh, cosh, tanh, asinh, acosh, atanh, exp, log, log2, log10, expm1, log1p, clz32, imul, fround. built-ins/Math: 42/45 → 45/45 (100%). conformance.sh: 148/148.
- 2026-05-08 — **`fn.constructor === Function` for function instances.** Per ES, every function instance's `constructor` slot points to the `Function` global. Was returning undefined for `(function () {}).constructor`. Added `constructor` to the function-property cond in `js-get-prop`; returns `js-function-global`. Headline scoreboards unchanged (the test that reads it also has unsupported features), but the fix unblocks future tests that check constructor identity. conformance.sh: 148/148.