JVM_IR: fix Result types in continuations & remove more codegen hacks
#KT-47129 Fixed
This commit is contained in:
+6
@@ -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))
|
||||
|
||||
-4
@@ -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) {
|
||||
|
||||
+1
-9
@@ -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
|
||||
|
||||
|
||||
+1
-1
@@ -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 {
|
||||
|
||||
+8
-1
@@ -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()!!
|
||||
}
|
||||
}
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+5
@@ -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");
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java
Generated
+5
@@ -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");
|
||||
|
||||
Generated
+5
@@ -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");
|
||||
|
||||
Generated
+5
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user