tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Object.js (11376B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 // ES stage 4 proposal
      6 function ObjectGetOwnPropertyDescriptors(O) {
      7  // Step 1.
      8  var obj = ToObject(O);
      9 
     10  // Step 2.
     11  var keys = std_Reflect_ownKeys(obj);
     12 
     13  // Step 3.
     14  var descriptors = {};
     15 
     16  // Step 4.
     17  for (var index = 0, len = keys.length; index < len; index++) {
     18    var key = keys[index];
     19 
     20    // Steps 4.a-b.
     21    var desc = ObjectGetOwnPropertyDescriptor(obj, key);
     22 
     23    // Step 4.c.
     24    if (typeof desc !== "undefined") {
     25      DefineDataProperty(descriptors, key, desc);
     26    }
     27  }
     28 
     29  // Step 5.
     30  return descriptors;
     31 }
     32 
     33 /* ES6 draft rev 32 (2015 Feb 2) 19.1.2.9. */
     34 function ObjectGetPrototypeOf(obj) {
     35  return std_Reflect_getPrototypeOf(ToObject(obj));
     36 }
     37 
     38 /* ES6 draft rev 32 (2015 Feb 2) 19.1.2.11. */
     39 function ObjectIsExtensible(obj) {
     40  return IsObject(obj) && std_Reflect_isExtensible(obj);
     41 }
     42 
     43 /* ES2015 19.1.3.5 Object.prototype.toLocaleString */
     44 function Object_toLocaleString() {
     45  // Step 1.
     46  var O = this;
     47 
     48  // Step 2.
     49  return callContentFunction(O.toString, O);
     50 }
     51 
     52 // ES 2017 draft bb96899bb0d9ef9be08164a26efae2ee5f25e875 19.1.3.7
     53 function Object_valueOf() {
     54  // Step 1.
     55  return ToObject(this);
     56 }
     57 
     58 // ES 2018 draft 19.1.3.2
     59 function Object_hasOwnProperty(V) {
     60  // Implement hasOwnProperty as a pseudo function that becomes a JSOp
     61  // to easier add an inline cache for this.
     62  return hasOwn(V, this);
     63 }
     64 
     65 // ES 2021 draft rev 0b988b7700de675331ac360d164c978d6ea452ec
     66 // B.2.2.1.1 get Object.prototype.__proto__
     67 function $ObjectProtoGetter() {
     68  return std_Reflect_getPrototypeOf(ToObject(this));
     69 }
     70 SetCanonicalName($ObjectProtoGetter, "get __proto__");
     71 
     72 // ES 2021 draft rev 0b988b7700de675331ac360d164c978d6ea452ec
     73 // B.2.2.1.2 set Object.prototype.__proto__
     74 function $ObjectProtoSetter(proto) {
     75  return callFunction(std_Object_setProto, this, proto);
     76 }
     77 SetCanonicalName($ObjectProtoSetter, "set __proto__");
     78 
     79 // ES7 draft (2016 March 8) B.2.2.3
     80 function ObjectDefineSetter(name, setter) {
     81  // Step 1.
     82  var object = ToObject(this);
     83 
     84  // Step 2.
     85  if (!IsCallable(setter)) {
     86    ThrowTypeError(JSMSG_BAD_GETTER_OR_SETTER, "setter");
     87  }
     88 
     89  // Step 4.
     90  var key = TO_PROPERTY_KEY(name);
     91 
     92  // Steps 3, 5.
     93  DefineProperty(
     94    object,
     95    key,
     96    ACCESSOR_DESCRIPTOR_KIND | ATTR_ENUMERABLE | ATTR_CONFIGURABLE,
     97    null,
     98    setter,
     99    true
    100  );
    101 
    102  // Step 6. (implicit)
    103 }
    104 
    105 // ES7 draft (2016 March 8) B.2.2.2
    106 function ObjectDefineGetter(name, getter) {
    107  // Step 1.
    108  var object = ToObject(this);
    109 
    110  // Step 2.
    111  if (!IsCallable(getter)) {
    112    ThrowTypeError(JSMSG_BAD_GETTER_OR_SETTER, "getter");
    113  }
    114 
    115  // Step 4.
    116  var key = TO_PROPERTY_KEY(name);
    117 
    118  // Steps 3, 5.
    119  DefineProperty(
    120    object,
    121    key,
    122    ACCESSOR_DESCRIPTOR_KIND | ATTR_ENUMERABLE | ATTR_CONFIGURABLE,
    123    getter,
    124    null,
    125    true
    126  );
    127 
    128  // Step 6. (implicit)
    129 }
    130 
    131 // ES7 draft (2016 March 8) B.2.2.5
    132 function ObjectLookupSetter(name) {
    133  // Step 1.
    134  var object = ToObject(this);
    135 
    136  // Step 2.
    137  var key = TO_PROPERTY_KEY(name);
    138 
    139  do {
    140    // Step 3.a.
    141    var desc = GetOwnPropertyDescriptorToArray(object, key);
    142 
    143    // Step 3.b.
    144    if (desc) {
    145      // Step.b.i.
    146      if (desc[PROP_DESC_ATTRS_AND_KIND_INDEX] & ACCESSOR_DESCRIPTOR_KIND) {
    147        return desc[PROP_DESC_SETTER_INDEX];
    148      }
    149 
    150      // Step.b.i.
    151      return undefined;
    152    }
    153 
    154    // Step 3.c.
    155    object = std_Reflect_getPrototypeOf(object);
    156  } while (object !== null);
    157 
    158  // Step 3.d. (implicit)
    159 }
    160 
    161 // ES7 draft (2016 March 8) B.2.2.4
    162 function ObjectLookupGetter(name) {
    163  // Step 1.
    164  var object = ToObject(this);
    165 
    166  // Step 2.
    167  var key = TO_PROPERTY_KEY(name);
    168 
    169  do {
    170    // Step 3.a.
    171    var desc = GetOwnPropertyDescriptorToArray(object, key);
    172 
    173    // Step 3.b.
    174    if (desc) {
    175      // Step.b.i.
    176      if (desc[PROP_DESC_ATTRS_AND_KIND_INDEX] & ACCESSOR_DESCRIPTOR_KIND) {
    177        return desc[PROP_DESC_GETTER_INDEX];
    178      }
    179 
    180      // Step.b.ii.
    181      return undefined;
    182    }
    183 
    184    // Step 3.c.
    185    object = std_Reflect_getPrototypeOf(object);
    186  } while (object !== null);
    187 
    188  // Step 3.d. (implicit)
    189 }
    190 
    191 // ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
    192 // 19.1.2.6 Object.getOwnPropertyDescriptor ( O, P )
    193 function ObjectGetOwnPropertyDescriptor(obj, propertyKey) {
    194  // Steps 1-3.
    195  var desc = GetOwnPropertyDescriptorToArray(obj, propertyKey);
    196 
    197  // Step 4 (Call to 6.2.4.4 FromPropertyDescriptor).
    198 
    199  // 6.2.4.4 FromPropertyDescriptor, step 1.
    200  if (!desc) {
    201    return undefined;
    202  }
    203 
    204  // 6.2.4.4 FromPropertyDescriptor, steps 2-5, 8-11.
    205  var attrsAndKind = desc[PROP_DESC_ATTRS_AND_KIND_INDEX];
    206  if (attrsAndKind & DATA_DESCRIPTOR_KIND) {
    207    return {
    208      value: desc[PROP_DESC_VALUE_INDEX],
    209      writable: !!(attrsAndKind & ATTR_WRITABLE),
    210      enumerable: !!(attrsAndKind & ATTR_ENUMERABLE),
    211      configurable: !!(attrsAndKind & ATTR_CONFIGURABLE),
    212    };
    213  }
    214 
    215  // 6.2.4.4 FromPropertyDescriptor, steps 2-3, 6-11.
    216  assert(
    217    attrsAndKind & ACCESSOR_DESCRIPTOR_KIND,
    218    "expected accessor property descriptor"
    219  );
    220  return {
    221    get: desc[PROP_DESC_GETTER_INDEX],
    222    set: desc[PROP_DESC_SETTER_INDEX],
    223    enumerable: !!(attrsAndKind & ATTR_ENUMERABLE),
    224    configurable: !!(attrsAndKind & ATTR_CONFIGURABLE),
    225  };
    226 }
    227 
    228 // ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
    229 // 19.1.2.4 Object.defineProperty ( O, P, Attributes )
    230 // 26.1.3 Reflect.defineProperty ( target, propertyKey, attributes )
    231 function ObjectOrReflectDefineProperty(obj, propertyKey, attributes, strict) {
    232  // Step 1.
    233  if (!IsObject(obj)) {
    234    ThrowTypeError(JSMSG_OBJECT_REQUIRED, DecompileArg(0, obj));
    235  }
    236 
    237  // Step 2.
    238  propertyKey = TO_PROPERTY_KEY(propertyKey);
    239 
    240  // Step 3 (Call to 6.2.4.5 ToPropertyDescriptor).
    241 
    242  // 6.2.4.5 ToPropertyDescriptor, step 1.
    243  if (!IsObject(attributes)) {
    244    ThrowTypeError(
    245      JSMSG_OBJECT_REQUIRED_PROP_DESC,
    246      DecompileArg(2, attributes)
    247    );
    248  }
    249 
    250  // 6.2.4.5 ToPropertyDescriptor, step 2.
    251  var attrs = 0;
    252  var hasValue = false;
    253  var value;
    254  var getter = null;
    255  var setter = null;
    256 
    257  // 6.2.4.5 ToPropertyDescriptor, steps 3-4.
    258  if ("enumerable" in attributes) {
    259    attrs |= attributes.enumerable ? ATTR_ENUMERABLE : ATTR_NONENUMERABLE;
    260  }
    261 
    262  // 6.2.4.5 ToPropertyDescriptor, steps 5-6.
    263  if ("configurable" in attributes) {
    264    attrs |= attributes.configurable ? ATTR_CONFIGURABLE : ATTR_NONCONFIGURABLE;
    265  }
    266 
    267  // 6.2.4.5 ToPropertyDescriptor, steps 7-8.
    268  if ("value" in attributes) {
    269    attrs |= DATA_DESCRIPTOR_KIND;
    270    value = attributes.value;
    271    hasValue = true;
    272  }
    273 
    274  // 6.2.4.5 ToPropertyDescriptor, steps 9-10.
    275  if ("writable" in attributes) {
    276    attrs |= DATA_DESCRIPTOR_KIND;
    277    attrs |= attributes.writable ? ATTR_WRITABLE : ATTR_NONWRITABLE;
    278  }
    279 
    280  // 6.2.4.5 ToPropertyDescriptor, steps 11-12.
    281  if ("get" in attributes) {
    282    attrs |= ACCESSOR_DESCRIPTOR_KIND;
    283    getter = attributes.get;
    284    if (!IsCallable(getter) && getter !== undefined) {
    285      ThrowTypeError(JSMSG_BAD_GET_SET_FIELD, "get");
    286    }
    287  }
    288 
    289  // 6.2.4.5 ToPropertyDescriptor, steps 13-14.
    290  if ("set" in attributes) {
    291    attrs |= ACCESSOR_DESCRIPTOR_KIND;
    292    setter = attributes.set;
    293    if (!IsCallable(setter) && setter !== undefined) {
    294      ThrowTypeError(JSMSG_BAD_GET_SET_FIELD, "set");
    295    }
    296  }
    297 
    298  if (attrs & ACCESSOR_DESCRIPTOR_KIND) {
    299    // 6.2.4.5 ToPropertyDescriptor, step 15.
    300    if (attrs & DATA_DESCRIPTOR_KIND) {
    301      ThrowTypeError(JSMSG_INVALID_DESCRIPTOR);
    302    }
    303 
    304    // Step 4 (accessor descriptor property).
    305    return DefineProperty(obj, propertyKey, attrs, getter, setter, strict);
    306  }
    307 
    308  // Step 4 (data property descriptor with value).
    309  if (hasValue) {
    310    // Use the inlinable DefineDataProperty function when possible.
    311    if (strict) {
    312      if (
    313        (attrs & (ATTR_ENUMERABLE | ATTR_CONFIGURABLE | ATTR_WRITABLE)) ===
    314        (ATTR_ENUMERABLE | ATTR_CONFIGURABLE | ATTR_WRITABLE)
    315      ) {
    316        DefineDataProperty(obj, propertyKey, value);
    317        return true;
    318      }
    319    }
    320 
    321    // The fifth argument is set to |null| to mark that |value| is present.
    322    return DefineProperty(obj, propertyKey, attrs, value, null, strict);
    323  }
    324 
    325  // Step 4 (generic property descriptor or data property without value).
    326  return DefineProperty(obj, propertyKey, attrs, undefined, undefined, strict);
    327 }
    328 
    329 // ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
    330 // 19.1.2.4 Object.defineProperty ( O, P, Attributes )
    331 function ObjectDefineProperty(obj, propertyKey, attributes) {
    332  // Steps 1-4.
    333  if (!ObjectOrReflectDefineProperty(obj, propertyKey, attributes, true)) {
    334    // Not standardized yet: https://github.com/tc39/ecma262/pull/688
    335    return null;
    336  }
    337 
    338  // Step 5.
    339  return obj;
    340 }
    341 
    342 // Proposal https://tc39.github.io/proposal-object-from-entries/
    343 // 1. Object.fromEntries ( iterable )
    344 function ObjectFromEntries(iter) {
    345  // We omit the usual step number comments here because they don't help.
    346  // This implementation inlines AddEntriesFromIterator and
    347  // CreateDataPropertyOnObject, so it looks more like the polyfill
    348  // <https://github.com/tc39/proposal-object-from-entries/blob/master/polyfill.js>
    349  // than the spec algorithm.
    350  var obj = {};
    351 
    352  for (var pair of allowContentIter(iter)) {
    353    if (!IsObject(pair)) {
    354      ThrowTypeError(JSMSG_INVALID_MAP_ITERABLE, "Object.fromEntries");
    355    }
    356    DefineDataProperty(obj, pair[0], pair[1]);
    357  }
    358 
    359  return obj;
    360 }
    361 
    362 // Proposal https://github.com/tc39/proposal-accessible-object-hasownproperty
    363 // 1. Object.hasOwn ( O, P )
    364 function ObjectHasOwn(O, P) {
    365  // Step 1.
    366  var obj = ToObject(O);
    367  // Step 2-3.
    368  return hasOwn(P, obj);
    369 }
    370 
    371 // Array Grouping proposal
    372 //
    373 // Object.groupBy ( items, callbackfn )
    374 //
    375 // https://tc39.es/proposal-array-grouping/#sec-object.groupby
    376 function ObjectGroupBy(items, callbackfn) {
    377  // Step 1. (Call to GroupBy is inlined.)
    378 
    379  // GroupBy, step 1.
    380  if (IsNullOrUndefined(items)) {
    381    ThrowTypeError(
    382      JSMSG_UNEXPECTED_TYPE,
    383      DecompileArg(0, items),
    384      items === null ? "null" : "undefined"
    385    );
    386  }
    387 
    388  // GroupBy, step 2.
    389  if (!IsCallable(callbackfn)) {
    390    ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn));
    391  }
    392 
    393  // Step 2.
    394  var obj = std_Object_create(null);
    395 
    396  // GroupBy, step 3. (Not applicable in our implementation.)
    397 
    398  // GroupBy, step 4.
    399  var k = 0;
    400 
    401  // GroupBy, steps 4 and 6.
    402  for (var value of allowContentIter(items)) {
    403    // GroupBy, step 6.a. (Not applicable)
    404    assert(k < 2 ** 53 - 1, "out-of-memory happens before k exceeds 2^53 - 1");
    405 
    406    // GroupBy, steps 6.b-d. (Implicit through for-of loop.)
    407 
    408    // GroupBy, step 6.e.
    409    var key = callContentFunction(callbackfn, undefined, value, k);
    410 
    411    // GroupBy, step 6.f. (Implicit through for-of loop.)
    412 
    413    // GroupBy, step 6.g.i.
    414    key = TO_PROPERTY_KEY(key);
    415 
    416    // GroupBy, step 6.g.ii. (Implicit through for-of loop.)
    417 
    418    // GroupBy, step 6.h. (Not applicable)
    419 
    420    // GroupBy, step 6.i. (Inlined call to AddValueToKeyedGroup.)
    421    var elements = obj[key];
    422    if (elements === undefined) {
    423      DefineDataProperty(obj, key, [value]);
    424    } else {
    425      DefineDataProperty(elements, elements.length, value);
    426    }
    427 
    428    // GroupBy, step 6.j.
    429    k += 1;
    430  }
    431 
    432  // Step 3. (Result object already populated in the previous loop.)
    433 
    434  // Step 4.
    435  return obj;
    436 }