// Copyright 2011 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.

// We want to test the context chain shape.  In each of the tests cases
// below, the outer with is to force a runtime lookup of the identifier 'x'
// to actually verify that the inner context has been discarded.  A static
// lookup of 'x' might accidentally succeed.

{
  let x = 2;
  L: {
    let x = 3;
    assertEquals(3, x);
    break L;
    assertTrue(false);
  }
  assertEquals(2, x);
}

do {
  let x = 4;
  assertEquals(4,x);
  {
    let x = 5;
    assertEquals(5, x);
    continue;
    assertTrue(false);
  }
} while (false);

var caught = false;
try {
  {
    let xx = 18;
    throw 25;
    assertTrue(false);
  }
} catch (e) {
  caught = true;
  assertEquals(25, e);
  (function () {
    try {
      // NOTE: This checks that the block scope containing xx has been
      // removed from the context chain.
      eval('xx');
      assertTrue(false);  // should not reach here
    } catch (e2) {
      assertTrue(e2 instanceof ReferenceError);
    }
  })();
}
assertTrue(caught);


(function(x) {
  label: {
    let x = 'inner';
    break label;
  }
  assertEquals('outer', eval('x'));
})('outer');


(function(x) {
  label: {
    let x = 'middle';
    {
      let x = 'inner';
      break label;
    }
  }
  assertEquals('outer', eval('x'));
})('outer');


(function(x) {
  for (var i = 0; i < 10; ++i) {
    let x = 'inner' + i;
    continue;
  }
  assertEquals('outer', eval('x'));
})('outer');


(function(x) {
  label: for (var i = 0; i < 10; ++i) {
    let x = 'middle' + i;
    for (var j = 0; j < 10; ++j) {
      let x = 'inner' + j;
      continue label;
    }
  }
  assertEquals('outer', eval('x'));
})('outer');


(function(x) {
  try {
    let x = 'inner';
    throw 0;
  } catch (e) {
    assertEquals('outer', eval('x'));
  }
})('outer');


(function(x) {
  try {
    let x = 'middle';
    {
      let x = 'inner';
      throw 0;
    }
  } catch (e) {
    assertEquals('outer', eval('x'));
  }
})('outer');


try {
  (function(x) {
    try {
      let x = 'inner';
      throw 0;
    } finally {
      assertEquals('outer', eval('x'));
    }
  })('outer');
} catch (e) {
  if (e instanceof MjsUnitAssertionError) throw e;
}


try {
  (function(x) {
    try {
      let x = 'middle';
      {
        let x = 'inner';
        throw 0;
      }
    } finally {
      assertEquals('outer', eval('x'));
    }
  })('outer');
} catch (e) {
  if (e instanceof MjsUnitAssertionError) throw e;
}


// Verify that the context is correctly set in the stack frame after exiting
// from eval.
function f() {}

(function(x) {
  label: {
    let x = 'inner';
    break label;
  }
  f();  // The context could be restored from the stack after the call.
  assertEquals('outer', eval('x'));
})('outer');


(function(x) {
  for (var i = 0; i < 10; ++i) {
    let x = 'inner';
    continue;
  }
  f();
  assertEquals('outer', eval('x'));
})('outer');


(function(x) {
  try {
    let x = 'inner';
    throw 0;
  } catch (e) {
    f();
    assertEquals('outer', eval('x'));
  }
})('outer');


try {
  (function(x) {
    try {
      let x = 'inner';
      throw 0;
    } finally {
      f();
      assertEquals('outer', eval('x'));
    }
  })('outer');
} catch (e) {
  if (e instanceof MjsUnitAssertionError) throw e;
}
