From 4e554113a927b7549b6a9602e994ee73d4959834 Mon Sep 17 00:00:00 2001 From: giles Date: Thu, 7 May 2026 14:24:52 +0000 Subject: [PATCH] js-on-sx: js-new-call accepts list-typed constructor returns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit new Array(1,2,3) was returning an empty wrapper object because js-new-call only honoured a non-undefined return when (type-of ret) === "dict"; SX lists (representing JS arrays) were silently discarded. Widened the check to accept "list" too. Fixes new Array(1,2,3).length, String(new Array(1,2,3)), and any constructor whose body returns a list. built-ins/String: 67/99 → 69/99 (canonical). conformance.sh: 148/148. --- lib/js/runtime.sx | 4 +++- lib/js/test262-scoreboard.json | 18 +++++++++--------- lib/js/test262-scoreboard.md | 12 ++++++------ plans/js-on-sx.md | 2 ++ 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/lib/js/runtime.sx b/lib/js/runtime.sx index 55a1e282..abbe9c8b 100644 --- a/lib/js/runtime.sx +++ b/lib/js/runtime.sx @@ -624,7 +624,9 @@ (let ((ret (js-call-with-this obj ctor args))) (if - (and (not (js-undefined? ret)) (= (type-of ret) "dict")) + (and + (not (js-undefined? ret)) + (or (= (type-of ret) "dict") (= (type-of ret) "list"))) ret obj)))))) diff --git a/lib/js/test262-scoreboard.json b/lib/js/test262-scoreboard.json index 01d4a143..ee01de05 100644 --- a/lib/js/test262-scoreboard.json +++ b/lib/js/test262-scoreboard.json @@ -1,26 +1,26 @@ { "totals": { - "pass": 67, - "fail": 26, + "pass": 69, + "fail": 24, "skip": 1, "timeout": 6, "total": 100, "runnable": 99, - "pass_rate": 67.7 + "pass_rate": 69.7 }, "categories": [ { "category": "built-ins/String", "total": 100, - "pass": 67, - "fail": 26, + "pass": 69, + "fail": 24, "skip": 1, "timeout": 6, - "pass_rate": 67.7, + "pass_rate": 69.7, "top_failures": [ [ "Test262Error (assertion failed)", - 14 + 12 ], [ "TypeError: not a function", @@ -44,7 +44,7 @@ "top_failure_modes": [ [ "Test262Error (assertion failed)", - 14 + 12 ], [ "TypeError: not a function", @@ -68,6 +68,6 @@ ] ], "pinned_commit": "d5e73fc8d2c663554fb72e2380a8c2bc1a318a33", - "elapsed_seconds": 364.7, + "elapsed_seconds": 344.4, "workers": 1 } \ No newline at end of file diff --git a/lib/js/test262-scoreboard.md b/lib/js/test262-scoreboard.md index 29a5d168..a0d35f36 100644 --- a/lib/js/test262-scoreboard.md +++ b/lib/js/test262-scoreboard.md @@ -1,13 +1,13 @@ # test262 scoreboard Pinned commit: `d5e73fc8d2c663554fb72e2380a8c2bc1a318a33` -Wall time: 364.7s +Wall time: 344.4s -**Total:** 67/99 runnable passed (67.7%). Raw: pass=67 fail=26 skip=1 timeout=6 total=100. +**Total:** 69/99 runnable passed (69.7%). Raw: pass=69 fail=24 skip=1 timeout=6 total=100. ## Top failure modes -- **14x** Test262Error (assertion failed) +- **12x** Test262Error (assertion failed) - **8x** TypeError: not a function - **6x** Timeout - **2x** Unhandled: Not callable: \\\ @@ -18,13 +18,13 @@ Wall time: 364.7s | Category | Pass | Fail | Skip | Timeout | Total | Pass % | |---|---:|---:|---:|---:|---:|---:| -| built-ins/String | 67 | 26 | 1 | 6 | 100 | 67.7% | +| built-ins/String | 69 | 24 | 1 | 6 | 100 | 69.7% | ## Per-category top failures (min 10 runnable, worst first) -### built-ins/String (67/99 — 67.7%) +### built-ins/String (69/99 — 69.7%) -- **14x** Test262Error (assertion failed) +- **12x** Test262Error (assertion failed) - **8x** TypeError: not a function - **6x** Timeout - **2x** Unhandled: Not callable: \\\ diff --git a/plans/js-on-sx.md b/plans/js-on-sx.md index ce1d87f3..488cc623 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-new-call` accepts list-typed constructor returns (not just dict).** `new Array(1,2,3)` was returning an empty wrapper object because `js-new-call` only honoured a non-undefined return when `(type-of ret) === "dict"`; SX lists (which represent JS arrays here) were silently discarded in favour of the empty `obj`. Widened the check to accept `"list"` returns. Fixes `new Array(1,2,3).length`, `String(new Array(1,2,3))`, and any constructor whose body returns a list. built-ins/String 67/99 → 69/99 (canonical), 70/99 → 71/99 (isolated). conformance.sh: 148/148. + - 2026-05-07 — **`js-num-from-string` uses `pow` (float) instead of `js-pow-int` for the exponent.** Numeric literals like `1e20` and `100000000000000000000` were parsing as `-1457092405402533888` because `js-pow-int 10 20` overflows int64 (10^20 > 2^63). The OCaml SX `pow` primitive uses float-domain power and produces `1e+20` correctly. Replaced the single `(js-pow-int 10 e)` call in `js-num-from-string` with `(pow 10 e)`. Fixes `String(1e20)`, `String(1e30)`, `String(100000000000000000000)`, etc. With isolation built-ins/String 67/99 → 70/99. conformance.sh: 148/148. - 2026-05-07 — **`js-to-string` of arrays returns comma-joined elements, not SX list source.** `String([1,2,3])` was returning `"(1 2 3)"` (SX `(str v)` formatting) — should be `"1,2,3"`. Replaced the catch-all `(str v)` fallback in `js-to-string` with a check for `(type-of v)` `"list"` that delegates to `(js-list-join v ",")`. Fixes `String(new Array(...))`, `"" + arr`, and any implicit array-to-string coercion. built-ins/String 65/99 → 67/99. conformance.sh: 148/148.