diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCallGenerator.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCallGenerator.kt new file mode 100644 index 00000000000..695509a416b --- /dev/null +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCallGenerator.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.backend.jvm.codegen + +import org.jetbrains.kotlin.backend.jvm.lower.suspendFunctionOriginal +import org.jetbrains.kotlin.codegen.AsmUtil +import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor +import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression +import org.jetbrains.kotlin.ir.util.render + +interface IrInlineCallGenerator : IrCallGenerator { + override fun genCall( + callableMethod: IrCallableMethod, + codegen: ExpressionCodegen, + expression: IrFunctionAccessExpression, + isInsideIfCondition: Boolean, + ) { + val element = codegen.context.psiSourceManager.findPsiElement(expression, codegen.irFunction) + ?: codegen.context.psiSourceManager.findPsiElement(codegen.irFunction) + if (!codegen.state.globalInlineContext.enterIntoInlining( + expression.symbol.owner.suspendFunctionOriginal().toIrBasedDescriptor(), element) + ) { + val message = "Call is a part of inline call cycle: ${expression.render()}" + AsmUtil.genThrow(codegen.visitor, "java/lang/UnsupportedOperationException", message) + return + } + try { + genInlineCall(callableMethod, codegen, expression, isInsideIfCondition) + } finally { + codegen.state.globalInlineContext.exitFromInlining() + } + } + + fun genInlineCall( + callableMethod: IrCallableMethod, + codegen: ExpressionCodegen, + expression: IrFunctionAccessExpression, + isInsideIfCondition: 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 d9a2a278ae6..c4384267e92 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 @@ -7,8 +7,10 @@ package org.jetbrains.kotlin.backend.jvm.codegen import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.ir.isInlineParameter -import org.jetbrains.kotlin.backend.jvm.lower.suspendFunctionOriginal -import org.jetbrains.kotlin.codegen.* +import org.jetbrains.kotlin.codegen.IrExpressionLambda +import org.jetbrains.kotlin.codegen.JvmKotlinType +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.FunctionDescriptor @@ -41,7 +43,7 @@ class IrInlineCodegen( InlineCodegen( codegen, state, function.toIrBasedDescriptor(), methodOwner, signature, typeParameterMappings, sourceCompiler, reifiedTypeInliner ), - IrCallGenerator { + IrInlineCallGenerator { override fun generateAssertFieldIfNeeded(info: RootInliningContext) { if (info.generateAssertField) { @@ -134,33 +136,20 @@ class IrInlineCodegen( invocationParamBuilder.markValueParametersStart() } - override fun genCall( + override fun genInlineCall( callableMethod: IrCallableMethod, codegen: ExpressionCodegen, expression: IrFunctionAccessExpression, isInsideIfCondition: Boolean, ) { - val element = codegen.context.psiSourceManager.findPsiElement(expression, codegen.irFunction) - ?: codegen.context.psiSourceManager.findPsiElement(codegen.irFunction) - if (!state.globalInlineContext.enterIntoInlining( - expression.symbol.owner.suspendFunctionOriginal().toIrBasedDescriptor(), element) - ) { - val message = "Call is a part of inline call cycle: ${expression.render()}" - AsmUtil.genThrow(codegen.v, "java/lang/UnsupportedOperationException", message) - return - } - try { - performInline( - expression.symbol.owner.typeParameters.map { it.symbol }, - // Always look for default lambdas to allow custom default argument handling in compiler plugins. - true, - false, - codegen.typeMapper.typeSystem, - registerLineNumberAfterwards = isInsideIfCondition, - ) - } finally { - state.globalInlineContext.exitFromInlining() - } + performInline( + expression.symbol.owner.typeParameters.map { it.symbol }, + // Always look for default lambdas to allow custom default argument handling in compiler plugins. + true, + false, + codegen.typeMapper.typeSystem, + registerLineNumberAfterwards = isInsideIfCondition, + ) } private fun rememberClosure( diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineDefaultCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineDefaultCodegen.kt index 7c91c7e116d..fce4d6ecf24 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineDefaultCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineDefaultCodegen.kt @@ -20,7 +20,7 @@ import org.jetbrains.org.objectweb.asm.Type * Such calls are inlined verbatim in the JVM backend (see InlineCodegenForDefaultBody.kt). * For compatibility we have to do the same thing in the JVM IR backend. */ -object IrInlineDefaultCodegen : IrCallGenerator { +object IrInlineDefaultCodegen : IrInlineCallGenerator { override fun genValueAndPut( irValueParameter: IrValueParameter, argumentExpression: IrExpression, @@ -34,7 +34,12 @@ object IrInlineDefaultCodegen : IrCallGenerator { assert(argumentExpression is IrGetValue || argumentExpression is IrTypeOperatorCall && argumentExpression.argument is IrGetValue) } - override fun genCall(callableMethod: IrCallableMethod, codegen: ExpressionCodegen, expression: IrFunctionAccessExpression) { + override fun genInlineCall( + callableMethod: IrCallableMethod, + codegen: ExpressionCodegen, + expression: IrFunctionAccessExpression, + isInsideIfCondition: Boolean + ) { val function = expression.symbol.owner val nodeAndSmap = codegen.classCodegen.generateMethodNode(function, codegen.delegatedPropertyOptimizer) val childSourceMapper = SourceMapCopier(codegen.smap, nodeAndSmap.classSMAP)