JVM_IR: unify generateStateMachineFor{Lambda,NamedFunction}
This commit is contained in:
+6
-31
@@ -33,7 +33,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
|
|||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||||
|
|
||||||
internal fun generateStateMachineForNamedFunction(
|
internal fun generateStateMachine(
|
||||||
irFunction: IrFunction,
|
irFunction: IrFunction,
|
||||||
classCodegen: ClassCodegen,
|
classCodegen: ClassCodegen,
|
||||||
methodVisitor: MethodVisitor,
|
methodVisitor: MethodVisitor,
|
||||||
@@ -42,12 +42,11 @@ internal fun generateStateMachineForNamedFunction(
|
|||||||
obtainContinuationClassBuilder: () -> ClassBuilder,
|
obtainContinuationClassBuilder: () -> ClassBuilder,
|
||||||
element: KtElement
|
element: KtElement
|
||||||
): MethodVisitor {
|
): MethodVisitor {
|
||||||
assert(irFunction.isSuspend)
|
|
||||||
val state = classCodegen.state
|
val state = classCodegen.state
|
||||||
val languageVersionSettings = state.languageVersionSettings
|
val languageVersionSettings = state.languageVersionSettings
|
||||||
assert(languageVersionSettings.isReleaseCoroutines()) { "Experimental coroutines are unsupported in JVM_IR backend" }
|
assert(languageVersionSettings.isReleaseCoroutines()) { "Experimental coroutines are unsupported in JVM_IR backend" }
|
||||||
return CoroutineTransformerMethodVisitor(
|
return CoroutineTransformerMethodVisitor(
|
||||||
methodVisitor, access, signature.asmMethod.name, signature.asmMethod.descriptor, null, null,
|
methodVisitor, access, signature.asmMethod.name, signature.asmMethod.descriptor, signature.genericsSignature, null,
|
||||||
obtainClassBuilderForCoroutineState = obtainContinuationClassBuilder,
|
obtainClassBuilderForCoroutineState = obtainContinuationClassBuilder,
|
||||||
reportSuspensionPointInsideMonitor = { reportSuspensionPointInsideMonitor(element, state, it) },
|
reportSuspensionPointInsideMonitor = { reportSuspensionPointInsideMonitor(element, state, it) },
|
||||||
lineNumber = CodegenUtil.getLineNumberForElement(element, false) ?: 0,
|
lineNumber = CodegenUtil.getLineNumberForElement(element, false) ?: 0,
|
||||||
@@ -55,12 +54,12 @@ internal fun generateStateMachineForNamedFunction(
|
|||||||
languageVersionSettings = languageVersionSettings,
|
languageVersionSettings = languageVersionSettings,
|
||||||
shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||||
containingClassInternalName = classCodegen.visitor.thisName,
|
containingClassInternalName = classCodegen.visitor.thisName,
|
||||||
isForNamedFunction = true,
|
isForNamedFunction = irFunction.isSuspend, // SuspendLambda.invokeSuspend is not suspend
|
||||||
needDispatchReceiver = irFunction.dispatchReceiverParameter != null
|
needDispatchReceiver = irFunction.isSuspend && (irFunction.dispatchReceiverParameter != null
|
||||||
|| irFunction.origin == JvmLoweredDeclarationOrigin.SUSPEND_IMPL_STATIC_FUNCTION,
|
|| irFunction.origin == JvmLoweredDeclarationOrigin.SUSPEND_IMPL_STATIC_FUNCTION),
|
||||||
internalNameForDispatchReceiver = classCodegen.visitor.thisName,
|
internalNameForDispatchReceiver = classCodegen.visitor.thisName,
|
||||||
putContinuationParameterToLvt = false,
|
putContinuationParameterToLvt = false,
|
||||||
disableTailCallOptimizationForFunctionReturningUnit = irFunction.suspendFunctionOriginal().let {
|
disableTailCallOptimizationForFunctionReturningUnit = irFunction.isSuspend && irFunction.suspendFunctionOriginal().let {
|
||||||
it.returnType.isUnit() && it.anyOfOverriddenFunctionsReturnsNonUnit()
|
it.returnType.isUnit() && it.anyOfOverriddenFunctionsReturnsNonUnit()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -72,30 +71,6 @@ internal fun IrFunction.anyOfOverriddenFunctionsReturnsNonUnit(): Boolean {
|
|||||||
} == true
|
} == true
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun generateStateMachineForLambda(
|
|
||||||
classCodegen: ClassCodegen,
|
|
||||||
methodVisitor: MethodVisitor,
|
|
||||||
access: Int,
|
|
||||||
signature: JvmMethodGenericSignature,
|
|
||||||
element: KtElement
|
|
||||||
): MethodVisitor {
|
|
||||||
val state = classCodegen.state
|
|
||||||
val languageVersionSettings = state.languageVersionSettings
|
|
||||||
assert(languageVersionSettings.isReleaseCoroutines()) { "Experimental coroutines are unsupported in JVM_IR backend" }
|
|
||||||
return CoroutineTransformerMethodVisitor(
|
|
||||||
methodVisitor, access, signature.asmMethod.name, signature.asmMethod.descriptor, signature.genericsSignature, null,
|
|
||||||
obtainClassBuilderForCoroutineState = { classCodegen.visitor },
|
|
||||||
reportSuspensionPointInsideMonitor = { reportSuspensionPointInsideMonitor(element, state, it) },
|
|
||||||
lineNumber = CodegenUtil.getLineNumberForElement(element, false) ?: 0,
|
|
||||||
sourceFile = classCodegen.irClass.file.name,
|
|
||||||
languageVersionSettings = languageVersionSettings,
|
|
||||||
shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
|
||||||
containingClassInternalName = classCodegen.visitor.thisName,
|
|
||||||
isForNamedFunction = false,
|
|
||||||
disableTailCallOptimizationForFunctionReturningUnit = false
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun IrFunction.continuationParameter(): IrValueParameter? = when {
|
internal fun IrFunction.continuationParameter(): IrValueParameter? = when {
|
||||||
isInvokeSuspendOfLambda() || isInvokeSuspendForInlineOfLambda() -> dispatchReceiverParameter
|
isInvokeSuspendOfLambda() || isInvokeSuspendForInlineOfLambda() -> dispatchReceiverParameter
|
||||||
else -> valueParameters.singleOrNull { it.origin == JvmLoweredDeclarationOrigin.CONTINUATION_CLASS }
|
else -> valueParameters.singleOrNull { it.origin == JvmLoweredDeclarationOrigin.CONTINUATION_CLASS }
|
||||||
|
|||||||
+15
-22
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.backend.common.lower.BOUND_VALUE_PARAMETER
|
|||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||||
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
|
|
||||||
import org.jetbrains.kotlin.codegen.mangleNameIfNeeded
|
import org.jetbrains.kotlin.codegen.mangleNameIfNeeded
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.codegen.visitAnnotableParameterCount
|
import org.jetbrains.kotlin.codegen.visitAnnotableParameterCount
|
||||||
@@ -31,9 +30,7 @@ import org.jetbrains.kotlin.resolve.jvm.annotations.SYNCHRONIZED_ANNOTATION_FQ_N
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import org.jetbrains.kotlin.utils.sure
|
|
||||||
import org.jetbrains.org.objectweb.asm.*
|
import org.jetbrains.org.objectweb.asm.*
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
|
|
||||||
@@ -93,29 +90,25 @@ open class FunctionCodegen(
|
|||||||
generateAnnotationDefaultValueIfNeeded(methodVisitor)
|
generateAnnotationDefaultValueIfNeeded(methodVisitor)
|
||||||
} else {
|
} else {
|
||||||
val frameMap = createFrameMapWithReceivers()
|
val frameMap = createFrameMapWithReceivers()
|
||||||
methodVisitor = when {
|
if (irFunction.hasContinuation() || irFunction.isInvokeSuspendOfLambda()) {
|
||||||
irFunction.hasContinuation() -> {
|
if (irFunction is IrSimpleFunction && irFunction.parentAsClass.declarations.any {
|
||||||
if (irFunction.parentAsClass.declarations.any {
|
it is IrSimpleFunction && it.attributeOwnerId == irFunction.attributeOwnerId &&
|
||||||
(it as? IrAttributeContainer)?.attributeOwnerId == (irFunction as IrAttributeContainer).attributeOwnerId &&
|
|
||||||
it.nameForIrSerialization.asString() == irFunction.nameForIrSerialization.asString() + FOR_INLINE_SUFFIX &&
|
|
||||||
it.origin == JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE_CAPTURES_CROSSINLINE
|
it.origin == JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE_CAPTURES_CROSSINLINE
|
||||||
}
|
|
||||||
) {
|
|
||||||
// force generation of fake continuation for inliner.
|
|
||||||
continuationClassCodegen.value
|
|
||||||
}
|
}
|
||||||
generateStateMachineForNamedFunction(
|
) {
|
||||||
irFunction, classCodegen, methodVisitor,
|
// Force generation of fake continuation for inliner.
|
||||||
access = flags,
|
continuationClassCodegen.value
|
||||||
signature = signature,
|
|
||||||
obtainContinuationClassBuilder = { continuationClassCodegen.value.visitor },
|
|
||||||
element = psiElement()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
irFunction.isInvokeSuspendOfLambda() -> generateStateMachineForLambda(
|
// This has to be done lazily to avoid generating the class if tail call optimization makes it redundant.
|
||||||
classCodegen, methodVisitor, flags, signature, psiElement()
|
val getContinuation = {
|
||||||
|
if (irFunction.isSuspend)
|
||||||
|
continuationClassCodegen.value.visitor
|
||||||
|
else
|
||||||
|
classCodegen.visitor
|
||||||
|
}
|
||||||
|
methodVisitor = generateStateMachine(
|
||||||
|
irFunction, classCodegen, methodVisitor, flags, signature, getContinuation, psiElement()
|
||||||
)
|
)
|
||||||
else -> methodVisitor
|
|
||||||
}
|
}
|
||||||
ExpressionCodegen(irFunction, signature, frameMap, InstructionAdapter(methodVisitor), classCodegen, inlinedInto).generate()
|
ExpressionCodegen(irFunction, signature, frameMap, InstructionAdapter(methodVisitor), classCodegen, inlinedInto).generate()
|
||||||
methodVisitor.visitMaxs(-1, -1)
|
methodVisitor.visitMaxs(-1, -1)
|
||||||
|
|||||||
Reference in New Issue
Block a user