From 22de20e7e53bf5ca56e04fe5d1f2c8c4d6a15283 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Fri, 28 Feb 2020 15:29:17 +0100 Subject: [PATCH] JVM_IR: Generate PUBLIC constructor for suspend lambda if the lambda is inside inline function. --- .../backend/jvm/codegen/CoroutineCodegen.kt | 2 -- .../kotlin/backend/jvm/codegen/FunctionCodegen.kt | 15 ++++++++------- .../backend/jvm/lower/AddContinuationLowering.kt | 7 ++++--- .../codegen/boxInline/smap/crossroutines.kt | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/CoroutineCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/CoroutineCodegen.kt index b021d678812..8fd0b3c057e 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/CoroutineCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/CoroutineCodegen.kt @@ -184,5 +184,3 @@ internal fun generateFakeContinuationConstructorCall( pop() } } - -internal fun IrFunction.continuationClass(): IrClass = (body as IrBlockBody).statements.firstIsInstance() \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt index 1f9f0ff9ec3..bbae942531d 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt @@ -45,9 +45,7 @@ open class FunctionCodegen( val context = classCodegen.context val state = classCodegen.state - var continuationClassHasBeenGenerated = false - val continuationClassCodegen by lazy { - continuationClassHasBeenGenerated = true + val continuationClassCodegen = lazy { classCodegen.createLocalClassCodegen(irFunction.continuationClass(), irFunction).also { it.generate() } } @@ -104,13 +102,13 @@ open class FunctionCodegen( } ) { // force generation of fake continuation for inliner. - continuationClassCodegen + continuationClassCodegen.value } generateStateMachineForNamedFunction( irFunction, classCodegen, methodVisitor, access = flags, signature = signature, - obtainContinuationClassBuilder = { continuationClassCodegen.visitor }, + obtainContinuationClassBuilder = { continuationClassCodegen.value.visitor }, element = psiElement() ) } @@ -123,8 +121,8 @@ open class FunctionCodegen( methodVisitor.visitMaxs(-1, -1) } methodVisitor.visitEnd() - if (continuationClassHasBeenGenerated) { - continuationClassCodegen.done() + if (continuationClassCodegen.isInitialized()) { + continuationClassCodegen.value.done() } return signature @@ -155,6 +153,9 @@ open class FunctionCodegen( origin != JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE && origin != JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE_CAPTURES_CROSSINLINE + private fun IrFunction.continuationClass(): IrClass = + (body as IrBlockBody).statements.first { it is IrClass && it.origin == JvmLoweredDeclarationOrigin.CONTINUATION_CLASS } as IrClass + private fun IrFunction.getVisibilityForDefaultArgumentStub(): Int = when (visibility) { Visibilities.PUBLIC -> Opcodes.ACC_PUBLIC 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 3295be2dd46..8f8efb5bbfa 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 @@ -186,7 +186,7 @@ private class AddContinuationLowering(private val context: JvmBackendContext) : val parametersWithArguments = parametersFields.withIndex() .filter { info.reference.getValueArgument(it.index) != null } val fieldsForArguments = parametersWithArguments.map(IndexedValue::value) - val constructor = addPrimaryConstructorForLambda(info.arity, info.reference, fieldsForArguments) + val constructor = addPrimaryConstructorForLambda(info.arity, info.reference, fieldsForArguments, insideInlineFunction) val invokeToOverride = functionNClass.functions.single { it.owner.valueParameters.size == info.arity + 1 && it.owner.name.asString() == "invoke" } @@ -405,12 +405,13 @@ private class AddContinuationLowering(private val context: JvmBackendContext) : private fun IrClass.addPrimaryConstructorForLambda( arity: Int, reference: IrFunctionReference, - fields: List + fields: List, + insideInlineFunction: Boolean ): IrConstructor = addConstructor { isPrimary = true returnType = defaultType - visibility = JavaVisibilities.PACKAGE_VISIBILITY + visibility = if (insideInlineFunction) Visibilities.PUBLIC else JavaVisibilities.PACKAGE_VISIBILITY }.also { constructor -> for ((param, arg) in reference.getArguments()) { constructor.addValueParameter(name = param.name.asString(), type = arg.type) diff --git a/compiler/testData/codegen/boxInline/smap/crossroutines.kt b/compiler/testData/codegen/boxInline/smap/crossroutines.kt index 46e8ea6234b..cade4c8d63f 100644 --- a/compiler/testData/codegen/boxInline/smap/crossroutines.kt +++ b/compiler/testData/codegen/boxInline/smap/crossroutines.kt @@ -1,4 +1,4 @@ -// IGNORE_BACKEND_MULTI_MODULE: JVM_IR +// This test depends on line numbers // WITH_RUNTIME // FILE: 1.kt