JVM IR: Fix signature mapping for inline classes using new mangling
When resolving inline class methods in binary dependencies we look for methods matching both the new and the old mangling scheme. On the IR backend the method signature has to be computed for the inline class replacement, since the logic for signature mangling is not contained in the method signature mapping, unlike in the old backend.
This commit is contained in:
committed by
Ilmir Usmanov
parent
91717cdcdd
commit
9c4f8f7e54
+2
-3
@@ -382,14 +382,13 @@ val IrMemberAccessExpression<*>.psiElement: PsiElement?
|
||||
fun IrSimpleType.isRawType(): Boolean =
|
||||
hasAnnotation(JvmGeneratorExtensions.RAW_TYPE_ANNOTATION_FQ_NAME)
|
||||
|
||||
internal fun classFileContainsMethod(function: IrFunction, context: JvmBackendContext, name: String): Boolean? {
|
||||
val classId = function.parentClassId ?: return null
|
||||
internal fun classFileContainsMethod(classId: ClassId, function: IrFunction, context: JvmBackendContext): Boolean? {
|
||||
val originalDescriptor = context.methodSignatureMapper.mapSignatureWithGeneric(function).asmMethod.descriptor
|
||||
val descriptor = if (function.isSuspend)
|
||||
listOf(*Type.getArgumentTypes(originalDescriptor), Type.getObjectType("kotlin/coroutines/Continuation"))
|
||||
.joinToString(prefix = "(", postfix = ")", separator = "") + AsmTypes.OBJECT_TYPE
|
||||
else originalDescriptor
|
||||
return classFileContainsMethod(classId, context.state, Method(name, descriptor))
|
||||
return classFileContainsMethod(classId, context.state, Method(function.name.asString(), descriptor))
|
||||
}
|
||||
|
||||
val IrMemberWithContainerSource.parentClassId: ClassId?
|
||||
|
||||
+22
-8
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.classFileContainsMethod
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.parentClassId
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isCompiledToJvmDefault
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isFromJava
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isStaticInlineClassReplacement
|
||||
@@ -226,6 +227,27 @@ class MemoizedInlineClassReplacements(
|
||||
replacementOrigin: IrDeclarationOrigin,
|
||||
noFakeOverride: Boolean = false,
|
||||
body: IrFunction.() -> Unit
|
||||
): IrSimpleFunction {
|
||||
val useOldManglingScheme = context.state.useOldManglingSchemeForFunctionsWithInlineClassesInSignatures
|
||||
val replacement = buildReplacementInner(function, replacementOrigin, noFakeOverride, useOldManglingScheme, body)
|
||||
// When using the new mangling scheme we might run into dependencies using the old scheme
|
||||
// for which we will fall back to the old mangling scheme as well.
|
||||
if (
|
||||
!useOldManglingScheme &&
|
||||
replacement.name.asString().contains("-") &&
|
||||
function.parentClassId?.let { classFileContainsMethod(it, replacement, context) } == false
|
||||
) {
|
||||
return buildReplacementInner(function, replacementOrigin, noFakeOverride, true, body)
|
||||
}
|
||||
return replacement
|
||||
}
|
||||
|
||||
private fun buildReplacementInner(
|
||||
function: IrFunction,
|
||||
replacementOrigin: IrDeclarationOrigin,
|
||||
noFakeOverride: Boolean,
|
||||
useOldManglingScheme: Boolean,
|
||||
body: IrFunction.() -> Unit,
|
||||
): IrSimpleFunction = irFactory.buildFun {
|
||||
updateFrom(function)
|
||||
if (function is IrConstructor) {
|
||||
@@ -243,15 +265,7 @@ class MemoizedInlineClassReplacements(
|
||||
if (noFakeOverride) {
|
||||
isFakeOverride = false
|
||||
}
|
||||
val useOldManglingScheme = context.state.useOldManglingSchemeForFunctionsWithInlineClassesInSignatures
|
||||
name = mangledNameFor(function, mangleReturnTypes, useOldManglingScheme)
|
||||
if (
|
||||
!useOldManglingScheme &&
|
||||
name.asString().contains("-") &&
|
||||
classFileContainsMethod(function, context, name.asString()) == false
|
||||
) {
|
||||
name = mangledNameFor(function, mangleReturnTypes, true)
|
||||
}
|
||||
returnType = function.returnType
|
||||
}.apply {
|
||||
parent = function.parent
|
||||
|
||||
Reference in New Issue
Block a user