JVM_IR: support non-local break/continue in the inliner

Not in the frontend or psi2ir, though, so this not a complete
implementation of KT-1436, but rather a part of it that is currently
useful to make other code compile. In particular, lambdas passed to
array constructors and JVM-style `assert` are inlined as IR returnable
blocks, which are then converted into `do { ... } while (false)` loops,
so non-local returns from them become non-local `break`s.
This commit is contained in:
pyos
2020-02-18 12:48:59 +01:00
committed by max-kammerer
parent 4a17228621
commit 0f2ca5d84c
28 changed files with 660 additions and 155 deletions
@@ -0,0 +1,5 @@
// FILE: 1.kt
inline fun runReturning(f: () -> Nothing): Nothing = f()
// FILE: 2.kt
fun box() = Array<String>(1) { runReturning { return@Array "OK" } }[0]
@@ -0,0 +1,24 @@
// FILE: 1.kt
inline fun runReturning(f: () -> Nothing): Nothing = f()
// FILE: 2.kt
fun box(): String {
var r = ""
val x = Array<String>(1) ext@{
try {
Array<String>(1) {
try {
runReturning { throw RuntimeException() }
} catch (e: Throwable) {
r += "1"
return@ext "OK"
} finally {
r += "2"
}
}[0]
} finally {
r += "3"
}
}[0]
return if (r == "123") x else r
}
@@ -0,0 +1,5 @@
// FILE: 1.kt
inline fun runReturning(f: () -> Nothing): Nothing = f()
// FILE: 2.kt
fun box() = Array<String>(1) { run { runReturning { return@Array "OK" } } }[0]
@@ -0,0 +1,8 @@
// FILE: 1.kt
inline fun runReturning(f: () -> Nothing): Nothing = f()
// FILE: 2.kt
fun box(): String {
val result = "OK"
return Array<String>(1) { run { runReturning { return@Array result } } }[0]
}
@@ -0,0 +1,22 @@
// FILE: 1.kt
inline fun runReturning(f: () -> Nothing): Nothing = f()
// FILE: 2.kt
fun box(): String {
var r = ""
val x = try {
Array<String>(1) {
try {
runReturning { throw RuntimeException() }
} finally {
r += "1"
}
}[0]
} catch (e: Throwable) {
r += "2"
"OK"
} finally {
r += "3"
}
return if (r == "123") x else r
}
@@ -0,0 +1,19 @@
// FILE: 1.kt
inline fun runReturning(f: () -> Nothing): Nothing = f()
// FILE: 2.kt
fun box(): String {
var r = ""
val x = try {
Array<String>(1) {
try {
runReturning { return@Array "OK" }
} finally {
r += "O"
}
}[0]
} finally {
r += "K"
}
return r
}
@@ -0,0 +1,25 @@
// FILE: 1.kt
inline fun runReturning(f: () -> Nothing): Nothing = f()
// FILE: 2.kt
fun box(): String {
var r = ""
val x = try {
Array<String>(1) ext@{
try {
Array<String>(1) {
try {
runReturning { return@ext "OK" }
} finally {
r += "1"
}
}[0]
} finally {
r += "2"
}
}[0]
} finally {
r += "3"
}
return if (r == "123") x else r
}
@@ -0,0 +1,25 @@
// FILE: 1.kt
inline fun runReturning(f: () -> Nothing): Nothing = f()
// FILE: 2.kt
fun box(): String {
var r = ""
val x = try {
Array<String>(1) ext@{
try {
Array<String>(1) {
try {
runReturning { return@Array "OK" }
} finally {
r += "1"
}
}[0]
} finally {
r += "2"
}
}[0]
} finally {
r += "3"
}
return if (r == "123") x else r
}