JVM IR: do not use old KotlinTypeMapper when coercing inline classes
KotlinTypeMapper.mapInlineClassTypeAsDeclaration and mapUnderlyingTypeOfInlineClassType invoked mapType which is defined in descriptorBasedTypeSignatureMapping.kt and works on KotlinType. It didn't lead to any problems, other than the fact that we were constructing IrBasedClassDescriptor in JVM IR, and then KotlinType to pass it to mapType, on each call to StackValue.boxInlineClass or unboxInlineClass, which seems wasteful. Instead of this, refactor these utilities to use type markers instead, pass IrType and IrTypeMapper directly from JVM IR, and move the "static type mapper" logic (which is used only in the old backend) out of KotlinTypeMapper.
This commit is contained in:
+5
-5
@@ -468,7 +468,7 @@ class ExpressionCodegen(
|
||||
if (isSuspensionPoint != SuspensionPointKind.NEVER) {
|
||||
addSuspendMarker(mv, isStartNotEnd = false, isSuspensionPoint == SuspensionPointKind.NOT_INLINE)
|
||||
if (unboxedInlineClassIrType != null) {
|
||||
generateResumePathUnboxing(mv, unboxedInlineClassIrType.toIrBasedKotlinType())
|
||||
generateResumePathUnboxing(mv, unboxedInlineClassIrType, typeMapper)
|
||||
}
|
||||
addInlineMarker(mv, isStartNotEnd = false)
|
||||
}
|
||||
@@ -484,7 +484,7 @@ class ExpressionCodegen(
|
||||
mv.checkcast(unboxedInlineClassIrType.asmType)
|
||||
}
|
||||
if (irFunction.isInvokeSuspendOfContinuation()) {
|
||||
StackValue.boxInlineClass(unboxedInlineClassIrType.toIrBasedKotlinType(), mv)
|
||||
StackValue.boxInlineClass(unboxedInlineClassIrType, mv, typeMapper)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -637,7 +637,7 @@ class ExpressionCodegen(
|
||||
if (!irFunction.isInlineCallableReference) return
|
||||
if (irFunction.extensionReceiverParameter?.symbol == arg.symbol) return
|
||||
if (arg.type.isNullable() && arg.type.makeNotNull().unboxInlineClass().isNullable()) return
|
||||
StackValue.unboxInlineClass(OBJECT_TYPE, arg.type.erasedUpperBound.defaultType.toIrBasedKotlinType(), mv)
|
||||
StackValue.unboxInlineClass(OBJECT_TYPE, arg.type.erasedUpperBound.defaultType, mv, typeMapper)
|
||||
}
|
||||
|
||||
// We do not mangle functions if Result is the only parameter of the function,
|
||||
@@ -664,7 +664,7 @@ class ExpressionCodegen(
|
||||
// Result parameter of SAM-wrapper to Java SAM is already unboxed in visitGetValue, do not unbox it anymore
|
||||
if (irFunction.parentAsClass.superTypes.any { it.getClass()?.isFromJava() == true }) return
|
||||
|
||||
StackValue.unboxInlineClass(OBJECT_TYPE, arg.type.erasedUpperBound.defaultType.toIrBasedKotlinType(), mv)
|
||||
StackValue.unboxInlineClass(OBJECT_TYPE, arg.type.erasedUpperBound.defaultType, mv, typeMapper)
|
||||
}
|
||||
|
||||
private fun IrClass.isSamAdapter(): Boolean = this.superTypes.any { it.getClass()?.isFun == true }
|
||||
@@ -920,7 +920,7 @@ class ExpressionCodegen(
|
||||
expression.value.accept(this, data).materializeAt(returnType, returnIrType)
|
||||
// In case of non-local return from suspend lambda 'materializeAt' does not box return value, box it manually.
|
||||
if (isNonLocalReturn && owner.isInvokeSuspendOfLambda() && expression.value.type.isKotlinResult()) {
|
||||
StackValue.boxInlineClass(expression.value.type.toIrBasedKotlinType(), mv)
|
||||
StackValue.boxInlineClass(expression.value.type, mv, typeMapper)
|
||||
}
|
||||
generateFinallyBlocksIfNeeded(returnType, afterReturnLabel, data, null)
|
||||
expression.markLineNumber(startOffset = true)
|
||||
|
||||
+4
-1
@@ -40,7 +40,7 @@ import org.jetbrains.kotlin.ir.types.isKClass as isKClassImpl
|
||||
import org.jetbrains.kotlin.ir.util.isSuspendFunction as isSuspendFunctionImpl
|
||||
|
||||
class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBase(), TypeMappingContext<JvmSignatureWriter> {
|
||||
internal val typeSystem = IrTypeSystemContextImpl(context.irBuiltIns)
|
||||
override val typeSystem: IrTypeSystemContext = IrTypeSystemContextImpl(context.irBuiltIns)
|
||||
override val typeContext: TypeSystemCommonBackendContextForTypeMapping = IrTypeCheckerContextForTypeMapping(typeSystem, context)
|
||||
|
||||
override fun mapClass(classifier: ClassifierDescriptor): Type =
|
||||
@@ -53,6 +53,9 @@ class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBas
|
||||
error("Unknown descriptor: $classifier")
|
||||
}
|
||||
|
||||
override fun mapTypeCommon(type: KotlinTypeMarker, mode: TypeMappingMode): Type =
|
||||
mapType(type as IrType, mode)
|
||||
|
||||
private fun computeClassInternalName(irClass: IrClass): StringBuilder {
|
||||
context.getLocalClassType(irClass)?.internalName?.let {
|
||||
return StringBuilder(it)
|
||||
|
||||
+2
-7
@@ -12,15 +12,11 @@ import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.InlineClassAbi
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||
import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.isTypeParameter
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
import org.jetbrains.kotlin.ir.util.substitute
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.typeConstructor
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
@@ -50,12 +46,12 @@ abstract class PromisedValue(val codegen: ExpressionCodegen, val type: Type, val
|
||||
|
||||
when {
|
||||
isFromTypeUnboxed && !isToTypeUnboxed -> {
|
||||
StackValue.boxInlineClass(erasedSourceType.toIrBasedKotlinType(), mv)
|
||||
StackValue.boxInlineClass(erasedSourceType, mv, typeMapper)
|
||||
return
|
||||
}
|
||||
|
||||
!isFromTypeUnboxed && isToTypeUnboxed -> {
|
||||
StackValue.unboxInlineClass(type, erasedTargetType.toIrBasedKotlinType(), mv)
|
||||
StackValue.unboxInlineClass(type, erasedTargetType, mv, typeMapper)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -64,7 +60,6 @@ abstract class PromisedValue(val codegen: ExpressionCodegen, val type: Type, val
|
||||
if (type != target || (castForReified && irType.anyTypeArgument { it.isReified })) {
|
||||
StackValue.coerce(type, target, mv, type == target)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
abstract fun discard()
|
||||
|
||||
@@ -431,20 +431,22 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
|
||||
irClass.kind != ClassKind.INTERFACE && irClass.kind != ClassKind.ANNOTATION_CLASS
|
||||
} ?: owner.superTypes.first()
|
||||
|
||||
override fun KotlinTypeMarker.getSubstitutedUnderlyingType(): KotlinTypeMarker? {
|
||||
override fun KotlinTypeMarker.getUnsubstitutedUnderlyingType(): KotlinTypeMarker? {
|
||||
// Code in inlineClassesUtils.kt loads the property with the same name from the scope of the substituted type and takes its type.
|
||||
// This code below should have the same effect.
|
||||
val irClass = (this as? IrType)?.classOrNull?.owner?.takeIf { it.isInline } ?: return null
|
||||
val inlineClassParameter = irClass.primaryConstructor?.valueParameters?.singleOrNull()
|
||||
return inlineClassParameter?.let { parameter ->
|
||||
val irClass = (this as? IrType)?.classOrNull?.owner?.takeIf { it.isInline }
|
||||
return irClass?.primaryConstructor?.valueParameters?.singleOrNull()?.type
|
||||
}
|
||||
|
||||
override fun KotlinTypeMarker.getSubstitutedUnderlyingType(): KotlinTypeMarker? =
|
||||
getUnsubstitutedUnderlyingType()?.let { type ->
|
||||
// Taking only the type parameters of the class (and not its outer classes) is OK since inner classes are always top level
|
||||
IrTypeSubstitutor(
|
||||
irClass.typeParameters.map { it.symbol },
|
||||
(this as IrType).getClass()!!.typeParameters.map { it.symbol },
|
||||
(this as? IrSimpleType)?.arguments.orEmpty(),
|
||||
irBuiltIns
|
||||
).substitute(parameter.type)
|
||||
).substitute(type as IrType)
|
||||
}
|
||||
}
|
||||
|
||||
override fun TypeConstructorMarker.getPrimitiveType(): PrimitiveType? {
|
||||
if (this !is IrClassSymbol) return null
|
||||
|
||||
Reference in New Issue
Block a user