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