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.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
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.JetElement;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
|
|
||||||
@@ -37,7 +36,7 @@ public interface JetControlFlowBuilder {
|
|||||||
@Nullable
|
@Nullable
|
||||||
JetElement getCurrentLoop();
|
JetElement getCurrentLoop();
|
||||||
// Finally
|
// Finally
|
||||||
void enterTryFinally(@NotNull JetBlockExpression expression);
|
void enterTryFinally(@NotNull GenerationTrigger trigger);
|
||||||
|
|
||||||
void exitTryFinally();
|
void exitTryFinally();
|
||||||
// Subroutines
|
// Subroutines
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package org.jetbrains.jet.lang.cfg;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
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.JetElement;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
|
|
||||||
@@ -84,8 +83,8 @@ public class JetControlFlowBuilderAdapter implements JetControlFlowBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enterTryFinally(@NotNull JetBlockExpression expression) {
|
public void enterTryFinally(@NotNull GenerationTrigger trigger) {
|
||||||
builder.enterTryFinally(expression);
|
builder.enterTryFinally(trigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -272,25 +272,26 @@ public class JetControlFlowProcessor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitTryExpression(JetTryExpression expression) {
|
public void visitTryExpression(JetTryExpression expression) {
|
||||||
JetFinallySection finallyBlock = expression.getFinallyBlock();
|
final JetFinallySection finallyBlock = expression.getFinallyBlock();
|
||||||
if (finallyBlock != null) {
|
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();
|
List<JetCatchClause> catchClauses = expression.getCatchClauses();
|
||||||
if (catchClauses.isEmpty()) {
|
if (!catchClauses.isEmpty()) {
|
||||||
value(expression.getTryBlock(), true, false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Label catchBlock = builder.createUnboundLabel();
|
|
||||||
builder.nondeterministicJump(catchBlock);
|
|
||||||
|
|
||||||
value(expression.getTryBlock(), true, false);
|
|
||||||
|
|
||||||
Label afterCatches = builder.createUnboundLabel();
|
Label afterCatches = builder.createUnboundLabel();
|
||||||
builder.jump(afterCatches);
|
builder.jump(afterCatches);
|
||||||
|
|
||||||
builder.bindLabel(catchBlock);
|
builder.bindLabel(onException);
|
||||||
for (Iterator<JetCatchClause> iterator = catchClauses.iterator(); iterator.hasNext(); ) {
|
for (Iterator<JetCatchClause> iterator = catchClauses.iterator(); iterator.hasNext(); ) {
|
||||||
JetCatchClause catchClause = iterator.next();
|
JetCatchClause catchClause = iterator.next();
|
||||||
JetExpression catchBody = catchClause.getCatchBody();
|
JetExpression catchBody = catchClause.getCatchBody();
|
||||||
@@ -303,10 +304,13 @@ public class JetControlFlowProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
builder.bindLabel(afterCatches);
|
builder.bindLabel(afterCatches);
|
||||||
|
} else {
|
||||||
|
builder.bindLabel(onException);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (finallyBlock != null) {
|
if (finallyBlock != null) {
|
||||||
builder.exitTryFinally();
|
builder.exitTryFinally();
|
||||||
|
value(finallyBlock.getFinalExpression(), true, inCondition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+65
-15
@@ -1,10 +1,10 @@
|
|||||||
package org.jetbrains.jet.lang.cfg.pseudocode;
|
package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
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.JetControlFlowBuilder;
|
||||||
import org.jetbrains.jet.lang.cfg.JetControlFlowBuilderAdapter;
|
import org.jetbrains.jet.lang.cfg.JetControlFlowBuilderAdapter;
|
||||||
import org.jetbrains.jet.lang.cfg.Label;
|
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.JetElement;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression;
|
import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression;
|
||||||
@@ -16,11 +16,14 @@ import java.util.*;
|
|||||||
*/
|
*/
|
||||||
public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAdapter {
|
public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAdapter {
|
||||||
|
|
||||||
private final Stack<BlockInfo> loopInfo = new Stack<BlockInfo>();
|
private final Stack<BreakableBlockInfo> loopInfo = new Stack<BreakableBlockInfo>();
|
||||||
private final Map<JetElement, BlockInfo> elementToBlockInfo = new HashMap<JetElement, BlockInfo>();
|
private final Map<JetElement, BreakableBlockInfo> elementToBlockInfo = new HashMap<JetElement, BreakableBlockInfo>();
|
||||||
private int labelCount = 0;
|
private int labelCount = 0;
|
||||||
|
|
||||||
private final Stack<JetControlFlowInstructionsGeneratorWorker> builders = new Stack<JetControlFlowInstructionsGeneratorWorker>();
|
private final Stack<JetControlFlowInstructionsGeneratorWorker> builders = new Stack<JetControlFlowInstructionsGeneratorWorker>();
|
||||||
|
|
||||||
|
private final Stack<BlockInfo> allBlocks = new Stack<BlockInfo>();
|
||||||
|
|
||||||
private final JetPseudocodeTrace trace;
|
private final JetPseudocodeTrace trace;
|
||||||
|
|
||||||
public JetControlFlowInstructionsGenerator(JetPseudocodeTrace trace) {
|
public JetControlFlowInstructionsGenerator(JetPseudocodeTrace trace) {
|
||||||
@@ -94,16 +97,18 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
|||||||
public final Label enterLoop(@NotNull JetExpression expression, Label loopExitPoint) {
|
public final Label enterLoop(@NotNull JetExpression expression, Label loopExitPoint) {
|
||||||
Label label = createUnboundLabel();
|
Label label = createUnboundLabel();
|
||||||
bindLabel(label);
|
bindLabel(label);
|
||||||
BlockInfo blockInfo = new BlockInfo(expression, label, loopExitPoint);
|
BreakableBlockInfo blockInfo = new BreakableBlockInfo(expression, label, loopExitPoint);
|
||||||
loopInfo.push(blockInfo);
|
loopInfo.push(blockInfo);
|
||||||
elementToBlockInfo.put(expression, blockInfo);
|
elementToBlockInfo.put(expression, blockInfo);
|
||||||
|
allBlocks.push(blockInfo);
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void exitLoop(@NotNull JetExpression expression) {
|
public final void exitLoop(@NotNull JetExpression expression) {
|
||||||
BlockInfo info = loopInfo.pop();
|
BreakableBlockInfo info = loopInfo.pop();
|
||||||
elementToBlockInfo.remove(expression);
|
elementToBlockInfo.remove(expression);
|
||||||
|
allBlocks.pop();
|
||||||
bindLabel(info.getExitPoint());
|
bindLabel(info.getExitPoint());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,9 +120,10 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
|||||||
@Override
|
@Override
|
||||||
public void enterSubroutine(@NotNull JetElement subroutine, boolean isFunctionLiteral) {
|
public void enterSubroutine(@NotNull JetElement subroutine, boolean isFunctionLiteral) {
|
||||||
Label entryPoint = createUnboundLabel();
|
Label entryPoint = createUnboundLabel();
|
||||||
BlockInfo blockInfo = new BlockInfo(subroutine, entryPoint, createUnboundLabel());
|
BreakableBlockInfo blockInfo = new BreakableBlockInfo(subroutine, entryPoint, createUnboundLabel());
|
||||||
// subroutineInfo.push(blockInfo);
|
// subroutineInfo.push(blockInfo);
|
||||||
elementToBlockInfo.put(subroutine, blockInfo);
|
elementToBlockInfo.put(subroutine, blockInfo);
|
||||||
|
allBlocks.push(blockInfo);
|
||||||
bindLabel(entryPoint);
|
bindLabel(entryPoint);
|
||||||
add(new SubroutineEnterInstruction(subroutine));
|
add(new SubroutineEnterInstruction(subroutine));
|
||||||
}
|
}
|
||||||
@@ -134,29 +140,54 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Label getExitPoint(@NotNull JetElement labelElement) {
|
public Label getExitPoint(@NotNull JetElement labelElement) {
|
||||||
BlockInfo blockInfo = elementToBlockInfo.get(labelElement);
|
BreakableBlockInfo blockInfo = elementToBlockInfo.get(labelElement);
|
||||||
assert blockInfo != null : labelElement.getText();
|
assert blockInfo != null : labelElement.getText();
|
||||||
return blockInfo.getExitPoint();
|
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
|
@Override
|
||||||
public void exitSubroutine(@NotNull JetElement subroutine, boolean functionLiteral) {
|
public void exitSubroutine(@NotNull JetElement subroutine, boolean functionLiteral) {
|
||||||
bindLabel(getExitPoint(subroutine));
|
bindLabel(getExitPoint(subroutine));
|
||||||
add(new SubroutineExitInstruction(subroutine));
|
add(new SubroutineExitInstruction(subroutine));
|
||||||
elementToBlockInfo.remove(subroutine);
|
elementToBlockInfo.remove(subroutine);
|
||||||
// subroutineInfo.pop();
|
allBlocks.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void returnValue(@NotNull JetExpression returnExpression, @NotNull JetElement subroutine) {
|
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
|
@Override
|
||||||
public void returnNoValue(@NotNull JetElement returnExpression, @NotNull JetElement subroutine) {
|
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
|
@Override
|
||||||
@@ -176,16 +207,19 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void jump(@NotNull Label label) {
|
public void jump(@NotNull Label label) {
|
||||||
|
handleJumpInsideTryFinally(label);
|
||||||
add(new UnconditionalJumpInstruction(label));
|
add(new UnconditionalJumpInstruction(label));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void jumpOnFalse(@NotNull Label label) {
|
public void jumpOnFalse(@NotNull Label label) {
|
||||||
|
handleJumpInsideTryFinally(label);
|
||||||
add(new ConditionalJumpInstruction(false, label));
|
add(new ConditionalJumpInstruction(false, label));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void jumpOnTrue(@NotNull Label label) {
|
public void jumpOnTrue(@NotNull Label label) {
|
||||||
|
handleJumpInsideTryFinally(label);
|
||||||
add(new ConditionalJumpInstruction(true, label));
|
add(new ConditionalJumpInstruction(true, label));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,17 +230,19 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void nondeterministicJump(Label label) {
|
public void nondeterministicJump(Label label) {
|
||||||
|
handleJumpInsideTryFinally(label);
|
||||||
add(new NondeterministicJumpInstruction(label));
|
add(new NondeterministicJumpInstruction(label));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enterTryFinally(@NotNull JetBlockExpression expression) {
|
public void enterTryFinally(@NotNull GenerationTrigger generationTrigger) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
allBlocks.push(new TryFinallyBlockInfo(generationTrigger));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exitTryFinally() {
|
public void exitTryFinally() {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
BlockInfo pop = allBlocks.pop();
|
||||||
|
assert pop instanceof TryFinallyBlockInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 JetElement element;
|
||||||
private final Label entryPoint;
|
private final Label entryPoint;
|
||||||
private final Label exitPoint;
|
private final Label exitPoint;
|
||||||
|
|
||||||
private BlockInfo(JetElement element, Label entryPoint, Label exitPoint) {
|
private BreakableBlockInfo(JetElement element, Label entryPoint, Label exitPoint) {
|
||||||
this.element = element;
|
this.element = element;
|
||||||
this.entryPoint = entryPoint;
|
this.entryPoint = entryPoint;
|
||||||
this.exitPoint = exitPoint;
|
this.exitPoint = exitPoint;
|
||||||
|
|||||||
@@ -1238,7 +1238,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
|
|
||||||
myJetParsing.parseBlock();
|
myJetParsing.parseBlock();
|
||||||
|
|
||||||
|
boolean catchOrFinally = false;
|
||||||
while (at(CATCH_KEYWORD)) {
|
while (at(CATCH_KEYWORD)) {
|
||||||
|
catchOrFinally = true;
|
||||||
PsiBuilder.Marker catchBlock = mark();
|
PsiBuilder.Marker catchBlock = mark();
|
||||||
advance(); // CATCH_KEYWORD
|
advance(); // CATCH_KEYWORD
|
||||||
|
|
||||||
@@ -1249,6 +1251,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (at(FINALLY_KEYWORD)) {
|
if (at(FINALLY_KEYWORD)) {
|
||||||
|
catchOrFinally = true;
|
||||||
PsiBuilder.Marker finallyBlock = mark();
|
PsiBuilder.Marker finallyBlock = mark();
|
||||||
|
|
||||||
advance(); // FINALLY_KEYWORD
|
advance(); // FINALLY_KEYWORD
|
||||||
@@ -1258,6 +1261,10 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
finallyBlock.done(FINALLY);
|
finallyBlock.done(FINALLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!catchOrFinally) {
|
||||||
|
error("Expecting 'catch' or 'finally'");
|
||||||
|
}
|
||||||
|
|
||||||
tryExpression.done(TRY);
|
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 {
|
try {
|
||||||
processCFData(name, data);
|
processCFData(name, data);
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
if ("true".equals(System.getProperty("jet.control.flow.test.dump.graphs"))) {
|
if ("true".equals(System.getProperty("jet.control.flow.test.dump.graphs"))) {
|
||||||
dumpDot(name, data.values());
|
dumpDot(name, data.values());
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user