tor-browser

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

arguments-iterator-unmapped.js (3449B)


      1 // Test iteration with an unmapped arguments object.
      2 
      3 function simple() {
      4  function f() {
      5    "use strict";
      6 
      7    var sum = 0;
      8    for (var v of arguments) {
      9      sum += v;
     10    }
     11    return sum;
     12  }
     13 
     14  for (var i = 0; i < 100; ++i) {
     15    assertEq(f(1, 2, 3), 6);
     16  }
     17 }
     18 simple();
     19 
     20 function spreadCall() {
     21  function f() {
     22    var sum = 0;
     23    for (var v of arguments) {
     24      sum += v;
     25    }
     26    return sum;
     27  }
     28 
     29  function g() {
     30    "use strict";
     31    return f(...arguments);
     32  }
     33 
     34  for (var i = 0; i < 100; ++i) {
     35    assertEq(g(1, 2, 3), 6);
     36  }
     37 }
     38 spreadCall();
     39 
     40 function spreadArray() {
     41  function f() {
     42    "use strict";
     43 
     44    var arr = [...arguments];
     45    var sum = 0;
     46    for (var v of arr) {
     47      sum += v;
     48    }
     49    return sum;
     50  }
     51 
     52  for (var i = 0; i < 100; ++i) {
     53    assertEq(f(1, 2, 3), 6);
     54  }
     55 }
     56 spreadArray();
     57 
     58 function reifyIterator() {
     59  var reify = false;
     60  function f() {
     61    "use strict";
     62 
     63    if (reify) {
     64      // Redefining any property attributes will reify the iterator property.
     65      Object.defineProperty(arguments, Symbol.iterator, {
     66        writable: false
     67      });
     68    }
     69 
     70    var sum = 0;
     71    for (var v of arguments) {
     72      sum += v;
     73    }
     74    return sum;
     75  }
     76 
     77  for (var i = 0; i <= 100; ++i) {
     78    reify = i >= 50;
     79    assertEq(f(1, 2, 3), 6);
     80  }
     81 }
     82 reifyIterator();
     83 
     84 function overwriteIterator() {
     85  var callCount = 0;
     86  function Iterator() {
     87    callCount += 1;
     88    return Array.prototype[Symbol.iterator].call(this);
     89  }
     90 
     91  var overwrite = false;
     92  function f() {
     93    "use strict";
     94 
     95    if (overwrite) {
     96      arguments[Symbol.iterator] = Iterator;
     97    }
     98 
     99    var sum = 0;
    100    for (var v of arguments) {
    101      sum += v;
    102    }
    103    return sum;
    104  }
    105 
    106  for (var i = 0; i <= 100; ++i) {
    107    overwrite = i > 50;
    108    assertEq(f(1, 2, 3), 6);
    109  }
    110  assertEq(callCount, 50);
    111 }
    112 overwriteIterator();
    113 
    114 function deleteIterator() {
    115  var remove = false;
    116  function f() {
    117    "use strict";
    118 
    119    // Deleting Symbol.iterator won't change the shape of the arguments object.
    120    // That's why we need to use a separate guard instruction to check if the
    121    // iterator property was modified.
    122    if (remove) {
    123      delete arguments[Symbol.iterator];
    124    }
    125 
    126    var sum = 0;
    127    for (var v of arguments) {
    128      sum += v;
    129    }
    130    return sum;
    131  }
    132 
    133  var error;
    134  try {
    135    for (var i = 0; i <= 100; ++i) {
    136      remove = i === 100;
    137      assertEq(f(1, 2, 3), 6);
    138    }
    139  } catch (e) {
    140    error = e;
    141  }
    142  assertEq(error instanceof TypeError, true);
    143 }
    144 deleteIterator();
    145 
    146 function deleteIteratorInherit() {
    147  var callCount = 0;
    148  function Iterator() {
    149    callCount += 1;
    150    return Array.prototype[Symbol.iterator].call(this);
    151  }
    152 
    153  Object.prototype[Symbol.iterator] = Iterator;
    154 
    155  var remove = false;
    156  function f() {
    157    "use strict";
    158 
    159    // Deleting Symbol.iterator won't change the shape of the arguments object.
    160    // That's why we need to use a separate guard instruction to check if the
    161    // iterator property was modified.
    162    if (remove) {
    163      delete arguments[Symbol.iterator];
    164    }
    165 
    166    var sum = 0;
    167    for (var v of arguments) {
    168      sum += v;
    169    }
    170    return sum;
    171  }
    172 
    173  for (var i = 0; i <= 100; ++i) {
    174    remove = i === 100;
    175    assertEq(f(1, 2, 3), 6);
    176  }
    177  assertEq(callCount, 1);
    178 
    179  delete Object.prototype[Symbol.iterator];
    180 }
    181 deleteIteratorInherit();
    182 
    183 // Don't add tests below this point because |Object.prototype[Symbol.iterator]|
    184 // was modified, which may lead to engine-wide deoptimisations.