diff --git a/lib/js/runtime.sx b/lib/js/runtime.sx index 6b04c61a..98e2b712 100644 --- a/lib/js/runtime.sx +++ b/lib/js/runtime.sx @@ -2307,7 +2307,148 @@ (define js-object-freeze (fn (o) o)) -(define Object {:entries js-object-entries :values js-object-values :freeze js-object-freeze :assign js-object-assign :keys js-object-keys}) +(define + js-object-get-prototype-of + (fn + (o) + (cond + ((= o nil) (error "TypeError: Cannot convert null to object")) + ((js-undefined? o) + (error "TypeError: Cannot convert undefined to object")) + ((dict? o) + (if (contains? (keys o) "__proto__") (get o "__proto__") nil)) + (else nil)))) + +(define + js-object-set-prototype-of + (fn + (o proto) + (begin (when (dict? o) (dict-set! o "__proto__" proto)) o))) + +(define + js-object-create + (fn + (&rest args) + (let + ((proto (if (empty? args) nil (nth args 0)))) + (let + ((obj (dict))) + (begin + (when (not (= proto nil)) (dict-set! obj "__proto__" proto)) + (when + (and (>= (len args) 2) (dict? (nth args 1))) + (for-each + (fn + (k) + (dict-set! obj k (get (get (nth args 1) k) "value"))) + (keys (nth args 1)))) + obj))))) + +(define + js-object-define-property + (fn + (o key desc) + (begin + (when + (and (dict? o) (dict? desc) (contains? (keys desc) "value")) + (dict-set! o (js-to-string key) (get desc "value"))) + o))) + +(define + js-object-define-properties + (fn + (o descs) + (begin + (when + (and (dict? o) (dict? descs)) + (for-each + (fn (k) (js-object-define-property o k (get descs k))) + (keys descs))) + o))) + +(define + js-object-get-own-property-names + (fn + (o) + (cond + ((list? o) (let ((r (list))) (begin (js-list-keys-loop o 0 r) r))) + ((dict? o) (js-object-keys o)) + (else (list))))) + +(define + js-object-get-own-property-descriptor + (fn + (o key) + (if + (and (dict? o) (contains? (keys o) (js-to-string key))) + {:writable true :value (get o (js-to-string key)) :enumerable true :configurable true} + :js-undefined))) + +(define + js-object-get-own-property-descriptors + (fn + (o) + (let + ((out (dict))) + (begin + (when + (dict? o) + (for-each + (fn + (k) + (dict-set! out k (js-object-get-own-property-descriptor o k))) + (keys o))) + out)))) + +(define js-object-is-extensible (fn (o) (not (js-undefined? o)))) + +(define js-object-is-frozen (fn (o) false)) + +(define js-object-is-sealed (fn (o) false)) + +(define js-object-prevent-extensions (fn (o) o)) + +(define js-object-seal (fn (o) o)) + +(define + js-object-is + (fn + (a b) + (cond + ((and (js-number-is-nan a) (js-number-is-nan b)) true) + ((and (= a 0) (= b 0)) + (let ((ia (inspect a)) (ib (inspect b))) (= ia ib))) + (else (js-strict-eq a b))))) + +(define + js-object-from-entries + (fn + (iter) + (let + ((out (dict)) (lst (js-iterable-to-list iter))) + (begin + (for-each + (fn + (pair) + (when + (and (list? pair) (>= (len pair) 2)) + (dict-set! out (js-to-string (nth pair 0)) (nth pair 1)))) + lst) + out)))) + +(define + js-object-has-own + (fn + (o key) + (cond + ((dict? o) (contains? (keys o) (js-to-string key))) + ((list? o) + (let + ((idx (js-to-number key))) + (and (>= idx 0) (< idx (len o)) (integer? idx)))) + (else false)))) + +(define Object {:entries js-object-entries :defineProperties js-object-define-properties :preventExtensions js-object-prevent-extensions :prototype {} :values js-object-values :hasOwn js-object-has-own :freeze js-object-freeze :assign js-object-assign :isFrozen js-object-is-frozen :getOwnPropertyDescriptor js-object-get-own-property-descriptor :fromEntries js-object-from-entries :defineProperty js-object-define-property :setPrototypeOf js-object-set-prototype-of :getOwnPropertyNames js-object-get-own-property-names :getOwnPropertyDescriptors js-object-get-own-property-descriptors :create js-object-create :isExtensible js-object-is-extensible :is js-object-is :keys js-object-keys :getPrototypeOf js-object-get-prototype-of :isSealed js-object-is-sealed :seal js-object-seal}) (define js-delete-prop diff --git a/lib/js/test.sh b/lib/js/test.sh index 0dfe3f2e..0c14fd92 100755 --- a/lib/js/test.sh +++ b/lib/js/test.sh @@ -1213,6 +1213,26 @@ cat > "$TMPFILE" << 'EPOCHS' (epoch 3709) (eval "(js-eval \"var a=[1,2,3]; a.keys().join(',')\")") +;; ── Phase 11.objglobal: Object.getPrototypeOf, .create, .is, .hasOwn etc. ── +(epoch 3900) +(eval "(js-eval \"var o = Object.create(null); o.x=5; o.x\")") +(epoch 3901) +(eval "(js-eval \"Object.is(NaN, NaN)\")") +(epoch 3902) +(eval "(js-eval \"Object.is(0, 0)\")") +(epoch 3903) +(eval "(js-eval \"Object.hasOwn({a:1}, 'a')\")") +(epoch 3904) +(eval "(js-eval \"Object.hasOwn({a:1}, 'b')\")") +(epoch 3905) +(eval "(js-eval \"Object.fromEntries([['a',1],['b',2]]).a\")") +(epoch 3906) +(eval "(js-eval \"var o = {a:1}; Object.defineProperty(o,'b',{value:42}); o.b\")") +(epoch 3907) +(eval "(js-eval \"var o = {a:1}; Object.getOwnPropertyNames(o).length\")") +(epoch 3908) +(eval "(js-eval \"Object.isExtensible({})\")") + ;; ── Phase 11.globals: NaN / Infinity / strict-eq ───────────── (epoch 3750) (eval "(js-eval \"typeof NaN\")") @@ -1927,6 +1947,17 @@ check 3707 "arr.toReversed" '"2,1,3"' check 3708 "arr.toSorted" '"1,1,3,4,5"' check 3709 "arr.keys" '"0,1,2"' +# ── Phase 11.objglobal: Object.getPrototypeOf, .create, .is, .hasOwn ── +check 3900 "Object.create(null)" '5' +check 3901 "Object.is(NaN,NaN)" 'true' +check 3902 "Object.is(0,0)" 'true' +check 3903 "Object.hasOwn a" 'true' +check 3904 "Object.hasOwn missing" 'false' +check 3905 "Object.fromEntries" '1' +check 3906 "Object.defineProperty" '42' +check 3907 "Object.getOwnPropertyNames" '1' +check 3908 "Object.isExtensible" 'true' + # ── Phase 11.globals: NaN / Infinity / strict-eq ───────────── check 3750 "typeof NaN" '"number"' check 3751 "isNaN(NaN)" 'true'