JVM_IR: Generate PUBLIC constructor for suspend lambda

if the lambda is inside inline function.
This commit is contained in:
Ilmir Usmanov
2020-02-28 15:29:17 +01:00
parent 42420cb6fc
commit 22de20e7e5
4 changed files with 13 additions and 13 deletions
@@ -184,5 +184,3 @@ internal fun generateFakeContinuationConstructorCall(
pop() pop()
} }
} }
internal fun IrFunction.continuationClass(): IrClass = (body as IrBlockBody).statements.firstIsInstance<IrClass>()
@@ -45,9 +45,7 @@ open class FunctionCodegen(
val context = classCodegen.context val context = classCodegen.context
val state = classCodegen.state val state = classCodegen.state
var continuationClassHasBeenGenerated = false val continuationClassCodegen = lazy {
val continuationClassCodegen by lazy {
continuationClassHasBeenGenerated = true
classCodegen.createLocalClassCodegen(irFunction.continuationClass(), irFunction).also { it.generate() } classCodegen.createLocalClassCodegen(irFunction.continuationClass(), irFunction).also { it.generate() }
} }
@@ -104,13 +102,13 @@ open class FunctionCodegen(
} }
) { ) {
// force generation of fake continuation for inliner. // force generation of fake continuation for inliner.
continuationClassCodegen continuationClassCodegen.value
} }
generateStateMachineForNamedFunction( generateStateMachineForNamedFunction(
irFunction, classCodegen, methodVisitor, irFunction, classCodegen, methodVisitor,
access = flags, access = flags,
signature = signature, signature = signature,
obtainContinuationClassBuilder = { continuationClassCodegen.visitor }, obtainContinuationClassBuilder = { continuationClassCodegen.value.visitor },
element = psiElement() element = psiElement()
) )
} }
@@ -123,8 +121,8 @@ open class FunctionCodegen(
methodVisitor.visitMaxs(-1, -1) methodVisitor.visitMaxs(-1, -1)
} }
methodVisitor.visitEnd() methodVisitor.visitEnd()
if (continuationClassHasBeenGenerated) { if (continuationClassCodegen.isInitialized()) {
continuationClassCodegen.done() continuationClassCodegen.value.done()
} }
return signature return signature
@@ -155,6 +153,9 @@ open class FunctionCodegen(
origin != JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE && origin != JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE &&
origin != JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE_CAPTURES_CROSSINLINE 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 = private fun IrFunction.getVisibilityForDefaultArgumentStub(): Int =
when (visibility) { when (visibility) {
Visibilities.PUBLIC -> Opcodes.ACC_PUBLIC Visibilities.PUBLIC -> Opcodes.ACC_PUBLIC
@@ -186,7 +186,7 @@ private class AddContinuationLowering(private val context: JvmBackendContext) :
val parametersWithArguments = parametersFields.withIndex() val parametersWithArguments = parametersFields.withIndex()
.filter { info.reference.getValueArgument(it.index) != null } .filter { info.reference.getValueArgument(it.index) != null }
val fieldsForArguments = parametersWithArguments.map(IndexedValue<IrField>::value) val fieldsForArguments = parametersWithArguments.map(IndexedValue<IrField>::value)
val constructor = addPrimaryConstructorForLambda(info.arity, info.reference, fieldsForArguments) val constructor = addPrimaryConstructorForLambda(info.arity, info.reference, fieldsForArguments, insideInlineFunction)
val invokeToOverride = functionNClass.functions.single { val invokeToOverride = functionNClass.functions.single {
it.owner.valueParameters.size == info.arity + 1 && it.owner.name.asString() == "invoke" 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( private fun IrClass.addPrimaryConstructorForLambda(
arity: Int, arity: Int,
reference: IrFunctionReference, reference: IrFunctionReference,
fields: List<IrField> fields: List<IrField>,
insideInlineFunction: Boolean
): IrConstructor = ): IrConstructor =
addConstructor { addConstructor {
isPrimary = true isPrimary = true
returnType = defaultType returnType = defaultType
visibility = JavaVisibilities.PACKAGE_VISIBILITY visibility = if (insideInlineFunction) Visibilities.PUBLIC else JavaVisibilities.PACKAGE_VISIBILITY
}.also { constructor -> }.also { constructor ->
for ((param, arg) in reference.getArguments()) { for ((param, arg) in reference.getArguments()) {
constructor.addValueParameter(name = param.name.asString(), type = arg.type) constructor.addValueParameter(name = param.name.asString(), type = arg.type)
+1 -1
View File
@@ -1,4 +1,4 @@
// IGNORE_BACKEND_MULTI_MODULE: JVM_IR // This test depends on line numbers
// WITH_RUNTIME // WITH_RUNTIME
// FILE: 1.kt // FILE: 1.kt