JVM_IR: fix Result types in continuations & remove more codegen hacks

#KT-47129 Fixed
This commit is contained in:
pyos
2021-06-04 15:39:40 +02:00
committed by Ilmir Usmanov
parent e8490f950a
commit 0bd8d16fe2
13 changed files with 69 additions and 17 deletions
@@ -10259,6 +10259,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/genericParameterResult.kt");
}
@Test
@TestMetadata("kt47129.kt")
public void testKt47129() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/kt47129.kt");
}
@Test
@TestMetadata("nonLocalReturn.kt")
public void testNonLocalReturn() throws Exception {
@@ -250,6 +250,8 @@ class JvmSymbols(
klass.inlineClassRepresentation = InlineClassRepresentation(Name.identifier("value"), irBuiltIns.anyNType as IrSimpleType)
}
val resultOfAnyType: IrType = resultClassStub.typeWith(irBuiltIns.anyNType)
val continuationImplClass: IrClassSymbol =
createClass(FqName("kotlin.coroutines.jvm.internal.ContinuationImpl"), classModality = Modality.ABSTRACT) { klass ->
val continuationType = continuationClass.typeWith(irBuiltIns.anyNType)
@@ -258,7 +260,7 @@ class JvmSymbols(
addValueParameter(SUSPEND_FUNCTION_COMPLETION_PARAMETER_NAME, continuationType.makeNullable())
}
klass.addFunction(INVOKE_SUSPEND_METHOD_NAME, irBuiltIns.anyNType, Modality.ABSTRACT).apply {
addValueParameter(SUSPEND_CALL_RESULT_NAME, resultClassStub.typeWith(irBuiltIns.anyNType))
addValueParameter(SUSPEND_CALL_RESULT_NAME, resultOfAnyType)
}
}
@@ -291,7 +293,7 @@ class JvmSymbols(
)
}
klass.addFunction(INVOKE_SUSPEND_METHOD_NAME, irBuiltIns.anyNType, Modality.ABSTRACT, DescriptorVisibilities.PROTECTED).apply {
addValueParameter(SUSPEND_CALL_RESULT_NAME, resultClassStub.typeWith(irBuiltIns.anyNType))
addValueParameter(SUSPEND_CALL_RESULT_NAME, resultOfAnyType)
}
klass.addFunction(SUSPEND_FUNCTION_CREATE_METHOD_NAME, continuationClass.typeWith(irBuiltIns.unitType), Modality.OPEN).apply {
addValueParameter(SUSPEND_FUNCTION_COMPLETION_PARAMETER_NAME, continuationClass.typeWith(irBuiltIns.nothingType))
@@ -934,10 +934,6 @@ class ExpressionCodegen(
val (returnType, returnIrType) = owner.returnAsmAndIrTypes()
val afterReturnLabel = Label()
expression.value.accept(this, data).materializeAt(returnType, returnIrType)
// In case of non-local return from suspend lambda 'materializeAt' does not box return value, box it manually.
if (isNonLocalReturn && owner.isInvokeSuspendOfLambda() && expression.value.type.isKotlinResult()) {
StackValue.boxInlineClass(expression.value.type, mv, typeMapper)
}
generateFinallyBlocksIfNeeded(returnType, afterReturnLabel, data, null)
expression.markLineNumber(startOffset = true)
if (isNonLocalReturn) {
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.backend.jvm.codegen
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.ir.eraseTypeParameters
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.*
import org.jetbrains.kotlin.codegen.AsmUtil
@@ -32,15 +31,8 @@ abstract class PromisedValue(val codegen: ExpressionCodegen, val type: Type, val
val fromTypeRepresentation = erasedSourceType.getClass()!!.inlineClassRepresentation
val toTypeRepresentation = erasedTargetType.getClass()!!.inlineClassRepresentation
// Boxing and unboxing kotlin.Result leads to CCE in generated code
val doNotCoerceKotlinResultInContinuation =
(codegen.irFunction.parentAsClass.origin == JvmLoweredDeclarationOrigin.CONTINUATION_CLASS ||
(codegen.irFunction.parentAsClass.origin == JvmLoweredDeclarationOrigin.SUSPEND_LAMBDA &&
!codegen.irFunction.isInvokeSuspendOfLambda()))
&& (irType.isKotlinResult() || irTarget.isKotlinResult())
// Coerce inline classes
if ((fromTypeRepresentation != null || toTypeRepresentation != null) && !doNotCoerceKotlinResultInContinuation) {
if (fromTypeRepresentation != null || toTypeRepresentation != null) {
val isFromTypeUnboxed = fromTypeRepresentation?.underlyingType?.let(typeMapper::mapType) == type
val isToTypeUnboxed = toTypeRepresentation?.underlyingType?.let(typeMapper::mapType) == target
@@ -105,7 +105,7 @@ private class AddContinuationLowering(context: JvmBackendContext) : SuspendLower
val resultField = addField {
origin = JvmLoweredDeclarationOrigin.CONTINUATION_CLASS_RESULT_FIELD
name = Name.identifier(context.state.languageVersionSettings.dataFieldName())
type = context.irBuiltIns.anyNType
type = context.ir.symbols.resultOfAnyType
visibility = JavaDescriptorVisibilities.PACKAGE_VISIBILITY
}
val capturedThisField = dispatchReceiverParameter?.let {
@@ -340,7 +340,14 @@ private class SuspendLambdaLowering(context: JvmBackendContext) : SuspendLowerin
}
private fun IrBlockBodyBuilder.callInvokeSuspend(invokeSuspend: IrSimpleFunction, lambda: IrExpression): IrExpression =
irCallOp(invokeSuspend.symbol, invokeSuspend.returnType, lambda, irUnit())
irCallOp(invokeSuspend.symbol, invokeSuspend.returnType, lambda, irCall(
this@SuspendLambdaLowering.context.ir.symbols.unsafeCoerceIntrinsic,
this@SuspendLambdaLowering.context.ir.symbols.resultOfAnyType
).apply {
putTypeArgument(0, context.irBuiltIns.anyNType)
putTypeArgument(1, type)
putValueArgument(0, irUnit())
})
private fun IrClass.addPrimaryConstructorForLambda(superClass: IrClass, arity: Int): IrConstructor =
addConstructor {
@@ -0,0 +1,17 @@
// WITH_RUNTIME
import kotlin.coroutines.*
fun <T> runBlocking(c: suspend () -> T): T {
var res: T? = null
c.startCoroutine(Continuation(EmptyCoroutineContext) {
res = it.getOrThrow()
})
return res!!
}
fun box(): String = runBlocking { // Non-inline lambda;
run { // In it an inline lambda
val foo = { Result.success("OK") } // Unboxes Result.
foo().getOrNull()!!
}
}
@@ -10259,6 +10259,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/genericParameterResult.kt");
}
@Test
@TestMetadata("kt47129.kt")
public void testKt47129() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/kt47129.kt");
}
@Test
@TestMetadata("nonLocalReturn.kt")
public void testNonLocalReturn() throws Exception {
@@ -10259,6 +10259,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/genericParameterResult.kt");
}
@Test
@TestMetadata("kt47129.kt")
public void testKt47129() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/kt47129.kt");
}
@Test
@TestMetadata("nonLocalReturn.kt")
public void testNonLocalReturn() throws Exception {
@@ -8109,6 +8109,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/genericParameterResult.kt");
}
@TestMetadata("kt47129.kt")
public void testKt47129() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/kt47129.kt");
}
@TestMetadata("nonLocalReturn.kt")
public void testNonLocalReturn() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/nonLocalReturn.kt");
@@ -7213,6 +7213,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/genericParameterResult.kt");
}
@TestMetadata("kt47129.kt")
public void testKt47129() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/kt47129.kt");
}
@TestMetadata("nonLocalReturn.kt")
public void testNonLocalReturn() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/nonLocalReturn.kt");
@@ -6619,6 +6619,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/genericParameterResult.kt");
}
@TestMetadata("kt47129.kt")
public void testKt47129() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/kt47129.kt");
}
@TestMetadata("nonLocalReturn.kt")
public void testNonLocalReturn() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/nonLocalReturn.kt");
@@ -6619,6 +6619,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/genericParameterResult.kt");
}
@TestMetadata("kt47129.kt")
public void testKt47129() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/kt47129.kt");
}
@TestMetadata("nonLocalReturn.kt")
public void testNonLocalReturn() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/nonLocalReturn.kt");