diff --git a/lib/js/runtime.sx b/lib/js/runtime.sx index a0578f2a..737d8e3f 100644 --- a/lib/js/runtime.sx +++ b/lib/js/runtime.sx @@ -4227,8 +4227,21 @@ (fn (o) (cond + ((or (= o nil) (js-undefined? o)) + (raise (js-new-call TypeError (js-args "Object.getOwnPropertyNames called on null or undefined")))) ((list? o) - (let ((r (list))) (begin (js-list-keys-loop o 0 r) r))) + (let + ((r (list))) + (begin + (js-list-keys-loop o 0 r) + (append! r "length") + r))) + ((= (type-of o) "string") + (let ((result (list)) (n (len o))) + (begin + (js-string-keys-loop result 0 n) + (append! result "length") + result))) ((dict? o) (js-own-property-names-ordered o)) (else (list))))) diff --git a/plans/js-on-sx.md b/plans/js-on-sx.md index d59628ba..7dc07ef4 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-09 — **`Object.getOwnPropertyNames` throws on null/undefined and includes `"length"` for strings/arrays.** Was returning `(list)` for non-list/non-dict inputs; per spec it ToObject's the argument and returns own keys including the implicit `"length"` property for strings/arrays. Added explicit branches: null/undefined → TypeError, string → `["0","1",…,"n-1","length"]` via `js-string-keys-loop` then append, list → indices + `"length"`, dict → existing ordered path. Result: built-ins/Object/getOwnPropertyNames 19/30 → 20/30. Object 30/30 holds. conformance.sh: 148/148. + - 2026-05-09 — **`Object.values`/`entries` throw on null/undefined and walk strings.** Same shape as the previous `Object.keys` fix. Both methods returned `(list)` for non-dict input; per spec they ToObject the argument and yield the property values / `[k, v]` pairs. Added explicit branches: null/undefined → TypeError, string → walk character indices, dict → iterate own enumerable keys (skipping internal `__js_order__` / `__proto__`). Result: built-ins/Object/values 5/16 → 8/16, entries 5/17 → 9/17. Object 30/30 holds. conformance.sh: 148/148. - 2026-05-09 — **`Object.keys` throws TypeError on null/undefined and walks indices on strings/arrays.** Was returning `(list)` for non-dict input — `Object.keys(null)` silently returned `[]` instead of throwing per spec, and `Object.keys("abc")` returned `[]` instead of `["0","1","2"]`. Added explicit branches: null/undefined → TypeError, string/list → `["0","1",..."n-1"]` via `js-string-keys-loop`. Result: built-ins/Object/keys 19/30 → 22/30. Object 30/30, Map 18/30 unchanged. conformance.sh: 148/148.