diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index f2d7eb78df6..5dfc5230e0f 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -74,6 +74,7 @@ import org.jetbrains.kotlin.resolve.jvm.*; import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature; +import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature; import org.jetbrains.kotlin.resolve.scopes.receivers.*; import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor; import org.jetbrains.kotlin.types.KotlinType; @@ -2641,11 +2642,20 @@ public class ExpressionCodegen extends KtVisitor impleme unwrapInitialSignatureDescriptor(DescriptorUtils.unwrapFakeOverride((FunctionDescriptor) descriptor.getOriginal())), bindingContext, state ); + + PsiSourceCompilerForInline sourceCompiler = new PsiSourceCompilerForInline(this, callElement); + FunctionDescriptor functionDescriptor = + InlineUtil.isArrayConstructorWithLambda(original) + ? FictitiousArrayConstructor.create((ConstructorDescriptor) original) : original.getOriginal(); + + sourceCompiler.initializeInlineFunctionContext(functionDescriptor); + JvmMethodSignature signature = typeMapper.mapSignatureWithGeneric(functionDescriptor, sourceCompiler.getContextKind()); + Type methodOwner = typeMapper.mapImplementationOwner(functionDescriptor); if (isDefaultCompilation) { - return new InlineCodegenForDefaultBody(original, this, state, new PsiSourceCompilerForInline(this, callElement)); + return new InlineCodegenForDefaultBody(functionDescriptor, this, state, methodOwner, signature, sourceCompiler); } else { - return new PsiInlineCodegen(this, state, original, typeParameterMappings, new PsiSourceCompilerForInline(this, callElement)); + return new PsiInlineCodegen(this, state, functionDescriptor, methodOwner, signature, typeParameterMappings, sourceCompiler); } } 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 c708051c998..ae54af65149 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt @@ -25,7 +25,6 @@ import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.inline.InlineUtil import org.jetbrains.kotlin.resolve.inline.isInlineOnly -import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource @@ -45,13 +44,15 @@ import kotlin.math.max abstract class InlineCodegen( protected val codegen: T, protected val state: GenerationState, - function: FunctionDescriptor, + protected val functionDescriptor: FunctionDescriptor, + private val methodOwner: Type, + protected val jvmSignature: JvmMethodSignature, private val typeParameterMappings: TypeParameterMappings, protected val sourceCompiler: SourceCompilerForInline ) { init { - assert(InlineUtil.isInline(function) || InlineUtil.isArrayConstructorWithLambda(function)) { - "InlineCodegen can inline only inline functions and array constructors: " + function + assert(InlineUtil.isInline(functionDescriptor)) { + "InlineCodegen can inline only inline functions: $functionDescriptor" } } @@ -65,14 +66,6 @@ abstract class InlineCodegen( private val reifiedTypeInliner = ReifiedTypeInliner(typeParameterMappings, state.typeMapper, state.languageVersionSettings) - protected val functionDescriptor: FunctionDescriptor = - if (InlineUtil.isArrayConstructorWithLambda(function)) - FictitiousArrayConstructor.create(function as ConstructorDescriptor) - else - function.original - - protected val jvmSignature: JvmMethodGenericSignature - private val isSameModule: Boolean protected val invocationParamBuilder = ParametersBuilder.newBuilder() @@ -91,12 +84,10 @@ abstract class InlineCodegen( protected var methodHandleInDefaultMethodIndex = -1 init { - sourceCompiler.initializeInlineFunctionContext(functionDescriptor) - jvmSignature = typeMapper.mapSignatureWithGeneric(functionDescriptor, sourceCompiler.contextKind) isSameModule = sourceCompiler.isCallInsideSameModuleAsDeclared(functionDescriptor) if (functionDescriptor !is FictitiousArrayConstructor) { - val functionOrAccessorName = typeMapper.mapAsmMethod(function).name + val functionOrAccessorName = jvmSignature.asmMethod.name //track changes for property accessor and @JvmName inline functions/property accessors if (functionOrAccessorName != functionDescriptor.name.asString()) { val scope = getMemberScope(functionDescriptor) @@ -146,7 +137,7 @@ abstract class InlineCodegen( ) { var nodeAndSmap: SMAPAndMethodNode? = null try { - nodeAndSmap = createInlineMethodNode(functionDescriptor, jvmSignature, callDefault, typeArguments, state, sourceCompiler) + nodeAndSmap = createInlineMethodNode(functionDescriptor, methodOwner, jvmSignature, callDefault, typeArguments, state, sourceCompiler) endCall(inlineCall(nodeAndSmap, callDefault)) } catch (e: CompilationException) { throw e @@ -524,6 +515,7 @@ abstract class InlineCodegen( internal fun createInlineMethodNode( functionDescriptor: FunctionDescriptor, + methodOwner: Type, jvmSignature: JvmMethodSignature, callDefault: Boolean, typeArguments: Map?, @@ -540,8 +532,7 @@ abstract class InlineCodegen( else mangleSuspendInlineFunctionAsmMethodIfNeeded(functionDescriptor, jvmSignature.asmMethod) - val owner = state.typeMapper.mapImplementationOwner(functionDescriptor) - val methodId = MethodId(owner.internalName, asmMethod) + val methodId = MethodId(methodOwner.internalName, asmMethod) val directMember = getDirectMemberAndCallableFromObject(functionDescriptor) if (!isBuiltInArrayIntrinsic(functionDescriptor) && directMember !is DescriptorWithContainerSource) { return sourceCompilerForInline.doCreateMethodNodeFromSource(functionDescriptor, jvmSignature, callDefault, asmMethod) 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 80c1a15a64e..a204144aaec 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenForDefaultBody.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenForDefaultBody.kt @@ -7,48 +7,32 @@ package org.jetbrains.kotlin.codegen.inline import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.state.GenerationState -import org.jetbrains.kotlin.descriptors.ConstructorDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.inline.InlineUtil -import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature +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.MethodNode class InlineCodegenForDefaultBody( - function: FunctionDescriptor, + private val function: FunctionDescriptor, codegen: ExpressionCodegen, val state: GenerationState, + private val methodOwner: Type, + private val jvmSignature: JvmMethodSignature, private val sourceCompilerForInline: SourceCompilerForInline ) : CallGenerator { - private val sourceMapper: SourceMapper = codegen.parentCodegen.orCreateSourceMapper - private val functionDescriptor = - if (InlineUtil.isArrayConstructorWithLambda(function)) - FictitiousArrayConstructor.create(function as ConstructorDescriptor) - else - function.original - - - init { - sourceCompilerForInline.initializeInlineFunctionContext(functionDescriptor) - } - - - private val jvmSignature: JvmMethodGenericSignature - private val methodStartLabel = Label() init { assert(InlineUtil.isInline(function)) { - "InlineCodegen can inline only inline functions and array constructors: $function" + "InlineCodegenForDefaultBody can inline only inline functions: $function" } - sourceCompilerForInline.initializeInlineFunctionContext(functionDescriptor) - jvmSignature = state.typeMapper.mapSignatureWithGeneric(functionDescriptor, sourceCompilerForInline.contextKind) //InlineCodegenForDefaultBody created just after visitCode call codegen.v.visitLabel(methodStartLabel) @@ -56,7 +40,7 @@ class InlineCodegenForDefaultBody( override fun genCallInner(callableMethod: Callable, resolvedCall: ResolvedCall<*>?, callDefault: Boolean, codegen: ExpressionCodegen) { val nodeAndSmap = - InlineCodegen.createInlineMethodNode(functionDescriptor, jvmSignature, callDefault, null, state, sourceCompilerForInline) + InlineCodegen.createInlineMethodNode(function, methodOwner, jvmSignature, callDefault, null, state, sourceCompilerForInline) val childSourceMapper = InlineCodegen.createNestedSourceMapper(nodeAndSmap, sourceMapper) val node = nodeAndSmap.node 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 0ba094dcb06..4540cd22931 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineCodegen.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.resolve.inline.InlineUtil import org.jetbrains.kotlin.resolve.inline.InlineUtil.isInlinableParameterExpression import org.jetbrains.kotlin.resolve.jvm.AsmTypes 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.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Type @@ -29,9 +30,13 @@ class PsiInlineCodegen( codegen: ExpressionCodegen, state: GenerationState, function: FunctionDescriptor, + methodOwner: Type, + signature: JvmMethodSignature, typeParameterMappings: TypeParameterMappings, sourceCompiler: SourceCompilerForInline -) : InlineCodegen(codegen, state, function, typeParameterMappings, sourceCompiler), CallGenerator { +) : InlineCodegen( + codegen, state, function, methodOwner, signature, typeParameterMappings, sourceCompiler +), CallGenerator { override fun generateAssertFieldIfNeeded(info: RootInliningContext) { if (info.generateAssertField) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt index 73ff8e4680f..2e22b940c52 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt @@ -75,8 +75,6 @@ interface SourceCompilerForInline { val compilationContextFunctionDescriptor: FunctionDescriptor fun getContextLabels(): Set - - fun initializeInlineFunctionContext(functionDescriptor: FunctionDescriptor) } @@ -357,7 +355,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid return InlineCodegen.getDeclarationLabels(DescriptorToSourceUtils.descriptorToDeclaration(descriptor), descriptor) } - override fun initializeInlineFunctionContext(functionDescriptor: FunctionDescriptor) { + fun initializeInlineFunctionContext(functionDescriptor: FunctionDescriptor) { context = getContext( functionDescriptor, functionDescriptor, diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index 42128cf96e0..f2cbe65e9ff 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -12,8 +12,11 @@ import org.jetbrains.kotlin.backend.jvm.intrinsics.JavaClassProperty import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry import org.jetbrains.kotlin.backend.jvm.lower.constantValue import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.unboxInlineClass -import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.AsmUtil.* +import org.jetbrains.kotlin.codegen.BaseExpressionCodegen +import org.jetbrains.kotlin.codegen.CallGenerator +import org.jetbrains.kotlin.codegen.OwnerKind +import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.coroutines.INVOKE_SUSPEND_METHOD_NAME import org.jetbrains.kotlin.codegen.inline.* import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner.Companion.putNeedClassReificationMarker @@ -40,6 +43,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind +import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.keysToMap @@ -323,7 +327,7 @@ class ExpressionCodegen( val callable = methodSignatureMapper.mapToCallableMethod(expression) val callee = expression.symbol.owner - val callGenerator = getOrCreateCallGenerator(expression, data) + val callGenerator = getOrCreateCallGenerator(expression, data, callable.signature) val asmType = if (expression is IrConstructorCall) typeMapper.mapTypeAsDeclaration(expression.type) else expression.asmType when { @@ -957,7 +961,9 @@ class ExpressionCodegen( return classReference.onStack } - private fun getOrCreateCallGenerator(element: IrFunctionAccessExpression, data: BlockInfo): IrCallGenerator { + private fun getOrCreateCallGenerator( + element: IrFunctionAccessExpression, data: BlockInfo, signature: JvmMethodSignature + ): IrCallGenerator { if (!element.symbol.owner.isInlineFunctionCall(context) || classCodegen.irClass.fileParent.fileEntry is MultifileFacadeFileEntry ) { @@ -993,7 +999,9 @@ class ExpressionCodegen( } val original = (callee as? IrSimpleFunction)?.resolveFakeOverride() ?: irFunction - return IrInlineCodegen(this, state, original.descriptor, mappings, IrSourceCompilerForInline(state, element, this, data)) + val methodOwner = callee.parent.safeAs()?.let(typeMapper::mapClass) ?: MethodSignatureMapper.FAKE_OWNER_TYPE + val sourceCompiler = IrSourceCompilerForInline(state, element, this, data) + return IrInlineCodegen(this, state, original.descriptor, methodOwner, signature, mappings, sourceCompiler) } private fun consumeReifiedOperationMarker(typeParameter: IrTypeParameter) { 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 30e083a5da1..5a0f05980fd 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 @@ -5,10 +5,13 @@ package org.jetbrains.kotlin.backend.jvm.codegen -import org.jetbrains.kotlin.backend.jvm.ir.isInlineParameter import org.jetbrains.kotlin.backend.jvm.JvmBackendContext -import org.jetbrains.kotlin.codegen.* +import org.jetbrains.kotlin.backend.jvm.ir.isInlineParameter import org.jetbrains.kotlin.codegen.AsmUtil.BOUND_REFERENCE_RECEIVER +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 @@ -19,6 +22,7 @@ import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.dump import org.jetbrains.kotlin.ir.util.getArguments +import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.utils.keysToMap import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.commons.Method @@ -27,10 +31,13 @@ class IrInlineCodegen( codegen: ExpressionCodegen, state: GenerationState, function: FunctionDescriptor, + methodOwner: Type, + signature: JvmMethodSignature, typeParameterMappings: IrTypeParameterMappings, sourceCompiler: SourceCompilerForInline -) : InlineCodegen(codegen, state, function, typeParameterMappings.toTypeParameterMappings(), sourceCompiler), - IrCallGenerator { +) : InlineCodegen( + codegen, state, function, methodOwner, signature, typeParameterMappings.toTypeParameterMappings(), sourceCompiler +), IrCallGenerator { override fun generateAssertFieldIfNeeded(info: RootInliningContext) { // TODO: JVM assertions are not implemented yet in IR backend } 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 ce9c4d8743b..3263e68b7f1 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 @@ -156,10 +156,6 @@ class IrSourceCompilerForInline( return setOf(codegen.irFunction.name.asString()) } - override fun initializeInlineFunctionContext(functionDescriptor: FunctionDescriptor) { - //TODO - } - private class FakeClassCodegen(irFunction: IrFunction, codegen: ClassCodegen) : ClassCodegen(irFunction.parent as IrClass, codegen.context) { @@ -241,4 +237,4 @@ class IrSourceCompilerForInline( } } } -} \ No newline at end of file +} diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt index 6f1f8c8f721..5c66fb7475d 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt @@ -61,8 +61,7 @@ class MethodSignatureMapper(context: JvmBackendContext) { // we still need to return some IrCallableMethod with some owner instance, but that owner will be ignored at the call site. // Here we return a fake type, but this needs to be refactored so that we never call mapToCallableMethod on intrinsics. // TODO: get rid of fake owner here - val fakeOwner = Type.getObjectType("kotlin/internal/ir/Intrinsic") - return IrCallableMethod(fakeOwner, Opcodes.INVOKESTATIC, mapSignatureSkipGeneric(callee), false) + return IrCallableMethod(FAKE_OWNER_TYPE, Opcodes.INVOKESTATIC, mapSignatureSkipGeneric(callee), false) } val owner = typeMapper.mapClass(calleeParent) @@ -119,4 +118,8 @@ class MethodSignatureMapper(context: JvmBackendContext) { } return current } + + companion object { + val FAKE_OWNER_TYPE = Type.getObjectType("kotlin/internal/ir/Intrinsic") + } }