/* 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 // // than the spec algorithm. var obj = {}; for (var 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); } // Array Grouping proposal // // Object.groupBy ( items, callbackfn ) // // https://tc39.es/proposal-array-grouping/#sec-object.groupby function ObjectGroupBy(items, callbackfn) { // Step 1. (Call to GroupBy is inlined.) // GroupBy, step 1. if (IsNullOrUndefined(items)) { ThrowTypeError( JSMSG_UNEXPECTED_TYPE, DecompileArg(0, items), items === null ? "null" : "undefined" ); } // GroupBy, step 2. if (!IsCallable(callbackfn)) { ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); } // Step 2. var obj = std_Object_create(null); // GroupBy, step 3. (Not applicable in our implementation.) // GroupBy, step 4. var k = 0; // GroupBy, steps 4 and 6. for (var value of allowContentIter(items)) { // GroupBy, step 6.a. (Not applicable) assert(k < 2 ** 53 - 1, "out-of-memory happens before k exceeds 2^53 - 1"); // GroupBy, steps 6.b-d. (Implicit through for-of loop.) // GroupBy, step 6.e. var key = callContentFunction(callbackfn, undefined, value, k); // GroupBy, step 6.f. (Implicit through for-of loop.) // GroupBy, step 6.g.i. key = TO_PROPERTY_KEY(key); // GroupBy, step 6.g.ii. (Implicit through for-of loop.) // GroupBy, step 6.h. (Not applicable) // GroupBy, step 6.i. (Inlined call to AddValueToKeyedGroup.) var elements = obj[key]; if (elements === undefined) { DefineDataProperty(obj, key, [value]); } else { DefineDataProperty(elements, elements.length, value); } // GroupBy, step 6.j. k += 1; } // Step 3. (Result object already populated in the previous loop.) // Step 4. return obj; }