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
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;
}
@@ -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 {
@@ -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,
@@ -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<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 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])
}
}
@@ -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
@@ -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<IrType>
get() = (0 until typeArgumentsCount).map { getTypeArgument(it)!! }
companion object {
fun create(
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) ->
irFunSymbol.toKey()!! to PrimitiveComparison(type, operator)
}
@@ -1,5 +1,4 @@
// TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM_IR
// WITH_REFLECT
open class C
@@ -1,5 +1,4 @@
// TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM_IR
// WITH_REFLECT
interface C {