tor-browser

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

recover-rest.js (8124B)


      1 // Prevent GC from cancelling/discarding Ion compilations.
      2 gczeal(0);
      3 
      4 // This function is used to force a bailout when it is inlined, and to recover
      5 // the frame which is inlining this function.
      6 var resumeHere = function (i) { if (i >= 99) bailout(); };
      7 
      8 // This function is used to cause an invalidation after having removed a branch
      9 // after DCE. This is made to check if we correctly recover an array
     10 // allocation.
     11 var uceFault = function (i) {
     12  if (i > 98)
     13    uceFault = function (i) { return true; };
     14  return false;
     15 };
     16 
     17 function empty() {}
     18 
     19 var globalArgs;
     20 function escape(args) { globalArgs = args; }
     21 
     22 // Check rest array length.
     23 function length(i, ...rest) {
     24  assertRecoveredOnBailout(rest, true);
     25  return rest.length;
     26 }
     27 
     28 function lengthBail(i, ...rest) {
     29  resumeHere(i);
     30  assertRecoveredOnBailout(rest, true);
     31  return rest.length;
     32 }
     33 
     34 // Check rest array content.
     35 function content(...rest) {
     36  assertEq(rest[0], rest[1]);
     37  assertRecoveredOnBailout(rest, true);
     38  return rest.length;
     39 }
     40 
     41 function contentBail(...rest) {
     42  resumeHere(rest[0]);
     43  assertEq(rest[0], rest[1]);
     44  assertRecoveredOnBailout(rest, true);
     45  return rest.length;
     46 }
     47 
     48 function contentExtraFormals(i, ...rest) {
     49  assertEq(rest[0], i);
     50  assertRecoveredOnBailout(rest, true);
     51  return rest.length;
     52 }
     53 function contentExtraFormalsBail(i, ...rest) {
     54  resumeHere(i);
     55  assertEq(rest[0], i);
     56  assertRecoveredOnBailout(rest, true);
     57  return rest.length;
     58 }
     59 
     60 // No scalar replacement when the rest array is modified.
     61 function setLength(i, ...rest) {
     62  rest.length = 0;
     63  assertRecoveredOnBailout(rest, false);
     64  return rest.length;
     65 }
     66 
     67 function setLengthBail(i, ...rest) {
     68  resumeHere(i);
     69  rest.length = 0;
     70  assertRecoveredOnBailout(rest, false);
     71  return rest.length;
     72 }
     73 
     74 function setContent(i, ...rest) {
     75  rest[0] = "bad";
     76  assertRecoveredOnBailout(rest, false);
     77  return rest.length;
     78 }
     79 
     80 function setContentBail(i, ...rest) {
     81  resumeHere(i);
     82  rest[0] = "bad";
     83  assertRecoveredOnBailout(rest, false);
     84  return rest.length;
     85 }
     86 
     87 function deleteContent(i, ...rest) {
     88  delete rest[0];
     89  assertRecoveredOnBailout(rest, false);
     90  return rest.length;
     91 }
     92 
     93 function deleteContentBail(i, ...rest) {
     94  resumeHere(i);
     95  delete rest[0];
     96  assertRecoveredOnBailout(rest, false);
     97  return rest.length;
     98 }
     99 
    100 // No scalar replacement when the rest array escapes.
    101 function escapes(i, ...rest) {
    102  escape(rest);
    103  assertRecoveredOnBailout(rest, false);
    104  return rest.length;
    105 }
    106 
    107 function escapesBail(i, ...rest) {
    108  resumeHere(i);
    109  escape(rest);
    110  assertRecoveredOnBailout(rest, false);
    111  return rest.length;
    112 }
    113 
    114 // Check rest array with Function.prototype.apply.
    115 function apply(...rest) {
    116  empty.apply(null, rest);
    117  assertRecoveredOnBailout(rest, true);
    118  return rest.length;
    119 }
    120 
    121 function applyBail(...rest) {
    122  resumeHere(rest[0]);
    123  empty.apply(null, rest);
    124  assertRecoveredOnBailout(rest, true);
    125  return rest.length;
    126 }
    127 
    128 function applyExtraFormals(i, ...rest) {
    129  empty.apply(null, rest);
    130  assertRecoveredOnBailout(rest, true);
    131  return rest.length;
    132 }
    133 
    134 function applyExtraFormalsBail(i, ...rest) {
    135  resumeHere(i);
    136  empty.apply(null, rest);
    137  assertRecoveredOnBailout(rest, true);
    138  return rest.length;
    139 }
    140 
    141 // Check rest array with spread.
    142 function spread(...rest) {
    143  empty(...rest);
    144  assertRecoveredOnBailout(rest, true);
    145  return rest.length;
    146 }
    147 
    148 function spreadBail(...rest) {
    149  resumeHere(rest[0]);
    150  empty(...rest);
    151  assertRecoveredOnBailout(rest, true);
    152  return rest.length;
    153 }
    154 
    155 function spreadExtraFormals(i, ...rest) {
    156  empty(...rest);
    157  assertRecoveredOnBailout(rest, true);
    158  return rest.length;
    159 }
    160 
    161 function spreadExtraFormalsBail(i, ...rest) {
    162  resumeHere(i);
    163  empty(...rest);
    164  assertRecoveredOnBailout(rest, true);
    165  return rest.length;
    166 }
    167 
    168 // Extra args currently not supported.
    169 function spreadExtraArgs(...rest) {
    170  empty(0, ...rest);
    171  assertRecoveredOnBailout(rest, false);
    172  return rest.length;
    173 }
    174 
    175 function spreadExtraArgsBail(...rest) {
    176  resumeHere(rest[0]);
    177  empty(0, ...rest);
    178  assertRecoveredOnBailout(rest, false);
    179  return rest.length;
    180 }
    181 
    182 // Check rest array with new spread.
    183 function newSpread(...rest) {
    184  new empty(...rest);
    185  assertRecoveredOnBailout(rest, true);
    186  return rest.length;
    187 }
    188 
    189 function newSpreadBail(...rest) {
    190  resumeHere(rest[0]);
    191  new empty(...rest);
    192  assertRecoveredOnBailout(rest, true);
    193  return rest.length;
    194 }
    195 
    196 function newSpreadExtraFormals(i, ...rest) {
    197  new empty(...rest);
    198  assertRecoveredOnBailout(rest, true);
    199  return rest.length;
    200 }
    201 
    202 function newSpreadExtraFormalsBail(i, ...rest) {
    203  resumeHere(i);
    204  new empty(...rest);
    205  assertRecoveredOnBailout(rest, true);
    206  return rest.length;
    207 }
    208 
    209 // Extra args currently not supported.
    210 function newSpreadExtraArgs(...rest) {
    211  new empty(0, ...rest);
    212  assertRecoveredOnBailout(rest, false);
    213  return rest.length;
    214 }
    215 
    216 function newSpreadExtraArgsBail(...rest) {
    217  resumeHere(rest[0]);
    218  new empty(0, ...rest);
    219  assertRecoveredOnBailout(rest, false);
    220  return rest.length;
    221 }
    222 
    223 // The arguments object isn't mapped.
    224 function setArgs(i, ...rest) {
    225  arguments[1] = "fail";
    226  assertEq(rest[0], i);
    227  assertRecoveredOnBailout(rest, true);
    228  return rest.length;
    229 }
    230 
    231 function setArgsBail(i, ...rest) {
    232  resumeHere(i);
    233  arguments[1] = "fail";
    234  assertEq(rest[0], i);
    235  assertRecoveredOnBailout(rest, true);
    236  return rest.length;
    237 }
    238 
    239 // Check that we correctly allocate the array after taking the recover path.
    240 var uceFault_recoverLength = eval(`(${uceFault})`.replace('uceFault', 'uceFault_recoverLength'));
    241 function recoverLength(i, ...rest) {
    242  if (uceFault_recoverLength(i) || uceFault_recoverLength(i)) {
    243    return rest.length;
    244  }
    245  assertRecoveredOnBailout(rest, true);
    246  return 0;
    247 }
    248 
    249 var uceFault_recoverContent = eval(`(${uceFault})`.replace('uceFault', 'uceFault_recoverContent'));
    250 function recoverContent(i, ...rest) {
    251  if (uceFault_recoverContent(i) || uceFault_recoverContent(i)) {
    252    return rest[0];
    253  }
    254  assertRecoveredOnBailout(rest, true);
    255  return 0;
    256 }
    257 
    258 var uceFault_recoverApply = eval(`(${uceFault})`.replace('uceFault', 'uceFault_recoverApply'));
    259 function recoverApply(i, ...rest) {
    260  if (uceFault_recoverApply(i) || uceFault_recoverApply(i)) {
    261    return empty.apply(null, rest);
    262  }
    263  assertRecoveredOnBailout(rest, true);
    264  return 0;
    265 }
    266 
    267 var uceFault_recoverSpread = eval(`(${uceFault})`.replace('uceFault', 'uceFault_recoverSpread'));
    268 function recoverSpread(i, ...rest) {
    269  if (uceFault_recoverSpread(i) || uceFault_recoverSpread(i)) {
    270    return empty(...rest);
    271  }
    272  assertRecoveredOnBailout(rest, true);
    273  return 0;
    274 }
    275 
    276 var uceFault_recoverNewSpread = eval(`(${uceFault})`.replace('uceFault', 'uceFault_recoverNewSpread'));
    277 function recoverNewSpread(i, ...rest) {
    278  if (uceFault_recoverNewSpread(i) || uceFault_recoverNewSpread(i)) {
    279    return new empty(...rest);
    280  }
    281  assertRecoveredOnBailout(rest, true);
    282  return 0;
    283 }
    284 
    285 var uceFault_recoverSetArgs = eval(`(${uceFault})`.replace('uceFault', 'uceFault_recoverSetArgs'));
    286 function recoverSetArgs(i, ...rest) {
    287  arguments[1] = "fail";
    288  if (uceFault_recoverSetArgs(i) || uceFault_recoverSetArgs(i)) {
    289    // Ensure arguments[1] isn't mapped to rest[0].
    290    assertEq(rest[0], "ok");
    291    return 0;
    292  }
    293  assertRecoveredOnBailout(rest, true);
    294  return 0;
    295 }
    296 
    297 // Prevent compilation of the top-level
    298 eval(`(${resumeHere})`);
    299 
    300 for (let i = 0; i < 100; i++) {
    301  length(i);
    302  lengthBail(i);
    303  content(i, i);
    304  contentBail(i, i);
    305  contentExtraFormals(i, i);
    306  contentExtraFormalsBail(i, i);
    307  setLength(i);
    308  setLengthBail(i);
    309  setContent(i, i);
    310  setContentBail(i, i);
    311  deleteContent(i, i);
    312  deleteContentBail(i, i);
    313  escapes(i);
    314  escapesBail(i);
    315  apply(i);
    316  applyBail(i);
    317  applyExtraFormals(i);
    318  applyExtraFormalsBail(i);
    319  spread(i);
    320  spreadBail(i);
    321  spreadExtraFormals(i);
    322  spreadExtraFormalsBail(i);
    323  spreadExtraArgs(i);
    324  spreadExtraArgsBail(i);
    325  newSpread(i);
    326  newSpreadBail(i);
    327  newSpreadExtraFormals(i);
    328  newSpreadExtraFormalsBail(i);
    329  newSpreadExtraArgs(i);
    330  newSpreadExtraArgsBail(i);
    331  setArgs(i, i);
    332  setArgsBail(i, i);
    333 
    334  recoverLength(i);
    335  recoverContent(i);
    336  recoverApply(i);
    337  recoverSpread(i);
    338  recoverNewSpread(i);
    339  recoverSetArgs(i, "ok");
    340 }