Fix improper handling of coroutine interceptors

Don't use coroutine facade in following cases:
* When calling coroutine functions in non-suspend mode (i.e.
  suspend flag is either false or skipped).
* When passing continuation from suspend function to suspend function.

Use facade only for corresponding intrinsics.
Reason: interceptor should not be called on each suspend function
invocation, it should be called after resume from innermost
suspend function.

Fix KT-17067. The example provided with the issue is very similar to
dispatchResume.kt which passes after these changes.

Add test to prove that KT-17446 is no more reproducible.
This commit is contained in:
Alexey Andreev
2017-04-13 12:40:09 +03:00
parent f3ed75998e
commit 7e6df03421
15 changed files with 91 additions and 36 deletions
@@ -1,6 +1,6 @@
// WITH_RUNTIME
// WITH_COROUTINES
// IGNORE_BACKEND: JS, NATIVE
// IGNORE_BACKEND: NATIVE
import kotlin.coroutines.experimental.*
import kotlin.coroutines.experimental.intrinsics.*
import kotlin.test.assertEquals
@@ -0,0 +1,48 @@
// IGNORE_BACKEND: NATIVE
// WITH_RUNTIME
// WITH_COROUTINES
import kotlin.coroutines.experimental.*
import kotlin.coroutines.experimental.intrinsics.suspendCoroutineOrReturn
import kotlin.coroutines.experimental.intrinsics.COROUTINE_SUSPENDED
fun box(): String {
async {
log += "1;"
wait()
log += "2;"
}
while (postponed != null) {
log += "suspended;"
postponed!!()
}
if (log != "1;wait2;suspended;wait;suspended;2;") return "fail: $log"
return "OK"
}
fun async(f: suspend () -> Unit) {
f.startCoroutine(handleResultContinuation {
postponed = null
})
}
suspend fun wait(): Unit {
wait2()
log += "wait;"
return suspendCoroutineOrReturn { c ->
postponed = { c.resume(Unit) }
COROUTINE_SUSPENDED
}
}
suspend fun wait2(): Unit = suspendCoroutineOrReturn { c ->
log += "wait2;"
postponed = { c.resume(Unit) }
COROUTINE_SUSPENDED
}
var postponed: (() -> Unit)? = { }
var log = ""
@@ -1,4 +1,4 @@
// IGNORE_BACKEND: JS, NATIVE
// IGNORE_BACKEND: NATIVE
// WITH_RUNTIME
// WITH_COROUTINES
import kotlin.coroutines.experimental.*