From 7a096b305f11bece9e39ffd8875a766db5df677a Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Wed, 26 Jun 2019 17:34:48 +0300 Subject: [PATCH] Do not mangle functions with inline classes when the only inline class in arguments is kotlin.Result. Fix returnTarget for suspend function views. --- .../backend/jvm/codegen/ExpressionCodegen.kt | 2 +- .../jvm/lower/AddContinuationLowering.kt | 17 ++++++++++++++++- .../MemoizedInlineClassReplacements.kt | 9 ++++++++- .../coroutines/debug/runtimeDebugMetadata.kt | 2 +- .../codegen/box/coroutines/illegalState.kt | 1 - .../suspendCoroutineFromStateMachine.kt | 1 - .../tailCallOptimizations/tryCatch.kt | 1 + .../varCaptuedInCoroutineIntrinsic.kt | 1 + 8 files changed, 28 insertions(+), 6 deletions(-) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index 9489c9929a3..d5852bfbaee 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -402,7 +402,7 @@ class ExpressionCodegen( expression ) - val returnType = callee.returnType.substitute(typeSubstitutionMap) + val returnType = callee.returnType if (callee.isSuspend && !irFunction.isInvokeSuspendInContinuation()) { addSuspendMarker(mv, isStartNotEnd = false) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt index 2b6ebeb4e33..88a67bc3f9e 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt @@ -349,6 +349,7 @@ private class AddContinuationLowering(private val context: JvmBackendContext) : private fun addContinuationParameter(irFile: IrFile, suspendLambdas: Set): Set { val views = hashSetOf() + // Collect all suspend functions irFile.acceptVoid(object : IrElementVisitorVoid { override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) @@ -363,6 +364,20 @@ private class AddContinuationLowering(private val context: JvmBackendContext) : } } }) + // fix return targets + for (view in views) { + view.transformChildrenVoid(object : IrElementTransformerVoid() { + override fun visitReturn(expression: IrReturn): IrExpression { + val owner = expression.returnTargetSymbol.owner as? IrSimpleFunction + ?: return super.visitReturn(expression) + val ownerView = owner.getOrCreateView() + if (ownerView == owner) return super.visitReturn(expression) + val result = + IrReturnImpl(expression.startOffset, expression.endOffset, ownerView.returnType, ownerView.symbol, expression.value) + return super.visitReturn(result) + } + }) + } return views } @@ -416,7 +431,7 @@ private class AddContinuationLowering(private val context: JvmBackendContext) : override fun visitCall(expression: IrCall): IrExpression { if (!expression.isSuspend) return super.visitCall(expression) val view = (expression.symbol.owner as IrSimpleFunction).getOrCreateView() - val res = IrCallImpl(expression.startOffset, expression.endOffset, expression.type, view.symbol).apply { + val res = IrCallImpl(expression.startOffset, expression.endOffset, view.returnType, view.symbol).apply { copyTypeArgumentsFrom(expression) dispatchReceiver = expression.dispatchReceiver for (i in 0 until expression.valueArgumentsCount) { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/inlineclasses/MemoizedInlineClassReplacements.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/inlineclasses/MemoizedInlineClassReplacements.kt index 20c75b74791..db9624e5ce9 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/inlineclasses/MemoizedInlineClassReplacements.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/inlineclasses/MemoizedInlineClassReplacements.kt @@ -18,10 +18,14 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol +import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.util.constructedClass import org.jetbrains.kotlin.ir.util.defaultType import org.jetbrains.kotlin.ir.util.explicitParameters +import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.storage.LockBasedStorageManager class IrReplacementFunction( @@ -49,7 +53,10 @@ class MemoizedInlineClassReplacements { } private val IrFunction.hasInlineClassParameters: Boolean - get() = explicitParameters.any { it.type.erasedUpperBound.isInline } || (this is IrConstructor && constructedClass.isInline) + get() = explicitParameters.any { it.type.erasedUpperBound.isInline && !it.type.isDontMangleType() } + || (this is IrConstructor && constructedClass.isInline) + + private fun IrType.isDontMangleType() = getClass()?.fqNameWhenAvailable == DescriptorUtils.RESULT_FQ_NAME private val IrFunction.hasStaticReplacement: Boolean get() = origin != IrDeclarationOrigin.FAKE_OVERRIDE && diff --git a/compiler/testData/codegen/box/coroutines/debug/runtimeDebugMetadata.kt b/compiler/testData/codegen/box/coroutines/debug/runtimeDebugMetadata.kt index d05d10dba12..1003ddc1636 100644 --- a/compiler/testData/codegen/box/coroutines/debug/runtimeDebugMetadata.kt +++ b/compiler/testData/codegen/box/coroutines/debug/runtimeDebugMetadata.kt @@ -1,4 +1,4 @@ -// IGNORE_BACKEND: JVM_IR + // TARGET_BACKEND: JVM // WITH_RUNTIME // FULL_JDK diff --git a/compiler/testData/codegen/box/coroutines/illegalState.kt b/compiler/testData/codegen/box/coroutines/illegalState.kt index 1569efb22b1..49c184fb8d8 100644 --- a/compiler/testData/codegen/box/coroutines/illegalState.kt +++ b/compiler/testData/codegen/box/coroutines/illegalState.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // WITH_RUNTIME // WITH_COROUTINES // TARGET_BACKEND: JVM diff --git a/compiler/testData/codegen/box/coroutines/suspendCoroutineFromStateMachine.kt b/compiler/testData/codegen/box/coroutines/suspendCoroutineFromStateMachine.kt index f795d3b4f14..4e2fd0f4157 100644 --- a/compiler/testData/codegen/box/coroutines/suspendCoroutineFromStateMachine.kt +++ b/compiler/testData/codegen/box/coroutines/suspendCoroutineFromStateMachine.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // WITH_RUNTIME // WITH_COROUTINES // COMMON_COROUTINES_TEST diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/tryCatch.kt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/tryCatch.kt index 6b9518e2e61..b78790400a7 100644 --- a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/tryCatch.kt +++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/tryCatch.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND: JVM_IR // KJS_WITH_FULL_RUNTIME // WITH_RUNTIME // WITH_COROUTINES diff --git a/compiler/testData/codegen/box/coroutines/varCaptuedInCoroutineIntrinsic.kt b/compiler/testData/codegen/box/coroutines/varCaptuedInCoroutineIntrinsic.kt index 2c75e3c721c..cff0202e63a 100644 --- a/compiler/testData/codegen/box/coroutines/varCaptuedInCoroutineIntrinsic.kt +++ b/compiler/testData/codegen/box/coroutines/varCaptuedInCoroutineIntrinsic.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND: JVM_IR // WITH_RUNTIME // WITH_COROUTINES // COMMON_COROUTINES_TEST