Fix VerifyError in coroutines caused by null spilling
While within a method by the JVM spec null-value has a special Nothing-like type, when we spill it for a coroutine, we must choose some real type to CHECKCAST to after restoring the variable's value. But the problem is that such a real type depends on usage of that null value, and there may be more than one usage. The solution is not to spill such variables into fields, but instead init them with ACONST_NULL after each suspension point #KT-16122 Fixed
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
suspend fun foo(value: String): String = suspendCoroutineOrReturn { x ->
|
||||
x.resume(value)
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
fun bar(x: String?, y: String, z: String): String {
|
||||
if (x != null) throw RuntimeException("fail 0")
|
||||
return y + z
|
||||
}
|
||||
|
||||
suspend fun baz1(): String {
|
||||
return bar(null, foo("O"), foo("K"))
|
||||
}
|
||||
|
||||
suspend fun baz2(): String {
|
||||
var x = null
|
||||
|
||||
for (i in 1..3) {
|
||||
x = null
|
||||
}
|
||||
|
||||
return bar(x, foo("O"), foo("K"))
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var result = ""
|
||||
|
||||
builder {
|
||||
result = baz1()
|
||||
|
||||
if (result != "OK") throw RuntimeException("fail 1")
|
||||
result = baz2()
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user