summaryrefslogtreecommitdiffstats
path: root/js/src/builtin/Object.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--js/src/builtin/Object.js369
1 files changed, 369 insertions, 0 deletions
diff --git a/js/src/builtin/Object.js b/js/src/builtin/Object.js
new file mode 100644
index 0000000000..6193f1125c
--- /dev/null
+++ b/js/src/builtin/Object.js
@@ -0,0 +1,369 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// ES stage 4 proposal
+function ObjectGetOwnPropertyDescriptors(O) {
+ // Step 1.
+ var obj = ToObject(O);
+
+ // Step 2.
+ var keys = std_Reflect_ownKeys(obj);
+
+ // Step 3.
+ var descriptors = {};
+
+ // Step 4.
+ for (var index = 0, len = keys.length; index < len; index++) {
+ var key = keys[index];
+
+ // Steps 4.a-b.
+ var desc = ObjectGetOwnPropertyDescriptor(obj, key);
+
+ // Step 4.c.
+ if (typeof desc !== "undefined") {
+ DefineDataProperty(descriptors, key, desc);
+ }
+ }
+
+ // Step 5.
+ return descriptors;
+}
+
+/* ES6 draft rev 32 (2015 Feb 2) 19.1.2.9. */
+function ObjectGetPrototypeOf(obj) {
+ return std_Reflect_getPrototypeOf(ToObject(obj));
+}
+
+/* ES6 draft rev 32 (2015 Feb 2) 19.1.2.11. */
+function ObjectIsExtensible(obj) {
+ return IsObject(obj) && std_Reflect_isExtensible(obj);
+}
+
+/* ES2015 19.1.3.5 Object.prototype.toLocaleString */
+function Object_toLocaleString() {
+ // Step 1.
+ var O = this;
+
+ // Step 2.
+ return callContentFunction(O.toString, O);
+}
+
+// ES 2017 draft bb96899bb0d9ef9be08164a26efae2ee5f25e875 19.1.3.7
+function Object_valueOf() {
+ // Step 1.
+ return ToObject(this);
+}
+
+// ES 2018 draft 19.1.3.2
+function Object_hasOwnProperty(V) {
+ // Implement hasOwnProperty as a pseudo function that becomes a JSOp
+ // to easier add an inline cache for this.
+ return hasOwn(V, this);
+}
+
+// ES 2021 draft rev 0b988b7700de675331ac360d164c978d6ea452ec
+// B.2.2.1.1 get Object.prototype.__proto__
+function $ObjectProtoGetter() {
+ return std_Reflect_getPrototypeOf(ToObject(this));
+}
+SetCanonicalName($ObjectProtoGetter, "get __proto__");
+
+// ES 2021 draft rev 0b988b7700de675331ac360d164c978d6ea452ec
+// B.2.2.1.2 set Object.prototype.__proto__
+function $ObjectProtoSetter(proto) {
+ return callFunction(std_Object_setProto, this, proto);
+}
+SetCanonicalName($ObjectProtoSetter, "set __proto__");
+
+// ES7 draft (2016 March 8) B.2.2.3
+function ObjectDefineSetter(name, setter) {
+ // Step 1.
+ var object = ToObject(this);
+
+ // Step 2.
+ if (!IsCallable(setter)) {
+ ThrowTypeError(JSMSG_BAD_GETTER_OR_SETTER, "setter");
+ }
+
+ // Step 4.
+ var key = TO_PROPERTY_KEY(name);
+
+ // Steps 3, 5.
+ DefineProperty(
+ object,
+ key,
+ ACCESSOR_DESCRIPTOR_KIND | ATTR_ENUMERABLE | ATTR_CONFIGURABLE,
+ null,
+ setter,
+ true
+ );
+
+ // Step 6. (implicit)
+}
+
+// ES7 draft (2016 March 8) B.2.2.2
+function ObjectDefineGetter(name, getter) {
+ // Step 1.
+ var object = ToObject(this);
+
+ // Step 2.
+ if (!IsCallable(getter)) {
+ ThrowTypeError(JSMSG_BAD_GETTER_OR_SETTER, "getter");
+ }
+
+ // Step 4.
+ var key = TO_PROPERTY_KEY(name);
+
+ // Steps 3, 5.
+ DefineProperty(
+ object,
+ key,
+ ACCESSOR_DESCRIPTOR_KIND | ATTR_ENUMERABLE | ATTR_CONFIGURABLE,
+ getter,
+ null,
+ true
+ );
+
+ // Step 6. (implicit)
+}
+
+// ES7 draft (2016 March 8) B.2.2.5
+function ObjectLookupSetter(name) {
+ // Step 1.
+ var object = ToObject(this);
+
+ // Step 2.
+ var key = TO_PROPERTY_KEY(name);
+
+ do {
+ // Step 3.a.
+ var desc = GetOwnPropertyDescriptorToArray(object, key);
+
+ // Step 3.b.
+ if (desc) {
+ // Step.b.i.
+ if (desc[PROP_DESC_ATTRS_AND_KIND_INDEX] & ACCESSOR_DESCRIPTOR_KIND) {
+ return desc[PROP_DESC_SETTER_INDEX];
+ }
+
+ // Step.b.i.
+ return undefined;
+ }
+
+ // Step 3.c.
+ object = std_Reflect_getPrototypeOf(object);
+ } while (object !== null);
+
+ // Step 3.d. (implicit)
+}
+
+// ES7 draft (2016 March 8) B.2.2.4
+function ObjectLookupGetter(name) {
+ // Step 1.
+ var object = ToObject(this);
+
+ // Step 2.
+ var key = TO_PROPERTY_KEY(name);
+
+ do {
+ // Step 3.a.
+ var desc = GetOwnPropertyDescriptorToArray(object, key);
+
+ // Step 3.b.
+ if (desc) {
+ // Step.b.i.
+ if (desc[PROP_DESC_ATTRS_AND_KIND_INDEX] & ACCESSOR_DESCRIPTOR_KIND) {
+ return desc[PROP_DESC_GETTER_INDEX];
+ }
+
+ // Step.b.ii.
+ return undefined;
+ }
+
+ // Step 3.c.
+ object = std_Reflect_getPrototypeOf(object);
+ } while (object !== null);
+
+ // Step 3.d. (implicit)
+}
+
+// ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
+// 19.1.2.6 Object.getOwnPropertyDescriptor ( O, P )
+function ObjectGetOwnPropertyDescriptor(obj, propertyKey) {
+ // Steps 1-3.
+ var desc = GetOwnPropertyDescriptorToArray(obj, propertyKey);
+
+ // Step 4 (Call to 6.2.4.4 FromPropertyDescriptor).
+
+ // 6.2.4.4 FromPropertyDescriptor, step 1.
+ if (!desc) {
+ return undefined;
+ }
+
+ // 6.2.4.4 FromPropertyDescriptor, steps 2-5, 8-11.
+ var attrsAndKind = desc[PROP_DESC_ATTRS_AND_KIND_INDEX];
+ if (attrsAndKind & DATA_DESCRIPTOR_KIND) {
+ return {
+ value: desc[PROP_DESC_VALUE_INDEX],
+ writable: !!(attrsAndKind & ATTR_WRITABLE),
+ enumerable: !!(attrsAndKind & ATTR_ENUMERABLE),
+ configurable: !!(attrsAndKind & ATTR_CONFIGURABLE),
+ };
+ }
+
+ // 6.2.4.4 FromPropertyDescriptor, steps 2-3, 6-11.
+ assert(
+ attrsAndKind & ACCESSOR_DESCRIPTOR_KIND,
+ "expected accessor property descriptor"
+ );
+ return {
+ get: desc[PROP_DESC_GETTER_INDEX],
+ set: desc[PROP_DESC_SETTER_INDEX],
+ enumerable: !!(attrsAndKind & ATTR_ENUMERABLE),
+ configurable: !!(attrsAndKind & ATTR_CONFIGURABLE),
+ };
+}
+
+// ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
+// 19.1.2.4 Object.defineProperty ( O, P, Attributes )
+// 26.1.3 Reflect.defineProperty ( target, propertyKey, attributes )
+function ObjectOrReflectDefineProperty(obj, propertyKey, attributes, strict) {
+ // Step 1.
+ if (!IsObject(obj)) {
+ ThrowTypeError(JSMSG_OBJECT_REQUIRED, DecompileArg(0, obj));
+ }
+
+ // Step 2.
+ propertyKey = TO_PROPERTY_KEY(propertyKey);
+
+ // Step 3 (Call to 6.2.4.5 ToPropertyDescriptor).
+
+ // 6.2.4.5 ToPropertyDescriptor, step 1.
+ if (!IsObject(attributes)) {
+ ThrowTypeError(
+ JSMSG_OBJECT_REQUIRED_PROP_DESC,
+ DecompileArg(2, attributes)
+ );
+ }
+
+ // 6.2.4.5 ToPropertyDescriptor, step 2.
+ var attrs = 0;
+ var hasValue = false;
+ var value;
+ var getter = null;
+ var setter = null;
+
+ // 6.2.4.5 ToPropertyDescriptor, steps 3-4.
+ if ("enumerable" in attributes) {
+ attrs |= attributes.enumerable ? ATTR_ENUMERABLE : ATTR_NONENUMERABLE;
+ }
+
+ // 6.2.4.5 ToPropertyDescriptor, steps 5-6.
+ if ("configurable" in attributes) {
+ attrs |= attributes.configurable ? ATTR_CONFIGURABLE : ATTR_NONCONFIGURABLE;
+ }
+
+ // 6.2.4.5 ToPropertyDescriptor, steps 7-8.
+ if ("value" in attributes) {
+ attrs |= DATA_DESCRIPTOR_KIND;
+ value = attributes.value;
+ hasValue = true;
+ }
+
+ // 6.2.4.5 ToPropertyDescriptor, steps 9-10.
+ if ("writable" in attributes) {
+ attrs |= DATA_DESCRIPTOR_KIND;
+ attrs |= attributes.writable ? ATTR_WRITABLE : ATTR_NONWRITABLE;
+ }
+
+ // 6.2.4.5 ToPropertyDescriptor, steps 11-12.
+ if ("get" in attributes) {
+ attrs |= ACCESSOR_DESCRIPTOR_KIND;
+ getter = attributes.get;
+ if (!IsCallable(getter) && getter !== undefined) {
+ ThrowTypeError(JSMSG_BAD_GET_SET_FIELD, "get");
+ }
+ }
+
+ // 6.2.4.5 ToPropertyDescriptor, steps 13-14.
+ if ("set" in attributes) {
+ attrs |= ACCESSOR_DESCRIPTOR_KIND;
+ setter = attributes.set;
+ if (!IsCallable(setter) && setter !== undefined) {
+ ThrowTypeError(JSMSG_BAD_GET_SET_FIELD, "set");
+ }
+ }
+
+ if (attrs & ACCESSOR_DESCRIPTOR_KIND) {
+ // 6.2.4.5 ToPropertyDescriptor, step 15.
+ if (attrs & DATA_DESCRIPTOR_KIND) {
+ ThrowTypeError(JSMSG_INVALID_DESCRIPTOR);
+ }
+
+ // Step 4 (accessor descriptor property).
+ return DefineProperty(obj, propertyKey, attrs, getter, setter, strict);
+ }
+
+ // Step 4 (data property descriptor with value).
+ if (hasValue) {
+ // Use the inlinable DefineDataProperty function when possible.
+ if (strict) {
+ if (
+ (attrs & (ATTR_ENUMERABLE | ATTR_CONFIGURABLE | ATTR_WRITABLE)) ===
+ (ATTR_ENUMERABLE | ATTR_CONFIGURABLE | ATTR_WRITABLE)
+ ) {
+ DefineDataProperty(obj, propertyKey, value);
+ return true;
+ }
+ }
+
+ // The fifth argument is set to |null| to mark that |value| is present.
+ return DefineProperty(obj, propertyKey, attrs, value, null, strict);
+ }
+
+ // Step 4 (generic property descriptor or data property without value).
+ return DefineProperty(obj, propertyKey, attrs, undefined, undefined, strict);
+}
+
+// ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
+// 19.1.2.4 Object.defineProperty ( O, P, Attributes )
+function ObjectDefineProperty(obj, propertyKey, attributes) {
+ // Steps 1-4.
+ if (!ObjectOrReflectDefineProperty(obj, propertyKey, attributes, true)) {
+ // Not standardized yet: https://github.com/tc39/ecma262/pull/688
+ return null;
+ }
+
+ // Step 5.
+ return obj;
+}
+
+// Proposal https://tc39.github.io/proposal-object-from-entries/
+// 1. Object.fromEntries ( iterable )
+function ObjectFromEntries(iter) {
+ // We omit the usual step number comments here because they don't help.
+ // This implementation inlines AddEntriesFromIterator and
+ // CreateDataPropertyOnObject, so it looks more like the polyfill
+ // <https://github.com/tc39/proposal-object-from-entries/blob/master/polyfill.js>
+ // than the spec algorithm.
+ const obj = {};
+
+ for (const pair of allowContentIter(iter)) {
+ if (!IsObject(pair)) {
+ ThrowTypeError(JSMSG_INVALID_MAP_ITERABLE, "Object.fromEntries");
+ }
+ DefineDataProperty(obj, pair[0], pair[1]);
+ }
+
+ return obj;
+}
+
+// Proposal https://github.com/tc39/proposal-accessible-object-hasownproperty
+// 1. Object.hasOwn ( O, P )
+function ObjectHasOwn(O, P) {
+ // Step 1.
+ var obj = ToObject(O);
+ // Step 2-3.
+ return hasOwn(P, obj);
+}