From 81f3e39f29bc008c0dd8e1ffe2d07abac2904574 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Thu, 1 Mar 2018 17:50:18 +0300 Subject: [PATCH] Do not generate ACONST_NULL as continuation of crossinline suspend lambda --- .../kotlin/codegen/ExpressionCodegen.java | 6 ++- .../kotlin/codegen/inline/InlineCodegen.kt | 2 +- .../codegen/boxInline/suspend/returnValue.kt | 46 +++++++++++++++++++ .../IrBlackBoxInlineCodegenTestGenerated.java | 6 +++ ...otlinAgainstInlineKotlinTestGenerated.java | 6 +++ .../BlackBoxInlineCodegenTestGenerated.java | 6 +++ ...otlinAgainstInlineKotlinTestGenerated.java | 6 +++ 7 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/codegen/boxInline/suspend/returnValue.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 3fd0b8d16e8..15aebb1c844 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -1103,7 +1103,11 @@ public class ExpressionCodegen extends KtVisitor impleme if (closure.isSuspend()) { // resultContinuation if (closure.isSuspendLambda()) { - v.aconst(null); + boolean isCrossinlineLambda = (callGenerator instanceof InlineCodegen) && + Objects.requireNonNull(((InlineCodegen) callGenerator).getActiveLambda()).isCrossInline; + if (!isCrossinlineLambda) { + v.aconst(null); + } } else { assert context.getFunctionDescriptor().isSuspend() : "Coroutines closure must be created only inside suspend functions"; diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt index 63503444b4c..213acdb091c 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt @@ -87,7 +87,7 @@ abstract class InlineCodegen( protected val expressionMap = linkedMapOf() - protected var activeLambda: LambdaInfo? = null + var activeLambda: LambdaInfo? = null; protected set private val defaultSourceMapper = sourceCompiler.lazySourceMapper diff --git a/compiler/testData/codegen/boxInline/suspend/returnValue.kt b/compiler/testData/codegen/boxInline/suspend/returnValue.kt new file mode 100644 index 00000000000..6a9117411bd --- /dev/null +++ b/compiler/testData/codegen/boxInline/suspend/returnValue.kt @@ -0,0 +1,46 @@ +// FILE: inlined.kt +// WITH_RUNTIME +// NO_CHECK_LAMBDA_INLINING +import kotlin.coroutines.experimental.* +import kotlin.coroutines.experimental.intrinsics.* + +inline suspend fun suspendThere(v: String): String = suspendCoroutineOrReturn { x -> + x.resume(v) + COROUTINE_SUSPENDED +} + +suspend inline fun complexSuspend(crossinline c: suspend () -> String): String { + return run { + c() + } +} + +// FILE: inleneSite.kt +import kotlin.coroutines.experimental.* +import kotlin.coroutines.experimental.intrinsics.* + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(object: Continuation { + override val context: CoroutineContext + get() = EmptyCoroutineContext + + override fun resume(value: Unit) { + } + + override fun resumeWithException(exception: Throwable) { + throw exception + } + }) +} + +suspend fun suspendHere(): String = suspendThere("O") + +fun box(): String { + var result = "" + + builder { + result = suspendHere() + complexSuspend { suspendThere("K") } + } + + return result +} diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java index c5aac7becac..43517d270bc 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java @@ -3477,6 +3477,12 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli doTest(fileName); } + @TestMetadata("returnValue.kt") + public void testReturnValue() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/suspend/returnValue.kt"); + doTest(fileName); + } + @TestMetadata("tryCatchStackTransform.kt") public void testTryCatchStackTransform() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/suspend/tryCatchStackTransform.kt"); diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java index 9fb7a725362..e5878292cca 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java @@ -3477,6 +3477,12 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC doTest(fileName); } + @TestMetadata("returnValue.kt") + public void testReturnValue() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/suspend/returnValue.kt"); + doTest(fileName); + } + @TestMetadata("tryCatchStackTransform.kt") public void testTryCatchStackTransform() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/suspend/tryCatchStackTransform.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java index 4501acc2436..962427eaec8 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java @@ -3477,6 +3477,12 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo doTest(fileName); } + @TestMetadata("returnValue.kt") + public void testReturnValue() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/suspend/returnValue.kt"); + doTest(fileName); + } + @TestMetadata("tryCatchStackTransform.kt") public void testTryCatchStackTransform() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/suspend/tryCatchStackTransform.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java index 328397a1b19..5d0f226978f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java @@ -3477,6 +3477,12 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi doTest(fileName); } + @TestMetadata("returnValue.kt") + public void testReturnValue() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/suspend/returnValue.kt"); + doTest(fileName); + } + @TestMetadata("tryCatchStackTransform.kt") public void testTryCatchStackTransform() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/suspend/tryCatchStackTransform.kt");