// 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());
