From 598c6009f240c87abcf79252cd19c4c4ad6eddd9 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 6 Aug 2019 05:09:41 +0200 Subject: [PATCH] JVM IR: extract method signature mapping to MethodSignatureMapper --- .../kotlin/backend/jvm/JvmBackendContext.kt | 2 + .../jetbrains/kotlin/backend/jvm/JvmLower.kt | 2 +- .../backend/jvm/codegen/ClassCodegen.kt | 5 +- .../backend/jvm/codegen/ExpressionCodegen.kt | 15 +++--- .../backend/jvm/codegen/FunctionCodegen.kt | 2 +- .../backend/jvm/codegen/IrInlineCodegen.kt | 7 +-- .../jvm/codegen/IrSourceCompilerForInline.kt | 3 +- .../backend/jvm/codegen/IrTypeMapper.kt | 36 ++----------- .../jvm/codegen/MethodSignatureMapper.kt | 50 +++++++++++++++++++ .../backend/jvm/intrinsics/IntrinsicMethod.kt | 2 +- 10 files changed, 74 insertions(+), 50 deletions(-) create mode 100644 compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt index d2a5e868420..ac836f97d7a 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.ir.Ir import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig import org.jetbrains.kotlin.backend.jvm.codegen.IrTypeMapper +import org.jetbrains.kotlin.backend.jvm.codegen.MethodSignatureMapper import org.jetbrains.kotlin.backend.jvm.descriptors.JvmDeclarationFactory import org.jetbrains.kotlin.backend.jvm.descriptors.JvmSharedVariablesManager import org.jetbrains.kotlin.backend.jvm.intrinsics.IrIntrinsicMethods @@ -44,6 +45,7 @@ class JvmBackendContext( override val sharedVariablesManager = JvmSharedVariablesManager(state.module, builtIns, irBuiltIns) val typeMapper = IrTypeMapper(this) + val methodSignatureMapper = MethodSignatureMapper(this) private val symbolTable = symbolTable.lazyWrapper override val ir = JvmIr(irModuleFragment, this.symbolTable) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt index 0ec915c7f58..f10b9168080 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt @@ -75,7 +75,7 @@ private val propertiesPhase = makeIrFilePhase( val baseName = if (context.state.languageVersionSettings.supportsFeature(LanguageFeature.UseGetterNameForPropertyAnnotationsMethodOnJvm)) { property.getter?.let { getter -> - context.typeMapper.mapFunctionName(getter, OwnerKind.IMPLEMENTATION) + context.methodSignatureMapper.mapFunctionName(getter, OwnerKind.IMPLEMENTATION) } ?: JvmAbi.getterName(property.name.asString()) } else { property.name.asString() diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt index edcfb1dfed4..a568e5375f6 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt @@ -49,6 +49,7 @@ open class ClassCodegen protected constructor( val state = context.state val typeMapper = context.typeMapper + val methodSignatureMapper = context.methodSignatureMapper val descriptor = irClass.descriptor @@ -246,7 +247,7 @@ open class ClassCodegen protected constructor( val fieldType = typeMapper.mapType(field) val fieldSignature = if (field.origin == IrDeclarationOrigin.DELEGATE) null - else typeMapper.mapFieldSignature(field) + else methodSignatureMapper.mapFieldSignature(field) val fieldName = field.name.asString() // The ConstantValue attribute makes the initializer part of the ABI, which is why since 1.4 // it is no longer set unless the property is explicitly `const`. @@ -342,7 +343,7 @@ open class ClassCodegen protected constructor( // in the source. val containingDeclaration = irClass.symbol.owner.parent if (containingDeclaration is IrFunction) { - val method = typeMapper.mapAsmMethod(containingDeclaration) + val method = methodSignatureMapper.mapAsmMethod(containingDeclaration) visitor.visitOuterClass(outerClassName, method.name, method.descriptor) } else if (irClass.isAnonymousObject) { visitor.visitOuterClass(outerClassName, null, null) 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 01fa3bb0cd1..341dead30df 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 @@ -106,9 +106,9 @@ class ExpressionCodegen( var finallyDepth = 0 - val typeMapper = classCodegen.typeMapper - val context = classCodegen.context + val typeMapper = context.typeMapper + val methodSignatureMapper = context.methodSignatureMapper private val state = classCodegen.state @@ -176,7 +176,7 @@ class ExpressionCodegen( if (irFunction.origin != JvmLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER) { irFunction.markLineNumber(startOffset = irFunction is IrConstructor && irFunction.isPrimary) } - val returnType = typeMapper.mapReturnType(irFunction) + val returnType = methodSignatureMapper.mapReturnType(irFunction) val returnIrType = if (irFunction !is IrConstructor) irFunction.returnType else context.irBuiltIns.unitType result.coerce(returnType, returnIrType).materialize() mv.areturn(returnType) @@ -458,7 +458,7 @@ class ExpressionCodegen( val realField = expression.symbol.owner.resolveFakeOverride()!! val fieldType = typeMapper.mapType(realField.type) - val ownerType = typeMapper.mapImplementationOwner(expression.symbol.owner).internalName + val ownerType = methodSignatureMapper.mapImplementationOwner(expression.symbol.owner).internalName val fieldName = realField.name.asString() val isStatic = expression.receiver == null expression.markLineNumber(startOffset = true) @@ -567,7 +567,8 @@ class ExpressionCodegen( ?: error("Unsupported IrReturnTarget: $returnTarget") //TODO: should be owner != irFunction val isNonLocalReturn = - typeMapper.mapFunctionName(owner, OwnerKind.IMPLEMENTATION) != typeMapper.mapFunctionName(irFunction, OwnerKind.IMPLEMENTATION) + methodSignatureMapper.mapFunctionName(owner, OwnerKind.IMPLEMENTATION) != + methodSignatureMapper.mapFunctionName(irFunction, OwnerKind.IMPLEMENTATION) if (isNonLocalReturn && state.isInlineDisabled) { //TODO: state.diagnostics.report(Errors.NON_LOCAL_RETURN_IN_DISABLED_INLINE.on(expression)) genThrow( @@ -578,7 +579,7 @@ class ExpressionCodegen( } val target = data.findBlock { it.returnSymbol == expression.returnTargetSymbol } - val returnType = typeMapper.mapReturnType(owner) + val returnType = methodSignatureMapper.mapReturnType(owner) val afterReturnLabel = Label() expression.value.accept(this, data).coerce(returnType, owner.returnType).materialize() generateFinallyBlocksIfNeeded(returnType, afterReturnLabel, data, target) @@ -984,7 +985,7 @@ class ExpressionCodegen( } private fun resolveToCallable(irCall: IrFunctionAccessExpression, isSuper: Boolean): IrCallableMethod = - typeMapper.mapToCallableMethod(irCall.symbol.owner, isSuper) + methodSignatureMapper.mapToCallableMethod(irCall.symbol.owner, isSuper) private fun getOrCreateCallGenerator(element: IrFunctionAccessExpression, data: BlockInfo): IrCallGenerator { if (!element.symbol.owner.isInlineFunctionCall(context) || diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt index df867eb1755..6883a47b8a5 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt @@ -45,7 +45,7 @@ open class FunctionCodegen( } private fun doGenerate(): JvmMethodGenericSignature { - val signature = classCodegen.typeMapper.mapSignatureWithGeneric(irFunction, OwnerKind.IMPLEMENTATION) + val signature = classCodegen.methodSignatureMapper.mapSignatureWithGeneric(irFunction, OwnerKind.IMPLEMENTATION) val flags = calculateMethodFlags(irFunction.isStatic) var methodVisitor = createMethod(flags, signature) 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 185402e4778..30e083a5da1 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 @@ -120,8 +120,8 @@ class IrInlineCodegen( ): LambdaInfo { val referencedFunction = irReference.symbol.owner return IrExpressionLambdaImpl( - irReference, referencedFunction, codegen.typeMapper, parameter.isCrossinline, boundReceiver != null, - parameter.type.isExtensionFunctionType + irReference, referencedFunction, codegen.typeMapper, codegen.methodSignatureMapper, parameter.isCrossinline, + boundReceiver != null, parameter.type.isExtensionFunctionType ).also { lambda -> val closureInfo = invocationParamBuilder.addNextValueParameter(type, true, null, parameter.index) closureInfo.functionalArgument = lambda @@ -134,6 +134,7 @@ class IrExpressionLambdaImpl( val reference: IrFunctionReference, val function: IrFunction, private val typeMapper: IrTypeMapper, + private val methodSignatureMapper: MethodSignatureMapper, isCrossInline: Boolean, override val isBoundCallableReference: Boolean, override val isExtensionLambda: Boolean @@ -163,7 +164,7 @@ class IrExpressionLambdaImpl( } } - private val loweredMethod = typeMapper.mapAsmMethod(function) + private val loweredMethod = methodSignatureMapper.mapAsmMethod(function) val capturedParamsInDesc: List = loweredMethod.argumentTypes.drop(if (isExtensionLambda) 1 else 0).take(capturedVars.size) 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 8154aeed054..f566476e50d 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 @@ -55,8 +55,7 @@ class IrSourceCompilerForInline( override val inlineCallSiteInfo: InlineCallSiteInfo get() { //TODO: support nested inline calls - val typeMapper = codegen.typeMapper - val signature = typeMapper.mapSignatureSkipGeneric(codegen.irFunction) + val signature = codegen.methodSignatureMapper.mapSignatureSkipGeneric(codegen.irFunction) return InlineCallSiteInfo( codegen.classCodegen.type.internalName, signature.asmMethod.name, diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrTypeMapper.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrTypeMapper.kt index ddb8855f0e8..5a068d98c88 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrTypeMapper.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrTypeMapper.kt @@ -12,11 +12,12 @@ import org.jetbrains.kotlin.builtins.transformSuspendFunctionToRuntimeFunctionTy import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.ClassBuilderMode import org.jetbrains.kotlin.codegen.JvmCodegenUtil -import org.jetbrains.kotlin.codegen.OwnerKind import org.jetbrains.kotlin.codegen.signature.AsmTypeFactory import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper -import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrPackageFragment +import org.jetbrains.kotlin.ir.declarations.IrTypeParameter import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.impl.originalKotlinType @@ -27,11 +28,8 @@ import org.jetbrains.kotlin.load.kotlin.computeExpandedTypeForInlineClass import org.jetbrains.kotlin.load.kotlin.mapBuiltInType import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.resolve.jvm.AsmTypes -import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature -import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.types.Variance import org.jetbrains.org.objectweb.asm.Type -import org.jetbrains.org.objectweb.asm.commons.Method class IrTypeMapper(private val context: JvmBackendContext) { val kotlinTypeMapper: KotlinTypeMapper = context.state.typeMapper @@ -44,34 +42,6 @@ class IrTypeMapper(private val context: JvmBackendContext) { context.getLocalClassInfo(irClass)?.internalName ?: JvmCodegenUtil.sanitizeNameIfNeeded(computeInternalName(irClass), context.state.languageVersionSettings) - fun mapAsmMethod(irFunction: IrFunction): Method = - kotlinTypeMapper.mapAsmMethod(irFunction.descriptor) - - fun mapFieldSignature(irField: IrField) = - kotlinTypeMapper.mapFieldSignature(irField.type.toKotlinType(), irField.descriptor) - - fun mapFunctionName(irFunction: IrFunction, ownerKind: OwnerKind): String = - kotlinTypeMapper.mapFunctionName(irFunction.descriptor, ownerKind) - - fun mapImplementationOwner(irDeclaration: IrDeclaration): Type = - kotlinTypeMapper.mapImplementationOwner(irDeclaration.descriptor) - - fun mapReturnType(irFunction: IrFunction): Type = - kotlinTypeMapper.mapReturnType(irFunction.descriptor) - - fun mapSignatureSkipGeneric(f: IrFunction, kind: OwnerKind = OwnerKind.IMPLEMENTATION): JvmMethodSignature = - kotlinTypeMapper.mapSignatureSkipGeneric(f.descriptor, kind) - - fun mapSignatureWithGeneric(f: IrFunction, kind: OwnerKind): JvmMethodGenericSignature = - kotlinTypeMapper.mapSignatureWithGeneric(f.descriptor, kind) - - fun mapToCallableMethod(f: IrFunction, superCall: Boolean): IrCallableMethod = - with(kotlinTypeMapper.mapToCallableMethod(f.descriptor, superCall)) { - IrCallableMethod( - owner, valueParameterTypes, invokeOpcode, getAsmMethod(), dispatchReceiverType, extensionReceiverType, isInterfaceMethod - ) - } - fun writeFormalTypeParameters(irParameters: List, sw: JvmSignatureWriter) = kotlinTypeMapper.writeFormalTypeParameters(irParameters.map { it.descriptor }, sw) 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 new file mode 100644 index 00000000000..f563fa036d1 --- /dev/null +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2010-2019 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.JvmBackendContext +import org.jetbrains.kotlin.codegen.OwnerKind +import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper +import org.jetbrains.kotlin.ir.declarations.IrDeclaration +import org.jetbrains.kotlin.ir.declarations.IrField +import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.types.toKotlinType +import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature +import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature +import org.jetbrains.org.objectweb.asm.Type +import org.jetbrains.org.objectweb.asm.commons.Method + +class MethodSignatureMapper(context: JvmBackendContext) { + private val kotlinTypeMapper: KotlinTypeMapper = context.state.typeMapper + + fun mapAsmMethod(irFunction: IrFunction): Method = + kotlinTypeMapper.mapAsmMethod(irFunction.descriptor) + + fun mapFieldSignature(irField: IrField): String? = + kotlinTypeMapper.mapFieldSignature(irField.type.toKotlinType(), irField.descriptor) + + fun mapFunctionName(irFunction: IrFunction, ownerKind: OwnerKind): String = + kotlinTypeMapper.mapFunctionName(irFunction.descriptor, ownerKind) + + fun mapImplementationOwner(irDeclaration: IrDeclaration): Type = + kotlinTypeMapper.mapImplementationOwner(irDeclaration.descriptor) + + fun mapReturnType(irFunction: IrFunction): Type = + kotlinTypeMapper.mapReturnType(irFunction.descriptor) + + fun mapSignatureSkipGeneric(f: IrFunction, kind: OwnerKind = OwnerKind.IMPLEMENTATION): JvmMethodSignature = + kotlinTypeMapper.mapSignatureSkipGeneric(f.descriptor, kind) + + fun mapSignatureWithGeneric(f: IrFunction, kind: OwnerKind): JvmMethodGenericSignature = + kotlinTypeMapper.mapSignatureWithGeneric(f.descriptor, kind) + + fun mapToCallableMethod(f: IrFunction, superCall: Boolean): IrCallableMethod = + with(kotlinTypeMapper.mapToCallableMethod(f.descriptor, superCall)) { + IrCallableMethod( + owner, valueParameterTypes, invokeOpcode, getAsmMethod(), dispatchReceiverType, extensionReceiverType, isInterfaceMethod + ) + } +} diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IntrinsicMethod.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IntrinsicMethod.kt index b07663d9434..97609f3921d 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IntrinsicMethod.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IntrinsicMethod.kt @@ -26,7 +26,7 @@ abstract class IntrinsicMethod { open fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? = with(codegen) { - val descriptor = typeMapper.mapSignatureSkipGeneric(expression.symbol.owner) + val descriptor = methodSignatureMapper.mapSignatureSkipGeneric(expression.symbol.owner) val stackValue = toCallable(expression, descriptor, context).invoke(mv, codegen, data) return object : PromisedValue(this, stackValue.type, expression.type) { override fun materialize() = stackValue.put(mv)