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");
|
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
|
@Test
|
||||||
@TestMetadata("nonLocalReturn.kt")
|
@TestMetadata("nonLocalReturn.kt")
|
||||||
public void testNonLocalReturn() throws Exception {
|
public void testNonLocalReturn() throws Exception {
|
||||||
|
|||||||
@@ -250,6 +250,8 @@ class JvmSymbols(
|
|||||||
klass.inlineClassRepresentation = InlineClassRepresentation(Name.identifier("value"), irBuiltIns.anyNType as IrSimpleType)
|
klass.inlineClassRepresentation = InlineClassRepresentation(Name.identifier("value"), irBuiltIns.anyNType as IrSimpleType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val resultOfAnyType: IrType = resultClassStub.typeWith(irBuiltIns.anyNType)
|
||||||
|
|
||||||
val continuationImplClass: IrClassSymbol =
|
val continuationImplClass: IrClassSymbol =
|
||||||
createClass(FqName("kotlin.coroutines.jvm.internal.ContinuationImpl"), classModality = Modality.ABSTRACT) { klass ->
|
createClass(FqName("kotlin.coroutines.jvm.internal.ContinuationImpl"), classModality = Modality.ABSTRACT) { klass ->
|
||||||
val continuationType = continuationClass.typeWith(irBuiltIns.anyNType)
|
val continuationType = continuationClass.typeWith(irBuiltIns.anyNType)
|
||||||
@@ -258,7 +260,7 @@ class JvmSymbols(
|
|||||||
addValueParameter(SUSPEND_FUNCTION_COMPLETION_PARAMETER_NAME, continuationType.makeNullable())
|
addValueParameter(SUSPEND_FUNCTION_COMPLETION_PARAMETER_NAME, continuationType.makeNullable())
|
||||||
}
|
}
|
||||||
klass.addFunction(INVOKE_SUSPEND_METHOD_NAME, irBuiltIns.anyNType, Modality.ABSTRACT).apply {
|
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 {
|
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 {
|
klass.addFunction(SUSPEND_FUNCTION_CREATE_METHOD_NAME, continuationClass.typeWith(irBuiltIns.unitType), Modality.OPEN).apply {
|
||||||
addValueParameter(SUSPEND_FUNCTION_COMPLETION_PARAMETER_NAME, continuationClass.typeWith(irBuiltIns.nothingType))
|
addValueParameter(SUSPEND_FUNCTION_COMPLETION_PARAMETER_NAME, continuationClass.typeWith(irBuiltIns.nothingType))
|
||||||
|
|||||||
-4
@@ -934,10 +934,6 @@ class ExpressionCodegen(
|
|||||||
val (returnType, returnIrType) = owner.returnAsmAndIrTypes()
|
val (returnType, returnIrType) = owner.returnAsmAndIrTypes()
|
||||||
val afterReturnLabel = Label()
|
val afterReturnLabel = Label()
|
||||||
expression.value.accept(this, data).materializeAt(returnType, returnIrType)
|
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)
|
generateFinallyBlocksIfNeeded(returnType, afterReturnLabel, data, null)
|
||||||
expression.markLineNumber(startOffset = true)
|
expression.markLineNumber(startOffset = true)
|
||||||
if (isNonLocalReturn) {
|
if (isNonLocalReturn) {
|
||||||
|
|||||||
+1
-9
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.jvm.codegen
|
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.ir.eraseTypeParameters
|
||||||
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.*
|
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.*
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
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 fromTypeRepresentation = erasedSourceType.getClass()!!.inlineClassRepresentation
|
||||||
val toTypeRepresentation = erasedTargetType.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
|
// Coerce inline classes
|
||||||
if ((fromTypeRepresentation != null || toTypeRepresentation != null) && !doNotCoerceKotlinResultInContinuation) {
|
if (fromTypeRepresentation != null || toTypeRepresentation != null) {
|
||||||
val isFromTypeUnboxed = fromTypeRepresentation?.underlyingType?.let(typeMapper::mapType) == type
|
val isFromTypeUnboxed = fromTypeRepresentation?.underlyingType?.let(typeMapper::mapType) == type
|
||||||
val isToTypeUnboxed = toTypeRepresentation?.underlyingType?.let(typeMapper::mapType) == target
|
val isToTypeUnboxed = toTypeRepresentation?.underlyingType?.let(typeMapper::mapType) == target
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -105,7 +105,7 @@ private class AddContinuationLowering(context: JvmBackendContext) : SuspendLower
|
|||||||
val resultField = addField {
|
val resultField = addField {
|
||||||
origin = JvmLoweredDeclarationOrigin.CONTINUATION_CLASS_RESULT_FIELD
|
origin = JvmLoweredDeclarationOrigin.CONTINUATION_CLASS_RESULT_FIELD
|
||||||
name = Name.identifier(context.state.languageVersionSettings.dataFieldName())
|
name = Name.identifier(context.state.languageVersionSettings.dataFieldName())
|
||||||
type = context.irBuiltIns.anyNType
|
type = context.ir.symbols.resultOfAnyType
|
||||||
visibility = JavaDescriptorVisibilities.PACKAGE_VISIBILITY
|
visibility = JavaDescriptorVisibilities.PACKAGE_VISIBILITY
|
||||||
}
|
}
|
||||||
val capturedThisField = dispatchReceiverParameter?.let {
|
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 =
|
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 =
|
private fun IrClass.addPrimaryConstructorForLambda(superClass: IrClass, arity: Int): IrConstructor =
|
||||||
addConstructor {
|
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");
|
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
|
@Test
|
||||||
@TestMetadata("nonLocalReturn.kt")
|
@TestMetadata("nonLocalReturn.kt")
|
||||||
public void testNonLocalReturn() throws Exception {
|
public void testNonLocalReturn() throws Exception {
|
||||||
|
|||||||
+6
@@ -10259,6 +10259,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/genericParameterResult.kt");
|
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
|
@Test
|
||||||
@TestMetadata("nonLocalReturn.kt")
|
@TestMetadata("nonLocalReturn.kt")
|
||||||
public void testNonLocalReturn() throws Exception {
|
public void testNonLocalReturn() throws Exception {
|
||||||
|
|||||||
+5
@@ -8109,6 +8109,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/genericParameterResult.kt");
|
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")
|
@TestMetadata("nonLocalReturn.kt")
|
||||||
public void testNonLocalReturn() throws Exception {
|
public void testNonLocalReturn() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/nonLocalReturn.kt");
|
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");
|
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")
|
@TestMetadata("nonLocalReturn.kt")
|
||||||
public void testNonLocalReturn() throws Exception {
|
public void testNonLocalReturn() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/nonLocalReturn.kt");
|
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");
|
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")
|
@TestMetadata("nonLocalReturn.kt")
|
||||||
public void testNonLocalReturn() throws Exception {
|
public void testNonLocalReturn() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/nonLocalReturn.kt");
|
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");
|
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")
|
@TestMetadata("nonLocalReturn.kt")
|
||||||
public void testNonLocalReturn() throws Exception {
|
public void testNonLocalReturn() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/nonLocalReturn.kt");
|
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/nonLocalReturn.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user