JVM_IR fix special bridge generation for inline classes

This commit is contained in:
Dmitry Petrov
2021-02-01 16:03:39 +03:00
parent 8172ae5d89
commit 4ec369ac5b
23 changed files with 410 additions and 24 deletions
@@ -17,10 +17,8 @@ import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.*
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.unboxInlineClass
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.*
@@ -593,17 +591,23 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
fun computeJvmMethod(function: IrFunction): Method =
signatureCache.getOrPut(function.symbol) { context.methodSignatureMapper.mapAsmMethod(function) }
private fun canHaveSpecialBridge(function: IrSimpleFunction): Boolean {
if (function.name in specialBridgeMethods.specialMethodNames)
return true
// Function name could be mangled by inline class rules
val functionName = function.name.asString()
if (specialBridgeMethods.specialMethodNames.any { functionName.startsWith(it.asString() + "-") })
return true
return false
}
fun computeSpecialBridge(function: IrSimpleFunction): SpecialBridge? {
// Optimization: do not try to compute special bridge for irrelevant methods.
val correspondingProperty = function.correspondingPropertySymbol
if (correspondingProperty != null) {
if (correspondingProperty.owner.name !in specialBridgeMethods.specialPropertyNames) return null
} else {
// 'remove' and 'removeAt' functions can be mangled by inline class rules
if (function.name !in specialBridgeMethods.specialMethodNames &&
!function.name.asString().startsWith("removeAt-") &&
!function.name.asString().startsWith("remove-")
) {
if (!canHaveSpecialBridge(function)) {
return null
}
}