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()
}
}
internal fun IrFunction.continuationClass(): IrClass = (body as IrBlockBody).statements.firstIsInstance<IrClass>()
@@ -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
@@ -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<IrField>::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<IrField>
fields: List<IrField>,
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)
+1 -1
View File
@@ -1,4 +1,4 @@
// IGNORE_BACKEND_MULTI_MODULE: JVM_IR
// This test depends on line numbers
// WITH_RUNTIME
// FILE: 1.kt