[JVM_IR] Box primitive types in class literals of reified type arguments
Bytecode inliner boxes primitive types in class literals of reified type arguments. This is by design, and we should backport this behaviour to IR inliner. ^KT-60144: Fixed
This commit is contained in:
committed by
Space Team
parent
ade1354a84
commit
cfcdc6f0ae
@@ -326,6 +326,16 @@ private val apiVersionIsAtLeastEvaluationPhase = makeIrModulePhase(
|
||||
prerequisite = setOf(functionInliningPhase)
|
||||
)
|
||||
|
||||
private val inlinedClassReferencesBoxingPhase = makeIrModulePhase(
|
||||
{ context ->
|
||||
if (!context.irInlinerIsEnabled()) return@makeIrModulePhase FileLoweringPass.Empty
|
||||
InlinedClassReferencesBoxingLowering(context)
|
||||
},
|
||||
name = "InlinedClassReferencesBoxingLowering",
|
||||
description = "Replace inlined primitive types in class references with boxed versions",
|
||||
prerequisite = setOf(functionInliningPhase, markNecessaryInlinedClassesAsRegenerated)
|
||||
)
|
||||
|
||||
private val constEvaluationPhase = makeIrModulePhase<JvmBackendContext>(
|
||||
::ConstEvaluationLowering,
|
||||
name = "ConstEvaluationLowering",
|
||||
@@ -476,6 +486,7 @@ private fun buildJvmLoweringPhases(
|
||||
apiVersionIsAtLeastEvaluationPhase then
|
||||
createSeparateCallForInlinedLambdas then
|
||||
markNecessaryInlinedClassesAsRegenerated then
|
||||
inlinedClassReferencesBoxingPhase then
|
||||
|
||||
buildLoweringsPhase(phases) then
|
||||
generateMultifileFacadesPhase then
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.getAttributeOwnerBeforeInline
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.expressions.IrClassReference
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.buildSimpleType
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
|
||||
internal class InlinedClassReferencesBoxingLowering(val context: JvmBackendContext) : FileLoweringPass, IrElementVisitorVoid {
|
||||
override fun lower(irFile: IrFile) {
|
||||
irFile.acceptChildrenVoid(this)
|
||||
}
|
||||
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
|
||||
override fun visitClassReference(expression: IrClassReference) {
|
||||
super.visitClassReference(expression)
|
||||
|
||||
val wasTypeParameterClassRefBeforeInline =
|
||||
(expression.getAttributeOwnerBeforeInline() as? IrClassReference)?.classType?.classifierOrNull is IrTypeParameterSymbol
|
||||
|
||||
if (wasTypeParameterClassRefBeforeInline && expression.classType.isPrimitiveType()) {
|
||||
// Making primitive type nullable is effectively boxing
|
||||
val boxedPrimitive = expression.classType.makeNullable()
|
||||
require(boxedPrimitive is IrSimpleType) {
|
||||
"Type is expected to be ${IrSimpleType::class.simpleName}: ${boxedPrimitive.render()}"
|
||||
}
|
||||
expression.classType = boxedPrimitive
|
||||
val classReferenceType = expression.type
|
||||
require(classReferenceType is IrSimpleType && classReferenceType.isKClass()) {
|
||||
"Type of the type reference is expected to be KClass: ${classReferenceType.render()}"
|
||||
}
|
||||
expression.type = classReferenceType.buildSimpleType {
|
||||
arguments = listOf(boxedPrimitive)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -937,14 +937,14 @@ class JvmSymbols(
|
||||
throw AssertionError("Array type expected: ${arrayType.render()}")
|
||||
}
|
||||
|
||||
private val javaLangInteger: IrClassSymbol = createJavaPrimitiveClass(FqName("java.lang.Integer"), irBuiltIns.intType)
|
||||
val javaLangInteger: IrClassSymbol = createJavaPrimitiveClass(FqName("java.lang.Integer"), irBuiltIns.intType)
|
||||
|
||||
val compareUnsignedInt: IrSimpleFunctionSymbol = javaLangInteger.functionByName("compareUnsigned")
|
||||
val divideUnsignedInt: IrSimpleFunctionSymbol = javaLangInteger.functionByName("divideUnsigned")
|
||||
val remainderUnsignedInt: IrSimpleFunctionSymbol = javaLangInteger.functionByName("remainderUnsigned")
|
||||
val toUnsignedStringInt: IrSimpleFunctionSymbol = javaLangInteger.functionByName("toUnsignedString")
|
||||
|
||||
private val javaLangLong: IrClassSymbol = createJavaPrimitiveClass(FqName("java.lang.Long"), irBuiltIns.longType)
|
||||
val javaLangLong: IrClassSymbol = createJavaPrimitiveClass(FqName("java.lang.Long"), irBuiltIns.longType)
|
||||
|
||||
val compareUnsignedLong: IrSimpleFunctionSymbol = javaLangLong.functionByName("compareUnsigned")
|
||||
val divideUnsignedLong: IrSimpleFunctionSymbol = javaLangLong.functionByName("divideUnsigned")
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_INLINER: IR
|
||||
|
||||
// WITH_STDLIB
|
||||
|
||||
inline fun <reified T : Any> check(expected: String) {
|
||||
|
||||
-2
@@ -1,6 +1,4 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_INLINER: IR
|
||||
|
||||
// WITH_STDLIB
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_INLINER: IR
|
||||
|
||||
// WITH_STDLIB
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_INLINER: IR
|
||||
|
||||
// WITH_STDLIB
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_INLINER: IR
|
||||
|
||||
// WITH_STDLIB
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_INLINER: IR
|
||||
|
||||
// WITH_STDLIB
|
||||
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_INLINER: IR
|
||||
|
||||
// WITH_STDLIB
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_INLINER: IR
|
||||
|
||||
// WITH_STDLIB
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_INLINER: IR
|
||||
|
||||
// WITH_STDLIB
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_INLINER: IR
|
||||
|
||||
// WITH_STDLIB
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
-2
@@ -1,6 +1,4 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_INLINER: IR
|
||||
|
||||
// WITH_STDLIB
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_INLINER: IR
|
||||
|
||||
// WITH_STDLIB
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
Reference in New Issue
Block a user