// Copyright 2008 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Flags: --expose-gc function Catch(f, g) { var r; try { r = f(); } catch (o) { return g(o); } return r; } function CatchReturn(f, g) { try { return f(); } catch (o) { return g(o); } } var a = [Catch, CatchReturn] for (var n in a) { var c = a[n]; assertEquals(1, c(function() { return 1; })); assertEquals('bar', c(function() { return 'bar'; })); assertEquals(1, c(function () { throw 1; }, function (x) { return x; })); assertEquals('bar', c(function () { throw 'bar'; }, function (x) { return x; })); } assertEquals(1, (function() { try { return 1; } finally { } })()); assertEquals(1, (function() { try { return 1; } finally { var x = 12; } })()); assertEquals(2, (function() { try { } finally { return 2; } })()); assertEquals(4, (function() { try { return 3; } finally { return 4; } })()); function f(x, n, v) { try { return x; } finally { x[n] = v; } } assertEquals(2, f({}, 'foo', 2).foo); assertEquals(5, f({}, 'bar', 5).bar); function guard(f) { try { f(); } catch (o) { return o; } } assertEquals('baz', guard(function() { throw 'baz'; })); assertEquals(2, (function() { try { throw {}; } catch(e) {} finally { return 2; } })()); assertEquals(1, guard(function() { try { throw 1; } finally { } })); assertEquals(2, guard(function() { try { throw 2; } finally { var x = 12; } })); assertEquals(4, guard(function() { try { throw 3; } finally { throw 4; } })); (function () { var iter = 1000000; for (var i = 1; i <= iter; i++) { try { if (i == iter) gc(); } finally { if (i == iter) gc(); } } })(); function trycatch(a) { var o; try { throw 1; } catch (o) { a.push(o); try { throw 2; } catch (o) { a.push(o); } a.push(o); } a.push(o); } var a = []; trycatch(a); assertEquals(4, a.length); assertEquals(1, a[0], "a[0]"); assertEquals(2, a[1], "a[1]"); assertEquals(1, a[2], "a[2]"); assertTrue(typeof a[3] === 'undefined', "a[3]"); assertTrue(typeof o === 'undefined', "global.o"); function return_from_nested_catch(x) { try { try { return x; } catch (o) { return -1; } } catch (o) { return -2; } } assertEquals(0, return_from_nested_catch(0)); assertEquals(1, return_from_nested_catch(1)); function return_from_nested_finally(x) { var a = [x-2]; try { try { return a; } finally { a[0]++; } } finally { a[0]++; } } assertEquals(0, return_from_nested_finally(0)[0]); assertEquals(1, return_from_nested_finally(1)[0]); function break_from_catch(x) { x--; L: { try { x++; if (false) return -1; break L; } catch (o) { x--; } } return x; } assertEquals(0, break_from_catch(0)); assertEquals(1, break_from_catch(1)); function break_from_finally(x) { L: { try { x++; if (false) return -1; break L; } finally { x--; } x--; } return x; } assertEquals(0, break_from_finally(0), "break from finally"); assertEquals(1, break_from_finally(1), "break from finally"); function continue_from_catch(x) { x--; var cont = true; while (cont) { try { x++; if (false) return -1; cont = false; continue; } catch (o) { x--; } } return x; } assertEquals(0, continue_from_catch(0)); assertEquals(1, continue_from_catch(1)); function continue_from_finally(x) { var cont = true; while (cont) { try { x++; if (false) return -1; cont = false; continue; } finally { x--; } x--; } return x; } assertEquals(0, continue_from_finally(0)); assertEquals(1, continue_from_finally(1)); function continue_alot_from_finally(x) { var j = 0; for (var i = 0; i < x;) { try { j++; continue; j++; // should not happen } finally { i++; // must happen } j++; // should not happen } return j; } assertEquals(100, continue_alot_from_finally(100)); assertEquals(200, continue_alot_from_finally(200)); function break_from_nested_catch(x) { x -= 2; L: { try { x++; try { x++; if (false) return -1; break L; } catch (o) { x--; } } catch (o) { x--; } } return x; } assertEquals(0, break_from_nested_catch(0)); assertEquals(1, break_from_nested_catch(1)); function break_from_nested_finally(x) { L: { try { x++; try { x++; if (false) return -1; break L; } finally { x--; } } finally { x--; } x--; // should not happen } return x; } assertEquals(0, break_from_nested_finally(0)); assertEquals(1, break_from_nested_finally(1)); function continue_from_nested_catch(x) { x -= 2; var cont = true; while (cont) { try { x++; try { x++; if (false) return -1; cont = false; continue; } catch (o) { x--; } } catch (o) { x--; } } return x; } assertEquals(0, continue_from_nested_catch(0)); assertEquals(1, continue_from_nested_catch(1)); function continue_from_nested_finally(x) { var cont = true; while (cont) { try { x++; try { x++; if (false) return -1; cont = false; continue; } finally { x--; } } finally { x--; } x--; // should not happen } return x; } assertEquals(0, continue_from_nested_finally(0)); assertEquals(1, continue_from_nested_finally(1)); var caught = false; var finalized = false; var broke = true; L: try { break L; broke = false; } catch (o) { caught = true; } finally { finalized = true; } assertTrue(broke); assertFalse(caught); assertTrue(finalized); function return_from_nested_finally_in_finally() { try { return 1; } finally { try { return 2; } finally { return 42; } } } assertEquals(42, return_from_nested_finally_in_finally()); function break_from_nested_finally_in_finally() { L: try { return 1; } finally { try { return 2; } finally { break L; } } return 42; } assertEquals(42, break_from_nested_finally_in_finally()); function continue_from_nested_finally_in_finally() { do { try { return 1; } finally { try { return 2; } finally { continue; } } } while (false); return 42; } assertEquals(42, continue_from_nested_finally_in_finally());