JVM IR: Mangle overridden symbols in non-inline functions (KT-52394)
This commit is contained in:
+3
-15
@@ -343,14 +343,12 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
||||
for (override in irFunction.allOverridden()) {
|
||||
if (override.isFakeOverride) continue
|
||||
|
||||
val target = override.mangleFunctionIfNeeded()
|
||||
|
||||
val signature = target.jvmMethod
|
||||
val signature = override.jvmMethod
|
||||
if (targetMethod != signature && signature !in blacklist) {
|
||||
val bridge = generated.getOrPut(signature) {
|
||||
Bridge(target, signature)
|
||||
Bridge(override, signature)
|
||||
}
|
||||
bridge.overriddenSymbols += target.symbol
|
||||
bridge.overriddenSymbols += override.symbol
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,16 +360,6 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
||||
.forEach { irClass.addBridge(it, bridgeTarget) }
|
||||
}
|
||||
|
||||
private fun IrSimpleFunction.mangleFunctionIfNeeded(): IrSimpleFunction {
|
||||
if (!hasMangledReturnType && !hasMangledParameters) return this
|
||||
val replacement = context.inlineClassReplacements.getReplacementFunction(this) ?: return this
|
||||
if (name.asString().substringAfterLast('-') == replacement.name.asString().substringAfterLast('-')) {
|
||||
// function is already mangled
|
||||
return this
|
||||
}
|
||||
return replacement
|
||||
}
|
||||
|
||||
private fun IrSimpleFunction.isClashingWithPotentialBridge(name: Name, signature: Method): Boolean =
|
||||
(!this.isFakeOverride || this.modality == Modality.FINAL) && this.name == name && this.jvmMethod == signature
|
||||
|
||||
|
||||
+10
@@ -81,6 +81,16 @@ internal abstract class JvmValueClassAbstractLowering(val context: JvmBackendCon
|
||||
val replacement = replacements.getReplacementFunction(function)
|
||||
if (replacement == null) {
|
||||
function.transformChildrenVoid()
|
||||
// Non-mangled functions can override mangled functions under some conditions, e.g., a function
|
||||
// `fun f(): Nothing` can override a function `fun f(): UInt`. The former is not mangled, while
|
||||
// the latter is.
|
||||
//
|
||||
// This is a potential problem for bridge generation, where we have to ensure that the overridden
|
||||
// symbols are always up to date. Right now they might not be since we lower each file independently
|
||||
// and since deserialized declarations are not mangled at all.
|
||||
if (function is IrSimpleFunction) {
|
||||
function.overriddenSymbols = replacements.replaceOverriddenSymbols(function)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
+14
-3
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildProperty
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
|
||||
import org.jetbrains.kotlin.ir.types.isInt
|
||||
@@ -304,11 +305,21 @@ class MemoizedInlineClassReplacements(
|
||||
}
|
||||
}
|
||||
|
||||
overriddenSymbols = function.overriddenSymbols.map {
|
||||
getReplacementFunction(it.owner)?.symbol ?: it
|
||||
}
|
||||
overriddenSymbols = replaceOverriddenSymbols(function)
|
||||
}
|
||||
|
||||
body()
|
||||
}
|
||||
|
||||
override val replaceOverriddenSymbols: (IrSimpleFunction) -> List<IrSimpleFunctionSymbol> =
|
||||
storageManager.createMemoizedFunction { irSimpleFunction ->
|
||||
irSimpleFunction.overriddenSymbols.map {
|
||||
computeOverrideReplacement(it.owner).symbol
|
||||
}
|
||||
}
|
||||
|
||||
private fun computeOverrideReplacement(function: IrSimpleFunction): IrSimpleFunction =
|
||||
getReplacementFunction(function) ?: function.also {
|
||||
function.overriddenSymbols = replaceOverriddenSymbols(function)
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.jvm
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFactory
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
@@ -29,4 +30,8 @@ class MemoizedMultiFieldValueClassReplacements(
|
||||
override val getReplacementFunction: (IrFunction) -> IrSimpleFunction? = storageManager.createMemoizedFunctionWithNullableValues {
|
||||
TODO()
|
||||
}
|
||||
|
||||
override val replaceOverriddenSymbols: (IrSimpleFunction) -> List<IrSimpleFunctionSymbol> = storageManager.createMemoizedFunction {
|
||||
TODO()
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.jvm
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFactory
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
|
||||
abstract class MemoizedValueClassAbstractReplacements(protected val irFactory: IrFactory, protected val context: JvmBackendContext) {
|
||||
/**
|
||||
@@ -17,4 +18,5 @@ abstract class MemoizedValueClassAbstractReplacements(protected val irFactory: I
|
||||
|
||||
abstract val originalFunctionForStaticReplacement: MutableMap<IrFunction, IrFunction>
|
||||
|
||||
abstract val replaceOverriddenSymbols: (IrSimpleFunction) -> List<IrSimpleFunctionSymbol>
|
||||
}
|
||||
Reference in New Issue
Block a user