Fix IR types in JVM_IR BridgeLowering
Properly implement the java erasure rules on IrTypes and fix the types for dispatch and extension receivers.
This commit is contained in:
committed by
max-kammerer
parent
c885cadde4
commit
2da0315d2e
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.ir
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||
|
||||
/**
|
||||
* Computes the erased class for this type parameter according to the java erasure rules.
|
||||
*/
|
||||
val IrTypeParameter.erasedUpperBound: IrClass
|
||||
get() {
|
||||
// Pick the (necessarily unique) non-interface upper bound if it exists
|
||||
for (type in superTypes) {
|
||||
val irClass = type.classOrNull?.owner ?: continue
|
||||
if (!irClass.isJvmInterface) return irClass
|
||||
}
|
||||
|
||||
// Otherwise, choose either the first IrClass supertype or recurse.
|
||||
// In the first case, all supertypes are interface types and the choice was arbitrary.
|
||||
// In the second case, there is only a single supertype.
|
||||
return superTypes.first().erasedUpperBound
|
||||
}
|
||||
|
||||
val IrType.erasedUpperBound: IrClass
|
||||
get() = when (val classifier = classifierOrNull) {
|
||||
is IrClassSymbol -> classifier.owner
|
||||
is IrTypeParameterSymbol -> classifier.owner.erasedUpperBound
|
||||
else -> throw IllegalStateException()
|
||||
}
|
||||
+8
-26
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.backend.common.lower.irNot
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
@@ -30,20 +31,14 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrErrorType
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.defaultType
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||
import org.jetbrains.kotlin.ir.util.isInterface
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
@@ -278,9 +273,9 @@ private class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass
|
||||
superQualifierSymbol = if (invokeStatically) maybeOrphanedTarget.parentAsClass.symbol else null
|
||||
).apply {
|
||||
passTypeArgumentsFrom(this@createBridgeBody)
|
||||
dispatchReceiver = irImplicitCast(irGet(dispatchReceiverParameter!!), dispatchReceiverParameter!!.type)
|
||||
dispatchReceiver = irGet(dispatchReceiverParameter!!)
|
||||
extensionReceiverParameter?.let {
|
||||
extensionReceiver = irImplicitCast(irGet(it), extensionReceiverParameter!!.type)
|
||||
extensionReceiver = irImplicitCast(irGet(it), maybeOrphanedTarget.extensionReceiverParameter!!.type)
|
||||
}
|
||||
valueParameters.forEach {
|
||||
putValueArgument(it.index, irImplicitCast(irGet(it), maybeOrphanedTarget.valueParameters[it.index].type))
|
||||
@@ -341,36 +336,23 @@ private class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass
|
||||
// TODO: should be a type mapper functionality.
|
||||
private fun IrType.eraseTypeParameters() = when (this) {
|
||||
is IrErrorType -> this
|
||||
is IrSimpleType -> {
|
||||
val owner = classifier.owner
|
||||
when (owner) {
|
||||
is IrSimpleType ->
|
||||
when (val owner = classifier.owner) {
|
||||
is IrClass -> this
|
||||
is IrTypeParameter -> {
|
||||
val upperBound = owner.upperBoundClass()
|
||||
val upperBound = owner.erasedUpperBound
|
||||
IrSimpleTypeImpl(
|
||||
upperBound.symbol,
|
||||
hasQuestionMark,
|
||||
isNullable(),
|
||||
List(upperBound.typeParameters.size) { IrStarProjectionImpl }, // Should not affect JVM signature, but may result in an invalid type object
|
||||
owner.annotations
|
||||
)
|
||||
}
|
||||
else -> error("Unknown IrSimpleType classifier kind: $owner")
|
||||
}
|
||||
}
|
||||
else -> error("Unknown IrType kind: $this")
|
||||
}
|
||||
|
||||
private fun IrTypeParameter.upperBoundClass(): IrClass {
|
||||
val simpleSuperClassifiers = superTypes.asSequence().filterIsInstance<IrSimpleType>().map { it.classifier }
|
||||
return simpleSuperClassifiers
|
||||
.filterIsInstance<IrClassSymbol>()
|
||||
.let {
|
||||
it.firstOrNull { !it.owner.isInterface } ?: it.firstOrNull()
|
||||
}?.owner ?:
|
||||
simpleSuperClassifiers.filterIsInstance<IrTypeParameterSymbol>().map { it.owner.upperBoundClass() }.firstOrNull() ?:
|
||||
context.irBuiltIns.anyClass.owner
|
||||
}
|
||||
|
||||
private fun IrSimpleFunction.findAllReachableDeclarations() =
|
||||
findAllReachableDeclarations(FunctionHandleForIrFunction(this)).map { it.irFunction }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user