JVM IR: extract method signature mapping to MethodSignatureMapper

This commit is contained in:
Alexander Udalov
2019-08-06 05:09:41 +02:00
parent 6191fc10f0
commit 598c6009f2
10 changed files with 74 additions and 50 deletions
@@ -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)
@@ -75,7 +75,7 @@ private val propertiesPhase = makeIrFilePhase<JvmBackendContext>(
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()
@@ -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)
@@ -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<ReturnableBlockInfo> { 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) ||
@@ -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)
@@ -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<Type> =
loweredMethod.argumentTypes.drop(if (isExtensionLambda) 1 else 0).take(capturedVars.size)
@@ -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,
@@ -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<IrTypeParameter>, sw: JvmSignatureWriter) =
kotlinTypeMapper.writeFormalTypeParameters(irParameters.map { it.descriptor }, sw)
@@ -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
)
}
}
@@ -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)