Check variables, captured by outer object when searching for suspend crossinline parameters

This commit is contained in:
Ilmir Usmanov
2019-04-17 19:33:33 +03:00
parent 7c14f4c6ae
commit a793055ec2
14 changed files with 387 additions and 27 deletions
@@ -0,0 +1,283 @@
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
// CHECK_STATE_MACHINE
// FILE: inlineMe.kt
package test
import helpers.*
interface SuspendRunnable {
suspend fun run1()
suspend fun run2()
}
inline fun inlineMe(crossinline c1: suspend () -> Unit, crossinline c2: suspend () -> Unit) = object : SuspendRunnable {
override suspend fun run1() {
c1(); c1()
}
override suspend fun run2() {
c2(); c2()
}
}
inline fun inlineMe2(crossinline c1: suspend () -> Unit, crossinline c2: suspend () -> Unit) = inlineMe({ c1(); c1() }) { c2(); c2() }
inline fun inlineMe3(crossinline c1: suspend () -> Unit, crossinline c2: suspend () -> Unit) = object : SuspendRunnable {
override suspend fun run1() {
val sr = inlineMe({ c1(); c1() }) { c2(); c2() }
sr.run1()
sr.run2()
}
override suspend fun run2() {
val sr = inlineMe2({ c1(); c1() }) { c2(); c2() }
sr.run1()
sr.run2()
}
}
inline fun inlineMe4(crossinline c1: suspend () -> Unit, crossinline c2: suspend () -> Unit) = object : SuspendRunnable {
override suspend fun run1() {
val sr = suspend {
c1();
c2()
}
sr()
sr()
}
override suspend fun run2() {
val sr = object : SuspendRunnable {
override suspend fun run1() {
c1(); c1()
}
override suspend fun run2() {
c2(); c2()
}
}
sr.run1()
sr.run2()
}
}
inline fun inlineMe5(crossinline c1: suspend () -> Unit) = inlineMe({ c1(); c1() }) {
StateMachineChecker.suspendHere()
}
// FILE: A.java
import test.InlineMeKt;
import helpers.CoroutineUtilKt;
import helpers.EmptyContinuation;
import kotlin.Unit;
public class A {
public static Object call() {
return InlineMeKt.inlineMe((continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation),
(continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation));
}
public static Object call2() {
return InlineMeKt.inlineMe2((continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation),
(continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation));
}
public static Object call3() {
return InlineMeKt.inlineMe3((continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation),
(continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation));
}
public static Object call4() {
return InlineMeKt.inlineMe4((continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation),
(continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation));
}
public static Object call5() {
return InlineMeKt.inlineMe5((continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation));
}
}
// FILE: box.kt
import test.*
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(CheckStateMachineContinuation)
}
fun box(): String {
builder {
(A.call() as SuspendRunnable).run1()
}
StateMachineChecker.check(2)
StateMachineChecker.reset()
builder {
(A.call() as SuspendRunnable).run2()
}
StateMachineChecker.check(2)
StateMachineChecker.reset()
builder {
(A.call2() as SuspendRunnable).run1()
}
StateMachineChecker.check(4)
StateMachineChecker.reset()
builder {
(A.call2() as SuspendRunnable).run2()
}
StateMachineChecker.check(4)
StateMachineChecker.reset()
builder {
(A.call3() as SuspendRunnable).run1()
}
StateMachineChecker.check(8)
StateMachineChecker.reset()
builder {
(A.call3() as SuspendRunnable).run2()
}
StateMachineChecker.check(16)
StateMachineChecker.reset()
builder {
(A.call4() as SuspendRunnable).run1()
}
StateMachineChecker.check(4)
StateMachineChecker.reset()
builder {
(A.call4() as SuspendRunnable).run2()
}
StateMachineChecker.check(4)
StateMachineChecker.reset()
builder {
(A.call5() as SuspendRunnable).run1()
}
StateMachineChecker.check(4)
StateMachineChecker.reset()
builder {
(A.call5() as SuspendRunnable).run2()
}
StateMachineChecker.check(2)
StateMachineChecker.reset()
builder {
inlineMe({
StateMachineChecker.suspendHere()
StateMachineChecker.suspendHere()
}) {
StateMachineChecker.suspendHere()
StateMachineChecker.suspendHere()
}.run1()
}
StateMachineChecker.check(4)
StateMachineChecker.reset()
builder {
inlineMe({
StateMachineChecker.suspendHere()
StateMachineChecker.suspendHere()
}) {
StateMachineChecker.suspendHere()
StateMachineChecker.suspendHere()
}.run2()
}
StateMachineChecker.check(4)
StateMachineChecker.reset()
builder {
inlineMe2 ({
StateMachineChecker.suspendHere()
StateMachineChecker.suspendHere()
}) {
StateMachineChecker.suspendHere()
StateMachineChecker.suspendHere()
}.run1()
}
StateMachineChecker.check(8)
StateMachineChecker.reset()
builder {
inlineMe2 ({
StateMachineChecker.suspendHere()
StateMachineChecker.suspendHere()
}) {
StateMachineChecker.suspendHere()
StateMachineChecker.suspendHere()
}.run2()
}
StateMachineChecker.check(8)
StateMachineChecker.reset()
builder {
inlineMe3 ({
StateMachineChecker.suspendHere()
StateMachineChecker.suspendHere()
}) {
StateMachineChecker.suspendHere()
StateMachineChecker.suspendHere()
}.run1()
}
StateMachineChecker.check(16)
StateMachineChecker.reset()
builder {
inlineMe3 ({
StateMachineChecker.suspendHere()
StateMachineChecker.suspendHere()
}) {
StateMachineChecker.suspendHere()
StateMachineChecker.suspendHere()
}.run2()
}
StateMachineChecker.check(32)
StateMachineChecker.reset()
builder {
inlineMe4 ({
StateMachineChecker.suspendHere()
StateMachineChecker.suspendHere()
}) {
StateMachineChecker.suspendHere()
StateMachineChecker.suspendHere()
}.run1()
}
StateMachineChecker.check(8)
StateMachineChecker.reset()
builder {
inlineMe4 ({
StateMachineChecker.suspendHere()
StateMachineChecker.suspendHere()
}) {
StateMachineChecker.suspendHere()
StateMachineChecker.suspendHere()
}.run2()
}
StateMachineChecker.check(8)
StateMachineChecker.reset()
builder {
inlineMe5 {
StateMachineChecker.suspendHere()
StateMachineChecker.suspendHere()
}.run1()
}
StateMachineChecker.check(8)
StateMachineChecker.reset()
builder {
inlineMe5 {
StateMachineChecker.suspendHere()
StateMachineChecker.suspendHere()
}.run2()
}
StateMachineChecker.check(2)
StateMachineChecker.reset()
return "OK"
}
@@ -261,7 +261,13 @@ public final class CrossinlineKt$filter$$inlined$source$1 {
}
@kotlin.Metadata
@kotlin.coroutines.jvm.internal.DebugMetadata
public final class CrossinlineKt$fold$$inlined$consumeEach$1$1 {
field L$0: java.lang.Object
field L$1: java.lang.Object
field L$2: java.lang.Object
field L$3: java.lang.Object
field L$4: java.lang.Object
field label: int
synthetic field result: java.lang.Object
synthetic final field this$0: CrossinlineKt$fold$$inlined$consumeEach$1
@@ -271,6 +271,11 @@ public final class CrossinlineKt$filter$$inlined$source$1 {
@kotlin.Metadata
public final class CrossinlineKt$fold$$inlined$consumeEach$1$1 {
field L$0: java.lang.Object
field L$1: java.lang.Object
field L$2: java.lang.Object
field L$3: java.lang.Object
field L$4: java.lang.Object
synthetic field data: java.lang.Object
synthetic field exception: java.lang.Throwable
synthetic final field this$0: CrossinlineKt$fold$$inlined$consumeEach$1
@@ -140,7 +140,12 @@ public final class flow/InnerObjectRetransformationKt$flow$1 {
}
@kotlin.Metadata
@kotlin.coroutines.jvm.internal.DebugMetadata
public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1$1 {
field L$0: java.lang.Object
field L$1: java.lang.Object
field L$2: java.lang.Object
field L$3: java.lang.Object
field label: int
synthetic field result: java.lang.Object
synthetic final field this$0: flow.InnerObjectRetransformationKt$flowWith$$inlined$flow$1
@@ -149,6 +149,10 @@ public final class flow/InnerObjectRetransformationKt$flow$1 {
@kotlin.Metadata
public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1$1 {
field L$0: java.lang.Object
field L$1: java.lang.Object
field L$2: java.lang.Object
field L$3: java.lang.Object
synthetic field data: java.lang.Object
synthetic field exception: java.lang.Throwable
synthetic final field this$0: flow.InnerObjectRetransformationKt$flowWith$$inlined$flow$1