diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt index 385a868fb98..7365e345fa9 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt @@ -136,9 +136,7 @@ abstract class InlineCodegen( ) { var nodeAndSmap: SMAPAndMethodNode? = null try { - nodeAndSmap = createInlineMethodNode( - functionDescriptor, methodOwner, jvmSignature, mapDefaultSignature, typeArguments, typeSystem, state, sourceCompiler - ) + nodeAndSmap = createInlineMethodNode(mapDefaultSignature, typeArguments, typeSystem) endCall(inlineCall(nodeAndSmap, inlineDefaultLambdas), registerLineNumberAfterwards) } catch (e: CompilationException) { throw e @@ -274,6 +272,8 @@ abstract class InlineCodegen( abstract fun extractDefaultLambdas(node: MethodNode): List + abstract fun isLoadedFromBytecode(memberDescriptor: CallableMemberDescriptor): Boolean + fun generateAndInsertFinallyBlocks( intoNode: MethodNode, insertPoints: List, @@ -512,38 +512,33 @@ abstract class InlineCodegen( } - companion object { - - internal fun createInlineMethodNode( - functionDescriptor: FunctionDescriptor, - methodOwner: Type, - jvmSignature: JvmMethodSignature, - callDefault: Boolean, - typeArguments: List?, - typeSystem: TypeSystemCommonBackendContext, - state: GenerationState, - sourceCompilerForInline: SourceCompilerForInline - ): SMAPAndMethodNode { - val intrinsic = generateInlineIntrinsic(state, functionDescriptor, typeArguments, typeSystem) - if (intrinsic != null) { - return SMAPAndMethodNode(intrinsic, createDefaultFakeSMAP()) - } - - val asmMethod = if (callDefault) - state.typeMapper.mapDefaultMethod(functionDescriptor, sourceCompilerForInline.contextKind) - else - mangleSuspendInlineFunctionAsmMethodIfNeeded(functionDescriptor, jvmSignature.asmMethod) - - val directMember = getDirectMemberAndCallableFromObject(functionDescriptor) - if (!isBuiltInArrayIntrinsic(functionDescriptor) && directMember !is DescriptorWithContainerSource) { - val node = sourceCompilerForInline.doCreateMethodNodeFromSource(functionDescriptor, jvmSignature, callDefault, asmMethod) - node.node.preprocessSuspendMarkers(forInline = true, keepFakeContinuation = false) - return node - } - - return getCompiledMethodNodeInner(functionDescriptor, directMember, asmMethod, methodOwner, state, jvmSignature) + internal fun createInlineMethodNode( + callDefault: Boolean, + typeArguments: List?, + typeSystem: TypeSystemCommonBackendContext + ): SMAPAndMethodNode { + val intrinsic = generateInlineIntrinsic(state, functionDescriptor, typeArguments, typeSystem) + if (intrinsic != null) { + return SMAPAndMethodNode(intrinsic, createDefaultFakeSMAP()) } + val asmMethod = if (callDefault) + state.typeMapper.mapDefaultMethod(functionDescriptor, sourceCompiler.contextKind) + else + mangleSuspendInlineFunctionAsmMethodIfNeeded(functionDescriptor, jvmSignature.asmMethod) + + val directMember = getDirectMemberAndCallableFromObject(functionDescriptor) + if (!isBuiltInArrayIntrinsic(functionDescriptor) && !isLoadedFromBytecode(directMember)) { + val node = sourceCompiler.doCreateMethodNodeFromSource(functionDescriptor, jvmSignature, callDefault, asmMethod) + node.node.preprocessSuspendMarkers(forInline = true, keepFakeContinuation = false) + return node + } + + return getCompiledMethodNodeInner(functionDescriptor, directMember, asmMethod, methodOwner, state, jvmSignature) + } + + companion object { + internal fun createSpecialInlineMethodNodeFromBinaries(functionDescriptor: FunctionDescriptor, state: GenerationState): MethodNode { val directMember = getDirectMemberAndCallableFromObject(functionDescriptor) assert(directMember is DescriptorWithContainerSource) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenForDefaultBody.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenForDefaultBody.kt index 777ce5dec7f..d0b343c16e0 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenForDefaultBody.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenForDefaultBody.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.codegen.inline import org.jetbrains.kotlin.codegen.* -import org.jetbrains.kotlin.codegen.linkWithLabel import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor @@ -16,7 +15,6 @@ import org.jetbrains.kotlin.resolve.inline.InlineUtil import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Type -import org.jetbrains.org.objectweb.asm.tree.LabelNode import org.jetbrains.org.objectweb.asm.tree.MethodNode class InlineCodegenForDefaultBody( @@ -41,8 +39,10 @@ class InlineCodegenForDefaultBody( } override fun genCallInner(callableMethod: Callable, resolvedCall: ResolvedCall<*>?, callDefault: Boolean, codegen: ExpressionCodegen) { - val nodeAndSmap = InlineCodegen.createInlineMethodNode( - function, methodOwner, jvmSignature, callDefault, null, codegen.typeSystem, state, sourceCompilerForInline + val nodeAndSmap = PsiInlineCodegen( + codegen, state, function, methodOwner, jvmSignature, TypeParameterMappings(), sourceCompilerForInline + ).createInlineMethodNode( + callDefault, null, codegen.typeSystem ) val childSourceMapper = SourceMapCopier(sourceMapper, nodeAndSmap.classSMAP) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineCodegen.kt index 85781dd6a10..d50fd29e24b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineCodegen.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.DescriptorAsmUtil.getMethodAsmFlags import org.jetbrains.kotlin.codegen.binding.CodegenBinding import org.jetbrains.kotlin.codegen.state.GenerationState +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.psi.KtCallableReferenceExpression @@ -25,6 +26,7 @@ import org.jetbrains.kotlin.resolve.inline.InlineUtil.isInlinableParameterExpres import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Type @@ -208,4 +210,7 @@ class PsiInlineCodegen( ::PsiDefaultLambda ) } + + override fun isLoadedFromBytecode(memberDescriptor: CallableMemberDescriptor): Boolean = + memberDescriptor is DescriptorWithContainerSource } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt index 8ec2f91e44e..405ae417c54 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt @@ -13,9 +13,12 @@ import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.ValueKind import org.jetbrains.kotlin.codegen.inline.* import org.jetbrains.kotlin.codegen.state.GenerationState +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.descriptors.IrBasedPropertyDescriptor +import org.jetbrains.kotlin.ir.descriptors.IrBasedSimpleFunctionDescriptor import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType import org.jetbrains.kotlin.ir.expressions.* @@ -161,6 +164,13 @@ class IrInlineCodegen( ::IrDefaultLambda ) } + + override fun isLoadedFromBytecode(memberDescriptor: CallableMemberDescriptor): Boolean = + when (memberDescriptor) { + is IrBasedSimpleFunctionDescriptor -> memberDescriptor.owner.classId != null + is IrBasedPropertyDescriptor -> memberDescriptor.owner.classId != null + else -> false + } } class IrExpressionLambdaImpl( diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt index 31eca3332a6..5cbc6252281 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt @@ -394,7 +394,7 @@ fun IrSimpleType.isRawType(): Boolean = hasAnnotation(JvmGeneratorExtensions.RAW_TYPE_ANNOTATION_FQ_NAME) internal fun classFileContainsMethod(function: IrFunction, context: JvmBackendContext, name: String): Boolean? { - val classId = (function.containerSource as? JvmPackagePartSource)?.classId ?: (function.parent as? IrClass)?.classId ?: return null + val classId = function.classId ?: return null val originalDescriptor = context.methodSignatureMapper.mapSignatureWithGeneric(function).asmMethod.descriptor val descriptor = if (function.isSuspend) listOf(*Type.getArgumentTypes(originalDescriptor), Type.getObjectType("kotlin/coroutines/Continuation")) @@ -403,6 +403,12 @@ internal fun classFileContainsMethod(function: IrFunction, context: JvmBackendCo return classFileContainsMethod(classId, context.state, Method(name, descriptor)) } +val IrFunction.classId: ClassId? + get() = (containerSource as? JvmPackagePartSource)?.classId ?: (parent as? IrClass)?.classId + +val IrProperty.classId: ClassId? + get() = (containerSource as? JvmPackagePartSource)?.classId ?: (parent as? IrClass)?.classId + // Translated into IR-based terms from classifierDescriptor?.classId val IrClass.classId: ClassId? get() = when (val parent = parent) {