Index: src/codegen-arm.cc |
=================================================================== |
--- src/codegen-arm.cc (revision 312) |
+++ src/codegen-arm.cc (working copy) |
@@ -2761,19 +2761,14 @@ |
Comment cmnt(masm_, "[ case clause"); |
if (clause->is_default()) { |
+ // Continue matching cases. The program will execute the default case's |
+ // statements if it does not match any of the cases. |
+ __ b(&next); |
+ |
// Bind the default case label, so we can branch to it when we |
// have compared against all other cases. |
ASSERT(default_case.is_unused()); // at most one default clause |
- |
- // If the default case is the first (but not only) case, we have |
- // to jump past it for now. Once we're done with the remaining |
- // clauses, we'll branch back here. If it isn't the first case, |
- // we jump past it by avoiding to chain it into the next chain. |
- if (length > 1) { |
- if (i == 0) __ b(&next); |
- __ bind(&default_case); |
- } |
- |
+ __ bind(&default_case); |
} else { |
__ bind(&next); |
next.Unuse(); |
@@ -2782,11 +2777,16 @@ |
Load(clause->label()); |
Comparison(eq, true); |
Branch(false, &next); |
- // Entering the case statement -> remove the switch value from the stack |
- __ pop(r0); |
} |
+ // Entering the case statement for the first time. Remove the switch value |
+ // from the stack. |
+ __ pop(r0); |
+ |
// Generate code for the body. |
+ // This is also the target for the fall through from the previous case's |
+ // statements which has to skip over the matching code and the popping of |
+ // the switch value. |
__ bind(&fall_through); |
fall_through.Unuse(); |
VisitStatements(clause->statements()); |
@@ -2794,11 +2794,15 @@ |
} |
__ bind(&next); |
- // Reached the end of the case statements -> remove the switch value |
- // from the stack. |
- __ pop(r0); // __ Pop(no_reg) |
- if (default_case.is_bound()) __ b(&default_case); |
- |
+ // Reached the end of the case statements without matching any of the cases. |
+ if (default_case.is_bound()) { |
+ // A default case exists -> execute its statements. |
+ __ b(&default_case); |
+ } else { |
+ // Remove the switch value from the stack. |
+ __ pop(r0); |
+ } |
+ |
__ bind(&fall_through); |
__ bind(node->break_target()); |
} |