CFA: additional jumps to catch / finally generated in the end of try / before exits from try #KT-5469 Fixed

Also #KT-13612 Fixed
(cherry picked from commit 7c188b3)
This commit is contained in:
Mikhail Glukhikh
2016-04-20 17:34:19 +03:00
committed by Mikhail Glukhikh
parent 43954699a7
commit f8039249c6
28 changed files with 638 additions and 89 deletions
+65 -35
View File
@@ -14,10 +14,11 @@ L0:
jmp?(L2) NEXT:[mark({ 2 }), mark({ 1 })]
3 mark({ 1 })
r(1) -> <v0>
2 jmp(L3) NEXT:[mark({ 2 })]
2 jmp?(L2) NEXT:[mark({ 2 }), jmp(L3)]
jmp(L3) NEXT:[mark({ 2 })]
L2 [onExceptionToFinallyBlock]:
L4 [start finally]:
3 mark({ 2 }) PREV:[jmp?(L2)]
3 mark({ 2 }) PREV:[jmp?(L2), jmp?(L2)]
r(2) -> <v1>
L5 [finish finally]:
2 jmp(error) NEXT:[<ERROR>]
@@ -59,6 +60,7 @@ L0:
call(2 > 3, compareTo|<v1>, <v2>) -> <v3>
jf(L3|<v3>) NEXT:[read (Unit), mark({ return })]
4 mark({ return })
jmp?(L2) NEXT:[mark({ 2 }), mark({ 2 })]
L4 [start finally]:
5 mark({ 2 })
r(2) -> <v4>
@@ -69,9 +71,10 @@ L3 [else branch]:
read (Unit) PREV:[jf(L3|<v3>)]
L6 ['if' expression result]:
merge(if (2 > 3) { return }|!<v5>) -> <v6>
2 jmp(L7) NEXT:[mark({ 2 })]
2 jmp?(L2) NEXT:[mark({ 2 }), jmp(L7)]
jmp(L7) NEXT:[mark({ 2 })]
L2 [onExceptionToFinallyBlock]:
5 mark({ 2 }) PREV:[jmp?(L2)]
5 mark({ 2 }) PREV:[jmp?(L2), jmp?(L2), jmp?(L2)]
r(2) -> <v4>
2 jmp(error) NEXT:[<ERROR>]
L7 [skipFinallyToErrorBlock]:
@@ -112,10 +115,11 @@ L0:
d({ -> if (2 > 3) { return@l } }) NEXT:[<SINK>]
L3 [after local declaration]:
r({ -> if (2 > 3) { return@l } }) -> <v1> PREV:[jmp?(L3)]
2 jmp(L8) NEXT:[mark({ 2 })]
2 jmp?(L2) NEXT:[mark({ 2 }), jmp(L8)]
jmp(L8) NEXT:[mark({ 2 })]
L2 [onExceptionToFinallyBlock]:
L9 [start finally]:
3 mark({ 2 }) PREV:[jmp?(L2)]
3 mark({ 2 }) PREV:[jmp?(L2), jmp?(L2)]
r(2) -> <v2>
L10 [finish finally]:
2 jmp(error) NEXT:[<ERROR>]
@@ -217,6 +221,7 @@ L3:
call(2 > 3, compareTo|<v1>, <v2>) -> <v3>
jf(L6|<v3>) NEXT:[read (Unit), mark({ return@l })]
6 mark({ return@l })
jmp?(L5) NEXT:[mark({ 2 }), mark({ 2 })]
L7 [start finally]:
7 mark({ 2 })
r(2) -> <v4>
@@ -227,9 +232,10 @@ L6 [else branch]:
read (Unit) PREV:[jf(L6|<v3>)]
L9 ['if' expression result]:
merge(if (2 > 3) { return@l }|!<v5>) -> <v6>
4 jmp(L10) NEXT:[mark({ 2 })]
4 jmp?(L5) NEXT:[mark({ 2 }), jmp(L10)]
jmp(L10) NEXT:[mark({ 2 })]
L5 [onExceptionToFinallyBlock]:
7 mark({ 2 }) PREV:[jmp?(L5)]
7 mark({ 2 }) PREV:[jmp?(L5), jmp?(L5), jmp?(L5)]
r(2) -> <v4>
4 jmp(error) NEXT:[<ERROR>]
L10 [skipFinallyToErrorBlock]:
@@ -279,6 +285,7 @@ L4 [body entry point]:
call(2 > 3, compareTo|<v3>, <v4>) -> <v5>
jf(L8|<v5>) NEXT:[read (Unit), mark({ break@l })]
5 mark({ break@l })
jmp?(L7) NEXT:[mark({ 2 }), mark({ 2 })]
L9 [start finally]:
6 mark({ 2 })
r(2) -> <v6>
@@ -289,9 +296,10 @@ L8 [else branch]:
read (Unit) PREV:[jf(L8|<v5>)]
L11 ['if' expression result]:
merge(if (2 > 3) { break@l }|!<v7>) -> <v8>
3 jmp(L12) NEXT:[mark({ 2 })]
3 jmp?(L7) NEXT:[mark({ 2 }), jmp(L12)]
jmp(L12) NEXT:[mark({ 2 })]
L7 [onExceptionToFinallyBlock]:
6 mark({ 2 }) PREV:[jmp?(L7)]
6 mark({ 2 }) PREV:[jmp?(L7), jmp?(L7), jmp?(L7)]
r(2) -> <v6>
3 jmp(error) NEXT:[<ERROR>]
L12 [skipFinallyToErrorBlock]:
@@ -357,10 +365,11 @@ L4 [loop exit point]:
L6 [body exit point]:
read (Unit) PREV:[jmp(L4)]
r(5) -> <v9>
2 jmp(L10) NEXT:[mark({ 2 })]
2 jmp?(L2) NEXT:[mark({ 2 }), jmp(L10)]
jmp(L10) NEXT:[mark({ 2 })]
L2 [onExceptionToFinallyBlock]:
L11 [start finally]:
3 mark({ 2 }) PREV:[jmp?(L2)]
3 mark({ 2 }) PREV:[jmp?(L2), jmp?(L2)]
r(2) -> <v10>
L12 [finish finally]:
2 jmp(error) NEXT:[<ERROR>]
@@ -422,10 +431,11 @@ L9 ['if' expression result]:
L4 [loop exit point]:
L6 [body exit point]:
read (Unit) PREV:[jmp(L4)]
2 jmp(L10) NEXT:[mark({ 2 })]
2 jmp?(L2) NEXT:[mark({ 2 }), jmp(L10)]
jmp(L10) NEXT:[mark({ 2 })]
L2 [onExceptionToFinallyBlock]:
L11 [start finally]:
3 mark({ 2 }) PREV:[jmp?(L2)]
3 mark({ 2 }) PREV:[jmp?(L2), jmp?(L2)]
r(2) -> <v9>
L12 [finish finally]:
2 jmp(error) NEXT:[<ERROR>]
@@ -486,6 +496,7 @@ L4 [body entry point]:
call(2 > 3, compareTo|<v6>, <v7>) -> <v8>
jf(L8|<v8>) NEXT:[read (Unit), mark({ continue@l })]
6 mark({ continue@l })
jmp?(L7) NEXT:[mark({ 2 }), mark({ 2 })]
L9 [start finally]:
7 mark({ 2 })
r(2) -> <v9>
@@ -496,9 +507,10 @@ L8 [else branch]:
read (Unit) PREV:[jf(L8|<v8>)]
L11 ['if' expression result]:
merge(if (2 > 3) { continue@l }|!<v10>) -> <v11>
4 jmp(L12) NEXT:[mark({ 2 })]
4 jmp?(L7) NEXT:[mark({ 2 }), jmp(L12)]
jmp(L12) NEXT:[mark({ 2 })]
L7 [onExceptionToFinallyBlock]:
7 mark({ 2 }) PREV:[jmp?(L7)]
7 mark({ 2 }) PREV:[jmp?(L7), jmp?(L7), jmp?(L7)]
r(2) -> <v9>
4 jmp(error) NEXT:[<ERROR>]
L12 [skipFinallyToErrorBlock]:
@@ -573,10 +585,11 @@ L4 [loop exit point]:
L6 [body exit point]:
read (Unit) PREV:[jmp?(L4)]
3 r(5) -> <v12>
2 jmp(L10) NEXT:[mark({ 2 })]
2 jmp?(L2) NEXT:[mark({ 2 }), jmp(L10)]
jmp(L10) NEXT:[mark({ 2 })]
L2 [onExceptionToFinallyBlock]:
L11 [start finally]:
3 mark({ 2 }) PREV:[jmp?(L2)]
3 mark({ 2 }) PREV:[jmp?(L2), jmp?(L2)]
r(2) -> <v13>
L12 [finish finally]:
2 jmp(error) NEXT:[<ERROR>]
@@ -647,10 +660,11 @@ L9 ['if' expression result]:
L4 [loop exit point]:
L6 [body exit point]:
read (Unit) PREV:[jmp?(L4)]
2 jmp(L10) NEXT:[mark({ 2 })]
2 jmp?(L2) NEXT:[mark({ 2 }), jmp(L10)]
jmp(L10) NEXT:[mark({ 2 })]
L2 [onExceptionToFinallyBlock]:
L11 [start finally]:
3 mark({ 2 }) PREV:[jmp?(L2)]
3 mark({ 2 }) PREV:[jmp?(L2), jmp?(L2)]
r(2) -> <v12>
L12 [finish finally]:
2 jmp(error) NEXT:[<ERROR>]
@@ -682,6 +696,7 @@ L0:
mark(try { return 1 } finally { return 2 })
jmp?(L2) NEXT:[mark({ return 2 }), mark({ return 1 })]
3 mark({ return 1 })
jmp?(L2) NEXT:[mark({ return 2 }), r(1) -> <v0>]
r(1) -> <v0>
L3 [start finally]:
4 mark({ return 2 })
@@ -689,9 +704,10 @@ L3 [start finally]:
ret(*|<v1>) L1 NEXT:[<END>]
L4 [finish finally]:
- 3 ret(*|<v0>) L1 NEXT:[<END>] PREV:[]
- 2 jmp(L5) NEXT:[mark({ return 2 })] PREV:[]
- 2 jmp?(L2) NEXT:[mark({ return 2 }), jmp(L5)] PREV:[]
- jmp(L5) NEXT:[mark({ return 2 })] PREV:[]
L2 [onExceptionToFinallyBlock]:
4 mark({ return 2 }) PREV:[jmp?(L2)]
4 mark({ return 2 }) PREV:[jmp?(L2), jmp?(L2)]
r(2) -> <v1>
ret(*|<v1>) L1 NEXT:[<END>]
- 2 jmp(error) NEXT:[<ERROR>] PREV:[]
@@ -723,6 +739,7 @@ L0:
mark(try { return 1 } finally { doSmth(3) })
jmp?(L2) NEXT:[mark({ doSmth(3) }), mark({ return 1 })]
3 mark({ return 1 })
jmp?(L2) NEXT:[mark({ doSmth(3) }), r(1) -> <v0>]
r(1) -> <v0>
L3 [start finally]:
4 mark({ doSmth(3) })
@@ -731,9 +748,10 @@ L3 [start finally]:
call(doSmth(3), doSmth|<v1>) -> <v2>
L4 [finish finally]:
3 ret(*|<v0>) L1 NEXT:[<END>]
- 2 jmp(L5) NEXT:[mark({ doSmth(3) })] PREV:[]
- 2 jmp?(L2) NEXT:[mark({ doSmth(3) }), jmp(L5)] PREV:[]
- jmp(L5) NEXT:[mark({ doSmth(3) })] PREV:[]
L2 [onExceptionToFinallyBlock]:
4 mark({ doSmth(3) }) PREV:[jmp?(L2)]
4 mark({ doSmth(3) }) PREV:[jmp?(L2), jmp?(L2)]
r(3) -> <v1>
mark(doSmth(3))
call(doSmth(3), doSmth|<v1>) -> <v2>
@@ -771,6 +789,8 @@ L0:
jmp?(L2) NEXT:[v(e: UnsupportedOperationException), jmp?(L3)]
jmp?(L3) NEXT:[mark({ doSmth(3) }), mark({ return 1 })]
3 mark({ return 1 })
jmp?(L2) NEXT:[v(e: UnsupportedOperationException), jmp?(L3)]
jmp?(L3) NEXT:[mark({ doSmth(3) }), r(1) -> <v0>]
r(1) -> <v0>
L4 [start finally]:
4 mark({ doSmth(3) })
@@ -779,9 +799,11 @@ L4 [start finally]:
call(doSmth(3), doSmth|<v1>) -> <v2>
L5 [finish finally]:
3 ret(*|<v0>) L1 NEXT:[<END>]
- 2 jmp(L6) NEXT:[jmp(L7)] PREV:[]
- 2 jmp?(L2) NEXT:[v(e: UnsupportedOperationException), jmp?(L3)] PREV:[]
- jmp?(L3) NEXT:[mark({ doSmth(3) }), jmp(L6)] PREV:[]
- jmp(L6) NEXT:[jmp(L7)] PREV:[]
L2 [onException]:
3 v(e: UnsupportedOperationException) PREV:[jmp?(L2)]
3 v(e: UnsupportedOperationException) PREV:[jmp?(L2), jmp?(L2)]
magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v4>
w(e|<v4>)
4 mark({ doSmth(2) })
@@ -792,7 +814,7 @@ L2 [onException]:
L6 [afterCatches]:
2 jmp(L7) NEXT:[mark({ doSmth(3) })]
L3 [onExceptionToFinallyBlock]:
4 mark({ doSmth(3) }) PREV:[jmp?(L3)]
4 mark({ doSmth(3) }) PREV:[jmp?(L3), jmp?(L3)]
r(3) -> <v1>
mark(doSmth(3))
call(doSmth(3), doSmth|<v1>) -> <v2>
@@ -826,11 +848,13 @@ L0:
mark(try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) })
jmp?(L2) NEXT:[v(e: UnsupportedOperationException), mark({ return 1 })]
3 mark({ return 1 })
jmp?(L2) NEXT:[v(e: UnsupportedOperationException), r(1) -> <v0>]
r(1) -> <v0>
ret(*|<v0>) L1 NEXT:[<END>]
- 2 jmp(L3) NEXT:[merge(try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) }|!<v1>, <v4>) -> <v5>] PREV:[]
- 2 jmp?(L2) NEXT:[v(e: UnsupportedOperationException), jmp(L3)] PREV:[]
- jmp(L3) NEXT:[merge(try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) }|!<v1>, <v4>) -> <v5>] PREV:[]
L2 [onException]:
3 v(e: UnsupportedOperationException) PREV:[jmp?(L2)]
3 v(e: UnsupportedOperationException) PREV:[jmp?(L2), jmp?(L2)]
magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v2>
w(e|<v2>)
4 mark({ doSmth(2) })
@@ -867,6 +891,8 @@ L0:
jmp?(L2) NEXT:[v(e: UnsupportedOperationException), jmp?(L3)]
jmp?(L3) NEXT:[mark({ doSmth(3) }), mark({ return 1 })]
3 mark({ return 1 })
jmp?(L2) NEXT:[v(e: UnsupportedOperationException), jmp?(L3)]
jmp?(L3) NEXT:[mark({ doSmth(3) }), r(1) -> <v0>]
r(1) -> <v0>
L4 [start finally]:
4 mark({ doSmth(3) })
@@ -875,9 +901,11 @@ L4 [start finally]:
call(doSmth(3), doSmth|<v1>) -> <v2>
L5 [finish finally]:
3 ret(*|<v0>) L1 NEXT:[<END>]
- 2 jmp(L6) NEXT:[jmp(L7)] PREV:[]
- 2 jmp?(L2) NEXT:[v(e: UnsupportedOperationException), jmp?(L3)] PREV:[]
- jmp?(L3) NEXT:[mark({ doSmth(3) }), jmp(L6)] PREV:[]
- jmp(L6) NEXT:[jmp(L7)] PREV:[]
L2 [onException]:
3 v(e: UnsupportedOperationException) PREV:[jmp?(L2)]
3 v(e: UnsupportedOperationException) PREV:[jmp?(L2), jmp?(L2)]
magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v4>
w(e|<v4>)
4 mark({ return 2 })
@@ -891,7 +919,7 @@ L2 [onException]:
L6 [afterCatches]:
- 2 jmp(L7) NEXT:[mark({ doSmth(3) })] PREV:[]
L3 [onExceptionToFinallyBlock]:
4 mark({ doSmth(3) }) PREV:[jmp?(L3)]
4 mark({ doSmth(3) }) PREV:[jmp?(L3), jmp?(L3)]
r(3) -> <v1>
mark(doSmth(3))
call(doSmth(3), doSmth|<v1>) -> <v2>
@@ -932,9 +960,11 @@ L0:
r(1) -> <v0>
mark(doSmth(1))
call(doSmth(1), doSmth|<v0>) -> <v1>
2 jmp(L4) NEXT:[jmp(L7)]
2 jmp?(L2) NEXT:[v(e: UnsupportedOperationException), jmp?(L3)]
jmp?(L3) NEXT:[mark({ doSmth(3) }), jmp(L4)]
jmp(L4) NEXT:[jmp(L7)]
L2 [onException]:
3 v(e: UnsupportedOperationException) PREV:[jmp?(L2)]
3 v(e: UnsupportedOperationException) PREV:[jmp?(L2), jmp?(L2)]
magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v2>
w(e|<v2>)
4 mark({ return 2 })
@@ -950,7 +980,7 @@ L6 [finish finally]:
L4 [afterCatches]:
2 jmp(L7) NEXT:[mark({ doSmth(3) })] PREV:[jmp(L4)]
L3 [onExceptionToFinallyBlock]:
5 mark({ doSmth(3) }) PREV:[jmp?(L3)]
5 mark({ doSmth(3) }) PREV:[jmp?(L3), jmp?(L3)]
r(3) -> <v4>
mark(doSmth(3))
call(doSmth(3), doSmth|<v4>) -> <v5>
@@ -79,9 +79,11 @@ L0:
3 mark({ doSmth() })
mark(doSmth())
call(doSmth(), doSmth) -> <v0>
2 jmp(L4) NEXT:[jmp(L6)]
2 jmp?(L2) NEXT:[jmp?(L5), jmp?(L3)]
jmp?(L3) NEXT:[mark({ return 1 }), jmp(L4)]
jmp(L4) NEXT:[jmp(L6)]
L2 [onException]:
jmp?(L5) NEXT:[v(e: Exception), v(e: NullPointerException)] PREV:[jmp?(L2)]
jmp?(L5) NEXT:[v(e: Exception), v(e: NullPointerException)] PREV:[jmp?(L2), jmp?(L2)]
3 v(e: NullPointerException)
magic[FAKE_INITIALIZER](e: NullPointerException) -> <v1>
w(e|<v1>)
@@ -101,7 +103,7 @@ L4 [afterCatches]:
2 jmp(L6) NEXT:[mark({ return 1 })] PREV:[jmp(L4), jmp(L4), jmp(L4)]
L3 [onExceptionToFinallyBlock]:
L7 [start finally]:
3 mark({ return 1 }) PREV:[jmp?(L3)]
3 mark({ return 1 }) PREV:[jmp?(L3), jmp?(L3)]
r(1) -> <v5>
ret(*|<v5>) L1 NEXT:[<END>]
L8 [finish finally]:
@@ -155,9 +157,11 @@ L4 [body entry point]:
4 mark({ doSmth() })
mark(doSmth())
call(doSmth(), doSmth) -> <v1>
3 jmp(L9) NEXT:[jmp(L11)]
3 jmp?(L7) NEXT:[jmp?(L10), jmp?(L8)]
jmp?(L8) NEXT:[mark({ if (cond()) return else continue }), jmp(L9)]
jmp(L9) NEXT:[jmp(L11)]
L7 [onException]:
jmp?(L10) NEXT:[v(e: Exception), v(e: NullPointerException)] PREV:[jmp?(L7)]
jmp?(L10) NEXT:[v(e: Exception), v(e: NullPointerException)] PREV:[jmp?(L7), jmp?(L7)]
4 v(e: NullPointerException)
magic[FAKE_INITIALIZER](e: NullPointerException) -> <v2>
w(e|<v2>)
@@ -177,7 +181,7 @@ L9 [afterCatches]:
3 jmp(L11) NEXT:[mark({ if (cond()) return else continue })] PREV:[jmp(L9), jmp(L9), jmp(L9)]
L8 [onExceptionToFinallyBlock]:
L12 [start finally]:
4 mark({ if (cond()) return else continue }) PREV:[jmp?(L8)]
4 mark({ if (cond()) return else continue }) PREV:[jmp?(L8), jmp?(L8)]
mark(if (cond()) return else continue)
mark(cond())
call(cond(), cond) -> <v6>
@@ -240,9 +244,11 @@ L0:
3 mark({ doSmth() })
mark(doSmth())
call(doSmth(), doSmth) -> <v0>
2 jmp(L4) NEXT:[jmp(L6)]
2 jmp?(L2) NEXT:[jmp?(L5), jmp?(L3)]
jmp?(L3) NEXT:[mark({ while (cond()); }), jmp(L4)]
jmp(L4) NEXT:[jmp(L6)]
L2 [onException]:
jmp?(L5) NEXT:[v(e: Exception), v(e: NullPointerException)] PREV:[jmp?(L2)]
jmp?(L5) NEXT:[v(e: Exception), v(e: NullPointerException)] PREV:[jmp?(L2), jmp?(L2)]
3 v(e: NullPointerException)
magic[FAKE_INITIALIZER](e: NullPointerException) -> <v1>
w(e|<v1>)
@@ -262,7 +268,7 @@ L4 [afterCatches]:
2 jmp(L6) NEXT:[mark({ while (cond()); })] PREV:[jmp(L4), jmp(L4), jmp(L4)]
L3 [onExceptionToFinallyBlock]:
L7 [start finally]:
3 mark({ while (cond()); }) PREV:[jmp?(L3)]
3 mark({ while (cond()); }) PREV:[jmp?(L3), jmp?(L3)]
L8 [loop entry point]:
L12 [condition entry point]:
mark(cond()) PREV:[mark({ while (cond()); }), jmp(L8)]
@@ -320,10 +326,11 @@ L0:
3 mark({ doSmth() })
mark(doSmth())
call(doSmth(), doSmth) -> <v1>
2 jmp(L3) NEXT:[mark({ if(list != null) { } })]
2 jmp?(L2) NEXT:[mark({ if(list != null) { } }), jmp(L3)]
jmp(L3) NEXT:[mark({ if(list != null) { } })]
L2 [onExceptionToFinallyBlock]:
L4 [start finally]:
3 mark({ if(list != null) { } }) PREV:[jmp?(L2)]
3 mark({ if(list != null) { } }) PREV:[jmp?(L2), jmp?(L2)]
mark(if(list != null) { })
r(list) -> <v2>
r(null) -> <v3>
@@ -33,6 +33,7 @@ L12 [condition entry point]:
magic[VALUE_CONSUMER](true|<v2>) -> <v3>
L10 [body entry point]:
5 mark({ continue@outer })
jmp?(L7) NEXT:[mark({ break }), mark({ break })]
L13 [start finally]:
6 mark({ break })
jmp(L3) NEXT:[read (Unit)]
@@ -42,9 +43,10 @@ L14 [finish finally]:
L9 [loop exit point]:
L11 [body exit point]:
- read (Unit) PREV:[]
- 3 jmp(L15) NEXT:[mark({ break })] PREV:[]
- 3 jmp?(L7) NEXT:[mark({ break }), jmp(L15)] PREV:[]
- jmp(L15) NEXT:[mark({ break })] PREV:[]
L7 [onExceptionToFinallyBlock]:
6 mark({ break }) PREV:[jmp?(L7)]
6 mark({ break }) PREV:[jmp?(L7), jmp?(L7)]
jmp(L3) NEXT:[read (Unit)]
- 3 jmp(error) NEXT:[<ERROR>] PREV:[]
L15 [skipFinallyToErrorBlock]:
@@ -100,6 +102,7 @@ L12 [condition entry point]:
magic[VALUE_CONSUMER](true|<v2>) -> <v3>
L10 [body entry point]:
5 mark({ continue@outer })
jmp?(L7) NEXT:[mark({ return "OK" }), mark({ return "OK" })]
L13 [start finally]:
6 mark({ return "OK" })
mark("OK")
@@ -111,9 +114,10 @@ L14 [finish finally]:
L9 [loop exit point]:
L11 [body exit point]:
- read (Unit) PREV:[]
- 3 jmp(L15) NEXT:[mark({ return "OK" })] PREV:[]
- 3 jmp?(L7) NEXT:[mark({ return "OK" }), jmp(L15)] PREV:[]
- jmp(L15) NEXT:[mark({ return "OK" })] PREV:[]
L7 [onExceptionToFinallyBlock]:
6 mark({ return "OK" }) PREV:[jmp?(L7)]
6 mark({ return "OK" }) PREV:[jmp?(L7), jmp?(L7)]
mark("OK")
r("OK") -> <v4>
ret(*|<v4>) L1 NEXT:[<END>]
@@ -135,3 +139,71 @@ error:
sink:
<SINK> PREV:[<ERROR>, <END>]
=====================
== baz ==
fun baz(): String {
outer@while (true) {
try {
inner@while (true) {
continue@inner
}
} finally {
return "OK"
}
}
}
---------------------
L0:
1 <START>
2 mark({ outer@while (true) { try { inner@while (true) { continue@inner } } finally { return "OK" } } })
mark(outer@while (true) { try { inner@while (true) { continue@inner } } finally { return "OK" } })
L2 [loop entry point]:
L6 [condition entry point]:
r(true) -> <v0>
mark(while (true) { try { inner@while (true) { continue@inner } } finally { return "OK" } })
magic[VALUE_CONSUMER](true|<v0>) -> <v1>
L4 [body entry point]:
3 mark({ try { inner@while (true) { continue@inner } } finally { return "OK" } })
mark(try { inner@while (true) { continue@inner } } finally { return "OK" })
jmp?(L7) NEXT:[mark({ return "OK" }), mark({ inner@while (true) { continue@inner } })]
4 mark({ inner@while (true) { continue@inner } })
mark(inner@while (true) { continue@inner })
L8 [loop entry point]:
L12 [condition entry point]:
r(true) -> <v2> PREV:[mark(inner@while (true) { continue@inner }), jmp(L12)]
mark(while (true) { continue@inner })
magic[VALUE_CONSUMER](true|<v2>) -> <v3>
L10 [body entry point]:
5 mark({ continue@inner })
jmp(L12) NEXT:[r(true) -> <v2>]
- 4 jmp(L8) NEXT:[r(true) -> <v2>] PREV:[]
L9 [loop exit point]:
L11 [body exit point]:
- read (Unit) PREV:[]
- 3 jmp?(L7) NEXT:[mark({ return "OK" }), jmp(L13)] PREV:[]
- jmp(L13) NEXT:[mark({ return "OK" })] PREV:[]
L7 [onExceptionToFinallyBlock]:
L14 [start finally]:
4 mark({ return "OK" }) PREV:[jmp?(L7)]
mark("OK")
r("OK") -> <v6>
ret(*|<v6>) L1 NEXT:[<END>]
L15 [finish finally]:
- 3 jmp(error) NEXT:[<ERROR>] PREV:[]
L13 [skipFinallyToErrorBlock]:
L16 [copy of L7, onExceptionToFinallyBlock]:
- 4 mark({ return "OK" }) PREV:[]
- mark("OK") PREV:[]
- r("OK") -> <v6> PREV:[]
- ret(*|<v6>) L1 NEXT:[<END>] PREV:[]
- 3 merge(try { inner@while (true) { continue@inner } } finally { return "OK" }|!<v5>) -> <v8> PREV:[]
- 2 jmp(L2) NEXT:[r(true) -> <v0>] PREV:[]
L3 [loop exit point]:
L5 [body exit point]:
- read (Unit) PREV:[]
L1:
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v6>) L1]
error:
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>]
=====================
@@ -22,3 +22,15 @@ fun bar(): String {
}
}
}
fun baz(): String {
outer@while (true) {
try {
inner@while (true) {
continue@inner
}
} finally {
return "OK"
}
}
}
@@ -61,3 +61,34 @@ while (true) { try { while (true) { continue@outer } } finally { return "OK" } }
outer@while (true) { try { while (true) { continue@outer } } finally { return "OK" } } !<v9>: * COPY
{ outer@while (true) { try { while (true) { continue@outer } } finally { return "OK" } } } !<v9>: * COPY
=====================
== baz ==
fun baz(): String {
outer@while (true) {
try {
inner@while (true) {
continue@inner
}
} finally {
return "OK"
}
}
}
---------------------
<v1>: * NEW: magic[VALUE_CONSUMER](true|<v0>) -> <v1>
<v3>: * NEW: magic[VALUE_CONSUMER](true|<v2>) -> <v3>
true <v0>: Boolean NEW: r(true) -> <v0>
true <v2>: Boolean NEW: r(true) -> <v2>
continue@inner !<v4>: *
{ continue@inner } !<v4>: * COPY
while (true) { continue@inner } !<v5>: *
inner@while (true) { continue@inner } !<v5>: * COPY
{ inner@while (true) { continue@inner } } !<v5>: * COPY
"OK" <v6>: String NEW: r("OK") -> <v6>
return "OK" !<v7>: *
{ return "OK" } !<v7>: * COPY
try { inner@while (true) { continue@inner } } finally { return "OK" } <v8>: * NEW: merge(try { inner@while (true) { continue@inner } } finally { return "OK" }|!<v5>) -> <v8>
{ try { inner@while (true) { continue@inner } } finally { return "OK" } } <v8>: * COPY
while (true) { try { inner@while (true) { continue@inner } } finally { return "OK" } } !<v9>: *
outer@while (true) { try { inner@while (true) { continue@inner } } finally { return "OK" } } !<v9>: * COPY
{ outer@while (true) { try { inner@while (true) { continue@inner } } finally { return "OK" } } } !<v9>: * COPY
=====================
@@ -58,7 +58,8 @@ L0:
r(0) -> <v2>
mark(n < 0)
call(n < 0, compareTo|<v1>, <v2>) -> <v3>
jf(L3|<v3>) NEXT:[read (Unit), r(0) -> <v4>]
jf(L3|<v3>) NEXT:[read (Unit), jmp?(L2)]
jmp?(L2) NEXT:[mark({ for (i in 1..2) { } return bar() }), r(0) -> <v4>]
r(0) -> <v4>
L4 [start finally]:
4 mark({ for (i in 1..2) { } return bar() })
@@ -99,9 +100,10 @@ L12 [after local declaration]:
r({ return it }) -> <v14> PREV:[jmp?(L12)]
mark(let { return it })
call(let { return it }, let|<v13>, <v14>) -> <v15>
2 jmp(L20) NEXT:[mark({ for (i in 1..2) { } return bar() })]
2 jmp?(L2) NEXT:[mark({ for (i in 1..2) { } return bar() }), jmp(L20)]
jmp(L20) NEXT:[mark({ for (i in 1..2) { } return bar() })]
L2 [onExceptionToFinallyBlock]:
4 mark({ for (i in 1..2) { } return bar() }) PREV:[jmp?(L2)]
4 mark({ for (i in 1..2) { } return bar() }) PREV:[jmp?(L2), jmp?(L2), jmp?(L2)]
5 r(1) -> <v5>
r(2) -> <v6>
mark(1..2)
@@ -21,10 +21,11 @@ L0:
3 mark({ i = 1 })
r(1) -> <v1>
w(i|<v1>)
2 jmp(L3) NEXT:[mark({ fun bar() {} return i })]
2 jmp?(L2) NEXT:[mark({ fun bar() {} return i }), jmp(L3)]
jmp(L3) NEXT:[mark({ fun bar() {} return i })]
L2 [onExceptionToFinallyBlock]:
L4 [start finally]:
3 mark({ fun bar() {} return i }) PREV:[jmp?(L2)]
3 mark({ fun bar() {} return i }) PREV:[jmp?(L2), jmp?(L2)]
jmp?(L5) NEXT:[r(i) -> <v3>, d(fun bar() {})]
d(fun bar() {}) NEXT:[<SINK>]
L5 [after local declaration]: