JVM_IR: Generate PUBLIC constructor for suspend lambda
if the lambda is inside inline function.
This commit is contained in:
-2
@@ -184,5 +184,3 @@ internal fun generateFakeContinuationConstructorCall(
|
|||||||
pop()
|
pop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun IrFunction.continuationClass(): IrClass = (body as IrBlockBody).statements.firstIsInstance<IrClass>()
|
|
||||||
+8
-7
@@ -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
|
||||||
|
|||||||
+4
-3
@@ -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,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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user