IR: Refactor primitive arrays handling in the new IrBuiltIns

for better compatibility e.g. with native
This commit is contained in:
Ilya Chernikov
2021-06-29 11:51:27 +02:00
committed by TeamCityServer
parent 3b2bb2ba9f
commit 48a3c64901
10 changed files with 47 additions and 26 deletions
@@ -150,11 +150,11 @@ abstract class Symbols<out T : CommonBackendContext>(
val doubleArrayType get() = doubleArray.owner.defaultType
val booleanArrayType get() = booleanArray.owner.defaultType
val primitiveArrays get() = irBuiltIns.primitiveArrays
val primitiveArrays get() = irBuiltIns.primitiveTypesToPrimitiveArrays
val primitiveArraysToPrimitiveTypes get() = irBuiltIns.primitiveArraysToPrimitiveTypes
val unsignedArrays get() = irBuiltIns.unsignedArrays
val unsignedArrays get() = irBuiltIns.unsignedTypesToUnsignedArrays
val arrays = primitiveArrays + unsignedArrays + array
val arrays = primitiveArrays.values + unsignedArrays.values + array
val collection get() = irBuiltIns.collectionClass
val set get() = irBuiltIns.setClass
@@ -50,7 +50,7 @@ private class ArrayConstructorTransformer(
return when {
irConstructor.valueParameters.size != 2 -> null
clazz == context.irBuiltIns.arrayClass -> context.ir.symbols.arrayOfNulls // Array<T> has no unary constructor: it can only exist for Array<T?>
context.irBuiltIns.primitiveArrays.contains(clazz) -> clazz.constructors.single { it.owner.valueParameters.size == 1 }
context.irBuiltIns.primitiveArraysToPrimitiveTypes.contains(clazz) -> clazz.constructors.single { it.owner.valueParameters.size == 1 }
else -> null
}
}
@@ -6,8 +6,8 @@
package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
@@ -210,7 +210,7 @@ class ES6AddInternalParametersToConstructorPhase(val context: JsIrBackendContext
}
private fun IrConstructor.hasStrictSignature(): Boolean {
val primitives = with(context.irBuiltIns) { primitiveArrays + stringClass }
val primitives = with(context.irBuiltIns) { primitiveTypesToPrimitiveArrays.values + stringClass }
return with(parentAsClass) { isExternal || isInline || symbol in primitives }
}
}
@@ -23,7 +23,10 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
import org.jetbrains.kotlin.ir.types.isAny
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.ir.util.statements
import org.jetbrains.kotlin.ir.util.transformInPlace
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.name.Name
@@ -376,7 +379,7 @@ class ES6ConstructorLowering(val context: JsIrBackendContext) : BodyLoweringPass
//util
private fun IrConstructor.hasStrictSignature(): Boolean {
val primitives = with(context.irBuiltIns) { primitiveArrays + stringClass }
val primitives = with(context.irBuiltIns) { primitiveTypesToPrimitiveArrays.values + stringClass }
return with(parentAsClass) { isExternal || isInline || symbol in primitives }
}
}
@@ -183,5 +183,5 @@ fun IrFunction.isInlineFunctionCall(context: JvmBackendContext) =
// Constructors can't be marked as inline in metadata, hence this hack.
private fun IrFunction.isInlineArrayConstructor(context: JvmBackendContext): Boolean =
this is IrConstructor && valueParameters.size == 2 && constructedClass.symbol.let {
it == context.irBuiltIns.arrayClass || it in context.irBuiltIns.primitiveArrays
it == context.irBuiltIns.arrayClass || it in context.irBuiltIns.primitiveArraysToPrimitiveTypes
}
@@ -128,7 +128,7 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
).toMap()
private fun intrinsicsThatShouldHaveBeenLowered() =
(symbols.primitiveArrays.map { primitiveClassSymbol ->
(symbols.primitiveArrays.map { (_, primitiveClassSymbol) ->
val name = primitiveClassSymbol.owner.name.asString()
// IntArray -> intArrayOf
val arrayOfFunName = name.decapitalizeAsciiOnly() + "Of"
@@ -48,15 +48,8 @@ import org.jetbrains.kotlin.types.checker.intersectTypes
import org.jetbrains.kotlin.types.typeUtil.isPrimitiveNumberType
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
import org.jetbrains.kotlin.types.typeUtil.makeNullable
import kotlin.collections.Map
import kotlin.collections.contains
import kotlin.collections.get
import kotlin.collections.listOf
import kotlin.collections.mapOf
import kotlin.collections.mapTo
import kotlin.collections.set
import kotlin.collections.toMap
import kotlin.collections.zip
class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
@@ -443,7 +436,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
return memberScope.findSingleFunction(Name.identifier("to$targetTypeName"))
}
private val primitiveTypeMapping = context.irBuiltInsOverDescriptors.run { primitiveTypes.zip(primitiveIrTypes).toMap() }
private val primitiveTypeMapping: Map<SimpleType, IrType> = context.irBuiltInsOverDescriptors.run { primitiveTypes.zip(primitiveIrTypes).toMap() }
private fun kotlinTypeToIrType(kotlinType: KotlinType?) = kotlinType?.let { primitiveTypeMapping[it] }
private fun generateComparisonOperator(ktExpression: KtBinaryExpression, origin: IrStatementOrigin): IrExpression {
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.ir
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.builtins.UnsignedType
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
@@ -109,11 +110,11 @@ abstract class IrBuiltIns {
abstract val booleanArray: IrClassSymbol
abstract val primitiveArraysToPrimitiveTypes: Map<IrClassSymbol, PrimitiveType>
abstract val primitiveArrays: Set<IrClassSymbol>
abstract val primitiveTypesToPrimitiveArrays: Map<PrimitiveType, IrClassSymbol>
abstract val primitiveArrayElementTypes: Map<IrClassSymbol, IrType?>
abstract val primitiveArrayForType: Map<IrType?, IrClassSymbol>
abstract val unsignedArrays: Set<IrClassSymbol>
abstract val unsignedTypesToUnsignedArrays: Map<UnsignedType, IrClassSymbol>
abstract val lessFunByOperandType: Map<IrClassifierSymbol, IrSimpleFunctionSymbol>
abstract val lessOrEqualFunByOperandType: Map<IrClassifierSymbol, IrSimpleFunctionSymbol>
@@ -157,8 +158,12 @@ abstract class IrBuiltIns {
abstract fun suspendFunctionN(arity: Int): IrClass
abstract fun kSuspendFunctionN(arity: Int): IrClass
// TODO: drop variants from segments, add helper from whole fqn
abstract fun findFunctions(name: Name, vararg packageNameSegments: String = arrayOf("kotlin")): Iterable<IrSimpleFunctionSymbol>
abstract fun findFunctions(name: Name, packageFqName: FqName): Iterable<IrSimpleFunctionSymbol>
abstract fun findClass(name: Name, vararg packageNameSegments: String = arrayOf("kotlin")): IrClassSymbol?
abstract fun findClass(name: Name, packageFqName: FqName): IrClassSymbol?
abstract fun findBuiltInClassMemberFunctions(builtInClass: IrClassSymbol, name: Name): Iterable<IrSimpleFunctionSymbol>
abstract fun getBinaryOperator(name: Name, lhsType: IrType, rhsType: IrType): IrSimpleFunctionSymbol
abstract fun getUnaryOperator(name: Name, receiverType: IrType): IrSimpleFunctionSymbol
@@ -325,7 +325,7 @@ class IrBuiltInsOverDescriptors(
)
// TODO switch to IrType
val primitiveTypes = listOf(bool, char, byte, short, int, float, long, double)
val primitiveTypes = listOf(bool, builtIns.charType, builtIns.byteType, short, int, float, long, double)
override val primitiveIrTypes = listOf(booleanType, charType, byteType, shortType, intType, floatType, longType, doubleType)
override val primitiveIrTypesWithComparisons = listOf(charType, byteType, shortType, intType, floatType, longType, doubleType)
override val primitiveFloatingPointIrTypes = listOf(floatType, doubleType)
@@ -340,12 +340,15 @@ class IrBuiltInsOverDescriptors(
override val booleanArray = builtIns.getPrimitiveArrayClassDescriptor(PrimitiveType.BOOLEAN).toIrSymbol()
override val primitiveArraysToPrimitiveTypes = PrimitiveType.values().associate { builtIns.getPrimitiveArrayClassDescriptor(it).toIrSymbol() to it }
override val primitiveArrays = primitiveArraysToPrimitiveTypes.keys
override val primitiveTypesToPrimitiveArrays = primitiveArraysToPrimitiveTypes.map { (k, v) -> v to k }.toMap()
override val primitiveArrayElementTypes = primitiveArraysToPrimitiveTypes.mapValues { primitiveTypeToIrType[it.value] }
override val primitiveArrayForType = primitiveArrayElementTypes.asSequence().associate { it.value to it.key }
override val unsignedArrays: Set<IrClassSymbol> = UnsignedType.values().mapNotNullTo(mutableSetOf()) { unsignedType ->
builtIns.builtInsModule.findClassAcrossModuleDependencies(unsignedType.arrayClassId)?.toIrSymbol()
override val unsignedTypesToUnsignedArrays: Map<UnsignedType, IrClassSymbol> by lazy {
UnsignedType.values().mapNotNull { unsignedType ->
val array = builtIns.builtInsModule.findClassAcrossModuleDependencies(unsignedType.arrayClassId)?.toIrSymbol()
if (array == null) null else unsignedType to array
}.toMap()
}
override val lessFunByOperandType = primitiveIrTypesWithComparisons.defineComparisonOperatorForEachIrType(BuiltInOperatorNames.LESS)
@@ -409,12 +412,28 @@ class IrBuiltInsOverDescriptors(
symbolTable.referenceSimpleFunction(it)
}
override fun findFunctions(name: Name, packageFqName: FqName): Iterable<IrSimpleFunctionSymbol> =
builtIns.builtInsModule.getPackage(packageFqName).memberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND).map {
symbolTable.referenceSimpleFunction(it)
}
override fun findClass(name: Name, vararg packageNameSegments: String): IrClassSymbol? =
(builtInsPackage(*packageNameSegments).getContributedClassifier(
name,
NoLookupLocation.FROM_BACKEND
) as? ClassDescriptor)?.let { symbolTable.referenceClass(it) }
override fun findClass(name: Name, packageFqName: FqName): IrClassSymbol? =
(builtIns.builtInsModule.getPackage(packageFqName).memberScope.getContributedClassifier(
name,
NoLookupLocation.FROM_BACKEND
) as? ClassDescriptor)?.let { symbolTable.referenceClass(it) }
override fun findBuiltInClassMemberFunctions(builtInClass: IrClassSymbol, name: Name): Iterable<IrSimpleFunctionSymbol> =
builtInClass.descriptor.unsubstitutedMemberScope
.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND)
.map { symbolTable.referenceSimpleFunction(it) }
private val binaryOperatorCache = mutableMapOf<Triple<Name, IrType, IrType>, IrSimpleFunctionSymbol>()
override fun getBinaryOperator(name: Name, lhsType: IrType, rhsType: IrType): IrSimpleFunctionSymbol {
@@ -504,7 +523,7 @@ class IrBuiltInsOverDescriptors(
override fun suspendFunctionN(arity: Int): IrClass = functionFactory.suspendFunctionN(arity)
override fun kSuspendFunctionN(arity: Int): IrClass = functionFactory.kSuspendFunctionN(arity)
override val getProgressionLastElementByReturnType: Map<IrClassifierSymbol?, IrSimpleFunctionSymbol> =
override val getProgressionLastElementByReturnType: Map<IrClassifierSymbol?, IrSimpleFunctionSymbol> by lazy {
builtInsPackage("kotlin", "internal")
.getContributedFunctions(Name.identifier("getProgressionLastElement"), NoLookupLocation.FROM_BACKEND)
.filter { it.containingDeclaration !is BuiltInsPackageFragment }
@@ -514,6 +533,7 @@ class IrBuiltInsOverDescriptors(
klass to function
}
.toMap()
}
}
private inline fun MemberScope.findFirstFunction(name: String, predicate: (CallableMemberDescriptor) -> Boolean) =
@@ -240,7 +240,7 @@ abstract class DataClassMembersGenerator(
getIrProperty(property).backingField!!
val IrClassifierSymbol?.isArrayOrPrimitiveArray: Boolean
get() = this == context.irBuiltIns.arrayClass || this in context.irBuiltIns.primitiveArrays
get() = this == context.irBuiltIns.arrayClass || this in context.irBuiltIns.primitiveArraysToPrimitiveTypes
abstract fun declareSimpleFunction(startOffset: Int, endOffset: Int, functionDescriptor: FunctionDescriptor): IrFunction