JVM IR: reduce usages of IrTypeMapper.kotlinTypeMapper

This commit is contained in:
Alexander Udalov
2019-08-06 06:11:58 +02:00
parent 0c6ab69b52
commit f64afbf152
9 changed files with 39 additions and 45 deletions
@@ -236,7 +236,7 @@ public class AsmUtil {
} }
@Nullable @Nullable
private static Type boxPrimitiveType(@NotNull Type type) { public static Type boxPrimitiveType(@NotNull Type type) {
JvmPrimitiveType jvmPrimitiveType = primitiveTypeByAsmSort.get(type.getSort()); JvmPrimitiveType jvmPrimitiveType = primitiveTypeByAsmSort.get(type.getSort());
return jvmPrimitiveType != null ? asmTypeByFqNameWithoutInnerClasses(jvmPrimitiveType.getWrapperFqName()) : null; return jvmPrimitiveType != null ? asmTypeByFqNameWithoutInnerClasses(jvmPrimitiveType.getWrapperFqName()) : null;
} }
@@ -237,7 +237,7 @@ class ExpressionCodegen(
val name = if (param.origin == BOUND_RECEIVER_PARAMETER || isReceiver) { val name = if (param.origin == BOUND_RECEIVER_PARAMETER || isReceiver) {
getNameForReceiverParameter( getNameForReceiverParameter(
irFunction.descriptor, irFunction.descriptor,
typeMapper.kotlinTypeMapper.bindingContext, state.bindingContext,
context.configuration.languageVersionSettings context.configuration.languageVersionSettings
) )
} else { } else {
@@ -35,9 +35,6 @@ class IrTypeMapper(private val context: JvmBackendContext) {
val kotlinTypeMapper: KotlinTypeMapper = context.state.typeMapper val kotlinTypeMapper: KotlinTypeMapper = context.state.typeMapper
private val typeSystem = IrTypeCheckerContext(context.irBuiltIns) private val typeSystem = IrTypeCheckerContext(context.irBuiltIns)
val classBuilderMode: ClassBuilderMode
get() = kotlinTypeMapper.classBuilderMode
fun classInternalName(irClass: IrClass): String = fun classInternalName(irClass: IrClass): String =
context.getLocalClassInfo(irClass)?.internalName context.getLocalClassInfo(irClass)?.internalName
?: JvmCodegenUtil.sanitizeNameIfNeeded(computeInternalName(irClass), context.state.languageVersionSettings) ?: JvmCodegenUtil.sanitizeNameIfNeeded(computeInternalName(irClass), context.state.languageVersionSettings)
@@ -53,8 +50,14 @@ class IrTypeMapper(private val context: JvmBackendContext) {
} }
} }
fun boxType(irType: IrType): Type = fun boxType(irType: IrType): Type {
AsmUtil.boxType(mapType(irType), irType.toKotlinType(), kotlinTypeMapper) val irClass = irType.classOrNull?.owner
if (irClass != null && irClass.isInline) {
return mapTypeAsDeclaration(irType)
}
val type = mapType(irType)
return AsmUtil.boxPrimitiveType(type) ?: type
}
fun mapType( fun mapType(
type: IrType, type: IrType,
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.load.java.JavaVisibilities 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.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils 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.JvmMethodParameterKind
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.resolve.source.PsiSourceElement import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.org.objectweb.asm.MethodVisitor import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.Opcodes 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) { fun writeInnerClass(innerClass: IrClass, typeMapper: IrTypeMapper, context: JvmBackendContext, v: ClassBuilder) {
val outerClassInternalName = innerClass.parent.safeAs<IrClass>()?.let { typeMapper.classInternalName(it) } val outerClassInternalName = innerClass.parent.safeAs<IrClass>()?.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<ClassDescriptor>()?.let {
typeMapper.kotlinTypeMapper.classInternalName(it)
}
val innerName = innerClass.name.takeUnless { it.isSpecial }?.asString() val innerName = innerClass.name.takeUnless { it.isSpecial }?.asString()
val innerClassInternalName = typeMapper.classInternalName(innerClass) 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 */ /* Borrowed with modifications from AsmUtil.java */
@@ -379,22 +375,9 @@ internal fun getSignature(
sw.writeInterface() sw.writeInterface()
val jvmInterfaceType = typeMapper.mapSupertype(superType, sw) val jvmInterfaceType = typeMapper.mapSupertype(superType, sw)
sw.writeInterfaceEnd() sw.writeInterfaceEnd()
val jvmInterfaceInternalName = jvmInterfaceType.internalName
superInterfaces.add(jvmInterfaceInternalName) superInterfaces.add(jvmInterfaceType.internalName)
kotlinMarkerInterfaces.addIfNotNull(KOTLIN_MARKER_INTERFACES[kotlinInterfaceName])
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)
}
} }
} }
@@ -19,12 +19,14 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics
import com.intellij.psi.tree.IElementType import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.codegen.* 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.AsmUtil.comparisonOperandType
import org.jetbrains.kotlin.codegen.BranchedValue import org.jetbrains.kotlin.codegen.BranchedValue
import org.jetbrains.kotlin.codegen.NumberCompare import org.jetbrains.kotlin.codegen.NumberCompare
import org.jetbrains.kotlin.codegen.ObjectCompare import org.jetbrains.kotlin.codegen.ObjectCompare
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.lexer.KtSingleValueToken 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.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Label
@@ -87,7 +89,7 @@ class PrimitiveComparison(
private val operatorToken: KtSingleValueToken private val operatorToken: KtSingleValueToken
) : IntrinsicMethod() { ) : IntrinsicMethod() {
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? { 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 (left, right) = expression.receiverAndArgs()
val a = left.accept(codegen, data).coerce(parameterType, left.type).materialized val a = left.accept(codegen, data).coerce(parameterType, left.type).materialized
val b = right.accept(codegen, data).coerce(parameterType, right.type).materialized val b = right.accept(codegen, data).coerce(parameterType, right.type).materialized
@@ -13,7 +13,10 @@ import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression 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.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
@@ -65,27 +68,26 @@ open class IrIntrinsicFunction(
return StackValue.onStack(genInvokeInstructionWithResult(v)) return StackValue.onStack(genInvokeInstructionWithResult(v))
} }
fun loadArguments( private fun loadArguments(codegen: ExpressionCodegen, data: BlockInfo) {
codegen: ExpressionCodegen,
data: BlockInfo
) {
var offset = 0 var offset = 0
expression.dispatchReceiver?.let { genArg(it, codegen, offset++, data) } expression.dispatchReceiver?.let { genArg(it, codegen, offset++, data) }
expression.extensionReceiver?.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) val argument = expression.getValueArgument(i)
when { when {
argument != null -> argument != null ->
genArg(argument, codegen, i + offset, data) genArg(argument, codegen, i + offset, data)
descriptor.isVararg -> { valueParameter.isVararg -> {
val parameterType = codegen.typeMapper.kotlinTypeMapper.mapType(descriptor.type) // TODO: is there an easier way to get the substituted type of an empty vararg argument?
StackValue.operation(parameterType) { val arrayType = codegen.typeMapper.mapType(
valueParameter.type.substitute(expression.symbol.owner.typeParameters, expression.typeArguments)
)
StackValue.operation(arrayType) {
it.aconst(0) it.aconst(0)
it.newarray(AsmUtil.correctElementType(parameterType)) it.newarray(AsmUtil.correctElementType(arrayType))
}.put(parameterType, codegen.mv) }.put(arrayType, codegen.mv)
} }
else -> else -> error("Unknown parameter ${valueParameter.name} in: ${expression.dump()}")
error("Unknown parameter: $descriptor in $expression")
} }
} }
} }
@@ -94,6 +96,9 @@ open class IrIntrinsicFunction(
codegen.gen(expression, argsTypes[index], expression.type, data) codegen.gen(expression, argsTypes[index], expression.type, data)
} }
private val IrFunctionAccessExpression.typeArguments: List<IrType>
get() = (0 until typeArgumentsCount).map { getTypeArgument(it)!! }
companion object { companion object {
fun create( fun create(
expression: IrFunctionAccessExpression, expression: IrFunctionAccessExpression,
@@ -245,7 +245,10 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
} }
private fun primitiveComparisonIntrinsics(typeToIrFun: Map<SimpleType, IrSimpleFunctionSymbol>, operator: KtSingleValueToken) = private fun primitiveComparisonIntrinsics(
typeToIrFun: Map<SimpleType, IrSimpleFunctionSymbol>,
operator: KtSingleValueToken
): List<Pair<Key, PrimitiveComparison>> =
typeToIrFun.map { (type, irFunSymbol) -> typeToIrFun.map { (type, irFunSymbol) ->
irFunSymbol.toKey()!! to PrimitiveComparison(type, operator) irFunSymbol.toKey()!! to PrimitiveComparison(type, operator)
} }
@@ -1,5 +1,4 @@
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM_IR
// WITH_REFLECT // WITH_REFLECT
open class C open class C
@@ -1,5 +1,4 @@
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM_IR
// WITH_REFLECT // WITH_REFLECT
interface C { interface C {