[IR] Refactor ir infrastructure

- Remove range-based uniq id indexes using to link built ins
 - Limit KotlinType usages, replace them with corresponding IrType
This commit is contained in:
Roman Artemev
2019-10-28 10:50:15 +03:00
committed by romanart
parent 90d07eee53
commit a343a57207
22 changed files with 409 additions and 232 deletions
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl
import org.jetbrains.kotlin.ir.types.makeNullable
@@ -1144,21 +1145,22 @@ class Fir2IrVisitor(
}
// TODO: it's temporary hack which should be refactored
val simpleType = when (val classId = (firstType.type as? ConeClassLikeType)?.lookupTag?.classId) {
ClassId(FqName("kotlin"), FqName("Long"), false) -> irBuiltIns.builtIns.longType
ClassId(FqName("kotlin"), FqName("Int"), false) -> irBuiltIns.builtIns.intType
ClassId(FqName("kotlin"), FqName("Float"), false) -> irBuiltIns.builtIns.floatType
ClassId(FqName("kotlin"), FqName("Double"), false) -> irBuiltIns.builtIns.doubleType
ClassId(FqName("kotlin"), FqName("Long"), false) -> irBuiltIns.longType
ClassId(FqName("kotlin"), FqName("Int"), false) -> irBuiltIns.intType
ClassId(FqName("kotlin"), FqName("Float"), false) -> irBuiltIns.floatType
ClassId(FqName("kotlin"), FqName("Double"), false) -> irBuiltIns.doubleType
else -> {
return IrErrorCallExpressionImpl(
startOffset, endOffset, booleanType, "Comparison of arguments with unsupported type: $classId"
)
}
}
val classifier = simpleType.classifierOrFail
val (symbol, origin) = when (operation) {
FirOperation.LT -> irBuiltIns.lessFunByOperandType[simpleType] to IrStatementOrigin.LT
FirOperation.GT -> irBuiltIns.greaterFunByOperandType[simpleType] to IrStatementOrigin.GT
FirOperation.LT_EQ -> irBuiltIns.lessOrEqualFunByOperandType[simpleType] to IrStatementOrigin.LTEQ
FirOperation.GT_EQ -> irBuiltIns.greaterOrEqualFunByOperandType[simpleType] to IrStatementOrigin.GTEQ
FirOperation.LT -> irBuiltIns.lessFunByOperandType[classifier] to IrStatementOrigin.LT
FirOperation.GT -> irBuiltIns.greaterFunByOperandType[classifier] to IrStatementOrigin.GT
FirOperation.LT_EQ -> irBuiltIns.lessOrEqualFunByOperandType[classifier] to IrStatementOrigin.LTEQ
FirOperation.GT_EQ -> irBuiltIns.greaterOrEqualFunByOperandType[classifier] to IrStatementOrigin.GTEQ
else -> throw AssertionError("Unexpected comparison operation: $operation")
}
return primitiveOp2(startOffset, endOffset, symbol!!, booleanType, origin, first.toIrExpression(), second.toIrExpression())
@@ -18,8 +18,8 @@ import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.copyTypeArgumentsFrom
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.types.getClass
import org.jetbrains.kotlin.ir.types.toKotlinType
import org.jetbrains.kotlin.ir.util.constructedClass
import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.ir.util.functions
@@ -78,7 +78,7 @@ class ArrayConstructorLowering(val context: CommonBackendContext) : IrElementTra
val invoke = invokable.type.getClass()!!.functions.single { it.name == OperatorNameConventions.INVOKE }
val invokableVar = if (lambda == null) irTemporary(invokable) else null
+irWhile().apply {
condition = irCall(context.irBuiltIns.lessFunByOperandType[index.type.toKotlinType()]!!).apply {
condition = irCall(context.irBuiltIns.lessFunByOperandType[index.type.classifierOrFail]!!).apply {
putValueArgument(0, irGet(index))
putValueArgument(1, irGet(sizeVar))
}
@@ -78,10 +78,10 @@ internal sealed class ForLoopHeader(
with(builder) {
val builtIns = context.irBuiltIns
val progressionType = headerInfo.progressionType
val progressionKotlinType = progressionType.elementType(builtIns).toKotlinType()
val progressionElementType = progressionType.elementType(builtIns)
val compFun =
if (isLastInclusive) builtIns.lessOrEqualFunByOperandType[progressionKotlinType]!!
else builtIns.lessFunByOperandType[progressionKotlinType]!!
if (isLastInclusive) builtIns.lessOrEqualFunByOperandType[progressionElementType.classifierOrFail]!!
else builtIns.lessFunByOperandType[progressionElementType.classifierOrFail]!!
// The default condition depends on the direction.
when (headerInfo.direction) {
@@ -101,11 +101,11 @@ internal sealed class ForLoopHeader(
// If the direction is unknown, we check depending on the "step" value:
// // (use `<` if last is exclusive)
// (step > 0 && inductionVar <= last) || (step < 0 || last <= inductionVar)
val stepKotlinType = progressionType.stepType(builtIns).toKotlinType()
val stepType = progressionType.stepType(builtIns)
val isLong = progressionType == ProgressionType.LONG_PROGRESSION
context.oror(
context.andand(
irCall(builtIns.greaterFunByOperandType[stepKotlinType]!!).apply {
irCall(builtIns.greaterFunByOperandType[stepType.classifierOrFail]!!).apply {
putValueArgument(0, irGet(step))
putValueArgument(1, if (isLong) irLong(0) else irInt(0))
},
@@ -114,7 +114,7 @@ internal sealed class ForLoopHeader(
putValueArgument(1, lastExpression)
}),
context.andand(
irCall(builtIns.lessFunByOperandType[stepKotlinType]!!).apply {
irCall(builtIns.lessFunByOperandType[stepType.classifierOrFail]!!).apply {
putValueArgument(0, irGet(step))
putValueArgument(1, if (isLong) irLong(0) else irInt(0))
},
@@ -257,7 +257,7 @@ internal class StepHandler(
//
// We insert this check in the lowered form only if necessary.
val stepType = data.stepType(context.irBuiltIns)
val stepGreaterFun = context.irBuiltIns.greaterFunByOperandType[stepType.toKotlinType()]!!
val stepGreaterFun = context.irBuiltIns.greaterFunByOperandType[stepType.classifierOrFail]!!
val zeroStep = if (data == ProgressionType.LONG_PROGRESSION) irLong(0) else irInt(0)
val throwIllegalStepExceptionCall = {
irCall(context.irBuiltIns.illegalArgumentExceptionSymbol).apply {
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.impl.IrExternalPackageFragmentSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.ir.types.isLong
import org.jetbrains.kotlin.ir.util.constructors
@@ -92,7 +93,7 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
// Type checks:
val jsInstanceOf = binOpBool("jsInstanceOf")
val jsTypeOf = unOp("jsTypeOf", irBuiltIns.string)
val jsTypeOf = unOp("jsTypeOf", irBuiltIns.stringType)
// Number conversions:
@@ -336,18 +337,18 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
}
}
private fun unOp(name: String, returnType: KotlinType = irBuiltIns.anyN) =
irBuiltIns.run { defineOperator(name, returnType, listOf(anyN)) }
private fun unOp(name: String, returnType: IrType = irBuiltIns.anyNType) =
irBuiltIns.run { defineOperator(name, returnType, listOf(anyNType)) }
private fun unOpBool(name: String) = unOp(name, irBuiltIns.bool)
private fun unOpInt(name: String) = unOp(name, irBuiltIns.int)
private fun unOpBool(name: String) = unOp(name, irBuiltIns.booleanType)
private fun unOpInt(name: String) = unOp(name, irBuiltIns.intType)
private fun binOp(name: String, returnType: KotlinType = irBuiltIns.anyN) =
irBuiltIns.run { defineOperator(name, returnType, listOf(anyN, anyN)) }
private fun binOp(name: String, returnType: IrType = irBuiltIns.anyNType) =
irBuiltIns.run { defineOperator(name, returnType, listOf(anyNType, anyNType)) }
private fun tripleOp(name: String, returnType: KotlinType = irBuiltIns.anyN) =
irBuiltIns.run { defineOperator(name, returnType, listOf(anyN, anyN, anyN)) }
private fun tripleOp(name: String, returnType: IrType = irBuiltIns.anyNType) =
irBuiltIns.run { defineOperator(name, returnType, listOf(anyNType, anyNType, anyNType)) }
private fun binOpBool(name: String) = binOp(name, irBuiltIns.bool)
private fun binOpInt(name: String) = binOp(name, irBuiltIns.int)
private fun binOpBool(name: String) = binOp(name, irBuiltIns.booleanType)
private fun binOpInt(name: String) = binOp(name, irBuiltIns.intType)
}
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.ir.backend.js.lower.calls
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.irCall
@@ -16,13 +17,13 @@ import org.jetbrains.kotlin.types.SimpleType
typealias SymbolToTransformer = MutableMap<IrFunctionSymbol, (IrFunctionAccessExpression) -> IrExpression>
internal fun SymbolToTransformer.add(from: Map<SimpleType, IrFunctionSymbol>, to: IrFunctionSymbol) {
internal fun SymbolToTransformer.add(from: Map<IrClassifierSymbol, IrFunctionSymbol>, to: IrFunctionSymbol) {
from.forEach { _, func ->
add(func, to)
}
}
internal fun SymbolToTransformer.add(from: Map<SimpleType, IrFunctionSymbol>, to: (IrFunctionAccessExpression) -> IrExpression) {
internal fun SymbolToTransformer.add(from: Map<IrClassifierSymbol, IrFunctionSymbol>, to: (IrFunctionAccessExpression) -> IrExpression) {
from.forEach { _, func ->
add(func, to)
}
@@ -34,15 +34,15 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls
add(irBuiltIns.booleanNotSymbol, intrinsics.jsNot)
add(irBuiltIns.lessFunByOperandType.filterKeys { it != irBuiltIns.long }, intrinsics.jsLt)
add(irBuiltIns.lessOrEqualFunByOperandType.filterKeys { it != irBuiltIns.long }, intrinsics.jsLtEq)
add(irBuiltIns.greaterFunByOperandType.filterKeys { it != irBuiltIns.long }, intrinsics.jsGt)
add(irBuiltIns.greaterOrEqualFunByOperandType.filterKeys { it != irBuiltIns.long }, intrinsics.jsGtEq)
add(irBuiltIns.lessFunByOperandType.filterKeys { it != irBuiltIns.longClass }, intrinsics.jsLt)
add(irBuiltIns.lessOrEqualFunByOperandType.filterKeys { it != irBuiltIns.longClass }, intrinsics.jsLtEq)
add(irBuiltIns.greaterFunByOperandType.filterKeys { it != irBuiltIns.longClass }, intrinsics.jsGt)
add(irBuiltIns.greaterOrEqualFunByOperandType.filterKeys { it != irBuiltIns.longClass }, intrinsics.jsGtEq)
add(irBuiltIns.lessFunByOperandType[irBuiltIns.long]!!, transformLongComparison(intrinsics.jsLt))
add(irBuiltIns.lessOrEqualFunByOperandType[irBuiltIns.long]!!, transformLongComparison(intrinsics.jsLtEq))
add(irBuiltIns.greaterFunByOperandType[irBuiltIns.long]!!, transformLongComparison(intrinsics.jsGt))
add(irBuiltIns.greaterOrEqualFunByOperandType[irBuiltIns.long]!!, transformLongComparison(intrinsics.jsGtEq))
add(irBuiltIns.lessFunByOperandType[irBuiltIns.longClass]!!, transformLongComparison(intrinsics.jsLt))
add(irBuiltIns.lessOrEqualFunByOperandType[irBuiltIns.longClass]!!, transformLongComparison(intrinsics.jsLtEq))
add(irBuiltIns.greaterFunByOperandType[irBuiltIns.longClass]!!, transformLongComparison(intrinsics.jsGt))
add(irBuiltIns.greaterOrEqualFunByOperandType[irBuiltIns.longClass]!!, transformLongComparison(intrinsics.jsGtEq))
}
}
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.lexer.KtSingleValueToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.org.objectweb.asm.Opcodes.*
import org.jetbrains.org.objectweb.asm.Type
@@ -81,8 +80,8 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
) to Clone,
irBuiltIns.eqeqSymbol.toKey()!! to Equals(KtTokens.EQEQ),
irBuiltIns.eqeqeqSymbol.toKey()!! to Equals(KtTokens.EQEQEQ),
irBuiltIns.ieee754equalsFunByOperandType[irBuiltIns.float]!!.toKey()!! to Ieee754Equals(Type.FLOAT_TYPE),
irBuiltIns.ieee754equalsFunByOperandType[irBuiltIns.double]!!.toKey()!! to Ieee754Equals(Type.DOUBLE_TYPE),
irBuiltIns.ieee754equalsFunByOperandType[irBuiltIns.floatClass]!!.toKey()!! to Ieee754Equals(Type.FLOAT_TYPE),
irBuiltIns.ieee754equalsFunByOperandType[irBuiltIns.doubleClass]!!.toKey()!! to Ieee754Equals(Type.DOUBLE_TYPE),
irBuiltIns.booleanNotSymbol.toKey()!! to Not,
irBuiltIns.enumValueOfSymbol.toKey()!! to IrEnumValueOf,
irBuiltIns.noWhenBranchMatchedExceptionSymbol.toKey()!! to IrNoWhenBranchMatchedException,
@@ -240,11 +239,11 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
private fun primitiveComparisonIntrinsics(
typeToIrFun: Map<SimpleType, IrSimpleFunctionSymbol>,
typeToIrFun: Map<IrClassifierSymbol, IrSimpleFunctionSymbol>,
operator: KtSingleValueToken
): List<Pair<Key, PrimitiveComparison>> =
typeToIrFun.map { (type, irFunSymbol) ->
irFunSymbol.toKey()!! to PrimitiveComparison(type, operator)
irFunSymbol.toKey()!! to PrimitiveComparison(type.descriptor.defaultType, operator)
}
}
}
@@ -12,7 +12,9 @@ import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -70,13 +72,13 @@ class WasmSymbols(
context.irBuiltIns.doubleType to getInternalFunction("wasm_f64_eq")
)
private fun wasmString(simpleType: SimpleType): String = with(context.irBuiltIns) {
when (simpleType) {
bool, byte, short, char, int -> "i32"
float -> "f32"
double -> "f64"
long -> "i64"
else -> error("Unkonow primitive type")
private fun wasmString(classfier: IrClassifierSymbol): String = with(context.irBuiltIns) {
when (classfier) {
booleanClass, byteClass, shortClass, charClass, intClass -> "i32"
floatClass -> "f32"
doubleClass -> "f64"
longClass -> "i64"
else -> error("Unknown primitive type")
}
}
@@ -204,7 +204,7 @@ class DataClassMembersGenerator(
when (val typeConstructorDescriptor = type.constructor.declarationDescriptor) {
is ClassDescriptor ->
if (KotlinBuiltIns.isArrayOrPrimitiveArray(typeConstructorDescriptor))
context.irBuiltIns.dataClassArrayMemberHashCodeSymbol.descriptor
context.irBuiltIns.dataClassArrayMemberHashCode
else
type.memberScope.findFirstFunction("hashCode") { it.valueParameters.isEmpty() }
@@ -24,6 +24,9 @@ import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
import org.jetbrains.kotlin.ir.types.makeNotNull
import org.jetbrains.kotlin.ir.util.referenceFunction
@@ -316,7 +319,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
val comparisonInfo = getPrimitiveNumericComparisonInfo(expression)
val comparisonType = comparisonInfo?.comparisonType
val eqeqSymbol = context.irBuiltIns.ieee754equalsFunByOperandType[comparisonType] ?: context.irBuiltIns.eqeqSymbol
val eqeqSymbol = context.irBuiltIns.ieee754equalsFunByOperandType[kotlinTypeToIrType(comparisonType)?.classifierOrNull] ?: context.irBuiltIns.eqeqSymbol
val irEquals = primitiveOp2(
expression.startOffsetSkippingComments, expression.endOffset,
@@ -354,7 +357,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
if (comparisonInfo != null) {
val comparisonType = comparisonInfo.comparisonType
val eqeqSymbol =
context.irBuiltIns.ieee754equalsFunByOperandType[comparisonType] ?: context.irBuiltIns.eqeqSymbol
context.irBuiltIns.ieee754equalsFunByOperandType[kotlinTypeToIrType(comparisonType)?.classifierOrNull] ?: context.irBuiltIns.eqeqSymbol
primitiveOp2(
startOffset, endOffset,
eqeqSymbol,
@@ -432,6 +435,9 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
return memberScope.findSingleFunction(Name.identifier("to$targetTypeName"))
}
private val primitiveTypeMapping = context.irBuiltIns.run { primitiveTypes.zip(primitiveIrTypes).toMap() }
private fun kotlinTypeToIrType(kotlinType: KotlinType?) = kotlinType?.let { primitiveTypeMapping[it] }
private fun generateComparisonOperator(ktExpression: KtBinaryExpression, origin: IrStatementOrigin): IrExpression {
if (isDynamicBinaryOperator(ktExpression)) return generateDynamicBinaryExpression(ktExpression)
@@ -444,9 +450,10 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
val ktRight = ktExpression.right ?: throw AssertionError("No RHS in ${ktExpression.text}")
return if (comparisonInfo != null) {
val comparisonType = comparisonInfo.comparisonType
primitiveOp2(
startOffset, endOffset,
getComparisonOperatorSymbol(origin, comparisonInfo.comparisonType),
getComparisonOperatorSymbol(origin, kotlinTypeToIrType(comparisonType) ?: error("$comparisonType expected to be primitive")),
context.irBuiltIns.booleanType,
origin,
ktLeft.generateAsPrimitiveNumericComparisonOperand(comparisonInfo.leftType, comparisonInfo.comparisonType),
@@ -458,7 +465,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
primitiveOp2(
startOffset, endOffset,
getComparisonOperatorSymbol(origin, context.irBuiltIns.int),
getComparisonOperatorSymbol(origin, context.irBuiltIns.intType),
context.irBuiltIns.booleanType,
origin,
generateCall(resolvedCall, ktExpression, origin),
@@ -474,14 +481,14 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
) =
CallGenerator(statementGenerator).generateCall(ktExpression, statementGenerator.pregenerateCall(resolvedCall), origin)
private fun getComparisonOperatorSymbol(origin: IrStatementOrigin, primitiveNumericType: KotlinType): IrSimpleFunctionSymbol =
private fun getComparisonOperatorSymbol(origin: IrStatementOrigin, primitiveNumericType: IrType): IrSimpleFunctionSymbol =
when (origin) {
IrStatementOrigin.LT -> context.irBuiltIns.lessFunByOperandType
IrStatementOrigin.LTEQ -> context.irBuiltIns.lessOrEqualFunByOperandType
IrStatementOrigin.GT -> context.irBuiltIns.greaterFunByOperandType
IrStatementOrigin.GTEQ -> context.irBuiltIns.greaterOrEqualFunByOperandType
else -> throw AssertionError("Unexpected comparison operator: $origin")
}[primitiveNumericType]!!
}[primitiveNumericType.classifierOrFail]!!
private fun generateExclExclOperator(expression: KtPostfixExpression, origin: IrStatementOrigin): IrExpression {
val ktArgument = expression.baseExpression!!
@@ -5,6 +5,8 @@
package org.jetbrains.kotlin.ir.descriptors
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.descriptors.*
@@ -13,18 +15,25 @@ import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeBuilder
import org.jetbrains.kotlin.ir.types.impl.buildSimpleType
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
import org.jetbrains.kotlin.ir.types.makeNullable
import org.jetbrains.kotlin.ir.types.withHasQuestionMark
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.TypeTranslator
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.makeNullable
class IrBuiltIns(
val builtIns: KotlinBuiltIns,
@@ -35,34 +44,179 @@ class IrBuiltIns(
private val builtInsModule = builtIns.builtInsModule
private val packageFragment = IrBuiltinsPackageFragmentDescriptorImpl(builtInsModule, KOTLIN_INTERNAL_IR_FQN)
val irBuiltInsSymbols = mutableListOf<IrSimpleFunctionSymbol>()
val irBuiltInsSymbols = mutableListOf<IrBuiltinWithMangle>()
private val symbolTable = outerSymbolTable ?: SymbolTable()
private val packageFragmentDescriptor = IrBuiltinsPackageFragmentDescriptorImpl(builtInsModule, KOTLIN_INTERNAL_IR_FQN)
private val packageFragment =
IrExternalPackageFragmentImpl(symbolTable.referenceExternalPackageFragment(packageFragmentDescriptor), KOTLIN_INTERNAL_IR_FQN)
private fun ClassDescriptor.toIrSymbol() = symbolTable.referenceClass(this)
private fun KotlinType.toIrType() = typeTranslator.translateType(this)
fun defineOperator(name: String, returnType: KotlinType, valueParameterTypes: List<KotlinType>): IrSimpleFunctionSymbol {
val operatorDescriptor = IrSimpleBuiltinOperatorDescriptorImpl(packageFragment, Name.identifier(name), returnType)
for ((i, valueParameterType) in valueParameterTypes.withIndex()) {
operatorDescriptor.addValueParameter(
IrBuiltinValueParameterDescriptorImpl(operatorDescriptor, Name.identifier("arg$i"), i, valueParameterType)
)
fun defineOperator(name: String, returnType: IrType, valueParameterTypes: List<IrType>): IrSimpleFunctionSymbol {
val descriptor = WrappedSimpleFunctionDescriptor()
val symbol = symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, BUILTIN_OPERATOR, descriptor) {
val suffix = valueParameterTypes.joinToString(":", "[", "]") { t -> t.originalKotlinType?.toString() ?: "T" }
val operator = IrBuiltInOperator(it, Name.identifier(name), returnType, suffix)
operator.parent = packageFragment
packageFragment.declarations += operator
descriptor.bind(operator)
valueParameterTypes.mapIndexedTo(operator.valueParameters) { i, t ->
val valueParameterDescriptor = WrappedValueParameterDescriptor()
val valueParameterSymbol = IrValueParameterSymbolImpl(valueParameterDescriptor)
IrBuiltInOperatorValueParameter(valueParameterSymbol, i, t).apply {
valueParameterDescriptor.bind(this)
parent = operator
}
}
irBuiltInsSymbols += operator
operator
}
return operatorDescriptor.addStub()
return symbol.symbol
}
private fun <T : SimpleFunctionDescriptor> T.addStub(): IrSimpleFunctionSymbol =
symbolTable.referenceSimpleFunction(this).also {
irBuiltInsSymbols += it
private fun defineEnumValueOfOperator(): IrSimpleFunctionSymbol {
val name = Name.identifier("enumValueOf")
val typeParameterDescriptor: TypeParameterDescriptor
val valueParameterDescriptor: ValueParameterDescriptor
val descriptor = SimpleFunctionDescriptorImpl.create(
packageFragmentDescriptor,
Annotations.EMPTY,
name,
CallableMemberDescriptor.Kind.SYNTHESIZED,
SourceElement.NO_SOURCE
).apply {
typeParameterDescriptor = TypeParameterDescriptorImpl.createWithDefaultBound(
this, Annotations.EMPTY, true, Variance.INVARIANT, Name.identifier("T0"), 0
)
valueParameterDescriptor = ValueParameterDescriptorImpl(
this, null, 0, Annotations.EMPTY, Name.identifier("arg0"), string,
false, false, false, null, SourceElement.NO_SOURCE
)
val returnType = typeParameterDescriptor.typeConstructor.makeNonNullType()
initialize(null, null, listOf(typeParameterDescriptor), listOf(valueParameterDescriptor), returnType, Modality.FINAL, Visibilities.PUBLIC)
}
private fun defineComparisonOperator(name: String, operandType: KotlinType) =
defineOperator(name, bool, listOf(operandType, operandType))
val returnKotlinType = descriptor.returnType
val typeParameterSymbol = IrTypeParameterSymbolImpl(typeParameterDescriptor)
val typeParameter = IrBuiltInOperatorTypeParameter(typeParameterSymbol, Variance.INVARIANT, 0, true).apply {
superTypes += anyNType
}
private fun List<SimpleType>.defineComparisonOperatorForEachType(name: String) =
associate { it to defineComparisonOperator(name, it) }
val returnIrType = IrSimpleTypeBuilder().run {
classifier = typeParameterSymbol
kotlinType = returnKotlinType
buildSimpleType()
}
return symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, BUILTIN_OPERATOR, descriptor) {
val operator = IrBuiltInOperator(it, name, returnIrType, ":enum")
operator.parent = packageFragment
packageFragment.declarations += operator
val valueParameterSymbol = IrValueParameterSymbolImpl(valueParameterDescriptor)
val valueParameter = IrBuiltInOperatorValueParameter(valueParameterSymbol, 0, stringType)
valueParameter.parent = operator
typeParameter.parent = operator
operator.valueParameters += valueParameter
operator.typeParameters += typeParameter
irBuiltInsSymbols += operator
operator
}.symbol
}
private fun defineCheckNotNullOperator(): IrSimpleFunctionSymbol {
val name = Name.identifier("CHECK_NOT_NULL")
val typeParameterDescriptor: TypeParameterDescriptor
val valueParameterDescriptor: ValueParameterDescriptor
val returnKotlinType: SimpleType
val valueKotlinType: SimpleType
// Note: We still need a complete function descriptor here because `CHECK_NOT_NULL` is being substituted by psi2ir
val descriptor = SimpleFunctionDescriptorImpl.create(
packageFragmentDescriptor,
Annotations.EMPTY,
name,
CallableMemberDescriptor.Kind.SYNTHESIZED,
SourceElement.NO_SOURCE
).apply {
typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
this, Annotations.EMPTY, false, Variance.INVARIANT, Name.identifier("T0"), 0, SourceElement.NO_SOURCE
).apply {
addUpperBound(any)
setInitialized()
}
valueKotlinType = typeParameterDescriptor.typeConstructor.makeNullableType()
valueParameterDescriptor = ValueParameterDescriptorImpl(
this, null, 0, Annotations.EMPTY, Name.identifier("arg0"), valueKotlinType,
false, false, false, null, SourceElement.NO_SOURCE
)
returnKotlinType = typeParameterDescriptor.typeConstructor.makeNonNullType()
initialize(null, null, listOf(typeParameterDescriptor), listOf(valueParameterDescriptor), returnKotlinType, Modality.FINAL, Visibilities.PUBLIC)
}
val typeParameterSymbol = IrTypeParameterSymbolImpl(typeParameterDescriptor)
val typeParameter = IrBuiltInOperatorTypeParameter(typeParameterSymbol, Variance.INVARIANT, 0, true).apply {
superTypes += anyType
}
val returnIrType = IrSimpleTypeBuilder().run {
classifier = typeParameterSymbol
kotlinType = returnKotlinType
hasQuestionMark = false
buildSimpleType()
}
val valueIrType = IrSimpleTypeBuilder().run {
classifier = typeParameterSymbol
kotlinType = valueKotlinType
hasQuestionMark = true
buildSimpleType()
}
return symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, BUILTIN_OPERATOR, descriptor) {
val operator = IrBuiltInOperator(it, name, returnIrType, ":!!")
operator.parent = packageFragment
packageFragment.declarations += operator
val valueParameterSymbol = IrValueParameterSymbolImpl(valueParameterDescriptor)
val valueParameter = IrBuiltInOperatorValueParameter(valueParameterSymbol, 0, valueIrType)
valueParameter.parent = operator
typeParameter.parent = operator
operator.valueParameters += valueParameter
operator.typeParameters += typeParameter
irBuiltInsSymbols += operator
operator
}.symbol
}
private fun defineComparisonOperator(name: String, operandType: IrType) =
defineOperator(name, booleanType, listOf(operandType, operandType))
private fun List<IrType>.defineComparisonOperatorForEachIrType(name: String) =
associate { it.classifierOrFail to defineComparisonOperator(name, it) }
val any = builtIns.anyType
val anyN = builtIns.nullableAnyType
@@ -127,36 +281,6 @@ class IrBuiltIns(
val throwableType = builtIns.throwable.defaultType.toIrType()
val throwableClass = builtIns.throwable.toIrSymbol()
private class BuiltInIrTypePair(val type: IrType) {
val nType: IrType = with(type as IrSimpleType) {
IrSimpleTypeImpl(classifier, true, arguments, annotations)
}
}
private val primitiveTypesMapping = mapOf(
builtIns.any to BuiltInIrTypePair(anyType),
builtIns.boolean to BuiltInIrTypePair(booleanType),
builtIns.char to BuiltInIrTypePair(charType),
builtIns.number to BuiltInIrTypePair(numberType),
builtIns.byte to BuiltInIrTypePair(byteType),
builtIns.short to BuiltInIrTypePair(shortType),
builtIns.int to BuiltInIrTypePair(intType),
builtIns.long to BuiltInIrTypePair(longType),
builtIns.float to BuiltInIrTypePair(floatType),
builtIns.double to BuiltInIrTypePair(doubleType),
builtIns.nothing to BuiltInIrTypePair(nothingType),
builtIns.unit to BuiltInIrTypePair(unitType),
builtIns.string to BuiltInIrTypePair(stringType),
builtIns.throwable to BuiltInIrTypePair(throwableType)
)
fun getPrimitiveTypeOrNullByDescriptor(descriptor: ClassifierDescriptor, isNullable: Boolean) =
primitiveTypesMapping[descriptor]?.let {
if (isNullable) it.nType else it.type
} as IrSimpleType?
val primitiveIrTypes by lazy { listOf(booleanType, charType, byteType, shortType, intType, floatType, longType, doubleType) }
val kCallableClass = builtIns.kCallable.toIrSymbol()
val kPropertyClass = builtIns.kProperty.toIrSymbol()
val kDeclarationContainerClass = builtIns.kDeclarationContainer.toIrSymbol()
@@ -177,9 +301,10 @@ class IrBuiltIns(
}
// TODO switch to IrType
val primitiveTypes = listOf(bool, char, byte, short, int, long, float, double)
val primitiveTypesWithComparisons = listOf(char, byte, short, int, long, float, double)
val primitiveFloatingPointTypes = listOf(float, double)
val primitiveTypes = listOf(bool, char, byte, short, int, float, long, double)
val primitiveIrTypes = listOf(booleanType, charType, byteType, shortType, intType, floatType, longType, doubleType)
private val primitiveIrTypesWithComparisons = listOf(charType, byteType, shortType, intType, floatType, longType, doubleType)
private val primitiveFloatingPointIrTypes = listOf(floatType, doubleType)
val primitiveArrays = PrimitiveType.values().map { builtIns.getPrimitiveArrayClassDescriptor(it).toIrSymbol() }
val primitiveArrayElementTypes = primitiveArrays.zip(primitiveIrTypes).toMap()
val primitiveArrayForType = primitiveArrayElementTypes.asSequence().associate { it.value to it.key }
@@ -195,96 +320,45 @@ class IrBuiltIns(
PrimitiveType.DOUBLE to doubleType
)
val lessFunByOperandType = primitiveTypesWithComparisons.defineComparisonOperatorForEachType(OperatorNames.LESS)
val lessOrEqualFunByOperandType = primitiveTypesWithComparisons.defineComparisonOperatorForEachType(OperatorNames.LESS_OR_EQUAL)
val greaterOrEqualFunByOperandType = primitiveTypesWithComparisons.defineComparisonOperatorForEachType(OperatorNames.GREATER_OR_EQUAL)
val greaterFunByOperandType = primitiveTypesWithComparisons.defineComparisonOperatorForEachType(OperatorNames.GREATER)
val lessFunByOperandType = primitiveIrTypesWithComparisons.defineComparisonOperatorForEachIrType(OperatorNames.LESS)
val lessOrEqualFunByOperandType = primitiveIrTypesWithComparisons.defineComparisonOperatorForEachIrType(OperatorNames.LESS_OR_EQUAL)
val greaterOrEqualFunByOperandType = primitiveIrTypesWithComparisons.defineComparisonOperatorForEachIrType(OperatorNames.GREATER_OR_EQUAL)
val greaterFunByOperandType = primitiveIrTypesWithComparisons.defineComparisonOperatorForEachIrType(OperatorNames.GREATER)
val ieee754equalsFunByOperandType =
primitiveFloatingPointTypes.associateWith {
defineOperator(OperatorNames.IEEE754_EQUALS, bool, listOf(it.makeNullable(), it.makeNullable()))
}
primitiveFloatingPointIrTypes.map {
it.classifierOrFail to defineOperator(OperatorNames.IEEE754_EQUALS, booleanType, listOf(it.makeNullable(), it.makeNullable()))
}.toMap()
val booleanNot = builtIns.boolean.unsubstitutedMemberScope.getContributedFunctions(Name.identifier("not"), NoLookupLocation.FROM_BACKEND).single()
private val booleanNot = builtIns.boolean.unsubstitutedMemberScope.getContributedFunctions(Name.identifier("not"), NoLookupLocation.FROM_BACKEND).single()
val booleanNotSymbol = symbolTable.referenceSimpleFunction(booleanNot)
val eqeqeqSymbol = defineOperator(OperatorNames.EQEQEQ, bool, listOf(anyN, anyN))
val eqeqSymbol = defineOperator(OperatorNames.EQEQ, bool, listOf(anyN, anyN))
val throwCceSymbol = defineOperator(OperatorNames.THROW_CCE, nothing, listOf())
val throwIseSymbol = defineOperator(OperatorNames.THROW_ISE, nothing, listOf())
val andandSymbol = defineOperator(OperatorNames.ANDAND, bool, listOf(bool, bool))
val ororSymbol = defineOperator(OperatorNames.OROR, bool, listOf(bool, bool))
val noWhenBranchMatchedExceptionSymbol = defineOperator(OperatorNames.NO_WHEN_BRANCH_MATCHED_EXCEPTION, nothing, listOf())
val illegalArgumentExceptionSymbol = defineOperator(OperatorNames.ILLEGAL_ARGUMENT_EXCEPTION, nothing, listOf(string))
val eqeqeqSymbol = defineOperator(OperatorNames.EQEQEQ, booleanType, listOf(anyNType, anyNType))
val eqeqSymbol = defineOperator(OperatorNames.EQEQ, booleanType, listOf(anyNType, anyNType))
val throwCceSymbol = defineOperator(OperatorNames.THROW_CCE, nothingType, listOf())
val throwIseSymbol = defineOperator(OperatorNames.THROW_ISE, nothingType, listOf())
val andandSymbol = defineOperator(OperatorNames.ANDAND, booleanType, listOf(booleanType, booleanType))
val ororSymbol = defineOperator(OperatorNames.OROR, booleanType, listOf(booleanType, booleanType))
val noWhenBranchMatchedExceptionSymbol = defineOperator(OperatorNames.NO_WHEN_BRANCH_MATCHED_EXCEPTION, nothingType, listOf())
val illegalArgumentExceptionSymbol = defineOperator(OperatorNames.ILLEGAL_ARGUMENT_EXCEPTION, nothingType, listOf(stringType))
val eqeqeq = eqeqeqSymbol.descriptor
val eqeq = eqeqSymbol.descriptor
val throwCce = throwCceSymbol.descriptor
val noWhenBranchMatchedException = noWhenBranchMatchedExceptionSymbol.descriptor
val illegalArgumentException = illegalArgumentExceptionSymbol.descriptor
val enumValueOfSymbol = defineEnumValueOfOperator()
val checkNotNullSymbol = defineCheckNotNullOperator()
val enumValueOfSymbol =
SimpleFunctionDescriptorImpl.create(
packageFragment,
Annotations.EMPTY,
Name.identifier("enumValueOf"),
CallableMemberDescriptor.Kind.SYNTHESIZED,
SourceElement.NO_SOURCE
).apply {
val typeParameterT = TypeParameterDescriptorImpl.createWithDefaultBound(
this, Annotations.EMPTY, true, Variance.INVARIANT, Name.identifier("T"), 0
)
val valueParameterName = ValueParameterDescriptorImpl(
this, null, 0, Annotations.EMPTY, Name.identifier("name"), builtIns.stringType,
false, false, false, null, SourceElement.NO_SOURCE
)
val returnType = typeParameterT.typeConstructor.makeNonNullType()
initialize(null, null, listOf(typeParameterT), listOf(valueParameterName), returnType, Modality.FINAL, Visibilities.PUBLIC)
}.addStub()
val enumValueOf = enumValueOfSymbol.descriptor
val checkNotNullSymbol =
SimpleFunctionDescriptorImpl.create(
packageFragment,
Annotations.EMPTY,
Name.identifier("CHECK_NOT_NULL"),
CallableMemberDescriptor.Kind.SYNTHESIZED,
SourceElement.NO_SOURCE
).apply {
val typeParameterT = TypeParameterDescriptorImpl.createForFurtherModification(
this, Annotations.EMPTY, false, Variance.INVARIANT, Name.identifier("T"), 0, SourceElement.NO_SOURCE
).apply {
addUpperBound(builtIns.anyType)
setInitialized()
}
val valueParameterX = ValueParameterDescriptorImpl(
this, null, 0, Annotations.EMPTY, Name.identifier("x"), typeParameterT.typeConstructor.makeNullableType(),
false, false, false, null, SourceElement.NO_SOURCE
)
initialize(
null, null,
listOf(typeParameterT), listOf(valueParameterX), typeParameterT.typeConstructor.makeNonNullType(),
Modality.FINAL, Visibilities.PUBLIC
)
}.addStub()
val checkNotNull = checkNotNullSymbol.descriptor
private fun TypeConstructor.makeNonNullType() = KotlinTypeFactory.simpleType(Annotations.EMPTY, this, listOf(), false)
private fun TypeConstructor.makeNullableType() = KotlinTypeFactory.simpleType(Annotations.EMPTY, this, listOf(), true)
val dataClassArrayMemberHashCodeSymbol = defineOperator("dataClassArrayMemberHashCode", int, listOf(any))
val dataClassArrayMemberHashCodeSymbol = defineOperator("dataClassArrayMemberHashCode", intType, listOf(anyType))
val dataClassArrayMemberHashCode = dataClassArrayMemberHashCodeSymbol.descriptor
val dataClassArrayMemberToStringSymbol = defineOperator("dataClassArrayMemberToString", string, listOf(anyN))
val dataClassArrayMemberToStringSymbol = defineOperator("dataClassArrayMemberToString", stringType, listOf(anyNType))
val dataClassArrayMemberToString = dataClassArrayMemberToStringSymbol.descriptor
companion object {
val KOTLIN_INTERNAL_IR_FQN = FqName("kotlin.internal.ir")
val BUILTIN_OPERATOR = object : IrDeclarationOriginImpl("OPERATOR") {}
}
object OperatorNames {
@@ -0,0 +1,101 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.ir.descriptors
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrDeclarationBase
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionBase
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.SmartList
interface IrBuiltinWithMangle : IrDeclaration, IrSymbolOwner {
val mangle: String
}
class IrBuiltInOperator(
override val symbol: IrSimpleFunctionSymbol,
name: Name,
returnType: IrType,
val suffix: String
) : IrSimpleFunction, IrBuiltinWithMangle, IrFunctionBase(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrBuiltIns.BUILTIN_OPERATOR, name, Visibilities.PUBLIC, false, false, false, returnType
) {
override val modality get() = Modality.FINAL
override val isTailrec get() = false
override val isSuspend get() = false
override val isFakeOverride get() = false
override var correspondingPropertySymbol: IrPropertySymbol?
get() = null
set(_) {}
override val descriptor: FunctionDescriptor get() = symbol.descriptor
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitSimpleFunction(this, data)
}
override val overriddenSymbols: MutableList<IrSimpleFunctionSymbol> = SmartList()
override val mangle: String get() = "operator#$name@$suffix"
init {
symbol.bind(this)
}
}
class IrBuiltInOperatorValueParameter(override val symbol: IrValueParameterSymbol, override val index: Int, override val type: IrType) :
IrValueParameter, IrDeclarationBase(UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrBuiltIns.BUILTIN_OPERATOR) {
override val descriptor: ParameterDescriptor get() = symbol.descriptor
override val varargElementType: IrType? get() = null
override val isCrossinline: Boolean get() = false
override val isNoinline: Boolean get() = false
override var defaultValue: IrExpressionBody?
get() = null
set(_) {}
override val name: Name = Name.identifier("arg$index")
override fun <D> transform(transformer: IrElementTransformer<D>, data: D) =
transformer.visitValueParameter(this, data) as IrValueParameter
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R = visitor.visitValueParameter(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {}
init {
symbol.bind(this)
}
}
class IrBuiltInOperatorTypeParameter(
override val symbol: IrTypeParameterSymbol,
override val variance: Variance,
override val index: Int,
override val isReified: Boolean
) : IrTypeParameter, IrDeclarationBase(UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrBuiltIns.BUILTIN_OPERATOR) {
override val descriptor: TypeParameterDescriptor get() = symbol.descriptor
override val superTypes: MutableList<IrType> = SmartList()
override val name: Name = Name.identifier("T$index")
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrTypeParameter =
transformer.visitTypeParameter(this, data) as IrTypeParameter
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R = visitor.visitTypeParameter(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {}
init {
symbol.bind(this)
}
}
@@ -35,14 +35,12 @@ abstract class GlobalDeclarationTable(private val mangler: KotlinMangler, privat
constructor(mangler: KotlinMangler) : this(mangler, UniqIdClashTracker.DEFAULT_TRACKER)
protected open fun loadKnownBuiltins(builtIns: IrBuiltIns, startIndex: Long): Long {
var index = startIndex
protected fun loadKnownBuiltins(builtIns: IrBuiltIns) {
val mask = 1L shl 63
builtIns.knownBuiltins.forEach {
table[it.owner] = UniqId(index or mask).also { id -> clashTracker.commit(it.owner, id) }
index++
val index = with(mangler) { it.mangle.hashMangle }
table[it] = UniqId(index or mask).also { id -> clashTracker.commit(it, id) }
}
return index
}
open fun computeUniqIdByDeclaration(declaration: IrDeclaration): UniqId {
@@ -51,7 +51,7 @@ abstract class KotlinIrLinker(
val symbolTable: SymbolTable,
private val exportedDependencies: List<ModuleDescriptor>,
private val forwardModuleDescriptor: ModuleDescriptor?,
private val firstKnownBuiltinsIndex: Long
mangler: KotlinMangler
) : DescriptorUniqIdAware, IrDeserializer {
@@ -472,18 +472,18 @@ abstract class KotlinIrLinker(
protected abstract val descriptorReferenceDeserializer: DescriptorReferenceDeserializer
protected val indexAfterKnownBuiltins = loadKnownBuiltinSymbols()
private fun loadKnownBuiltinSymbols(): Long {
var currentIndex = firstKnownBuiltinsIndex
private fun loadKnownBuiltinSymbols(mangler: KotlinMangler) {
val mask = 1L shl 63
val globalDeserializedSymbols = globalDeserializationState.deserializedSymbols
builtIns.knownBuiltins.forEach {
globalDeserializedSymbols[UniqId(currentIndex or mask)] = it
assert(symbolTable.referenceSimpleFunction(it.descriptor) == it)
currentIndex++
val currentIndex = with(mangler) { it.mangle.hashMangle }
globalDeserializedSymbols[UniqId(currentIndex or mask)] = it.symbol
assert(symbolTable.referenceSimpleFunction(it.symbol.descriptor as SimpleFunctionDescriptor).owner === it)
}
return currentIndex
}
init {
loadKnownBuiltinSymbols(mangler)
}
private val ByteArray.codedInputStream: org.jetbrains.kotlin.protobuf.CodedInputStream
@@ -41,6 +41,6 @@ class JsUniqIdClashTracker : UniqIdClashTracker {
class JsGlobalDeclarationTable(builtIns: IrBuiltIns) : GlobalDeclarationTable(JsMangler, JsUniqIdClashTracker()) {
init {
loadKnownBuiltins(builtIns, PUBLIC_LOCAL_UNIQ_ID_EDGE)
loadKnownBuiltins(builtIns)
}
}
@@ -1,8 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
internal const val PUBLIC_LOCAL_UNIQ_ID_EDGE = 0x7FFF_FFFF_FFFF_FFFFL + 1L
@@ -22,7 +22,7 @@ class JsIrLinker(
logger: LoggingContext,
builtIns: IrBuiltIns,
symbolTable: SymbolTable
) : KotlinIrLinker(logger, builtIns, symbolTable, emptyList(), null, PUBLIC_LOCAL_UNIQ_ID_EDGE),
) : KotlinIrLinker(logger, builtIns, symbolTable, emptyList(), null, mangler),
DescriptorUniqIdAware by DeserializedDescriptorUniqIdAware {
override val descriptorReferenceDeserializer =
@@ -3,6 +3,6 @@ FILE fqName:<root> fileName:/dynamicExclExclOperator.kt
VALUE_PARAMETER name:d index:0 type:dynamic
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test (d: dynamic): dynamic declared in <root>'
CALL 'public final fun CHECK_NOT_NULL <T> (x: T of kotlin.internal.ir.CHECK_NOT_NULL?): T of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=dynamic origin=EXCLEXCL
<T>: dynamic
x: GET_VAR 'd: dynamic declared in <root>.test' type=dynamic origin=null
CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=dynamic origin=EXCLEXCL
<T0>: dynamic
arg0: GET_VAR 'd: dynamic declared in <root>.test' type=dynamic origin=null
+15 -15
View File
@@ -3,16 +3,16 @@ FILE fqName:<root> fileName:/bangbang.kt
VALUE_PARAMETER name:a index:0 type:kotlin.Any?
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test1 (a: kotlin.Any?): kotlin.Any declared in <root>'
CALL 'public final fun CHECK_NOT_NULL <T> (x: T of kotlin.internal.ir.CHECK_NOT_NULL?): T of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.Any origin=EXCLEXCL
<T>: kotlin.Any
x: GET_VAR 'a: kotlin.Any? declared in <root>.test1' type=kotlin.Any? origin=null
CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.Any origin=EXCLEXCL
<T0>: kotlin.Any
arg0: GET_VAR 'a: kotlin.Any? declared in <root>.test1' type=kotlin.Any? origin=null
FUN name:test2 visibility:public modality:FINAL <> (a:kotlin.Any?) returnType:kotlin.Int
VALUE_PARAMETER name:a index:0 type:kotlin.Any?
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test2 (a: kotlin.Any?): kotlin.Int declared in <root>'
CALL 'public final fun CHECK_NOT_NULL <T> (x: T of kotlin.internal.ir.CHECK_NOT_NULL?): T of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.Int origin=EXCLEXCL
<T>: kotlin.Int
x: BLOCK type=kotlin.Int? origin=SAFE_CALL
CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.Int origin=EXCLEXCL
<T0>: kotlin.Int
arg0: BLOCK type=kotlin.Int? origin=SAFE_CALL
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Any? [val]
GET_VAR 'a: kotlin.Any? declared in <root>.test2' type=kotlin.Any? origin=null
WHEN type=kotlin.Int? origin=null
@@ -30,9 +30,9 @@ FILE fqName:<root> fileName:/bangbang.kt
VALUE_PARAMETER name:a index:0 type:X of <root>.test3
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test3 <X> (a: X of <root>.test3): X of <root>.test3 declared in <root>'
CALL 'public final fun CHECK_NOT_NULL <T> (x: T of kotlin.internal.ir.CHECK_NOT_NULL?): T of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=X of <root>.test3 origin=EXCLEXCL
<T>: X of <root>.test3
x: GET_VAR 'a: X of <root>.test3 declared in <root>.test3' type=X of <root>.test3 origin=null
CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=X of <root>.test3 origin=EXCLEXCL
<T0>: X of <root>.test3
arg0: GET_VAR 'a: X of <root>.test3 declared in <root>.test3' type=X of <root>.test3 origin=null
FUN name:useString visibility:public modality:FINAL <> (s:kotlin.String) returnType:kotlin.Unit
VALUE_PARAMETER name:s index:0 type:kotlin.String
BLOCK_BODY
@@ -45,15 +45,15 @@ FILE fqName:<root> fileName:/bangbang.kt
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.String?
GET_VAR 'a: X of <root>.test4 declared in <root>.test4' type=X of <root>.test4 origin=null
then: TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public final fun CHECK_NOT_NULL <T> (x: T of kotlin.internal.ir.CHECK_NOT_NULL?): T of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=X of <root>.test4 origin=EXCLEXCL
<T>: X of <root>.test4
x: GET_VAR 'a: X of <root>.test4 declared in <root>.test4' type=X of <root>.test4 origin=null
CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=X of <root>.test4 origin=EXCLEXCL
<T0>: X of <root>.test4
arg0: GET_VAR 'a: X of <root>.test4 declared in <root>.test4' type=X of <root>.test4 origin=null
WHEN type=kotlin.Unit origin=IF
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.String?
GET_VAR 'a: X of <root>.test4 declared in <root>.test4' type=X of <root>.test4 origin=null
then: CALL 'public final fun useString (s: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
s: TYPE_OP type=kotlin.String origin=IMPLICIT_CAST typeOperand=kotlin.String
CALL 'public final fun CHECK_NOT_NULL <T> (x: T of kotlin.internal.ir.CHECK_NOT_NULL?): T of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=X of <root>.test4 origin=EXCLEXCL
<T>: X of <root>.test4
x: GET_VAR 'a: X of <root>.test4 declared in <root>.test4' type=X of <root>.test4 origin=null
CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=X of <root>.test4 origin=EXCLEXCL
<T0>: X of <root>.test4
arg0: GET_VAR 'a: X of <root>.test4 declared in <root>.test4' type=X of <root>.test4 origin=null
@@ -9,9 +9,9 @@ FILE fqName:<root> fileName:/eqeqRhsConditionPossiblyAffectingLhs.kt
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=NOT_INSTANCEOF typeOperand=kotlin.Double
GET_VAR 'x: kotlin.Any declared in <root>.test' type=kotlin.Any origin=null
then: CALL 'public final fun CHECK_NOT_NULL <T> (x: T of kotlin.internal.ir.CHECK_NOT_NULL?): T of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.Nothing origin=EXCLEXCL
<T>: kotlin.Nothing
x: CONST Null type=kotlin.Nothing? value=null
then: CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.Nothing origin=EXCLEXCL
<T0>: kotlin.Nothing
arg0: CONST Null type=kotlin.Nothing? value=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double
+6 -6
View File
@@ -51,9 +51,9 @@ FILE fqName:<root> fileName:/kt30020.kt
element: CONST Int type=kotlin.Int value=4
CALL 'public final fun plusAssign <T> (element: T of kotlin.collections.plusAssign): kotlin.Unit [inline] declared in kotlin.collections' type=kotlin.Unit origin=PLUSEQ
<T>: kotlin.Int
$receiver: CALL 'public final fun CHECK_NOT_NULL <T> (x: T of kotlin.internal.ir.CHECK_NOT_NULL?): T of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.collections.MutableList<kotlin.Any> origin=EXCLEXCL
<T>: kotlin.collections.MutableList<kotlin.Any>
x: BLOCK type=kotlin.collections.MutableList<kotlin.Any>? origin=SAFE_CALL
$receiver: CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.collections.MutableList<kotlin.Any> origin=EXCLEXCL
<T0>: kotlin.collections.MutableList<kotlin.Any>
arg0: BLOCK type=kotlin.collections.MutableList<kotlin.Any>? origin=SAFE_CALL
VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:<root>.X? [val]
GET_VAR 'nx: <root>.X? declared in <root>.test' type=<root>.X? origin=null
WHEN type=kotlin.collections.MutableList<kotlin.Any>? origin=null
@@ -69,9 +69,9 @@ FILE fqName:<root> fileName:/kt30020.kt
element: CONST Int type=kotlin.Int value=5
CALL 'public final fun plusAssign <T> (element: T of kotlin.collections.plusAssign): kotlin.Unit [inline] declared in kotlin.collections' type=kotlin.Unit origin=PLUSEQ
<T>: kotlin.Int
$receiver: CALL 'public final fun CHECK_NOT_NULL <T> (x: T of kotlin.internal.ir.CHECK_NOT_NULL?): T of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.collections.MutableList<kotlin.Any> origin=EXCLEXCL
<T>: kotlin.collections.MutableList<kotlin.Any>
x: BLOCK type=kotlin.collections.MutableList<kotlin.Any>? origin=SAFE_CALL
$receiver: CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.collections.MutableList<kotlin.Any> origin=EXCLEXCL
<T0>: kotlin.collections.MutableList<kotlin.Any>
arg0: BLOCK type=kotlin.collections.MutableList<kotlin.Any>? origin=SAFE_CALL
VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:<root>.X? [val]
GET_VAR 'nx: <root>.X? declared in <root>.test' type=<root>.X? origin=null
WHEN type=kotlin.collections.MutableList<kotlin.Any>? origin=null