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 21a32645c16..b81adf8b1d1 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt @@ -20,8 +20,6 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.inline.InlineUtil import org.jetbrains.kotlin.resolve.inline.isInlineOnly import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature -import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext -import org.jetbrains.kotlin.types.model.TypeParameterMarker import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Type @@ -83,31 +81,17 @@ abstract class InlineCodegen( AsmUtil.genThrow(codegen.visitor, "java/lang/UnsupportedOperationException", "Call is part of inline cycle: $text") } - protected fun endCall(result: InlineResult, registerLineNumberAfterwards: Boolean) { - leaveTemps() - - codegen.propagateChildReifiedTypeParametersUsages(result.reifiedTypeParametersUsages) - - state.factory.removeClasses(result.calcClassesToRemove()) - - codegen.markLineNumberAfterInlineIfNeeded(registerLineNumberAfterwards) - } - - fun performInline( - typeArguments: List?, - inlineDefaultLambdas: Boolean, - typeSystem: TypeSystemCommonBackendContext, - registerLineNumberAfterwards: Boolean, - ) { + fun performInline(inlineDefaultLambdas: Boolean, registerLineNumberAfterwards: Boolean) { var nodeAndSmap: SMAPAndMethodNode? = null try { - nodeAndSmap = - generateInlineIntrinsic(state, functionDescriptor, jvmSignature.asmMethod, typeArguments, typeSystem)?.let { - SMAPAndMethodNode(it, SMAP(listOf())) - } ?: sourceCompiler.compileInlineFunction(jvmSignature).apply { - node.preprocessSuspendMarkers(forInline = true, keepFakeContinuation = false) - } - endCall(inlineCall(nodeAndSmap, inlineDefaultLambdas), registerLineNumberAfterwards) + nodeAndSmap = sourceCompiler.compileInlineFunction(jvmSignature).apply { + node.preprocessSuspendMarkers(forInline = true, keepFakeContinuation = false) + } + val result = inlineCall(nodeAndSmap, inlineDefaultLambdas) + leaveTemps() + codegen.propagateChildReifiedTypeParametersUsages(result.reifiedTypeParametersUsages) + codegen.markLineNumberAfterInlineIfNeeded(registerLineNumberAfterwards) + state.factory.removeClasses(result.calcClassesToRemove()) } catch (e: CompilationException) { throw e } catch (e: InlineException) { 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 e5cbd3cb8a6..9befc9b13cd 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineCodegen.kt @@ -83,7 +83,7 @@ class PsiInlineCodegen( } } } - performInline(resolvedCall?.typeArguments?.keys?.toList(), callDefault, codegen.typeSystem, registerLineNumber) + performInline(callDefault, registerLineNumber) } finally { state.globalInlineContext.exitFromInlining() } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiSourceCompilerForInline.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiSourceCompilerForInline.kt index ac2cde8912f..3fd74e47a9b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiSourceCompilerForInline.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiSourceCompilerForInline.kt @@ -241,6 +241,10 @@ class PsiSourceCompilerForInline( } override fun compileInlineFunction(jvmSignature: JvmMethodSignature): SMAPAndMethodNode { + generateInlineIntrinsic(state.languageVersionSettings, functionDescriptor, jvmSignature.asmMethod, codegen.typeSystem)?.let { + return it + } + val asmMethod = if (callDefault) mapDefault() else jvmSignature.asmMethod val directMember = getDirectMemberAndCallableFromObject() diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineIntrinsics.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineIntrinsics.kt index b059be8079a..27b15c968db 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineIntrinsics.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineIntrinsics.kt @@ -16,7 +16,7 @@ import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForSuspendCorouti import org.jetbrains.kotlin.codegen.createMethodNodeForAlwaysEnabledAssert import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicArrayConstructors import org.jetbrains.kotlin.codegen.isBuiltinAlwaysEnabledAssert -import org.jetbrains.kotlin.codegen.state.GenerationState +import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.resolve.calls.checkers.TypeOfChecker @@ -30,26 +30,29 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.Method import org.jetbrains.org.objectweb.asm.tree.MethodNode -internal fun generateInlineIntrinsic( - state: GenerationState, - descriptor: FunctionDescriptor, - asmMethod: Method, - typeParameters: List?, - typeSystem: TypeSystemCommonBackendContext -): MethodNode? { - val languageVersionSettings = state.languageVersionSettings - - return when { - isSpecialEnumMethod(descriptor) -> - createSpecialEnumMethodBody(descriptor.name.asString(), typeParameters!!.single(), typeSystem) - TypeOfChecker.isTypeOf(descriptor) -> - typeSystem.createTypeOfMethodBody(typeParameters!!.single()) +fun generateInlineIntrinsicForIr(languageVersionSettings: LanguageVersionSettings, descriptor: FunctionDescriptor): SMAPAndMethodNode? = + when { + // TODO: implement these as codegen intrinsics (see IrIntrinsicMethods) descriptor.isBuiltInIntercepted(languageVersionSettings) -> createMethodNodeForIntercepted(languageVersionSettings) descriptor.isBuiltInCoroutineContext(languageVersionSettings) -> createMethodNodeForCoroutineContext(descriptor, languageVersionSettings) descriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn(languageVersionSettings) -> createMethodNodeForSuspendCoroutineUninterceptedOrReturn(languageVersionSettings) + else -> null + }?.let { SMAPAndMethodNode(it, SMAP(listOf())) } + +internal fun generateInlineIntrinsic( + languageVersionSettings: LanguageVersionSettings, + descriptor: FunctionDescriptor, + asmMethod: Method, + typeSystem: TypeSystemCommonBackendContext +): SMAPAndMethodNode? { + return generateInlineIntrinsicForIr(languageVersionSettings, descriptor) ?: when { + isSpecialEnumMethod(descriptor) -> + createSpecialEnumMethodBody(descriptor.name.asString(), descriptor.original.typeParameters.single(), typeSystem) + TypeOfChecker.isTypeOf(descriptor) -> + typeSystem.createTypeOfMethodBody(descriptor.original.typeParameters.single()) descriptor.isBuiltinAlwaysEnabledAssert() -> createMethodNodeForAlwaysEnabledAssert(descriptor) descriptor is FictitiousArrayConstructor -> @@ -59,7 +62,7 @@ internal fun generateInlineIntrinsic( IntrinsicArrayConstructors.isEmptyArray(descriptor) -> IntrinsicArrayConstructors.generateEmptyArrayBody(asmMethod) else -> null - } + }?.let { SMAPAndMethodNode(it, SMAP(listOf())) } } private fun isSpecialEnumMethod(descriptor: FunctionDescriptor): Boolean { 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 f491ec0ec3d..caad268137f 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 @@ -126,13 +126,8 @@ class IrInlineCodegen( expression: IrFunctionAccessExpression, isInsideIfCondition: Boolean, ) { - performInline( - expression.symbol.owner.typeParameters.map { it.symbol }, - // Always look for default lambdas to allow custom default argument handling in compiler plugins. - inlineDefaultLambdas = true, - codegen.typeMapper.typeSystem, - registerLineNumberAfterwards = isInsideIfCondition, - ) + // Always look for default lambdas to allow custom default argument handling in compiler plugins. + performInline(inlineDefaultLambdas = true, registerLineNumberAfterwards = isInsideIfCondition) } override fun genCycleStub(text: String, codegen: ExpressionCodegen) { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt index ced3015c0e4..331c1e935aa 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt @@ -104,10 +104,15 @@ class IrSourceCompilerForInline( return FunctionCodegen(lambdaInfo.function, codegen.classCodegen).generate(codegen, reifiedTypeParameters) } - override fun compileInlineFunction(jvmSignature: JvmMethodSignature): SMAPAndMethodNode = - callee.parentClassId?.let { containerId -> - loadCompiledInlineFunction(containerId, jvmSignature.asmMethod, callee.isSuspend, callee.hasMangledReturnType, state) - } ?: ClassCodegen.getOrCreate(callee.parentAsClass, codegen.context).generateMethodNode(callee) + override fun compileInlineFunction(jvmSignature: JvmMethodSignature): SMAPAndMethodNode { + generateInlineIntrinsicForIr(state.languageVersionSettings, callee.toIrBasedDescriptor())?.let { + return it + } + callee.parentClassId?.let { + return loadCompiledInlineFunction(it, jvmSignature.asmMethod, callee.isSuspend, callee.hasMangledReturnType, state) + } + return ClassCodegen.getOrCreate(callee.parentAsClass, codegen.context).generateMethodNode(callee) + } override fun hasFinallyBlocks() = data.hasFinallyBlocks()