recover-bigint.js (7026B)
1 // |jit-test| --ion-limit-script-size=off 2 3 setJitCompilerOption("baseline.warmup.trigger", 9); 4 setJitCompilerOption("ion.warmup.trigger", 20); 5 6 // Prevent the GC from cancelling Ion compilations, when we expect them to succeed 7 gczeal(0); 8 9 // Keep in sync with BigInt::MaxBitLength. 10 const maxBitLength = 1024 * 1024; 11 12 const maxBigInt = BigInt.asUintN(maxBitLength, -1n); 13 const minBigInt = -maxBigInt; 14 15 function resumeHere() {} 16 17 function bigIntAddBail(i) { 18 var x = [0n, maxBigInt][0 + (i >= 99)]; 19 20 var a = x + 1n; 21 22 // Add a function call to capture a resumepoint at the end of the call or 23 // inside the inlined block, such as the bailout does not rewind to the 24 // beginning of the function. 25 resumeHere(); 26 27 if (i >= 99) { 28 bailout(); 29 // Flag the computation as having removed uses to check that we properly 30 // report the error while executing the BigInt operation on bailout. 31 return a; 32 } 33 } 34 35 function bigIntSubBail(i) { 36 var x = [0n, minBigInt][0 + (i >= 99)]; 37 38 var a = x - 1n; 39 40 // Add a function call to capture a resumepoint at the end of the call or 41 // inside the inlined block, such as the bailout does not rewind to the 42 // beginning of the function. 43 resumeHere(); 44 45 if (i >= 99) { 46 bailout(); 47 // Flag the computation as having removed uses to check that we properly 48 // report the error while executing the BigInt operation on bailout. 49 return a; 50 } 51 } 52 53 function bigIntMulBail(i) { 54 var x = [0n, maxBigInt][0 + (i >= 99)]; 55 56 var a = x * 2n; 57 58 // Add a function call to capture a resumepoint at the end of the call or 59 // inside the inlined block, such as the bailout does not rewind to the 60 // beginning of the function. 61 resumeHere(); 62 63 if (i >= 99) { 64 bailout(); 65 // Flag the computation as having removed uses to check that we properly 66 // report the error while executing the BigInt operation on bailout. 67 return a; 68 } 69 } 70 71 function bigIntIncBail(i) { 72 var x = [0n, maxBigInt][0 + (i >= 99)]; 73 74 var a = x++; 75 76 // Add a function call to capture a resumepoint at the end of the call or 77 // inside the inlined block, such as the bailout does not rewind to the 78 // beginning of the function. 79 resumeHere(); 80 81 if (i >= 99) { 82 bailout(); 83 // Flag the computation as having removed uses to check that we properly 84 // report the error while executing the BigInt operation on bailout. 85 return x; 86 } 87 } 88 89 function bigIntDecBail(i) { 90 var x = [0n, minBigInt][0 + (i >= 99)]; 91 92 var a = x--; 93 94 // Add a function call to capture a resumepoint at the end of the call or 95 // inside the inlined block, such as the bailout does not rewind to the 96 // beginning of the function. 97 resumeHere(); 98 99 if (i >= 99) { 100 bailout(); 101 // Flag the computation as having removed uses to check that we properly 102 // report the error while executing the BigInt operation on bailout. 103 return x; 104 } 105 } 106 107 function bigIntBitNotBail(i) { 108 var x = [0n, maxBigInt][0 + (i >= 99)]; 109 110 var a = ~x; 111 112 // Add a function call to capture a resumepoint at the end of the call or 113 // inside the inlined block, such as the bailout does not rewind to the 114 // beginning of the function. 115 resumeHere(); 116 117 if (i >= 99) { 118 bailout(); 119 // Flag the computation as having removed uses to check that we properly 120 // report the error while executing the BigInt operation on bailout. 121 return a; 122 } 123 } 124 125 function bigIntLshBail(i) { 126 var shift = [0n, BigInt(maxBitLength)][0 + (i >= 99)]; 127 128 var a = 1n << shift; 129 130 // Add a function call to capture a resumepoint at the end of the call or 131 // inside the inlined block, such as the bailout does not rewind to the 132 // beginning of the function. 133 resumeHere(); 134 135 if (i >= 99) { 136 bailout(); 137 // Flag the computation as having removed uses to check that we properly 138 // report the error while executing the BigInt operation on bailout. 139 return a; 140 } 141 } 142 143 function bigIntRshBail(i) { 144 var shift = [0n, -BigInt(maxBitLength)][0 + (i >= 99)]; 145 146 var a = 1n >> shift; 147 148 // Add a function call to capture a resumepoint at the end of the call or 149 // inside the inlined block, such as the bailout does not rewind to the 150 // beginning of the function. 151 resumeHere(); 152 153 if (i >= 99) { 154 bailout(); 155 // Flag the computation as having removed uses to check that we properly 156 // report the error while executing the BigInt operation on bailout. 157 return a; 158 } 159 } 160 161 function bigIntAsUintBail(i) { 162 var x = [0, maxBitLength + 1][0 + (i >= 99)]; 163 164 var a = BigInt.asUintN(x, -1n); 165 166 // Add a function call to capture a resumepoint at the end of the call or 167 // inside the inlined block, such as the bailout does not rewind to the 168 // beginning of the function. 169 resumeHere(); 170 171 if (i >= 99) { 172 bailout(); 173 // Flag the computation as having removed uses to check that we properly 174 // report the error while executing the BigInt operation on bailout. 175 return a; 176 } 177 } 178 179 // Prevent compilation of the top-level 180 eval(`(${resumeHere})`); 181 182 // The bigIntXBail() functions create a BigInt which exceeds the maximum 183 // representable BigInt. This results in either throwing a RangeError or an 184 // out-of-memory error when the operation is recovered during a bailout. 185 186 try { 187 for (let i = 0; i < 100; i++) { 188 bigIntAddBail(i); 189 } 190 throw new Error("missing exception"); 191 } catch (e) { 192 assertEq(e instanceof RangeError || e === "out of memory", true, String(e)); 193 } 194 195 try { 196 for (let i = 0; i < 100; i++) { 197 bigIntSubBail(i); 198 } 199 throw new Error("missing exception"); 200 } catch (e) { 201 assertEq(e instanceof RangeError || e === "out of memory", true, String(e)); 202 } 203 204 try { 205 for (let i = 0; i < 100; i++) { 206 bigIntMulBail(i); 207 } 208 throw new Error("missing exception"); 209 } catch (e) { 210 assertEq(e instanceof RangeError || e === "out of memory", true, String(e)); 211 } 212 213 try { 214 for (let i = 0; i < 100; i++) { 215 bigIntIncBail(i); 216 } 217 throw new Error("missing exception"); 218 } catch (e) { 219 assertEq(e instanceof RangeError || e === "out of memory", true, String(e)); 220 } 221 222 try { 223 for (let i = 0; i < 100; i++) { 224 bigIntDecBail(i); 225 } 226 throw new Error("missing exception"); 227 } catch (e) { 228 assertEq(e instanceof RangeError || e === "out of memory", true, String(e)); 229 } 230 231 try { 232 for (let i = 0; i < 100; i++) { 233 bigIntBitNotBail(i); 234 } 235 throw new Error("missing exception"); 236 } catch (e) { 237 assertEq(e instanceof RangeError || e === "out of memory", true, String(e)); 238 } 239 240 try { 241 for (let i = 0; i < 100; i++) { 242 bigIntLshBail(i); 243 } 244 throw new Error("missing exception"); 245 } catch (e) { 246 assertEq(e instanceof RangeError || e === "out of memory", true, String(e)); 247 } 248 249 try { 250 for (let i = 0; i < 100; i++) { 251 bigIntRshBail(i); 252 } 253 throw new Error("missing exception"); 254 } catch (e) { 255 assertEq(e instanceof RangeError || e === "out of memory", true, String(e)); 256 } 257 258 try { 259 for (let i = 0; i < 100; i++) { 260 bigIntAsUintBail(i); 261 } 262 throw new Error("missing exception"); 263 } catch (e) { 264 assertEq(e instanceof RangeError || e === "out of memory", true, String(e)); 265 }