Support tailrec suspend functions in JVM backend

The main problem is that inside a state machine for a named suspend
function parameters of it's owner are available as a usual captured
closure parameters (i.e. through synthetic fields), while
TailRecursion codegen expects that parameters are straight local
variables.

So, the solution is just to define local var for each of real parameters
(all but the last continuation parameters) for tailrec functions.

 #KT-15759 Fixed
This commit is contained in:
Denis Zharkov
2017-02-01 16:46:36 +03:00
parent d7403ca185
commit 0878049f15
9 changed files with 172 additions and 27 deletions
@@ -0,0 +1,35 @@
// WITH_RUNTIME
// WITH_COROUTINES
// IGNORE_BACKEND: JS
import kotlin.coroutines.experimental.*
import kotlin.coroutines.experimental.intrinsics.*
import kotlin.test.assertEquals
suspend fun ArrayList<Int>.yield(v: Int): Unit = suspendCoroutineOrReturn { x ->
this.add(v)
x.resume(Unit)
COROUTINE_SUSPENDED
}
tailrec suspend fun ArrayList<Int>.fromTo(from: Int, to: Int) {
if (from > to) return
yield(from)
return fromTo(from + 1, to)
}
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
val result = arrayListOf<Int>()
builder {
result.fromTo(1, 5)
}
assertEquals(listOf(1, 2, 3, 4, 5), result)
return "OK"
}