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 30function Catch(f, g) { 31 var r; 32 try { r = f(); } catch (o) { return g(o); } 33 return r; 34} 35 36function CatchReturn(f, g) { 37 try { return f(); } catch (o) { return g(o); } 38} 39 40 41var a = [Catch, CatchReturn] 42for (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 51assertEquals(1, (function() { try { return 1; } finally { } })()); 52assertEquals(1, (function() { try { return 1; } finally { var x = 12; } })()); 53assertEquals(2, (function() { try { } finally { return 2; } })()); 54assertEquals(4, (function() { try { return 3; } finally { return 4; } })()); 55 56function f(x, n, v) { try { return x; } finally { x[n] = v; } } 57assertEquals(2, f({}, 'foo', 2).foo); 58assertEquals(5, f({}, 'bar', 5).bar); 59 60function guard(f) { try { f(); } catch (o) { return o; } } 61assertEquals('baz', guard(function() { throw 'baz'; })); 62assertEquals(2, (function() { try { throw {}; } catch(e) {} finally { return 2; } })()); 63assertEquals(1, guard(function() { try { throw 1; } finally { } })); 64assertEquals(2, guard(function() { try { throw 2; } finally { var x = 12; } })); 65assertEquals(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 78function 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} 93var a = []; 94trycatch(a); 95assertEquals(4, a.length); 96assertEquals(1, a[0], "a[0]"); 97assertEquals(2, a[1], "a[1]"); 98 99assertEquals(1, a[2], "a[2]"); 100assertTrue(typeof a[3] === 'undefined', "a[3]"); 101 102assertTrue(typeof o === 'undefined', "global.o"); 103 104 105function 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 117assertEquals(0, return_from_nested_catch(0)); 118assertEquals(1, return_from_nested_catch(1)); 119 120 121function 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 134assertEquals(0, return_from_nested_finally(0)[0]); 135assertEquals(1, return_from_nested_finally(1)[0]); 136 137 138function 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 153assertEquals(0, break_from_catch(0)); 154assertEquals(1, break_from_catch(1)); 155 156 157function 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 172assertEquals(0, break_from_finally(0), "break from finally"); 173assertEquals(1, break_from_finally(1), "break from finally"); 174 175 176function 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 192assertEquals(0, continue_from_catch(0)); 193assertEquals(1, continue_from_catch(1)); 194 195 196function 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 212assertEquals(0, continue_from_finally(0)); 213assertEquals(1, continue_from_finally(1)); 214 215 216function 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 232assertEquals(100, continue_alot_from_finally(100)); 233assertEquals(200, continue_alot_from_finally(200)); 234 235 236 237function 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 257assertEquals(0, break_from_nested_catch(0)); 258assertEquals(1, break_from_nested_catch(1)); 259 260 261function 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 281assertEquals(0, break_from_nested_finally(0)); 282assertEquals(1, break_from_nested_finally(1)); 283 284 285function 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 306assertEquals(0, continue_from_nested_catch(0)); 307assertEquals(1, continue_from_nested_catch(1)); 308 309 310function 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 331assertEquals(0, continue_from_nested_finally(0)); 332assertEquals(1, continue_from_nested_finally(1)); 333 334 335var caught = false; 336var finalized = false; 337var broke = true; 338L: try { 339 break L; 340 broke = false; 341} catch (o) { 342 caught = true; 343} finally { 344 finalized = true; 345} 346assertTrue(broke); 347assertFalse(caught); 348assertTrue(finalized); 349 350function 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 362assertEquals(42, return_from_nested_finally_in_finally()); 363 364function 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 377assertEquals(42, break_from_nested_finally_in_finally()); 378 379function 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 394assertEquals(42, continue_from_nested_finally_in_finally()); 395