diff --git a/lib/js/runtime.sx b/lib/js/runtime.sx index dabc3795..ad2c183f 100644 --- a/lib/js/runtime.sx +++ b/lib/js/runtime.sx @@ -1551,6 +1551,14 @@ (js-loose-eq (get a "__js_string_value__") b)) ((and (dict? b) (contains? (keys b) "__js_string_value__")) (js-loose-eq a (get b "__js_string_value__"))) + ((and (dict? a) (contains? (keys a) "__js_number_value__")) + (js-loose-eq (get a "__js_number_value__") b)) + ((and (dict? b) (contains? (keys b) "__js_number_value__")) + (js-loose-eq a (get b "__js_number_value__"))) + ((and (dict? a) (contains? (keys a) "__js_boolean_value__")) + (js-loose-eq (get a "__js_boolean_value__") b)) + ((and (dict? b) (contains? (keys b) "__js_boolean_value__")) + (js-loose-eq a (get b "__js_boolean_value__"))) (else false)))) (define js-loose-neq (fn (a b) (not (js-loose-eq a b)))) diff --git a/lib/js/test262-scoreboard.json b/lib/js/test262-scoreboard.json index 74da3b29..b245ec0d 100644 --- a/lib/js/test262-scoreboard.json +++ b/lib/js/test262-scoreboard.json @@ -1,22 +1,22 @@ { "totals": { - "pass": 77, - "fail": 16, + "pass": 78, + "fail": 15, "skip": 1, "timeout": 6, "total": 100, "runnable": 99, - "pass_rate": 77.8 + "pass_rate": 78.8 }, "categories": [ { "category": "built-ins/String", "total": 100, - "pass": 77, - "fail": 16, + "pass": 78, + "fail": 15, "skip": 1, "timeout": 6, - "pass_rate": 77.8, + "pass_rate": 78.8, "top_failures": [ [ "Test262Error (assertion failed)", @@ -33,10 +33,6 @@ [ "SyntaxError (parse/unsupported syntax)", 1 - ], - [ - "runner-error: sx_server closed stdout mid-epoch", - 1 ] ] } @@ -57,13 +53,9 @@ [ "SyntaxError (parse/unsupported syntax)", 1 - ], - [ - "runner-error: sx_server closed stdout mid-epoch", - 1 ] ], "pinned_commit": "d5e73fc8d2c663554fb72e2380a8c2bc1a318a33", - "elapsed_seconds": 238.6, + "elapsed_seconds": 226.1, "workers": 1 } \ No newline at end of file diff --git a/lib/js/test262-scoreboard.md b/lib/js/test262-scoreboard.md index 08f92328..dca36c35 100644 --- a/lib/js/test262-scoreboard.md +++ b/lib/js/test262-scoreboard.md @@ -1,9 +1,9 @@ # test262 scoreboard Pinned commit: `d5e73fc8d2c663554fb72e2380a8c2bc1a318a33` -Wall time: 238.6s +Wall time: 226.1s -**Total:** 77/99 runnable passed (77.8%). Raw: pass=77 fail=16 skip=1 timeout=6 total=100. +**Total:** 78/99 runnable passed (78.8%). Raw: pass=78 fail=15 skip=1 timeout=6 total=100. ## Top failure modes @@ -11,20 +11,18 @@ Wall time: 238.6s - **6x** Timeout - **1x** ReferenceError (undefined symbol) - **1x** SyntaxError (parse/unsupported syntax) -- **1x** runner-error: sx_server closed stdout mid-epoch ## Categories (worst pass-rate first, min 10 runnable) | Category | Pass | Fail | Skip | Timeout | Total | Pass % | |---|---:|---:|---:|---:|---:|---:| -| built-ins/String | 77 | 16 | 1 | 6 | 100 | 77.8% | +| built-ins/String | 78 | 15 | 1 | 6 | 100 | 78.8% | ## Per-category top failures (min 10 runnable, worst first) -### built-ins/String (77/99 — 77.8%) +### built-ins/String (78/99 — 78.8%) - **13x** Test262Error (assertion failed) - **6x** Timeout - **1x** ReferenceError (undefined symbol) - **1x** SyntaxError (parse/unsupported syntax) -- **1x** runner-error: sx_server closed stdout mid-epoch diff --git a/plans/js-on-sx.md b/plans/js-on-sx.md index e4402347..a59a3d2c 100644 --- a/plans/js-on-sx.md +++ b/plans/js-on-sx.md @@ -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-07 — **`js-loose-eq` unwraps Number and Boolean wrappers (was String-only).** `Object(1.1) == 1.1` was returning `false`: loose-eq only had a clause for `__js_string_value__`. Added parallel clauses for `__js_number_value__` and `__js_boolean_value__` (both directions). Now `new Number(5) == 5`, `Object(true) == true`, etc. built-ins/Object: 26/50 → 37/50. conformance.sh: 148/148. + - 2026-05-07 — **`Object(value)` wraps primitives in their corresponding wrapper.** Per ES spec, `Object('s') instanceof String === true`, `Object(42).constructor === Number`, etc. Was passing primitives through as-is, so `Object('s').constructor` was undefined. Added clauses to `Object.__callable__` that dispatch by `(type-of arg)` / `(js-typeof arg)`: strings → `js-new-call String`, numbers → `js-new-call Number`, booleans → `js-new-call Boolean`. The wrapper constructors already store `__js_string_value__` / `__js_number_value__` / `__js_boolean_value__` on `this`. built-ins/Object: 16/50 → 26/50. conformance.sh: 148/148. - 2026-05-07 — **`Object(null)` and `Object(undefined)` return a new empty object.** Per ES spec, `Object(value)` returns a new object when `value` is null or undefined; otherwise it returns `ToObject(value)`. Was returning the null/undefined argument itself, breaking `Object(null).toString()`. Added a clause to the `Object.__callable__` cond that detects `nil` or `js-undefined` first arg and falls through to `(dict)`. built-ins/Object: 15/50 → 16/50. conformance.sh: 148/148.