diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index f7c0fc961c8..e7e5969e585 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1156,17 +1156,17 @@ public class ExpressionCodegen extends JetVisitor implem private StackValue visitBreakOrContinueExpression(@NotNull JetLabelQualifiedExpression expression, StackValue receiver, boolean isBreak) { assert expression instanceof JetContinueExpression || expression instanceof JetBreakExpression; - JetSimpleNameExpression labelElement = expression.getTargetLabel(); + if (!blockStackElements.isEmpty()) { + BlockStackElement stackElement = blockStackElements.peek(); - for (int i = blockStackElements.size() - 1; i >= 0; --i) { - BlockStackElement stackElement = blockStackElements.get(i); if (stackElement instanceof FinallyBlockStackElement) { FinallyBlockStackElement finallyBlockStackElement = (FinallyBlockStackElement) stackElement; //noinspection ConstantConditions - genFinallyBlockOrGoto(finallyBlockStackElement, false, null); + genFinallyBlockOrGoto(finallyBlockStackElement, null); } else if (stackElement instanceof LoopBlockStackElement) { LoopBlockStackElement loopBlockStackElement = (LoopBlockStackElement) stackElement; + JetSimpleNameExpression labelElement = expression.getTargetLabel(); //noinspection ConstantConditions if (labelElement == null || loopBlockStackElement.targetLabel != null && @@ -1176,11 +1176,18 @@ public class ExpressionCodegen extends JetVisitor implem } } else { - throw new UnsupportedOperationException(); + throw new UnsupportedOperationException("Wrong BlockStackElement in processing stack"); } + + blockStackElements.pop(); + StackValue result = visitBreakOrContinueExpression(expression, receiver, isBreak); + blockStackElements.push(stackElement); + return result; + + } - throw new UnsupportedOperationException(); + throw new UnsupportedOperationException("Target label for break/continue not found"); } private StackValue generateSingleBranchIf( @@ -1510,32 +1517,36 @@ public class ExpressionCodegen extends JetVisitor implem } private void doFinallyOnReturn() { - for (int i = blockStackElements.size() - 1; i >= 0; --i) { - BlockStackElement stackElement = blockStackElements.get(i); + if(!blockStackElements.isEmpty()) { + BlockStackElement stackElement = blockStackElements.peek(); if (stackElement instanceof FinallyBlockStackElement) { FinallyBlockStackElement finallyBlockStackElement = (FinallyBlockStackElement) stackElement; - genFinallyBlockOrGoto(finallyBlockStackElement, true, null); + genFinallyBlockOrGoto(finallyBlockStackElement, null); } else if (stackElement instanceof LoopBlockStackElement) { - break; + } else { - throw new UnsupportedOperationException(); + throw new UnsupportedOperationException("Wrong BlockStackElement in processing stack"); } + + blockStackElements.pop(); + doFinallyOnReturn(); + blockStackElements.push(stackElement); } } private void genFinallyBlockOrGoto( @Nullable FinallyBlockStackElement finallyBlockStackElement, - boolean doPop, @Nullable Label tryCatchBlockEnd ) { - if (finallyBlockStackElement != null) { - assert finallyBlockStackElement.gaps.size() % 2 == 0; - JetTryExpression jetTryExpression = finallyBlockStackElement.expression; - if (doPop) { - blockStackElements.pop(); - } + if (finallyBlockStackElement != null) { + assert finallyBlockStackElement.gaps.size() % 2 == 0 : "Finally block gaps are inconsistent"; + + BlockStackElement topOfStack = blockStackElements.pop(); + assert topOfStack == finallyBlockStackElement : "Top element of stack doesn't equals processing finally block"; + + JetTryExpression jetTryExpression = finallyBlockStackElement.expression; Label finallyStart = new Label(); v.mark(finallyStart); finallyBlockStackElement.addGapLabel(finallyStart); @@ -1553,9 +1564,7 @@ public class ExpressionCodegen extends JetVisitor implem v.mark(finallyEnd); finallyBlockStackElement.addGapLabel(finallyEnd); - if (doPop) { - blockStackElements.push(finallyBlockStackElement); - } + blockStackElements.push(finallyBlockStackElement); } } @@ -3473,11 +3482,11 @@ The "returned" value of try expression with no finally is either the last expres v.mark(tryEnd); //do it before finally block generation - List