FIR CFG: reconfigure exception throwing paths in try expression
This commit is contained in:
committed by
Dmitriy Novozhilov
parent
146036010c
commit
1f1e1828a7
@@ -153,12 +153,12 @@ digraph complex_kt {
|
|||||||
22 -> {23};
|
22 -> {23};
|
||||||
23 -> {24};
|
23 -> {24};
|
||||||
24 -> {25};
|
24 -> {25};
|
||||||
25 -> {26};
|
25 -> {26 31};
|
||||||
26 -> {54 31 27};
|
26 -> {27};
|
||||||
27 -> {28};
|
27 -> {28};
|
||||||
28 -> {29};
|
28 -> {29};
|
||||||
29 -> {30};
|
29 -> {30};
|
||||||
30 -> {38};
|
30 -> {38 31};
|
||||||
31 -> {54 32};
|
31 -> {54 32};
|
||||||
32 -> {33};
|
32 -> {33};
|
||||||
33 -> {34};
|
33 -> {34};
|
||||||
|
|||||||
+3
-3
@@ -167,8 +167,8 @@ digraph inplaceLambdaInControlFlowExpressions_kt {
|
|||||||
}
|
}
|
||||||
37 -> {38};
|
37 -> {38};
|
||||||
38 -> {39};
|
38 -> {39};
|
||||||
39 -> {40};
|
39 -> {40 47};
|
||||||
40 -> {56 47 41};
|
40 -> {41};
|
||||||
41 -> {42};
|
41 -> {42};
|
||||||
42 -> {57};
|
42 -> {57};
|
||||||
42 -> {43} [color=red];
|
42 -> {43} [color=red];
|
||||||
@@ -176,7 +176,7 @@ digraph inplaceLambdaInControlFlowExpressions_kt {
|
|||||||
43 -> {44};
|
43 -> {44};
|
||||||
44 -> {45};
|
44 -> {45};
|
||||||
45 -> {46};
|
45 -> {46};
|
||||||
46 -> {52};
|
46 -> {52 47};
|
||||||
47 -> {56 48};
|
47 -> {56 48};
|
||||||
48 -> {49};
|
48 -> {49};
|
||||||
49 -> {50};
|
49 -> {50};
|
||||||
|
|||||||
+4
-4
@@ -308,13 +308,13 @@ digraph propertiesAndInitBlocks_kt {
|
|||||||
102 [label="Exit property" style="filled" fillcolor=red];
|
102 [label="Exit property" style="filled" fillcolor=red];
|
||||||
}
|
}
|
||||||
84 -> {85};
|
84 -> {85};
|
||||||
85 -> {86};
|
85 -> {86 91};
|
||||||
86 -> {102 91 87};
|
85 -> {96} [label=onUncaughtException];
|
||||||
86 -> {96} [label=onUncaughtException];
|
86 -> {87};
|
||||||
87 -> {88};
|
87 -> {88};
|
||||||
88 -> {89};
|
88 -> {89};
|
||||||
89 -> {90};
|
89 -> {90};
|
||||||
90 -> {96};
|
90 -> {96 91};
|
||||||
91 -> {102 92};
|
91 -> {102 92};
|
||||||
92 -> {93};
|
92 -> {93};
|
||||||
93 -> {94};
|
93 -> {94};
|
||||||
|
|||||||
@@ -56,13 +56,13 @@ digraph tryCatch_kt {
|
|||||||
}
|
}
|
||||||
0 -> {1};
|
0 -> {1};
|
||||||
1 -> {2};
|
1 -> {2};
|
||||||
2 -> {3};
|
2 -> {3 15 9};
|
||||||
3 -> {23 15 9 4};
|
3 -> {4};
|
||||||
4 -> {5};
|
4 -> {5};
|
||||||
5 -> {6};
|
5 -> {6};
|
||||||
6 -> {7};
|
6 -> {7};
|
||||||
7 -> {8};
|
7 -> {8};
|
||||||
8 -> {21};
|
8 -> {21 15 9};
|
||||||
9 -> {23 10};
|
9 -> {23 10};
|
||||||
10 -> {11};
|
10 -> {11};
|
||||||
11 -> {12};
|
11 -> {12};
|
||||||
@@ -118,12 +118,12 @@ digraph tryCatch_kt {
|
|||||||
}
|
}
|
||||||
24 -> {25};
|
24 -> {25};
|
||||||
25 -> {26};
|
25 -> {26};
|
||||||
26 -> {27};
|
26 -> {27 32};
|
||||||
27 -> {40 32 28};
|
27 -> {28};
|
||||||
28 -> {29};
|
28 -> {29};
|
||||||
29 -> {30};
|
29 -> {30};
|
||||||
30 -> {31};
|
30 -> {31};
|
||||||
31 -> {37};
|
31 -> {37 32};
|
||||||
32 -> {40 33};
|
32 -> {40 33};
|
||||||
33 -> {34};
|
33 -> {34};
|
||||||
34 -> {35};
|
34 -> {35};
|
||||||
@@ -261,8 +261,8 @@ digraph tryCatch_kt {
|
|||||||
46 -> {87} [style=dotted];
|
46 -> {87} [style=dotted];
|
||||||
47 -> {48};
|
47 -> {48};
|
||||||
48 -> {49};
|
48 -> {49};
|
||||||
49 -> {50};
|
49 -> {50 91 81};
|
||||||
50 -> {102 91 81 51};
|
50 -> {51};
|
||||||
51 -> {52};
|
51 -> {52};
|
||||||
52 -> {53};
|
52 -> {53};
|
||||||
53 -> {54};
|
53 -> {54};
|
||||||
@@ -294,7 +294,7 @@ digraph tryCatch_kt {
|
|||||||
77 -> {78} [style=dotted];
|
77 -> {78} [style=dotted];
|
||||||
78 -> {79};
|
78 -> {79};
|
||||||
79 -> {80};
|
79 -> {80};
|
||||||
80 -> {97};
|
80 -> {97 91 81};
|
||||||
81 -> {102 82};
|
81 -> {102 82};
|
||||||
82 -> {83};
|
82 -> {83};
|
||||||
83 -> {87};
|
83 -> {87};
|
||||||
|
|||||||
+4
-4
@@ -101,8 +101,8 @@ finally {
|
|||||||
11 -> {12};
|
11 -> {12};
|
||||||
12 -> {13};
|
12 -> {13};
|
||||||
13 -> {14};
|
13 -> {14};
|
||||||
14 -> {30 15};
|
13 -> {22} [label=onUncaughtException];
|
||||||
14 -> {22} [label=onUncaughtException];
|
14 -> {15};
|
||||||
15 -> {16};
|
15 -> {16};
|
||||||
16 -> {17};
|
16 -> {17};
|
||||||
17 -> {31};
|
17 -> {31};
|
||||||
@@ -192,8 +192,8 @@ finally {
|
|||||||
36 -> {37};
|
36 -> {37};
|
||||||
37 -> {38};
|
37 -> {38};
|
||||||
38 -> {39};
|
38 -> {39};
|
||||||
39 -> {55 40};
|
38 -> {47} [label=onUncaughtException];
|
||||||
39 -> {47} [label=onUncaughtException];
|
39 -> {40};
|
||||||
40 -> {41};
|
40 -> {41};
|
||||||
41 -> {42};
|
41 -> {42};
|
||||||
42 -> {43 56};
|
42 -> {43 56};
|
||||||
|
|||||||
+17
-4
@@ -84,6 +84,7 @@ class ControlFlowGraphBuilder {
|
|||||||
private val binaryOrExitNodes: Stack<BinaryOrExitNode> = stackOf()
|
private val binaryOrExitNodes: Stack<BinaryOrExitNode> = stackOf()
|
||||||
|
|
||||||
private val tryExitNodes: NodeStorage<FirTryExpression, TryExpressionExitNode> = NodeStorage()
|
private val tryExitNodes: NodeStorage<FirTryExpression, TryExpressionExitNode> = NodeStorage()
|
||||||
|
private val tryMainExitNodes: NodeStorage<FirTryExpression, TryMainBlockExitNode> = NodeStorage()
|
||||||
private val catchNodeStorages: Stack<NodeStorage<FirCatch, CatchClauseEnterNode>> = stackOf()
|
private val catchNodeStorages: Stack<NodeStorage<FirCatch, CatchClauseEnterNode>> = stackOf()
|
||||||
private val catchNodeStorage: NodeStorage<FirCatch, CatchClauseEnterNode> get() = catchNodeStorages.top()
|
private val catchNodeStorage: NodeStorage<FirCatch, CatchClauseEnterNode> get() = catchNodeStorages.top()
|
||||||
private val finallyEnterNodes: Stack<FinallyBlockEnterNode> = stackOf()
|
private val finallyEnterNodes: Stack<FinallyBlockEnterNode> = stackOf()
|
||||||
@@ -786,19 +787,21 @@ class ControlFlowGraphBuilder {
|
|||||||
levelCounter++
|
levelCounter++
|
||||||
val enterTryNodeBlock = createTryMainBlockEnterNode(tryExpression)
|
val enterTryNodeBlock = createTryMainBlockEnterNode(tryExpression)
|
||||||
addNewSimpleNode(enterTryNodeBlock)
|
addNewSimpleNode(enterTryNodeBlock)
|
||||||
addEdge(enterTryNodeBlock, exitTargetsForTry.top())
|
|
||||||
|
|
||||||
for (catch in tryExpression.catches) {
|
for (catch in tryExpression.catches) {
|
||||||
val catchNode = createCatchClauseEnterNode(catch)
|
val catchNode = createCatchClauseEnterNode(catch)
|
||||||
catchNodeStorage.push(catchNode)
|
catchNodeStorage.push(catchNode)
|
||||||
addEdge(enterTryNodeBlock, catchNode)
|
// a flow where an exception of interest is thrown and caught before executing any of try-main block.
|
||||||
|
addEdge(enterTryExpressionNode, catchNode)
|
||||||
|
// TODO: Should go to the finally block w/ a label, and exit to the exit target w/ the same label.
|
||||||
addEdge(catchNode, exitTargetsForTry.top())
|
addEdge(catchNode, exitTargetsForTry.top())
|
||||||
}
|
}
|
||||||
levelCounter++
|
levelCounter++
|
||||||
|
|
||||||
if (tryExpression.finallyBlock != null) {
|
if (tryExpression.finallyBlock != null) {
|
||||||
val finallyEnterNode = createFinallyBlockEnterNode(tryExpression)
|
val finallyEnterNode = createFinallyBlockEnterNode(tryExpression)
|
||||||
addEdge(enterTryNodeBlock, finallyEnterNode, label = UncaughtExceptionPath)
|
// a flow where an uncaught exception is thrown before executing any of try-main block.
|
||||||
|
addEdge(enterTryExpressionNode, finallyEnterNode, label = UncaughtExceptionPath)
|
||||||
finallyEnterNodes.push(finallyEnterNode)
|
finallyEnterNodes.push(finallyEnterNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -808,6 +811,7 @@ class ControlFlowGraphBuilder {
|
|||||||
fun exitTryMainBlock(tryExpression: FirTryExpression): TryMainBlockExitNode {
|
fun exitTryMainBlock(tryExpression: FirTryExpression): TryMainBlockExitNode {
|
||||||
levelCounter--
|
levelCounter--
|
||||||
val node = createTryMainBlockExitNode(tryExpression)
|
val node = createTryMainBlockExitNode(tryExpression)
|
||||||
|
tryMainExitNodes.push(node)
|
||||||
popAndAddEdge(node)
|
popAndAddEdge(node)
|
||||||
val finallyEnterNode = finallyEnterNodes.topOrNull()
|
val finallyEnterNode = finallyEnterNodes.topOrNull()
|
||||||
// NB: Check the level to avoid adding an edge to the finally block at an upper level.
|
// NB: Check the level to avoid adding an edge to the finally block at an upper level.
|
||||||
@@ -820,7 +824,13 @@ class ControlFlowGraphBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun enterCatchClause(catch: FirCatch): CatchClauseEnterNode {
|
fun enterCatchClause(catch: FirCatch): CatchClauseEnterNode {
|
||||||
return catchNodeStorage[catch]!!.also { lastNodes.push(it) }.also { levelCounter++ }
|
return catchNodeStorage[catch]!!.also {
|
||||||
|
val tryMainExitNode = tryMainExitNodes.top()
|
||||||
|
// a flow where an exception of interest is thrown and caught after executing all of try-main block.
|
||||||
|
addEdge(tryMainExitNode, it)
|
||||||
|
lastNodes.push(it)
|
||||||
|
levelCounter++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun exitCatchClause(catch: FirCatch): CatchClauseExitNode {
|
fun exitCatchClause(catch: FirCatch): CatchClauseExitNode {
|
||||||
@@ -847,7 +857,9 @@ class ControlFlowGraphBuilder {
|
|||||||
return createFinallyBlockExitNode(tryExpression).also {
|
return createFinallyBlockExitNode(tryExpression).also {
|
||||||
popAndAddEdge(it)
|
popAndAddEdge(it)
|
||||||
val tryExitNode = tryExitNodes.top()
|
val tryExitNode = tryExitNodes.top()
|
||||||
|
// a flow where either there wasn't any exception or caught if any.
|
||||||
addEdge(it, tryExitNode)
|
addEdge(it, tryExitNode)
|
||||||
|
// a flow that exits to the exit target while there was an uncaught exception.
|
||||||
addEdge(it, exitTargetsForTry.top(), label = UncaughtExceptionPath)
|
addEdge(it, exitTargetsForTry.top(), label = UncaughtExceptionPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -857,6 +869,7 @@ class ControlFlowGraphBuilder {
|
|||||||
): Pair<TryExpressionExitNode, UnionFunctionCallArgumentsNode?> {
|
): Pair<TryExpressionExitNode, UnionFunctionCallArgumentsNode?> {
|
||||||
levelCounter--
|
levelCounter--
|
||||||
catchNodeStorages.pop()
|
catchNodeStorages.pop()
|
||||||
|
tryMainExitNodes.pop()
|
||||||
val node = tryExitNodes.pop()
|
val node = tryExitNodes.pop()
|
||||||
node.updateDeadStatus()
|
node.updateDeadStatus()
|
||||||
lastNodes.push(node)
|
lastNodes.push(node)
|
||||||
|
|||||||
Reference in New Issue
Block a user