Try..finally supported by CF-builder
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
package org.jetbrains.jet.lang.cfg;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface GenerationTrigger {
|
||||
void generate();
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package org.jetbrains.jet.lang.cfg;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetBlockExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
|
||||
@@ -37,7 +36,7 @@ public interface JetControlFlowBuilder {
|
||||
@Nullable
|
||||
JetElement getCurrentLoop();
|
||||
// Finally
|
||||
void enterTryFinally(@NotNull JetBlockExpression expression);
|
||||
void enterTryFinally(@NotNull GenerationTrigger trigger);
|
||||
|
||||
void exitTryFinally();
|
||||
// Subroutines
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.jetbrains.jet.lang.cfg;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetBlockExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
|
||||
@@ -84,8 +83,8 @@ public class JetControlFlowBuilderAdapter implements JetControlFlowBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterTryFinally(@NotNull JetBlockExpression expression) {
|
||||
builder.enterTryFinally(expression);
|
||||
public void enterTryFinally(@NotNull GenerationTrigger trigger) {
|
||||
builder.enterTryFinally(trigger);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -272,25 +272,26 @@ public class JetControlFlowProcessor {
|
||||
|
||||
@Override
|
||||
public void visitTryExpression(JetTryExpression expression) {
|
||||
JetFinallySection finallyBlock = expression.getFinallyBlock();
|
||||
final JetFinallySection finallyBlock = expression.getFinallyBlock();
|
||||
if (finallyBlock != null) {
|
||||
builder.enterTryFinally(finallyBlock.getFinalExpression());
|
||||
builder.enterTryFinally(new GenerationTrigger() {
|
||||
@Override
|
||||
public void generate() {
|
||||
value(finallyBlock.getFinalExpression(), true, inCondition);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Label onException = builder.createUnboundLabel();
|
||||
builder.nondeterministicJump(onException);
|
||||
value(expression.getTryBlock(), true, inCondition);
|
||||
|
||||
List<JetCatchClause> catchClauses = expression.getCatchClauses();
|
||||
if (catchClauses.isEmpty()) {
|
||||
value(expression.getTryBlock(), true, false);
|
||||
}
|
||||
else {
|
||||
Label catchBlock = builder.createUnboundLabel();
|
||||
builder.nondeterministicJump(catchBlock);
|
||||
|
||||
value(expression.getTryBlock(), true, false);
|
||||
|
||||
if (!catchClauses.isEmpty()) {
|
||||
Label afterCatches = builder.createUnboundLabel();
|
||||
builder.jump(afterCatches);
|
||||
|
||||
builder.bindLabel(catchBlock);
|
||||
builder.bindLabel(onException);
|
||||
for (Iterator<JetCatchClause> iterator = catchClauses.iterator(); iterator.hasNext(); ) {
|
||||
JetCatchClause catchClause = iterator.next();
|
||||
JetExpression catchBody = catchClause.getCatchBody();
|
||||
@@ -303,10 +304,13 @@ public class JetControlFlowProcessor {
|
||||
}
|
||||
|
||||
builder.bindLabel(afterCatches);
|
||||
} else {
|
||||
builder.bindLabel(onException);
|
||||
}
|
||||
|
||||
if (finallyBlock != null) {
|
||||
builder.exitTryFinally();
|
||||
value(finallyBlock.getFinalExpression(), true, inCondition);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+65
-15
@@ -1,10 +1,10 @@
|
||||
package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.cfg.GenerationTrigger;
|
||||
import org.jetbrains.jet.lang.cfg.JetControlFlowBuilder;
|
||||
import org.jetbrains.jet.lang.cfg.JetControlFlowBuilderAdapter;
|
||||
import org.jetbrains.jet.lang.cfg.Label;
|
||||
import org.jetbrains.jet.lang.psi.JetBlockExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression;
|
||||
@@ -16,11 +16,14 @@ import java.util.*;
|
||||
*/
|
||||
public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAdapter {
|
||||
|
||||
private final Stack<BlockInfo> loopInfo = new Stack<BlockInfo>();
|
||||
private final Map<JetElement, BlockInfo> elementToBlockInfo = new HashMap<JetElement, BlockInfo>();
|
||||
private final Stack<BreakableBlockInfo> loopInfo = new Stack<BreakableBlockInfo>();
|
||||
private final Map<JetElement, BreakableBlockInfo> elementToBlockInfo = new HashMap<JetElement, BreakableBlockInfo>();
|
||||
private int labelCount = 0;
|
||||
|
||||
private final Stack<JetControlFlowInstructionsGeneratorWorker> builders = new Stack<JetControlFlowInstructionsGeneratorWorker>();
|
||||
|
||||
private final Stack<BlockInfo> allBlocks = new Stack<BlockInfo>();
|
||||
|
||||
private final JetPseudocodeTrace trace;
|
||||
|
||||
public JetControlFlowInstructionsGenerator(JetPseudocodeTrace trace) {
|
||||
@@ -94,16 +97,18 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
||||
public final Label enterLoop(@NotNull JetExpression expression, Label loopExitPoint) {
|
||||
Label label = createUnboundLabel();
|
||||
bindLabel(label);
|
||||
BlockInfo blockInfo = new BlockInfo(expression, label, loopExitPoint);
|
||||
BreakableBlockInfo blockInfo = new BreakableBlockInfo(expression, label, loopExitPoint);
|
||||
loopInfo.push(blockInfo);
|
||||
elementToBlockInfo.put(expression, blockInfo);
|
||||
allBlocks.push(blockInfo);
|
||||
return label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void exitLoop(@NotNull JetExpression expression) {
|
||||
BlockInfo info = loopInfo.pop();
|
||||
BreakableBlockInfo info = loopInfo.pop();
|
||||
elementToBlockInfo.remove(expression);
|
||||
allBlocks.pop();
|
||||
bindLabel(info.getExitPoint());
|
||||
}
|
||||
|
||||
@@ -115,9 +120,10 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
||||
@Override
|
||||
public void enterSubroutine(@NotNull JetElement subroutine, boolean isFunctionLiteral) {
|
||||
Label entryPoint = createUnboundLabel();
|
||||
BlockInfo blockInfo = new BlockInfo(subroutine, entryPoint, createUnboundLabel());
|
||||
BreakableBlockInfo blockInfo = new BreakableBlockInfo(subroutine, entryPoint, createUnboundLabel());
|
||||
// subroutineInfo.push(blockInfo);
|
||||
elementToBlockInfo.put(subroutine, blockInfo);
|
||||
allBlocks.push(blockInfo);
|
||||
bindLabel(entryPoint);
|
||||
add(new SubroutineEnterInstruction(subroutine));
|
||||
}
|
||||
@@ -134,29 +140,54 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
||||
|
||||
@Override
|
||||
public Label getExitPoint(@NotNull JetElement labelElement) {
|
||||
BlockInfo blockInfo = elementToBlockInfo.get(labelElement);
|
||||
BreakableBlockInfo blockInfo = elementToBlockInfo.get(labelElement);
|
||||
assert blockInfo != null : labelElement.getText();
|
||||
return blockInfo.getExitPoint();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void handleJumpInsideTryFinally(Label jumpTarget) {
|
||||
List<TryFinallyBlockInfo> finallyBlocks = new ArrayList<TryFinallyBlockInfo>();
|
||||
|
||||
for (int i = allBlocks.size() - 1; i >= 0; i--) {
|
||||
BlockInfo blockInfo = allBlocks.get(i);
|
||||
if (blockInfo instanceof BreakableBlockInfo) {
|
||||
BreakableBlockInfo breakableBlockInfo = (BreakableBlockInfo) blockInfo;
|
||||
if (jumpTarget == breakableBlockInfo.getExitPoint() || jumpTarget == breakableBlockInfo.getEntryPoint()) {
|
||||
for (int j = finallyBlocks.size() - 1; j >= 0; j--) {
|
||||
finallyBlocks.get(j).generateFinallyBlock();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (blockInfo instanceof TryFinallyBlockInfo) {
|
||||
TryFinallyBlockInfo tryFinallyBlockInfo = (TryFinallyBlockInfo) blockInfo;
|
||||
finallyBlocks.add(tryFinallyBlockInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitSubroutine(@NotNull JetElement subroutine, boolean functionLiteral) {
|
||||
bindLabel(getExitPoint(subroutine));
|
||||
add(new SubroutineExitInstruction(subroutine));
|
||||
elementToBlockInfo.remove(subroutine);
|
||||
// subroutineInfo.pop();
|
||||
allBlocks.pop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void returnValue(@NotNull JetExpression returnExpression, @NotNull JetElement subroutine) {
|
||||
add(new ReturnValueInstruction(returnExpression, getExitPoint(subroutine)));
|
||||
Label exitPoint = getExitPoint(subroutine);
|
||||
handleJumpInsideTryFinally(exitPoint);
|
||||
add(new ReturnValueInstruction(returnExpression, exitPoint));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void returnNoValue(@NotNull JetElement returnExpression, @NotNull JetElement subroutine) {
|
||||
add(new ReturnNoValueInstruction(returnExpression, getExitPoint(subroutine)));
|
||||
Label exitPoint = getExitPoint(subroutine);
|
||||
handleJumpInsideTryFinally(exitPoint);
|
||||
add(new ReturnNoValueInstruction(returnExpression, exitPoint));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -176,16 +207,19 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
||||
|
||||
@Override
|
||||
public void jump(@NotNull Label label) {
|
||||
handleJumpInsideTryFinally(label);
|
||||
add(new UnconditionalJumpInstruction(label));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpOnFalse(@NotNull Label label) {
|
||||
handleJumpInsideTryFinally(label);
|
||||
add(new ConditionalJumpInstruction(false, label));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpOnTrue(@NotNull Label label) {
|
||||
handleJumpInsideTryFinally(label);
|
||||
add(new ConditionalJumpInstruction(true, label));
|
||||
}
|
||||
|
||||
@@ -196,17 +230,19 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
||||
|
||||
@Override
|
||||
public void nondeterministicJump(Label label) {
|
||||
handleJumpInsideTryFinally(label);
|
||||
add(new NondeterministicJumpInstruction(label));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterTryFinally(@NotNull JetBlockExpression expression) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
public void enterTryFinally(@NotNull GenerationTrigger generationTrigger) {
|
||||
allBlocks.push(new TryFinallyBlockInfo(generationTrigger));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitTryFinally() {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
BlockInfo pop = allBlocks.pop();
|
||||
assert pop instanceof TryFinallyBlockInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -215,12 +251,26 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
||||
}
|
||||
}
|
||||
|
||||
private static class BlockInfo {
|
||||
private static abstract class BlockInfo {}
|
||||
|
||||
private static class TryFinallyBlockInfo extends BlockInfo {
|
||||
private final GenerationTrigger finallyBlock;
|
||||
|
||||
private TryFinallyBlockInfo(GenerationTrigger finallyBlock) {
|
||||
this.finallyBlock = finallyBlock;
|
||||
}
|
||||
|
||||
public void generateFinallyBlock() {
|
||||
finallyBlock.generate();
|
||||
}
|
||||
}
|
||||
|
||||
private static class BreakableBlockInfo extends BlockInfo {
|
||||
private final JetElement element;
|
||||
private final Label entryPoint;
|
||||
private final Label exitPoint;
|
||||
|
||||
private BlockInfo(JetElement element, Label entryPoint, Label exitPoint) {
|
||||
private BreakableBlockInfo(JetElement element, Label entryPoint, Label exitPoint) {
|
||||
this.element = element;
|
||||
this.entryPoint = entryPoint;
|
||||
this.exitPoint = exitPoint;
|
||||
|
||||
@@ -1238,7 +1238,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
|
||||
myJetParsing.parseBlock();
|
||||
|
||||
boolean catchOrFinally = false;
|
||||
while (at(CATCH_KEYWORD)) {
|
||||
catchOrFinally = true;
|
||||
PsiBuilder.Marker catchBlock = mark();
|
||||
advance(); // CATCH_KEYWORD
|
||||
|
||||
@@ -1249,6 +1251,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
}
|
||||
|
||||
if (at(FINALLY_KEYWORD)) {
|
||||
catchOrFinally = true;
|
||||
PsiBuilder.Marker finallyBlock = mark();
|
||||
|
||||
advance(); // FINALLY_KEYWORD
|
||||
@@ -1258,6 +1261,10 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
finallyBlock.done(FINALLY);
|
||||
}
|
||||
|
||||
if (!catchOrFinally) {
|
||||
error("Expecting 'catch' or 'finally'");
|
||||
}
|
||||
|
||||
tryExpression.done(TRY);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,437 @@
|
||||
== t3 ==
|
||||
fun t3() {
|
||||
try {
|
||||
1
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
}
|
||||
---------------------
|
||||
l0:
|
||||
<START>
|
||||
jmp?(l2)
|
||||
r(1)
|
||||
l2:
|
||||
r(2)
|
||||
l1:
|
||||
<END>
|
||||
=====================
|
||||
== t3 ==
|
||||
fun t3() {
|
||||
try {
|
||||
1
|
||||
if (2 > 3) {
|
||||
return
|
||||
}
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
}
|
||||
---------------------
|
||||
l0:
|
||||
<START>
|
||||
jmp?(l2)
|
||||
r(1)
|
||||
r(2)
|
||||
r(3)
|
||||
r(>)
|
||||
r(2 > 3)
|
||||
jf(l3)
|
||||
r(2)
|
||||
ret l1
|
||||
jmp(l4)
|
||||
l3:
|
||||
read (Unit)
|
||||
l2:
|
||||
l4:
|
||||
r(2)
|
||||
l1:
|
||||
<END>
|
||||
=====================
|
||||
== anonymous_0 ==
|
||||
{ () =>
|
||||
if (2 > 3) {
|
||||
return@
|
||||
}
|
||||
}
|
||||
---------------------
|
||||
l3:
|
||||
<START>
|
||||
r(2)
|
||||
r(3)
|
||||
r(>)
|
||||
r(2 > 3)
|
||||
jf(l5)
|
||||
ret l4
|
||||
jmp(l6)
|
||||
l5:
|
||||
read (Unit)
|
||||
l4:
|
||||
l6:
|
||||
<END>
|
||||
=====================
|
||||
== t3 ==
|
||||
fun t3() {
|
||||
try {
|
||||
1
|
||||
@{ () =>
|
||||
if (2 > 3) {
|
||||
return@
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
}
|
||||
---------------------
|
||||
l0:
|
||||
<START>
|
||||
jmp?(l2)
|
||||
r(1)
|
||||
rf({ () =>
|
||||
if (2 > 3) {
|
||||
return@
|
||||
}
|
||||
})
|
||||
l2:
|
||||
r(2)
|
||||
l1:
|
||||
<END>
|
||||
l3:
|
||||
<START>
|
||||
r(2)
|
||||
r(3)
|
||||
r(>)
|
||||
r(2 > 3)
|
||||
jf(l5)
|
||||
ret l4
|
||||
jmp(l6)
|
||||
l5:
|
||||
read (Unit)
|
||||
l4:
|
||||
l6:
|
||||
<END>
|
||||
=====================
|
||||
== anonymous_1 ==
|
||||
{ () =>
|
||||
try {
|
||||
1
|
||||
if (2 > 3) {
|
||||
return@
|
||||
}
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
}
|
||||
---------------------
|
||||
l2:
|
||||
<START>
|
||||
jmp?(l4)
|
||||
r(1)
|
||||
r(2)
|
||||
r(3)
|
||||
r(>)
|
||||
r(2 > 3)
|
||||
jf(l5)
|
||||
r(2)
|
||||
ret l3
|
||||
jmp(l6)
|
||||
l5:
|
||||
read (Unit)
|
||||
l4:
|
||||
l6:
|
||||
r(2)
|
||||
l3:
|
||||
<END>
|
||||
=====================
|
||||
== t3 ==
|
||||
fun t3() {
|
||||
@{ () =>
|
||||
try {
|
||||
1
|
||||
if (2 > 3) {
|
||||
return@
|
||||
}
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
}
|
||||
}
|
||||
---------------------
|
||||
l0:
|
||||
<START>
|
||||
rf({ () =>
|
||||
try {
|
||||
1
|
||||
if (2 > 3) {
|
||||
return@
|
||||
}
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
})
|
||||
l1:
|
||||
<END>
|
||||
l2:
|
||||
<START>
|
||||
jmp?(l4)
|
||||
r(1)
|
||||
r(2)
|
||||
r(3)
|
||||
r(>)
|
||||
r(2 > 3)
|
||||
jf(l5)
|
||||
r(2)
|
||||
ret l3
|
||||
jmp(l6)
|
||||
l5:
|
||||
read (Unit)
|
||||
l4:
|
||||
l6:
|
||||
r(2)
|
||||
l3:
|
||||
<END>
|
||||
=====================
|
||||
== t3 ==
|
||||
fun t3() {
|
||||
@ while(true) {
|
||||
try {
|
||||
1
|
||||
if (2 > 3) {
|
||||
break @
|
||||
}
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
}
|
||||
}
|
||||
---------------------
|
||||
l0:
|
||||
<START>
|
||||
l3:
|
||||
r(true)
|
||||
jf(l2)
|
||||
jmp?(l4)
|
||||
r(1)
|
||||
r(2)
|
||||
r(3)
|
||||
r(>)
|
||||
r(2 > 3)
|
||||
jf(l5)
|
||||
r(2)
|
||||
jmp(l2)
|
||||
jmp(l6)
|
||||
l5:
|
||||
read (Unit)
|
||||
l4:
|
||||
l6:
|
||||
r(2)
|
||||
jmp(l3)
|
||||
l1:
|
||||
l2:
|
||||
<END>
|
||||
=====================
|
||||
== t3 ==
|
||||
fun t3() {
|
||||
try {
|
||||
@ while(true) {
|
||||
1
|
||||
if (2 > 3) {
|
||||
break @
|
||||
}
|
||||
}
|
||||
5
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
}
|
||||
---------------------
|
||||
l0:
|
||||
<START>
|
||||
jmp?(l2)
|
||||
l4:
|
||||
r(true)
|
||||
jf(l3)
|
||||
r(1)
|
||||
r(2)
|
||||
r(3)
|
||||
r(>)
|
||||
r(2 > 3)
|
||||
jf(l5)
|
||||
jmp(l3)
|
||||
jmp(l6)
|
||||
l5:
|
||||
read (Unit)
|
||||
l6:
|
||||
jmp(l4)
|
||||
l3:
|
||||
r(5)
|
||||
l2:
|
||||
r(2)
|
||||
l1:
|
||||
<END>
|
||||
=====================
|
||||
== t3 ==
|
||||
fun t3() {
|
||||
try {
|
||||
@ while(true) {
|
||||
1
|
||||
if (2 > 3) {
|
||||
break @
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
}
|
||||
---------------------
|
||||
l0:
|
||||
<START>
|
||||
jmp?(l2)
|
||||
l4:
|
||||
r(true)
|
||||
jf(l3)
|
||||
r(1)
|
||||
r(2)
|
||||
r(3)
|
||||
r(>)
|
||||
r(2 > 3)
|
||||
jf(l5)
|
||||
jmp(l3)
|
||||
jmp(l6)
|
||||
l5:
|
||||
read (Unit)
|
||||
l6:
|
||||
jmp(l4)
|
||||
l2:
|
||||
l3:
|
||||
r(2)
|
||||
l1:
|
||||
<END>
|
||||
=====================
|
||||
== t3 ==
|
||||
fun t3(a : Int) {
|
||||
@ for (i in 1..a) {
|
||||
try {
|
||||
1
|
||||
if (2 > 3) {
|
||||
continue @
|
||||
}
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
}
|
||||
}
|
||||
---------------------
|
||||
l0:
|
||||
<START>
|
||||
r(1)
|
||||
r(a)
|
||||
r(..)
|
||||
r(1..a)
|
||||
jmp?(l2)
|
||||
l3:
|
||||
jmp?(l4)
|
||||
r(1)
|
||||
r(2)
|
||||
r(3)
|
||||
r(>)
|
||||
r(2 > 3)
|
||||
jf(l5)
|
||||
r(2)
|
||||
jmp(l3)
|
||||
jmp(l6)
|
||||
l5:
|
||||
read (Unit)
|
||||
l4:
|
||||
l6:
|
||||
r(2)
|
||||
jmp?(l3)
|
||||
l1:
|
||||
l2:
|
||||
<END>
|
||||
=====================
|
||||
== t3 ==
|
||||
fun t3(a : Int) {
|
||||
try {
|
||||
@ for (i in 1..a) {
|
||||
1
|
||||
if (2 > 3) {
|
||||
continue @
|
||||
}
|
||||
}
|
||||
5
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
}
|
||||
---------------------
|
||||
l0:
|
||||
<START>
|
||||
jmp?(l2)
|
||||
r(1)
|
||||
r(a)
|
||||
r(..)
|
||||
r(1..a)
|
||||
jmp?(l3)
|
||||
l4:
|
||||
r(1)
|
||||
r(2)
|
||||
r(3)
|
||||
r(>)
|
||||
r(2 > 3)
|
||||
jf(l5)
|
||||
jmp(l4)
|
||||
jmp(l6)
|
||||
l5:
|
||||
read (Unit)
|
||||
l6:
|
||||
jmp?(l4)
|
||||
l3:
|
||||
r(5)
|
||||
l2:
|
||||
r(2)
|
||||
l1:
|
||||
<END>
|
||||
=====================
|
||||
== t3 ==
|
||||
fun t3(a : Int) {
|
||||
try {
|
||||
@ for (i in 1..a) {
|
||||
1
|
||||
if (2 > 3) {
|
||||
continue @
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
}
|
||||
---------------------
|
||||
l0:
|
||||
<START>
|
||||
jmp?(l2)
|
||||
r(1)
|
||||
r(a)
|
||||
r(..)
|
||||
r(1..a)
|
||||
jmp?(l3)
|
||||
l4:
|
||||
r(1)
|
||||
r(2)
|
||||
r(3)
|
||||
r(>)
|
||||
r(2 > 3)
|
||||
jf(l5)
|
||||
jmp(l4)
|
||||
jmp(l6)
|
||||
l5:
|
||||
read (Unit)
|
||||
l6:
|
||||
jmp?(l4)
|
||||
l2:
|
||||
l3:
|
||||
r(2)
|
||||
l1:
|
||||
<END>
|
||||
=====================
|
||||
@@ -0,0 +1,125 @@
|
||||
fun t3() {
|
||||
try {
|
||||
1
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
}
|
||||
|
||||
fun t3() {
|
||||
try {
|
||||
1
|
||||
if (2 > 3) {
|
||||
return
|
||||
}
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
}
|
||||
|
||||
fun t3() {
|
||||
try {
|
||||
1
|
||||
@{ () =>
|
||||
if (2 > 3) {
|
||||
return@
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
}
|
||||
|
||||
fun t3() {
|
||||
@{ () =>
|
||||
try {
|
||||
1
|
||||
if (2 > 3) {
|
||||
return@
|
||||
}
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun t3() {
|
||||
@ while(true) {
|
||||
try {
|
||||
1
|
||||
if (2 > 3) {
|
||||
break @
|
||||
}
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun t3() {
|
||||
try {
|
||||
@ while(true) {
|
||||
1
|
||||
if (2 > 3) {
|
||||
break @
|
||||
}
|
||||
}
|
||||
5
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
}
|
||||
|
||||
fun t3() {
|
||||
try {
|
||||
@ while(true) {
|
||||
1
|
||||
if (2 > 3) {
|
||||
break @
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
}
|
||||
|
||||
fun t3(a : Int) {
|
||||
@ for (i in 1..a) {
|
||||
try {
|
||||
1
|
||||
if (2 > 3) {
|
||||
continue @
|
||||
}
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun t3(a : Int) {
|
||||
try {
|
||||
@ for (i in 1..a) {
|
||||
1
|
||||
if (2 > 3) {
|
||||
continue @
|
||||
}
|
||||
}
|
||||
5
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
}
|
||||
|
||||
fun t3(a : Int) {
|
||||
try {
|
||||
@ for (i in 1..a) {
|
||||
1
|
||||
if (2 > 3) {
|
||||
continue @
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,11 +68,14 @@ public class JetControlFlowTest extends JetTestCaseBase {
|
||||
|
||||
try {
|
||||
processCFData(name, data);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
finally {
|
||||
if ("true".equals(System.getProperty("jet.control.flow.test.dump.graphs"))) {
|
||||
dumpDot(name, data.values());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user