From 12e31a17603282699f500094597ce3a33694a89c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steven=20Sch=C3=A4fer?= Date: Mon, 3 Feb 2020 13:33:04 +0100 Subject: [PATCH] JVM IR: Use dispatchReceiver to calculate owner in MethodSignatureMapper --- .../kotlin/backend/jvm/DeclarationOrigins.kt | 1 + .../backend/jvm/codegen/IrTypeMapping.kt | 3 +++ .../jvm/codegen/MethodSignatureMapper.kt | 14 +++++++++-- .../MemoizedInlineClassReplacements.kt | 25 +++++++++++-------- 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt index ec98f18b31f..409b14c3582 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt @@ -31,6 +31,7 @@ interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin { object ENUM_MAPPINGS_FOR_WHEN : IrDeclarationOriginImpl("ENUM_MAPPINGS_FOR_WHEN", isSynthetic = true) object SYNTHETIC_INLINE_CLASS_MEMBER : IrDeclarationOriginImpl("SYNTHETIC_INLINE_CLASS_MEMBER", isSynthetic = true) object INLINE_CLASS_GENERATED_IMPL_METHOD : IrDeclarationOriginImpl("INLINE_CLASS_GENERATED_IMPL_METHOD") + object STATIC_INLINE_CLASS_REPLACEMENT : IrDeclarationOriginImpl("STATIC_INLINE_CLASS_REPLACEMENT") object GENERATED_ASSERTION_ENABLED_FIELD : IrDeclarationOriginImpl("GENERATED_ASSERTION_ENABLED_FIELD", isSynthetic = true) object GENERATED_MAIN_FOR_PARAMETERLESS_MAIN_METHOD : IrDeclarationOriginImpl("GENERATED_MAIN_FOR_PARAMETERLESS_MAIN_METHOD", isSynthetic = true) object SUSPEND_IMPL_STATIC_FUNCTION : IrDeclarationOriginImpl("SUSPEND_IMPL_STATIC_FUNCTION", isSynthetic = true) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrTypeMapping.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrTypeMapping.kt index 7d502396aac..b4928093f12 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrTypeMapping.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrTypeMapping.kt @@ -33,6 +33,9 @@ fun IrTypeMapper.mapSupertype(irType: IrType, sw: JvmSignatureWriter): Type = fun IrTypeMapper.mapClass(irClass: IrClass): Type = mapType(irClass.defaultType, TypeMappingMode.CLASS_DECLARATION) +fun IrTypeMapper.mapOwner(irClass: IrClass): Type = + mapType(irClass.defaultType, TypeMappingMode.GENERIC_ARGUMENT) + fun IrTypeMapper.mapTypeAsDeclaration(irType: IrType): Type = mapType(irType, TypeMappingMode.CLASS_DECLARATION) 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 4d8376f0904..d25d240af7e 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 @@ -293,10 +293,18 @@ class MethodSignatureMapper(private val context: JvmBackendContext) { if (valueArgumentsCount > 0) (getValueArgument(0) as? IrConst<*>)?.value as? Boolean ?: true else null } + private fun IrFunctionAccessExpression.computeCalleeParent(): IrClass { + if (this is IrCall) { + superQualifierSymbol?.let { return it.owner } + } + return dispatchReceiver?.type?.classOrNull?.owner + ?: symbol.owner.parentAsClass // Static call or type parameter + } + fun mapToCallableMethod(caller: IrFunction, expression: IrFunctionAccessExpression): IrCallableMethod { val callee = expression.symbol.owner - val calleeParent = callee.parentAsClass - val owner = typeMapper.mapClass(calleeParent) + val calleeParent = expression.computeCalleeParent() + val owner = typeMapper.mapOwner(calleeParent) if (callee !is IrSimpleFunction) { check(callee is IrConstructor) { "Function must be a simple function or a constructor: ${callee.render()}" } @@ -326,6 +334,8 @@ class MethodSignatureMapper(private val context: JvmBackendContext) { // Do not remap special builtin methods when called from a bridge. The bridges are there to provide the // remapped name or signature and forward to the actually declared method. if (caller.origin == IrDeclarationOrigin.BRIDGE || caller.origin == IrDeclarationOrigin.BRIDGE_SPECIAL) return null + // Do not remap calls to static replacements of inline class methods, since they have completely different signatures. + if (callee.origin == JvmLoweredDeclarationOrigin.STATIC_INLINE_CLASS_REPLACEMENT) return null val overriddenSpecialBuiltinFunction = callee.descriptor.original.getOverriddenBuiltinReflectingJvmDescriptor() if (overriddenSpecialBuiltinFunction != null && !superCall) { return mapSignatureSkipGeneric(context.referenceFunction(overriddenSpecialBuiltinFunction.original).owner) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/inlineclasses/MemoizedInlineClassReplacements.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/inlineclasses/MemoizedInlineClassReplacements.kt index 852761966ca..28c60f7dfcb 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/inlineclasses/MemoizedInlineClassReplacements.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/inlineclasses/MemoizedInlineClassReplacements.kt @@ -126,12 +126,8 @@ class MemoizedInlineClassReplacements { } private fun createMethodReplacement(function: IrFunction): IrSimpleFunction = - buildReplacement(function) { + buildReplacement(function, function.origin) { require(function.dispatchReceiverParameter != null && function is IrSimpleFunction) - overriddenSymbols = function.overriddenSymbols.map { - getReplacementFunction(it.owner)?.symbol ?: it - } - val newValueParameters = ArrayList() for ((index, parameter) in function.explicitParameters.withIndex()) { val name = if (parameter == function.extensionReceiverParameter) Name.identifier("\$receiver") else parameter.name @@ -151,7 +147,7 @@ class MemoizedInlineClassReplacements { } private fun createStaticReplacement(function: IrFunction): IrSimpleFunction = - buildReplacement(function) { + buildReplacement(function, JvmLoweredDeclarationOrigin.STATIC_INLINE_CLASS_REPLACEMENT) { val newValueParameters = ArrayList() for ((index, parameter) in function.explicitParameters.withIndex()) { val name = when (parameter) { @@ -172,11 +168,13 @@ class MemoizedInlineClassReplacements { valueParameters = newValueParameters } - private fun buildReplacement(function: IrFunction, body: IrFunctionImpl.() -> Unit) = + private fun buildReplacement(function: IrFunction, replacementOrigin: IrDeclarationOrigin, body: IrFunctionImpl.() -> Unit) = buildFunWithDescriptorForInlining(function.descriptor) { updateFrom(function) - if (function.origin == IrDeclarationOrigin.GENERATED_INLINE_CLASS_MEMBER) { - origin = JvmLoweredDeclarationOrigin.INLINE_CLASS_GENERATED_IMPL_METHOD + origin = if (function.origin == IrDeclarationOrigin.GENERATED_INLINE_CLASS_MEMBER) { + JvmLoweredDeclarationOrigin.INLINE_CLASS_GENERATED_IMPL_METHOD + } else { + replacementOrigin } name = mangledNameFor(function) returnType = function.returnType @@ -184,9 +182,16 @@ class MemoizedInlineClassReplacements { parent = function.parent annotations += function.annotations copyTypeParameters(function.allTypeParameters) - correspondingPropertySymbol = function.safeAs()?.correspondingPropertySymbol metadata = function.metadata function.safeAs>()?.metadata = null + + if (function is IrSimpleFunction) { + correspondingPropertySymbol = function.correspondingPropertySymbol + overriddenSymbols = function.overriddenSymbols.map { + getReplacementFunction(it.owner)?.symbol ?: it + } + } + body() } }