KT-5248 Don't wrap variable if it is captured only in inlined closures

Remove non-escaping Ref's on bytecode postprocessing pass.
This commit is contained in:
Dmitry Petrov
2017-01-31 15:43:17 +03:00
parent 3fc106572e
commit 3c09a26e16
38 changed files with 1115 additions and 26 deletions
@@ -0,0 +1,9 @@
inline fun runCrossInline(crossinline f: () -> Unit) {
f()
}
fun box(): String {
var x = ""
runCrossInline { x = "OK" }
return x
}
@@ -0,0 +1,7 @@
// WITH_RUNTIME
fun box(): String {
var x = ""
run { x = "OK" }
return x
}
@@ -0,0 +1,10 @@
// WITH_RUNTIME
fun box(): String {
var x = ""
run {
x += "O"
x += "K"
}
return x
}
@@ -0,0 +1,8 @@
// WITH_RUNTIME
fun box(): String {
var x = 0
run { x++ }
run { ++x }
return if (x == 2) "OK" else "Fail: $x"
}
@@ -0,0 +1,18 @@
// WITH_RUNTIME
class Host(var value: String) {
operator fun get(i: Int, j: Int, k: Int) = value
operator fun set(i: Int, j: Int, k: Int, newValue: String) {
value = newValue
}
}
fun box(): String {
var x = Host("")
run {
x[0, 0, 0] += "O"
x[0, 0, 0] += "K"
}
return x.value
}
@@ -0,0 +1,26 @@
// WITH_RUNTIME
fun box(): String {
var xl = 0L // Long, size 2
var xi = 0 // Int, size 1
var xd = 0.0 // Double, size 2
run {
xl++
xd += 1.0
xi++
}
run {
run {
xl++
xd += 1.0
xi++
}
}
if (xi != 2) return "fail: xi=$xi"
if (xl != 2L) return "fail: xl=$xl"
if (xd != 2.0) return "fail: xd=$xd"
return "OK"
}
@@ -0,0 +1,19 @@
// WITH_RUNTIME
fun box(): String {
run {
run {
var x = 0
run { ++x }
if (x == 0) return "fail"
}
run {
var x = 0
run { x++ }
if (x == 0) return "fail"
}
}
return "OK"
}
@@ -0,0 +1,41 @@
// WITH_RUNTIME
// WITH_COROUTINES
import kotlin.coroutines.experimental.*
import kotlin.coroutines.experimental.intrinsics.*
class Controller {
var result = ""
suspend fun <T> suspendWithResult(value: T): T = suspendCoroutineOrReturn { c ->
c.resume(value)
COROUTINE_SUSPENDED
}
}
fun builder(c: suspend Controller.() -> Unit): String {
val controller = Controller()
c.startCoroutine(controller, EmptyContinuation)
return controller.result
}
fun box(): String {
val value = builder {
var r = ""
for (x in listOf("O", "$", "K")) {
if (x == "$") continue
run {
r += suspendWithResult(x)
}
}
run {
r += "."
}
result = r
}
if (value != "OK.") return "fail: suspend in for body: $value"
return "OK"
}