From f64afbf15256579d0cb1cedb9acd3519a1263237 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 6 Aug 2019 06:11:58 +0200 Subject: [PATCH] JVM IR: reduce usages of IrTypeMapper.kotlinTypeMapper --- .../org/jetbrains/kotlin/codegen/AsmUtil.java | 2 +- .../backend/jvm/codegen/ExpressionCodegen.kt | 2 +- .../backend/jvm/codegen/IrTypeMapper.kt | 13 +++++--- .../backend/jvm/codegen/irCodegenUtils.kt | 25 +++------------ .../backend/jvm/intrinsics/CompareTo.kt | 4 ++- .../jvm/intrinsics/IrIntrinsicFunction.kt | 31 +++++++++++-------- .../jvm/intrinsics/IrIntrinsicMethods.kt | 5 ++- .../lambdaInLocalClassConstructor.kt | 1 - .../enclosing/lambdaInObjectExpression.kt | 1 - 9 files changed, 39 insertions(+), 45 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java index 2648c33c730..ef0c30360dc 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java @@ -236,7 +236,7 @@ public class AsmUtil { } @Nullable - private static Type boxPrimitiveType(@NotNull Type type) { + public static Type boxPrimitiveType(@NotNull Type type) { JvmPrimitiveType jvmPrimitiveType = primitiveTypeByAsmSort.get(type.getSort()); return jvmPrimitiveType != null ? asmTypeByFqNameWithoutInnerClasses(jvmPrimitiveType.getWrapperFqName()) : null; } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index 341dead30df..077bfaf4eca 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -237,7 +237,7 @@ class ExpressionCodegen( val name = if (param.origin == BOUND_RECEIVER_PARAMETER || isReceiver) { getNameForReceiverParameter( irFunction.descriptor, - typeMapper.kotlinTypeMapper.bindingContext, + state.bindingContext, context.configuration.languageVersionSettings ) } else { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrTypeMapper.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrTypeMapper.kt index 891acadd45e..07458862a2a 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrTypeMapper.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrTypeMapper.kt @@ -35,9 +35,6 @@ class IrTypeMapper(private val context: JvmBackendContext) { val kotlinTypeMapper: KotlinTypeMapper = context.state.typeMapper private val typeSystem = IrTypeCheckerContext(context.irBuiltIns) - val classBuilderMode: ClassBuilderMode - get() = kotlinTypeMapper.classBuilderMode - fun classInternalName(irClass: IrClass): String = context.getLocalClassInfo(irClass)?.internalName ?: JvmCodegenUtil.sanitizeNameIfNeeded(computeInternalName(irClass), context.state.languageVersionSettings) @@ -53,8 +50,14 @@ class IrTypeMapper(private val context: JvmBackendContext) { } } - fun boxType(irType: IrType): Type = - AsmUtil.boxType(mapType(irType), irType.toKotlinType(), kotlinTypeMapper) + fun boxType(irType: IrType): Type { + val irClass = irType.classOrNull?.owner + if (irClass != null && irClass.isInline) { + return mapTypeAsDeclaration(irType) + } + val type = mapType(irType) + return AsmUtil.boxPrimitiveType(type) ?: type + } fun mapType( type: IrType, diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt index 3c82ffc4fcd..04fe4d739af 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt @@ -27,7 +27,6 @@ import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.load.java.JavaVisibilities -import org.jetbrains.kotlin.load.kotlin.TypeMappingMode import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorUtils @@ -37,6 +36,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmClassSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.resolve.source.PsiSourceElement +import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.org.objectweb.asm.MethodVisitor import org.jetbrains.org.objectweb.asm.Opcodes @@ -108,13 +108,9 @@ val IrType.isExtensionFunctionType: Boolean fun writeInnerClass(innerClass: IrClass, typeMapper: IrTypeMapper, context: JvmBackendContext, v: ClassBuilder) { val outerClassInternalName = innerClass.parent.safeAs()?.let { typeMapper.classInternalName(it) } - /* TODO: So long as the type mapper works by descriptors, the internal name should be consistent with it. */ - val outerClassInternalNameByDescriptor = innerClass.descriptor.containingDeclaration.safeAs()?.let { - typeMapper.kotlinTypeMapper.classInternalName(it) - } val innerName = innerClass.name.takeUnless { it.isSpecial }?.asString() val innerClassInternalName = typeMapper.classInternalName(innerClass) - v.visitInnerClass(innerClassInternalName, outerClassInternalNameByDescriptor, innerName, innerClass.calculateInnerClassAccessFlags(context)) + v.visitInnerClass(innerClassInternalName, outerClassInternalName, innerName, innerClass.calculateInnerClassAccessFlags(context)) } /* Borrowed with modifications from AsmUtil.java */ @@ -379,22 +375,9 @@ internal fun getSignature( sw.writeInterface() val jvmInterfaceType = typeMapper.mapSupertype(superType, sw) sw.writeInterfaceEnd() - val jvmInterfaceInternalName = jvmInterfaceType.internalName - superInterfaces.add(jvmInterfaceInternalName) - - val kotlinMarkerInterfaceInternalName = KOTLIN_MARKER_INTERFACES.get(kotlinInterfaceName) - if (kotlinMarkerInterfaceInternalName != null) { - if (typeMapper.classBuilderMode === ClassBuilderMode.LIGHT_CLASSES) { - sw.writeInterface() - val kotlinCollectionType = - typeMapper.mapType(superClass.defaultType, TypeMappingMode.SUPER_TYPE_KOTLIN_COLLECTIONS_AS_IS, sw) - sw.writeInterfaceEnd() - superInterfaces.add(kotlinCollectionType.internalName) - } - - kotlinMarkerInterfaces.add(kotlinMarkerInterfaceInternalName) - } + superInterfaces.add(jvmInterfaceType.internalName) + kotlinMarkerInterfaces.addIfNotNull(KOTLIN_MARKER_INTERFACES[kotlinInterfaceName]) } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/CompareTo.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/CompareTo.kt index 30487b3d849..d7e9f43d9ea 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/CompareTo.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/CompareTo.kt @@ -19,12 +19,14 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics import com.intellij.psi.tree.IElementType import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.codegen.* +import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.codegen.AsmUtil.comparisonOperandType import org.jetbrains.kotlin.codegen.BranchedValue import org.jetbrains.kotlin.codegen.NumberCompare import org.jetbrains.kotlin.codegen.ObjectCompare import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression import org.jetbrains.kotlin.lexer.KtSingleValueToken +import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.org.objectweb.asm.Label @@ -87,7 +89,7 @@ class PrimitiveComparison( private val operatorToken: KtSingleValueToken ) : IntrinsicMethod() { override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? { - val parameterType = codegen.typeMapper.kotlinTypeMapper.mapType(primitiveNumberType) + val parameterType = Type.getType(JvmPrimitiveType.get(KotlinBuiltIns.getPrimitiveType(primitiveNumberType)!!).desc) val (left, right) = expression.receiverAndArgs() val a = left.accept(codegen, data).coerce(parameterType, left.type).materialized val b = right.accept(codegen, data).coerce(parameterType, right.type).materialized diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicFunction.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicFunction.kt index 29abf28ffc2..f5d0ef3e34b 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicFunction.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicFunction.kt @@ -13,7 +13,10 @@ import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression -import org.jetbrains.kotlin.resolve.calls.components.isVararg +import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.util.dump +import org.jetbrains.kotlin.ir.util.isVararg +import org.jetbrains.kotlin.ir.util.substitute import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.org.objectweb.asm.Type @@ -65,27 +68,26 @@ open class IrIntrinsicFunction( return StackValue.onStack(genInvokeInstructionWithResult(v)) } - fun loadArguments( - codegen: ExpressionCodegen, - data: BlockInfo - ) { + private fun loadArguments(codegen: ExpressionCodegen, data: BlockInfo) { var offset = 0 expression.dispatchReceiver?.let { genArg(it, codegen, offset++, data) } expression.extensionReceiver?.let { genArg(it, codegen, offset++, data) } - for ((i, descriptor) in expression.descriptor.valueParameters.withIndex()) { + for ((i, valueParameter) in expression.symbol.owner.valueParameters.withIndex()) { val argument = expression.getValueArgument(i) when { argument != null -> genArg(argument, codegen, i + offset, data) - descriptor.isVararg -> { - val parameterType = codegen.typeMapper.kotlinTypeMapper.mapType(descriptor.type) - StackValue.operation(parameterType) { + valueParameter.isVararg -> { + // TODO: is there an easier way to get the substituted type of an empty vararg argument? + val arrayType = codegen.typeMapper.mapType( + valueParameter.type.substitute(expression.symbol.owner.typeParameters, expression.typeArguments) + ) + StackValue.operation(arrayType) { it.aconst(0) - it.newarray(AsmUtil.correctElementType(parameterType)) - }.put(parameterType, codegen.mv) + it.newarray(AsmUtil.correctElementType(arrayType)) + }.put(arrayType, codegen.mv) } - else -> - error("Unknown parameter: $descriptor in $expression") + else -> error("Unknown parameter ${valueParameter.name} in: ${expression.dump()}") } } } @@ -94,6 +96,9 @@ open class IrIntrinsicFunction( codegen.gen(expression, argsTypes[index], expression.type, data) } + private val IrFunctionAccessExpression.typeArguments: List + get() = (0 until typeArgumentsCount).map { getTypeArgument(it)!! } + companion object { fun create( expression: IrFunctionAccessExpression, diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicMethods.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicMethods.kt index a6c541acf07..345e94b66e5 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicMethods.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicMethods.kt @@ -245,7 +245,10 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) { } - private fun primitiveComparisonIntrinsics(typeToIrFun: Map, operator: KtSingleValueToken) = + private fun primitiveComparisonIntrinsics( + typeToIrFun: Map, + operator: KtSingleValueToken + ): List> = typeToIrFun.map { (type, irFunSymbol) -> irFunSymbol.toKey()!! to PrimitiveComparison(type, operator) } diff --git a/compiler/testData/codegen/box/reflection/enclosing/lambdaInLocalClassConstructor.kt b/compiler/testData/codegen/box/reflection/enclosing/lambdaInLocalClassConstructor.kt index bee01e5a309..8fdee638e4f 100644 --- a/compiler/testData/codegen/box/reflection/enclosing/lambdaInLocalClassConstructor.kt +++ b/compiler/testData/codegen/box/reflection/enclosing/lambdaInLocalClassConstructor.kt @@ -1,5 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_BACKEND: JVM_IR // WITH_REFLECT open class C diff --git a/compiler/testData/codegen/box/reflection/enclosing/lambdaInObjectExpression.kt b/compiler/testData/codegen/box/reflection/enclosing/lambdaInObjectExpression.kt index 3e4c30d6c02..2a05c7f56f3 100644 --- a/compiler/testData/codegen/box/reflection/enclosing/lambdaInObjectExpression.kt +++ b/compiler/testData/codegen/box/reflection/enclosing/lambdaInObjectExpression.kt @@ -1,5 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_BACKEND: JVM_IR // WITH_REFLECT interface C {