Commit 016fcd4a authored by kasperl@chromium.org's avatar kasperl@chromium.org

Fix issue 86 by keeping track of the fact that finally blocks

are evaluated with an extra element on the stack, which needs
to be taken into account when breaking and continuing. 

I'll clean up the code and add an abstraction for manipulating
the break stack height in a future CL -- I want to try to get
rid of the separate local variable we keep around for the "state"
when running in a finally block.
Review URL: http://codereview.chromium.org/5625

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@400 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 3916eb38
......@@ -3182,6 +3182,12 @@ void ArmCodeGenerator::VisitTryFinally(TryFinally* node) {
// --- Finally block ---
__ bind(&finally_block);
// We keep a single element on the stack - the (possibly faked)
// result - while evaluating the finally block. Record it, so that a
// break/continue crossing this statement can restore the stack.
const int kFinallyStackSize = 1 * kPointerSize;
break_stack_height_ += kFinallyStackSize;
// Push the state on the stack. If necessary move the state to a
// local variable to avoid having extra values on the stack while
// evaluating the finally block.
......@@ -3203,7 +3209,12 @@ void ArmCodeGenerator::VisitTryFinally(TryFinally* node) {
}
__ pop(r2);
__ pop(r0); // Restore value or faked TOS.
// Restore return value or faked TOS.
__ pop(r0);
// Record the fact that the result has been removed from the stack.
break_stack_height_ -= kFinallyStackSize;
// Generate code that jumps to the right destination for all used
// shadow labels.
for (int i = 0; i <= nof_escapes; i++) {
......
......@@ -3492,7 +3492,7 @@ void Ia32CodeGenerator::VisitTryFinally(TryFinally* node) {
__ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER);
// TODO(1222589): remove the reliance of PushTryHandler on a cached TOS
__ push(eax); //
__ push(eax);
// Introduce shadow labels for all escapes from the try block,
// including returns. We should probably try to unify the escaping
......@@ -3558,6 +3558,12 @@ void Ia32CodeGenerator::VisitTryFinally(TryFinally* node) {
// --- Finally block ---
__ bind(&finally_block);
// We keep a single element on the stack - the (possibly faked)
// result - while evaluating the finally block. Record it, so that a
// break/continue crossing this statement can restore the stack.
const int kFinallyStackSize = 1 * kPointerSize;
break_stack_height_ += kFinallyStackSize;
// Push the state on the stack. If necessary move the state to a
// local variable to avoid having extra values on the stack while
// evaluating the finally block.
......@@ -3583,6 +3589,9 @@ void Ia32CodeGenerator::VisitTryFinally(TryFinally* node) {
// Restore return value or faked TOS.
__ pop(eax);
// Record the fact that the result has been removed from the stack.
break_stack_height_ -= kFinallyStackSize;
// Generate code that jumps to the right destination for all used
// shadow labels.
for (int i = 0; i <= nof_escapes; i++) {
......
......@@ -28,8 +28,9 @@
var aList = [1, 2, 3];
var loopCount = 0;
var leftThroughFinally = false;
var enteredFinally = false;
for (x in aList) {
leftThroughFinally = false;
leftThroughFinally = true;
try {
throw "ex1";
} catch(er1) {
......@@ -40,5 +41,6 @@ for (x in aList) {
}
leftThroughFinally = false;
}
assertEquals(loopCount, 3);
assertEquals(3, loopCount);
assertTrue(enteredFinally);
assertTrue(leftThroughFinally);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment