Support coroutines stack-unwinding in JVM backend

#KT-14924 In Progress
This commit is contained in:
Denis Zharkov
2016-11-29 10:30:33 +03:00
parent 27e4caf046
commit fcd9ee037e
86 changed files with 404 additions and 35 deletions
@@ -7,7 +7,7 @@ class Controller {
exception = t
}
suspend fun suspendHere(): Any = suspendWithCurrentContinuation { x ->}
suspend fun suspendHere(): Any = suspendWithCurrentContinuation { x -> }
// INTERCEPT_RESUME_PLACEHOLDER
}
@@ -7,6 +7,7 @@ class Controller {
suspend fun <T> await(t: T): T = suspendWithCurrentContinuation { c ->
c.resume(t)
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -7,6 +7,7 @@ class Controller {
suspend fun <T> suspendWithResult(value: T): T = suspendWithCurrentContinuation { c ->
c.resume(value)
Suspend
}
}
@@ -7,6 +7,7 @@ class Controller {
suspend fun <T> suspendWithResult(value: T): T = suspendWithCurrentContinuation { c ->
c.resume(value)
Suspend
}
}
@@ -7,6 +7,7 @@ class Controller {
suspend fun <T> suspendWithResult(value: T): T = suspendWithCurrentContinuation { c ->
c.resume(value)
Suspend
}
}
@@ -7,6 +7,7 @@ class Controller {
suspend fun <T> suspendWithResult(value: T): T = suspendWithCurrentContinuation { c ->
c.resume(value)
Suspend
}
}
@@ -7,6 +7,7 @@ class Controller {
suspend fun <T> suspendWithResult(value: T): T = suspendWithCurrentContinuation { c ->
c.resume(value)
Suspend
}
}
@@ -7,6 +7,7 @@ class Controller {
suspend fun <T> suspendWithResult(value: T): T = suspendWithCurrentContinuation { c ->
c.resume(value)
Suspend
}
}
@@ -12,6 +12,7 @@ class Controller {
suspend fun <T> suspendAndLog(value: T): T = suspendWithCurrentContinuation { c ->
result += "suspend($value);"
c.resume(value)
Suspend
}
operator fun handleResult(value: String, c: Continuation<Nothing>) {
@@ -8,6 +8,7 @@ class Controller {
suspend fun <T> suspendWithResult(value: T): T = suspendWithCurrentContinuation { c ->
result += "["
c.resume(value)
Suspend
}
}
@@ -8,11 +8,13 @@ class Controller {
suspend fun <T> suspendAndLog(value: T): T = suspendWithCurrentContinuation { c ->
result += "suspend($value);"
c.resume(value)
Suspend
}
suspend fun suspendLogAndThrow(exception: Throwable): Nothing = suspendWithCurrentContinuation { c ->
result += "throw(${exception.message});"
c.resumeWithException(exception)
Suspend
}
operator fun handleException(exception: Throwable, c: Continuation<Nothing>) {
@@ -8,6 +8,7 @@ class Controller {
suspend fun <T> suspendAndLog(value: T): T = suspendWithCurrentContinuation { c ->
result += "suspend($value);"
c.resume(value)
Suspend
}
operator fun handleException(exception: Throwable, c: Continuation<Nothing>) {
@@ -7,6 +7,7 @@ class Controller {
suspend fun <T> suspendWithResult(value: T): T = suspendWithCurrentContinuation { c ->
c.resume(value)
Suspend
}
}
@@ -3,6 +3,7 @@ class Controller {
var result = false
suspend fun suspendHere(): String = suspendWithCurrentContinuation { x ->
x.resume("OK")
Suspend
}
fun foo() {
@@ -2,6 +2,7 @@
class Controller {
suspend fun suspendHere(a: String = "abc", i: Int = 2): String = suspendWithCurrentContinuation { x ->
x.resume(a + "#" + (i + 1))
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -5,6 +5,7 @@ class Controller {
suspend fun suspendHere(): String = suspendWithCurrentContinuation { x ->
result++
x.resume("OK")
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -2,6 +2,7 @@
class Controller {
suspend fun <T> suspendHere(v: T): T = suspendWithCurrentContinuation { x ->
x.resume(v)
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
+2
View File
@@ -47,6 +47,8 @@ class GeneratorController<T>() : AbstractIterator<T>() {
suspend fun yield(value: T): Unit = suspendWithCurrentContinuation { c ->
setNext(value)
setNextStep(c)
Suspend
}
operator fun handleResult(result: Unit, c: Continuation<Nothing>) {
@@ -8,12 +8,16 @@ class Controller {
postponedActions.add {
x.resume(v)
}
Suspend
}
suspend fun suspendWithException(e: Exception): String = suspendWithCurrentContinuation { x ->
postponedActions.add {
x.resumeWithException(e)
}
Suspend
}
operator fun handleException(t: Throwable, c: Continuation<Nothing>) {
@@ -3,6 +3,7 @@ class Controller {
var isCompleted = false
suspend fun suspendHere(): String = suspendWithCurrentContinuation { x ->
x.resume("OK")
Suspend
}
operator fun handleResult(x: Unit, y: Continuation<Nothing>) {
@@ -5,6 +5,7 @@ class Controller {
suspend fun <T> suspendAndLog(value: T): T = suspendWithCurrentContinuation { x ->
log += "suspend($value);"
x.resume(value)
Suspend
}
operator fun handleResult(value: String, y: Continuation<Nothing>) {
@@ -5,6 +5,7 @@
class Controller {
suspend fun suspendHere(): Unit = suspendWithCurrentContinuation { x ->
x.resume(Unit)
Suspend
}
}
@@ -11,6 +11,7 @@ class Controller {
suspend inline fun suspendInline(v: String): String = suspendWithCurrentContinuation { x ->
withValue(v, x)
Suspend
}
suspend inline fun suspendInline(crossinline b: () -> String): String = suspendInline(b())
@@ -9,12 +9,16 @@ class Controller {
postponedActions.add {
x.resume(v)
}
Suspend
}
suspend fun suspendWithException(e: Exception): String = suspendWithCurrentContinuation { x ->
postponedActions.add {
x.resumeWithException(e)
}
Suspend
}
operator fun handleResult(x: String, c: Continuation<Nothing>) {
@@ -3,6 +3,7 @@ class Controller {
var i = 0
suspend fun suspendHere(): String = suspendWithCurrentContinuation { x ->
x.resume((i++).toString())
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -6,11 +6,13 @@ class Controller {
suspend fun runInstanceOf(): Boolean = suspendWithCurrentContinuation { x ->
val y: Any = x
x.resume(x is Continuation<*>)
Suspend
}
suspend fun runCast(): Boolean = suspendWithCurrentContinuation { x ->
val y: Any = x
x.resume(Continuation::class.isInstance(y as Continuation<*>))
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -2,6 +2,7 @@
class Controller {
suspend fun suspendHere(): Unit = suspendWithCurrentContinuation { x ->
x.resume(Unit)
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -2,6 +2,7 @@
class Controller {
suspend fun suspendHere(): Unit = suspendWithCurrentContinuation { x ->
x.resume(Unit)
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -2,6 +2,7 @@
class Controller {
suspend fun suspendHere(): Unit = suspendWithCurrentContinuation { x ->
x.resume(Unit)
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -2,6 +2,7 @@
class Controller {
suspend fun suspendHere(): Unit = suspendWithCurrentContinuation { x ->
x.resume(Unit)
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -2,6 +2,7 @@
class Controller {
suspend fun suspendHere(): Unit = suspendWithCurrentContinuation { x ->
x.resume(Unit)
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -2,6 +2,7 @@
class Controller {
suspend fun suspendHere(): Unit = suspendWithCurrentContinuation { x ->
x.resume(Unit)
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -4,6 +4,7 @@
class Controller {
suspend fun suspendHere(): Unit = suspendWithCurrentContinuation { x ->
x.resume(Unit)
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -2,6 +2,7 @@
class Controller {
suspend fun suspendHere(): Unit = suspendWithCurrentContinuation { x ->
x.resume(Unit)
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -4,6 +4,7 @@
class Controller {
suspend fun suspendHere(): Unit = suspendWithCurrentContinuation { x ->
x.resume(Unit)
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -2,6 +2,7 @@
class Controller {
suspend fun suspendHere(): Unit = suspendWithCurrentContinuation { x ->
x.resume(Unit)
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -2,6 +2,7 @@
class Controller {
suspend fun suspendHere(): String = suspendWithCurrentContinuation { x ->
x.resume("OK")
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
+1
View File
@@ -3,6 +3,7 @@ class Controller {
var result = "fail"
suspend fun <V> suspendHere(v: V): V = suspendWithCurrentContinuation { x ->
x.resume(v)
Suspend
}
operator fun handleResult(x: String, c: Continuation<Nothing>) {
@@ -2,6 +2,7 @@
class Controller {
suspend fun suspendHere(v: String): String = suspendWithCurrentContinuation { x ->
x.resume(v)
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -5,6 +5,7 @@ class Controller {
suspend fun suspendHere(v: String): Unit = suspendWithCurrentContinuation { x ->
result += v
x.resume(Unit)
Suspend
}
operator fun handleResult(u: Unit, v: Continuation<Nothing>) {
@@ -3,6 +3,7 @@ class Controller {
var wasHandleResultCalled = false
suspend fun suspendHere(): String = suspendWithCurrentContinuation { x ->
x.resume("OK")
Suspend
}
operator fun handleResult(x: Unit, y: Continuation<Nothing>) {
@@ -3,6 +3,7 @@ class Controller {
var wasHandleResultCalled = false
suspend fun suspendHere(): String = suspendWithCurrentContinuation { x ->
x.resume("OK")
Suspend
}
operator fun handleResult(x: Unit, y: Continuation<Nothing>) {
@@ -5,6 +5,7 @@ class Controller {
suspend fun suspendHere(v: String): Unit = suspendWithCurrentContinuation { x ->
this.v = v
x.resume(Unit)
Suspend
}
operator fun handleResult(u: Unit, v: Continuation<Nothing>) {
@@ -3,6 +3,7 @@
class Controller {
suspend fun suspendHere(): String = suspendWithCurrentContinuation { x ->
x.resume("OK")
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -6,6 +6,7 @@ package lib
class Controller {
suspend fun suspendHere(): String = suspendWithCurrentContinuation { x ->
x.resume("OK")
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -7,6 +7,7 @@ package lib
class Controller {
suspend fun String.suspendHere(): String = suspendWithCurrentContinuation { x ->
x.resume(this)
Suspend
}
inline suspend fun String.inlineSuspendHere(): String = suspendHere()
@@ -4,7 +4,7 @@ class Controller {
var result = "fail"
suspend fun suspendHere(): String = suspendWithCurrentContinuation { x ->
lastSuspension = x
Unit
Suspend
}
fun hasNext() = lastSuspension != null
@@ -4,7 +4,7 @@ class Controller {
var result = "fail"
suspend fun suspendHere(): String = suspendWithCurrentContinuation { x ->
lastSuspension = x
Unit
Suspend
}
fun hasNext() = lastSuspension != null
@@ -4,7 +4,7 @@ class Controller {
var result = "fail"
suspend fun suspendHere(): String = suspendWithCurrentContinuation { x ->
lastSuspension = x
Unit
Suspend
}
fun hasNext() = lastSuspension != null
@@ -4,7 +4,7 @@ class Controller {
var result = "fail"
suspend fun suspendHere(): String = suspendWithCurrentContinuation { x ->
lastSuspension = x
Unit
Suspend
}
fun hasNext() = lastSuspension != null
@@ -9,12 +9,16 @@ class Controller {
postponedActions.add {
x.resume(v)
}
Suspend
}
suspend fun suspendWithException(e: Exception): String = suspendWithCurrentContinuation { x ->
postponedActions.add {
x.resumeWithException(e)
}
Suspend
}
operator fun handleResult(x: String, c: Continuation<Nothing>) {
@@ -3,6 +3,7 @@ class Controller {
var cResult = 0
suspend fun suspendHere(v: Int): Int = suspendWithCurrentContinuation { x ->
x.resume(v * 2)
Suspend
}
operator fun handleResult(x: Int, y: Continuation<Nothing>) {
@@ -5,6 +5,7 @@ class Controller {
var cResult = 0
suspend fun suspendHere(v: Int): Int = suspendWithCurrentContinuation { x ->
x.resume(v * 2)
Suspend
}
operator fun handleResult(x: Int, y: Continuation<Nothing>) {
@@ -3,6 +3,7 @@ class Controller {
var res = 0
suspend fun suspendHere(): String = suspendWithCurrentContinuation { x ->
x.resume("OK")
Suspend
}
operator fun handleResult(x: Int, y: Continuation<Nothing>) {
+1
View File
@@ -2,6 +2,7 @@
class Controller {
suspend fun suspendHere(): String = suspendWithCurrentContinuation { x ->
x.resume("OK")
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -2,6 +2,7 @@
class Controller {
suspend fun suspendHere(): String = suspendWithCurrentContinuation { x ->
x.resumeWithException(RuntimeException("OK"))
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -3,6 +3,7 @@ class Controller {
var res = 0
suspend fun suspendHere(): String = suspendWithCurrentContinuation { x ->
x.resume("OK")
Suspend
}
operator fun handleResult(x: Int, y: Continuation<Nothing>) {
@@ -0,0 +1,19 @@
class Controller {
suspend fun suspendHere(): String = throw RuntimeException("OK")
// INTERCEPT_RESUME_PLACEHOLDER
}
fun builder(coroutine c: Controller.() -> Continuation<Unit>) {
c(Controller()).resume(Unit)
}
fun box(): String {
var result = ""
builder {
result = try { suspendHere() } catch (e: RuntimeException) { e.message!! }
}
return result
}
@@ -0,0 +1,36 @@
// WITH_RUNTIME
// WITH_REFLECT
// CHECK_NOT_CALLED: suspendInline_die06n$
// CHECK_NOT_CALLED: suspendInline_nesahw$
// CHECK_NOT_CALLED: suspendInline_grpnnl$
class Controller {
suspend inline fun suspendInline(v: String): String = v
suspend inline fun suspendInline(crossinline b: () -> String): String = suspendInline(b())
suspend inline fun <reified T : Any> suspendInline(): String = suspendInline({ T::class.simpleName!! })
// INTERCEPT_RESUME_PLACEHOLDER
}
fun builder(coroutine c: Controller.() -> Continuation<Unit>) {
c(Controller()).resume(Unit)
}
class OK
fun box(): String {
var result = ""
builder {
result = suspendInline("56")
if (result != "56") throw RuntimeException("fail 1")
result = suspendInline { "57" }
if (result != "57") throw RuntimeException("fail 2")
result = suspendInline<OK>()
}
return result
}
@@ -0,0 +1,19 @@
class Controller {
suspend fun suspendHere() = "OK"
// INTERCEPT_RESUME_PLACEHOLDER
}
fun builder(coroutine c: Controller.() -> Continuation<Unit>) {
c(Controller()).resume(Unit)
}
fun box(): String {
var result = ""
builder {
result = suspendHere()
}
return result
}
@@ -0,0 +1,47 @@
// IGNORE_BACKEND: JS
class Controller {
suspend fun suspendHere(): Int = suspendWithCurrentContinuation { x ->
1
}
suspend fun suspendThere(): String = suspendWithCurrentContinuation { x ->
"?"
}
// INTERCEPT_RESUME_PLACEHOLDER
}
fun builder(coroutine c: Controller.() -> Continuation<Unit>) {
c(Controller()).resume(Unit)
}
fun box(): String {
var result = ""
builder {
result += "-"
for (i in 0..10000) {
if (i % 2 == 0) {
result += suspendHere().toString()
}
else if (i == 3) {
result += suspendThere()
}
}
result += "+"
}
var mustBe = "-"
for (i in 0..10000) {
if (i % 2 == 0) {
mustBe += "1"
}
else if (i == 3) {
mustBe += "?"
}
}
mustBe += "+"
if (result != mustBe) return "fail: $result/$mustBe"
return "OK"
}
@@ -3,6 +3,7 @@ var globalResult = ""
class Controller {
suspend fun suspendWithValue(v: String): String = suspendWithCurrentContinuation { x ->
x.resume(v)
Suspend
}
operator fun handleResult(x: String, c: Continuation<Nothing>) {
@@ -4,6 +4,7 @@ class Controller {
suspend fun suspendThere(): String = suspendWithCurrentContinuation { x ->
x.resume("OK")
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -3,6 +3,7 @@
class Controller {
suspend fun String.suspendHere(): String = suspendWithCurrentContinuation { x ->
x.resume(this)
Suspend
}
inline suspend fun String.inlineSuspendHere(): String = suspendHere()
@@ -2,6 +2,7 @@
class Controller {
suspend fun suspendHere(v: Int): Int = suspendWithCurrentContinuation { x ->
x.resume(v * 2)
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -3,9 +3,11 @@ class Controller {
var i = 0
suspend fun suspendHere(): Int = suspendWithCurrentContinuation { x ->
x.resume(i++)
Suspend
}
suspend fun suspendThere(): String = suspendWithCurrentContinuation { x ->
x.resume("?")
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -2,14 +2,17 @@
class Controller {
suspend fun suspendHere(): String = suspendWithCurrentContinuation { x ->
x.resume("K")
Suspend
}
suspend fun suspendWithArgument(v: String): String = suspendWithCurrentContinuation { x ->
x.resume(v)
Suspend
}
suspend fun suspendWithDouble(v: Double): Double = suspendWithCurrentContinuation { x ->
x.resume(v)
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -9,12 +9,16 @@ class Controller {
postponedActions.add {
x.resume(v)
}
Suspend
}
suspend fun suspendWithException(e: Exception): String = suspendWithCurrentContinuation { x ->
postponedActions.add {
x.resumeWithException(e)
}
Suspend
}
operator fun handleResult(x: String, c: Continuation<Nothing>) {
@@ -9,12 +9,16 @@ class Controller {
postponedActions.add {
x.resume(v)
}
Suspend
}
suspend fun suspendWithException(e: Exception): String = suspendWithCurrentContinuation { x ->
postponedActions.add {
x.resumeWithException(e)
}
Suspend
}
operator fun handleResult(x: String, c: Continuation<Nothing>) {
@@ -2,6 +2,8 @@
class Controller {
suspend fun suspendHere(v: String): String = suspendWithCurrentContinuation { x ->
x.resume(v)
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -9,12 +9,16 @@ class Controller {
postponedActions.add {
x.resume(v)
}
Suspend
}
suspend fun suspendWithException(e: Exception): String = suspendWithCurrentContinuation { x ->
postponedActions.add {
x.resumeWithException(e)
}
Suspend
}
operator fun handleResult(x: String, c: Continuation<Nothing>) {
@@ -2,6 +2,7 @@
class Controller {
suspend fun suspendHere(): String = suspendWithCurrentContinuation { x ->
x.resume("OK")
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -2,6 +2,7 @@
class Controller {
suspend fun suspendHere(): String = suspendWithCurrentContinuation { x ->
x.resume("OK")
Suspend
}
// INTERCEPT_RESUME_PLACEHOLDER
@@ -1,7 +1,7 @@
@kotlin.Metadata
public final class Controller {
public method <init>(): void
public final method suspendHere(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): void
public final @org.jetbrains.annotations.Nullable method suspendHere(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object
}
@kotlin.Metadata
+2 -1
View File
@@ -19,4 +19,5 @@ fun box(): String {
}
// 1 GETSTATIC kotlin/Unit.INSTANCE : Lkotlin/Unit;
// 1 GETSTATIC
// 1 GETSTATIC kotlin/coroutines/Suspend.INSTANCE
// 2 GETSTATIC
+2
View File
@@ -60,6 +60,8 @@ class FutureController<T> {
else
machine.resumeWithException(throwable)
}
Suspend
}
operator fun handleResult(value: T, c: Continuation<Nothing>) {
+2
View File
@@ -56,6 +56,8 @@ class FutureController<T> {
else
machine.resumeWithException(throwable)
}
Suspend
}
operator fun handleResult(value: T, c: Continuation<Nothing>) {