1 // Copyright 2008 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 // Flags: --expose-gc 29 30 function Catch(f, g) { 31 var r; 32 try { r = f(); } catch (o) { return g(o); } 33 return r; 34 } 35 36 function CatchReturn(f, g) { 37 try { return f(); } catch (o) { return g(o); } 38 } 39 40 41 var a = [Catch, CatchReturn] 42 for (var n in a) { 43 var c = a[n]; 44 assertEquals(1, c(function() { return 1; })); 45 assertEquals('bar', c(function() { return 'bar'; })); 46 assertEquals(1, c(function () { throw 1; }, function (x) { return x; })); 47 assertEquals('bar', c(function () { throw 'bar'; }, function (x) { return x; })); 48 } 49 50 51 assertEquals(1, (function() { try { return 1; } finally { } })()); 52 assertEquals(1, (function() { try { return 1; } finally { var x = 12; } })()); 53 assertEquals(2, (function() { try { } finally { return 2; } })()); 54 assertEquals(4, (function() { try { return 3; } finally { return 4; } })()); 55 56 function f(x, n, v) { try { return x; } finally { x[n] = v; } } 57 assertEquals(2, f({}, 'foo', 2).foo); 58 assertEquals(5, f({}, 'bar', 5).bar); 59 60 function guard(f) { try { f(); } catch (o) { return o; } } 61 assertEquals('baz', guard(function() { throw 'baz'; })); 62 assertEquals(2, (function() { try { throw {}; } catch(e) {} finally { return 2; } })()); 63 assertEquals(1, guard(function() { try { throw 1; } finally { } })); 64 assertEquals(2, guard(function() { try { throw 2; } finally { var x = 12; } })); 65 assertEquals(4, guard(function() { try { throw 3; } finally { throw 4; } })); 66 67 (function () { 68 var iter = 1000000; 69 for (var i = 1; i <= iter; i++) { 70 try { 71 if (i == iter) gc(); 72 } finally { 73 if (i == iter) gc(); 74 } 75 } 76 })(); 77 78 function trycatch(a) { 79 var o; 80 try { 81 throw 1; 82 } catch (o) { 83 a.push(o); 84 try { 85 throw 2; 86 } catch (o) { 87 a.push(o); 88 } 89 a.push(o); 90 } 91 a.push(o); 92 } 93 var a = []; 94 trycatch(a); 95 assertEquals(4, a.length); 96 assertEquals(1, a[0], "a[0]"); 97 assertEquals(2, a[1], "a[1]"); 98 99 assertEquals(1, a[2], "a[2]"); 100 assertTrue(typeof a[3] === 'undefined', "a[3]"); 101 102 assertTrue(typeof o === 'undefined', "global.o"); 103 104 105 function return_from_nested_catch(x) { 106 try { 107 try { 108 return x; 109 } catch (o) { 110 return -1; 111 } 112 } catch (o) { 113 return -2; 114 } 115 } 116 117 assertEquals(0, return_from_nested_catch(0)); 118 assertEquals(1, return_from_nested_catch(1)); 119 120 121 function return_from_nested_finally(x) { 122 var a = [x-2]; 123 try { 124 try { 125 return a; 126 } finally { 127 a[0]++; 128 } 129 } finally { 130 a[0]++; 131 } 132 } 133 134 assertEquals(0, return_from_nested_finally(0)[0]); 135 assertEquals(1, return_from_nested_finally(1)[0]); 136 137 138 function break_from_catch(x) { 139 x--; 140 L: 141 { 142 try { 143 x++; 144 if (false) return -1; 145 break L; 146 } catch (o) { 147 x--; 148 } 149 } 150 return x; 151 } 152 153 assertEquals(0, break_from_catch(0)); 154 assertEquals(1, break_from_catch(1)); 155 156 157 function break_from_finally(x) { 158 L: 159 { 160 try { 161 x++; 162 if (false) return -1; 163 break L; 164 } finally { 165 x--; 166 } 167 x--; 168 } 169 return x; 170 } 171 172 assertEquals(0, break_from_finally(0), "break from finally"); 173 assertEquals(1, break_from_finally(1), "break from finally"); 174 175 176 function continue_from_catch(x) { 177 x--; 178 var cont = true; 179 while (cont) { 180 try { 181 x++; 182 if (false) return -1; 183 cont = false; 184 continue; 185 } catch (o) { 186 x--; 187 } 188 } 189 return x; 190 } 191 192 assertEquals(0, continue_from_catch(0)); 193 assertEquals(1, continue_from_catch(1)); 194 195 196 function continue_from_finally(x) { 197 var cont = true; 198 while (cont) { 199 try { 200 x++; 201 if (false) return -1; 202 cont = false; 203 continue; 204 } finally { 205 x--; 206 } 207 x--; 208 } 209 return x; 210 } 211 212 assertEquals(0, continue_from_finally(0)); 213 assertEquals(1, continue_from_finally(1)); 214 215 216 function continue_alot_from_finally(x) { 217 var j = 0; 218 for (var i = 0; i < x;) { 219 try { 220 j++; 221 continue; 222 j++; // should not happen 223 } finally { 224 i++; // must happen 225 } 226 j++; // should not happen 227 } 228 return j; 229 } 230 231 232 assertEquals(100, continue_alot_from_finally(100)); 233 assertEquals(200, continue_alot_from_finally(200)); 234 235 236 237 function break_from_nested_catch(x) { 238 x -= 2; 239 L: 240 { 241 try { 242 x++; 243 try { 244 x++; 245 if (false) return -1; 246 break L; 247 } catch (o) { 248 x--; 249 } 250 } catch (o) { 251 x--; 252 } 253 } 254 return x; 255 } 256 257 assertEquals(0, break_from_nested_catch(0)); 258 assertEquals(1, break_from_nested_catch(1)); 259 260 261 function break_from_nested_finally(x) { 262 L: 263 { 264 try { 265 x++; 266 try { 267 x++; 268 if (false) return -1; 269 break L; 270 } finally { 271 x--; 272 } 273 } finally { 274 x--; 275 } 276 x--; // should not happen 277 } 278 return x; 279 } 280 281 assertEquals(0, break_from_nested_finally(0)); 282 assertEquals(1, break_from_nested_finally(1)); 283 284 285 function continue_from_nested_catch(x) { 286 x -= 2; 287 var cont = true; 288 while (cont) { 289 try { 290 x++; 291 try { 292 x++; 293 if (false) return -1; 294 cont = false; 295 continue; 296 } catch (o) { 297 x--; 298 } 299 } catch (o) { 300 x--; 301 } 302 } 303 return x; 304 } 305 306 assertEquals(0, continue_from_nested_catch(0)); 307 assertEquals(1, continue_from_nested_catch(1)); 308 309 310 function continue_from_nested_finally(x) { 311 var cont = true; 312 while (cont) { 313 try { 314 x++; 315 try { 316 x++; 317 if (false) return -1; 318 cont = false; 319 continue; 320 } finally { 321 x--; 322 } 323 } finally { 324 x--; 325 } 326 x--; // should not happen 327 } 328 return x; 329 } 330 331 assertEquals(0, continue_from_nested_finally(0)); 332 assertEquals(1, continue_from_nested_finally(1)); 333 334 335 var caught = false; 336 var finalized = false; 337 var broke = true; 338 L: try { 339 break L; 340 broke = false; 341 } catch (o) { 342 caught = true; 343 } finally { 344 finalized = true; 345 } 346 assertTrue(broke); 347 assertFalse(caught); 348 assertTrue(finalized); 349 350 function return_from_nested_finally_in_finally() { 351 try { 352 return 1; 353 } finally { 354 try { 355 return 2; 356 } finally { 357 return 42; 358 } 359 } 360 } 361 362 assertEquals(42, return_from_nested_finally_in_finally()); 363 364 function break_from_nested_finally_in_finally() { 365 L: try { 366 return 1; 367 } finally { 368 try { 369 return 2; 370 } finally { 371 break L; 372 } 373 } 374 return 42; 375 } 376 377 assertEquals(42, break_from_nested_finally_in_finally()); 378 379 function continue_from_nested_finally_in_finally() { 380 do { 381 try { 382 return 1; 383 } finally { 384 try { 385 return 2; 386 } finally { 387 continue; 388 } 389 } 390 } while (false); 391 return 42; 392 } 393 394 assertEquals(42, continue_from_nested_finally_in_finally()); 395