tor-browser

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

Set.js (13359B)


      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 // ES2017 draft rev 0e10c9f29fca1385980c08a7d5e7bb3eb775e2e4
      6 // 23.2.1.1 Set, steps 6-8
      7 function SetConstructorInit(iterable) {
      8  var set = this;
      9 
     10  // Step 6.a.
     11  var adder = set.add;
     12 
     13  // Step 6.b.
     14  if (!IsCallable(adder)) {
     15    ThrowTypeError(JSMSG_NOT_FUNCTION, typeof adder);
     16  }
     17 
     18  // Steps 6.c-8.
     19  for (var nextValue of allowContentIter(iterable)) {
     20    callContentFunction(adder, set, nextValue);
     21  }
     22 }
     23 
     24 // ES2018 draft rev f83aa38282c2a60c6916ebc410bfdf105a0f6a54
     25 // 23.2.3.6 Set.prototype.forEach ( callbackfn [ , thisArg ] )
     26 function SetForEach(callbackfn, thisArg = undefined) {
     27  // Step 1.
     28  var S = this;
     29 
     30  // Steps 2-3.
     31  if (!IsObject(S) || (S = GuardToSetObject(S)) === null) {
     32    return callFunction(
     33      CallSetMethodIfWrapped,
     34      this,
     35      callbackfn,
     36      thisArg,
     37      "SetForEach"
     38    );
     39  }
     40 
     41  // Step 4.
     42  if (!IsCallable(callbackfn)) {
     43    ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
     44  }
     45 
     46  // Steps 5-8.
     47  var values = callFunction(std_Set_values, S);
     48 
     49  // Inlined: SetIteratorNext
     50  var setIterationResult = globalSetIterationResult;
     51 
     52  while (true) {
     53    var done = GetNextSetEntryForIterator(values, setIterationResult);
     54    if (done) {
     55      break;
     56    }
     57 
     58    var value = setIterationResult[0];
     59    setIterationResult[0] = null;
     60 
     61    callContentFunction(callbackfn, thisArg, value, value, S);
     62  }
     63 }
     64 
     65 // ES6 final draft 23.2.2.2.
     66 // Uncloned functions with `$` prefix are allocated as extended function
     67 // to store the original name in `SetCanonicalName`.
     68 function $SetSpecies() {
     69  // Step 1.
     70  return this;
     71 }
     72 SetCanonicalName($SetSpecies, "get [Symbol.species]");
     73 
     74 var globalSetIterationResult = CreateSetIterationResult();
     75 
     76 function SetIteratorNext() {
     77  // Step 1.
     78  var O = this;
     79 
     80  // Steps 2-3.
     81  if (!IsObject(O) || (O = GuardToSetIterator(O)) === null) {
     82    return callFunction(
     83      CallSetIteratorMethodIfWrapped,
     84      this,
     85      "SetIteratorNext"
     86    );
     87  }
     88 
     89  // Steps 4-5 (implemented in GetNextSetEntryForIterator).
     90  // Steps 8-9 (omitted).
     91 
     92  var setIterationResult = globalSetIterationResult;
     93 
     94  var retVal = { value: undefined, done: true };
     95 
     96  // Steps 10.a, 11.
     97  var done = GetNextSetEntryForIterator(O, setIterationResult);
     98  if (!done) {
     99    // Steps 10.b-c (omitted).
    100 
    101    // Step 6.
    102    var itemKind = UnsafeGetInt32FromReservedSlot(O, MAP_SET_ITERATOR_SLOT_ITEM_KIND);
    103 
    104    var result;
    105    if (itemKind === ITEM_KIND_VALUE) {
    106      // Step 10.d.i.
    107      result = setIterationResult[0];
    108    } else {
    109      // Step 10.d.ii.
    110      assert(itemKind === ITEM_KIND_KEY_AND_VALUE, itemKind);
    111      result = [setIterationResult[0], setIterationResult[0]];
    112    }
    113 
    114    setIterationResult[0] = null;
    115    retVal.value = result;
    116    retVal.done = false;
    117  }
    118 
    119  // Steps 7, 10.d, 12.
    120  return retVal;
    121 }
    122 
    123 // GetSetRecord ( obj )
    124 //
    125 // https://tc39.es/proposal-set-methods/#sec-getsetrecord
    126 function GetSetRecord(obj) {
    127  // Step 1.
    128  if (!IsObject(obj)) {
    129    ThrowTypeError(JSMSG_OBJECT_REQUIRED, obj === null ? "null" : typeof obj);
    130  }
    131 
    132  // Step 2.
    133  var rawSize = obj.size;
    134 
    135  // Step 3.
    136  var numSize = +rawSize;
    137 
    138  // Steps 4-5.
    139  if (numSize !== numSize) {
    140    if (rawSize === undefined) {
    141      ThrowTypeError(JSMSG_UNEXPECTED_TYPE, "size", "undefined");
    142    } else {
    143      ThrowTypeError(JSMSG_UNEXPECTED_TYPE, "size", "NaN");
    144    }
    145  }
    146 
    147  // Step 6.
    148  var intSize = ToInteger(numSize);
    149 
    150  // Step 7.
    151  if (intSize < 0) {
    152    ThrowRangeError(JSMSG_SET_NEGATIVE_SIZE);
    153  }
    154 
    155  // Step 8.
    156  var has = obj.has;
    157 
    158  // Step 9.
    159  if (!IsCallable(has)) {
    160    ThrowTypeError(JSMSG_PROPERTY_NOT_CALLABLE, "has");
    161  }
    162 
    163  // Step 10.
    164  var keys = obj.keys;
    165 
    166  // Step 11.
    167  if (!IsCallable(keys)) {
    168    ThrowTypeError(JSMSG_PROPERTY_NOT_CALLABLE, "keys");
    169  }
    170 
    171  // Step 12.
    172  return { set: obj, size: intSize, has, keys };
    173 }
    174 
    175 // 7.4.2 GetIteratorFromMethod ( obj, method )
    176 //
    177 // ES2024 draft rev a103b287cd19bdc51c7a3d8d7c1431b1506a74e2
    178 function GetIteratorFromMethod(setRec) {
    179  // Step 1.
    180  var keysIter = callContentFunction(setRec.keys, setRec.set);
    181 
    182  // Step 2.
    183  if (!IsObject(keysIter)) {
    184    ThrowTypeError(
    185      JSMSG_OBJECT_REQUIRED,
    186      keysIter === null ? "null" : typeof keysIter
    187    );
    188  }
    189 
    190  // Step 3. (Implemented in caller.)
    191 
    192  // Step 4.
    193  return keysIter;
    194 }
    195 
    196 // Set.prototype.union ( other )
    197 //
    198 // https://tc39.es/proposal-set-methods/#sec-set.prototype.union
    199 function SetUnion(other) {
    200  // Step 1.
    201  var O = this;
    202 
    203  // Step 2.
    204  if (!IsObject(O) || (O = GuardToSetObject(O)) === null) {
    205    return callFunction(CallSetMethodIfWrapped, this, other, "SetUnion");
    206  }
    207 
    208  // Step 3.
    209  var otherRec = GetSetRecord(other);
    210 
    211  // Step 4.
    212  var keysIter = GetIteratorFromMethod(otherRec);
    213  var keysIterNext = keysIter.next;
    214 
    215  // Steps 5 and 8-9. (Reordered)
    216  var result = SetCopy(O);
    217 
    218  // Steps 6-7.
    219  for (var nextValue of allowContentIterWithNext(keysIter, keysIterNext)) {
    220    // Step 7.a and 7.b.i. (Implicit through for-of loop)
    221 
    222    // Steps 7.b.ii-iii. (Implicit through std_Set_add)
    223 
    224    // Step 7.b.iii.1.
    225    callFunction(std_Set_add, result, nextValue);
    226  }
    227 
    228  // Step 10.
    229  return result;
    230 }
    231 
    232 // Set.prototype.intersection ( other )
    233 //
    234 // https://tc39.es/proposal-set-methods/#sec-set.prototype.intersection
    235 function SetIntersection(other) {
    236  // Step 1.
    237  var O = this;
    238 
    239  // Step 2.
    240  if (!IsObject(O) || (O = GuardToSetObject(O)) === null) {
    241    return callFunction(CallSetMethodIfWrapped, this, other, "SetIntersection");
    242  }
    243 
    244  // Step 3.
    245  var otherRec = GetSetRecord(other);
    246 
    247  // Steps 4 and 8-9. (Reordered)
    248  var Set = GetBuiltinConstructor("Set");
    249  var result = new Set();
    250 
    251  // Step 5.
    252  var thisSize = callFunction(std_Set_size, O);
    253 
    254  // Steps 6-7.
    255  if (thisSize <= otherRec.size) {
    256    // Steps 6.a-b.
    257    var values = callFunction(std_Set_values, O);
    258    var setIterationResult = globalSetIterationResult;
    259    while (true) {
    260      var done = GetNextSetEntryForIterator(values, setIterationResult);
    261      if (done) {
    262        break;
    263      }
    264 
    265      var value = setIterationResult[0];
    266      setIterationResult[0] = null;
    267 
    268      // Steps 6.b.i-ii. (Implicit through SetIterator)
    269 
    270      // Steps 6.b.iii.1-2.
    271      if (callContentFunction(otherRec.has, otherRec.set, value)) {
    272        // Steps 6.b.iii.2.a-b. (Implicit through std_Set_add)
    273 
    274        // Step 6.b.iii.2.c.i.
    275        callFunction(std_Set_add, result, value);
    276      }
    277 
    278      // Steps 6.b.iii.3-4. (Implicit through SetIterator)
    279    }
    280  } else {
    281    // Step 7.a.
    282    var keysIter = GetIteratorFromMethod(otherRec);
    283 
    284    // Steps 7.b-c.
    285    for (var nextValue of allowContentIterWithNext(keysIter, keysIter.next)) {
    286      // Step 7.c.i and 7.c.ii.1. (Implicit through for-of loop)
    287 
    288      // Steps 7.c.ii.2-4. (Implicit through std_Set_add)
    289 
    290      // Steps 7.c.ii.5-6.
    291      if (callFunction(std_Set_has, O, nextValue)) {
    292        callFunction(std_Set_add, result, nextValue);
    293      }
    294    }
    295  }
    296 
    297  // Step 10.
    298  return result;
    299 }
    300 
    301 // Set.prototype.difference ( other )
    302 //
    303 // https://tc39.es/proposal-set-methods/#sec-set.prototype.difference
    304 function SetDifference(other) {
    305  // Step 1.
    306  var O = this;
    307 
    308  // Step 2.
    309  if (!IsObject(O) || (O = GuardToSetObject(O)) === null) {
    310    return callFunction(CallSetMethodIfWrapped, this, other, "SetDifference");
    311  }
    312 
    313  // Step 3.
    314  var otherRec = GetSetRecord(other);
    315 
    316  // Steps 4 and 8-9. (Reordered)
    317  var result = SetCopy(O);
    318 
    319  // Step 5.
    320  var thisSize = callFunction(std_Set_size, O);
    321 
    322  // Steps 6-7.
    323  if (thisSize <= otherRec.size) {
    324    // Steps 6.a-b.
    325    var values = callFunction(std_Set_values, result);
    326    var setIterationResult = globalSetIterationResult;
    327    while (true) {
    328      var done = GetNextSetEntryForIterator(values, setIterationResult);
    329      if (done) {
    330        break;
    331      }
    332 
    333      var value = setIterationResult[0];
    334      setIterationResult[0] = null;
    335 
    336      // Steps 6.b.i-ii. (Implicit through SetIterator)
    337 
    338      // Steps 6.b.iii.1-2.
    339      if (callContentFunction(otherRec.has, otherRec.set, value)) {
    340        callFunction(std_Set_delete, result, value);
    341      }
    342    }
    343  } else {
    344    // Step 7.a.
    345    var keysIter = GetIteratorFromMethod(otherRec);
    346 
    347    // Steps 7.b-c.
    348    for (var nextValue of allowContentIterWithNext(keysIter, keysIter.next)) {
    349      // Step 7.c.i and 7.c.ii.1. (Implicit through for-of loop)
    350 
    351      // Steps 7.c.ii.2-3.
    352      callFunction(std_Set_delete, result, nextValue);
    353    }
    354  }
    355 
    356  // Step 10.
    357  return result;
    358 }
    359 
    360 // Set.prototype.symmetricDifference ( other )
    361 //
    362 // https://tc39.es/proposal-set-methods/#sec-set.prototype.symmetricdifference
    363 function SetSymmetricDifference(other) {
    364  // Step 1.
    365  var O = this;
    366 
    367  // Step 2.
    368  if (!IsObject(O) || (O = GuardToSetObject(O)) === null) {
    369    return callFunction(
    370      CallSetMethodIfWrapped,
    371      this,
    372      other,
    373      "SetSymmetricDifference"
    374    );
    375  }
    376 
    377  // Step 3.
    378  var otherRec = GetSetRecord(other);
    379 
    380  // Step 4.
    381  var keysIter = GetIteratorFromMethod(otherRec);
    382  var keysIterNext = keysIter.next;
    383 
    384  // Steps 5 and 8-9. (Reordered)
    385  var result = SetCopy(O);
    386 
    387  // Steps 6-7.
    388  for (var nextValue of allowContentIterWithNext(keysIter, keysIterNext)) {
    389    // Step 7.a and 7.b.i. (Implicit through for-of loop)
    390 
    391    // Steps 7.b.ii-iii. (Implicit through std_Set_has)
    392 
    393    // Steps 7.b.iv-v.
    394    if (callFunction(std_Set_has, O, nextValue)) {
    395      // Step 7.b.iv.1.
    396      callFunction(std_Set_delete, result, nextValue);
    397    } else {
    398      // Step 7.b.v.1.
    399      callFunction(std_Set_add, result, nextValue);
    400    }
    401  }
    402 
    403  // Step 10.
    404  return result;
    405 }
    406 
    407 // Set.prototype.isSubsetOf ( other )
    408 //
    409 // https://tc39.es/proposal-set-methods/#sec-set.prototype.issubsetof
    410 function SetIsSubsetOf(other) {
    411  // Step 1.
    412  var O = this;
    413 
    414  // Step 2.
    415  if (!IsObject(O) || (O = GuardToSetObject(O)) === null) {
    416    return callFunction(CallSetMethodIfWrapped, this, other, "SetIsSubsetOf");
    417  }
    418 
    419  // Step 3.
    420  var otherRec = GetSetRecord(other);
    421 
    422  // Step 4.
    423  var thisSize = callFunction(std_Set_size, O);
    424 
    425  // Step 5.
    426  if (thisSize > otherRec.size) {
    427    return false;
    428  }
    429 
    430  // Steps 6-7.
    431  var values = callFunction(std_Set_values, O);
    432  var setIterationResult = globalSetIterationResult;
    433  while (true) {
    434    var done = GetNextSetEntryForIterator(values, setIterationResult);
    435    if (done) {
    436      break;
    437    }
    438 
    439    var value = setIterationResult[0];
    440    setIterationResult[0] = null;
    441 
    442    // Steps 7.a-b. (Implicit through SetIterator)
    443 
    444    // Steps 7.c-d.
    445    if (!callContentFunction(otherRec.has, otherRec.set, value)) {
    446      return false;
    447    }
    448 
    449    // Steps 7.e-f. (Implicit through SetIterator)
    450  }
    451 
    452  // Step 7.
    453  return true;
    454 }
    455 
    456 // Set.prototype.isSupersetOf ( other )
    457 //
    458 // https://tc39.es/proposal-set-methods/#sec-set.prototype.issupersetof
    459 function SetIsSupersetOf(other) {
    460  // Step 1.
    461  var O = this;
    462 
    463  // Step 2.
    464  if (!IsObject(O) || (O = GuardToSetObject(O)) === null) {
    465    return callFunction(CallSetMethodIfWrapped, this, other, "SetIsSupersetOf");
    466  }
    467 
    468  // Step 3.
    469  var otherRec = GetSetRecord(other);
    470 
    471  // Step 4.
    472  var thisSize = callFunction(std_Set_size, O);
    473 
    474  // Step 5.
    475  if (thisSize < otherRec.size) {
    476    return false;
    477  }
    478 
    479  // Step 6.
    480  var keysIter = GetIteratorFromMethod(otherRec);
    481 
    482  // Steps 7-8.
    483  for (var nextValue of allowContentIterWithNext(keysIter, keysIter.next)) {
    484    // Step 8.a and 8.b.i. (Implicit through for-of loop)
    485 
    486    // Step 8.b.ii.
    487    if (!callFunction(std_Set_has, O, nextValue)) {
    488      // Step 8.b.ii.1. (Implicit through for-of loop)
    489 
    490      // Step 8.b.ii.2.
    491      return false;
    492    }
    493  }
    494 
    495  // Step 9.
    496  return true;
    497 }
    498 
    499 // Set.prototype.isDisjointFrom ( other )
    500 //
    501 // https://tc39.es/proposal-set-methods/#sec-set.prototype.isdisjointfrom
    502 function SetIsDisjointFrom(other) {
    503  // Step 1.
    504  var O = this;
    505 
    506  // Step 2.
    507  if (!IsObject(O) || (O = GuardToSetObject(O)) === null) {
    508    return callFunction(
    509      CallSetMethodIfWrapped,
    510      this,
    511      other,
    512      "SetIsDisjointFrom"
    513    );
    514  }
    515 
    516  // Step 3.
    517  var otherRec = GetSetRecord(other);
    518 
    519  // Step 4.
    520  var thisSize = callFunction(std_Set_size, O);
    521 
    522  // Steps 5-6.
    523  if (thisSize <= otherRec.size) {
    524    // Steps 5.a-b.
    525    var values = callFunction(std_Set_values, O);
    526    var setIterationResult = globalSetIterationResult;
    527    while (true) {
    528      var done = GetNextSetEntryForIterator(values, setIterationResult);
    529      if (done) {
    530        break;
    531      }
    532 
    533      var value = setIterationResult[0];
    534      setIterationResult[0] = null;
    535 
    536      // Step 5.b.i-ii. (Implicit through SetIterator)
    537 
    538      // Steps 5.b.iii.1-2.
    539      if (callContentFunction(otherRec.has, otherRec.set, value)) {
    540        return false;
    541      }
    542 
    543      // Steps 5.b.iii.3-4. (Implicit through SetIterator)
    544    }
    545  } else {
    546    // Step 6.a.
    547    var keysIter = GetIteratorFromMethod(otherRec);
    548 
    549    // Steps 6.b-c.
    550    for (var nextValue of allowContentIterWithNext(keysIter, keysIter.next)) {
    551      // Step 6.c.i and 6.c.ii.1. (Implicit through for-of loop)
    552 
    553      // Step 6.c.ii.2.
    554      if (callFunction(std_Set_has, O, nextValue)) {
    555        // Step 6.c.ii.2.a. (Implicit through for-of loop)
    556 
    557        // Step 6.c.ii.2.b.
    558        return false;
    559      }
    560    }
    561  }
    562 
    563  // Step 7.
    564  return true;
    565 }