[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.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.IrType 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.classifierOrNull
import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl
import org.jetbrains.kotlin.ir.types.makeNullable import org.jetbrains.kotlin.ir.types.makeNullable
@@ -1144,21 +1145,22 @@ class Fir2IrVisitor(
} }
// TODO: it's temporary hack which should be refactored // TODO: it's temporary hack which should be refactored
val simpleType = when (val classId = (firstType.type as? ConeClassLikeType)?.lookupTag?.classId) { val simpleType = when (val classId = (firstType.type as? ConeClassLikeType)?.lookupTag?.classId) {
ClassId(FqName("kotlin"), FqName("Long"), false) -> irBuiltIns.builtIns.longType ClassId(FqName("kotlin"), FqName("Long"), false) -> irBuiltIns.longType
ClassId(FqName("kotlin"), FqName("Int"), false) -> irBuiltIns.builtIns.intType ClassId(FqName("kotlin"), FqName("Int"), false) -> irBuiltIns.intType
ClassId(FqName("kotlin"), FqName("Float"), false) -> irBuiltIns.builtIns.floatType ClassId(FqName("kotlin"), FqName("Float"), false) -> irBuiltIns.floatType
ClassId(FqName("kotlin"), FqName("Double"), false) -> irBuiltIns.builtIns.doubleType ClassId(FqName("kotlin"), FqName("Double"), false) -> irBuiltIns.doubleType
else -> { else -> {
return IrErrorCallExpressionImpl( return IrErrorCallExpressionImpl(
startOffset, endOffset, booleanType, "Comparison of arguments with unsupported type: $classId" startOffset, endOffset, booleanType, "Comparison of arguments with unsupported type: $classId"
) )
} }
} }
val classifier = simpleType.classifierOrFail
val (symbol, origin) = when (operation) { val (symbol, origin) = when (operation) {
FirOperation.LT -> irBuiltIns.lessFunByOperandType[simpleType] to IrStatementOrigin.LT FirOperation.LT -> irBuiltIns.lessFunByOperandType[classifier] to IrStatementOrigin.LT
FirOperation.GT -> irBuiltIns.greaterFunByOperandType[simpleType] to IrStatementOrigin.GT FirOperation.GT -> irBuiltIns.greaterFunByOperandType[classifier] to IrStatementOrigin.GT
FirOperation.LT_EQ -> irBuiltIns.lessOrEqualFunByOperandType[simpleType] to IrStatementOrigin.LTEQ FirOperation.LT_EQ -> irBuiltIns.lessOrEqualFunByOperandType[classifier] to IrStatementOrigin.LTEQ
FirOperation.GT_EQ -> irBuiltIns.greaterOrEqualFunByOperandType[simpleType] to IrStatementOrigin.GTEQ FirOperation.GT_EQ -> irBuiltIns.greaterOrEqualFunByOperandType[classifier] to IrStatementOrigin.GTEQ
else -> throw AssertionError("Unexpected comparison operation: $operation") else -> throw AssertionError("Unexpected comparison operation: $operation")
} }
return primitiveOp2(startOffset, endOffset, symbol!!, booleanType, origin, first.toIrExpression(), second.toIrExpression()) 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.IrExpression
import org.jetbrains.kotlin.ir.expressions.copyTypeArgumentsFrom import org.jetbrains.kotlin.ir.expressions.copyTypeArgumentsFrom
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol 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.getClass
import org.jetbrains.kotlin.ir.types.toKotlinType
import org.jetbrains.kotlin.ir.util.constructedClass import org.jetbrains.kotlin.ir.util.constructedClass
import org.jetbrains.kotlin.ir.util.constructors import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.ir.util.functions 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 invoke = invokable.type.getClass()!!.functions.single { it.name == OperatorNameConventions.INVOKE }
val invokableVar = if (lambda == null) irTemporary(invokable) else null val invokableVar = if (lambda == null) irTemporary(invokable) else null
+irWhile().apply { +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(0, irGet(index))
putValueArgument(1, irGet(sizeVar)) putValueArgument(1, irGet(sizeVar))
} }
@@ -78,10 +78,10 @@ internal sealed class ForLoopHeader(
with(builder) { with(builder) {
val builtIns = context.irBuiltIns val builtIns = context.irBuiltIns
val progressionType = headerInfo.progressionType val progressionType = headerInfo.progressionType
val progressionKotlinType = progressionType.elementType(builtIns).toKotlinType() val progressionElementType = progressionType.elementType(builtIns)
val compFun = val compFun =
if (isLastInclusive) builtIns.lessOrEqualFunByOperandType[progressionKotlinType]!! if (isLastInclusive) builtIns.lessOrEqualFunByOperandType[progressionElementType.classifierOrFail]!!
else builtIns.lessFunByOperandType[progressionKotlinType]!! else builtIns.lessFunByOperandType[progressionElementType.classifierOrFail]!!
// The default condition depends on the direction. // The default condition depends on the direction.
when (headerInfo.direction) { when (headerInfo.direction) {
@@ -101,11 +101,11 @@ internal sealed class ForLoopHeader(
// If the direction is unknown, we check depending on the "step" value: // If the direction is unknown, we check depending on the "step" value:
// // (use `<` if last is exclusive) // // (use `<` if last is exclusive)
// (step > 0 && inductionVar <= last) || (step < 0 || last <= inductionVar) // (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 val isLong = progressionType == ProgressionType.LONG_PROGRESSION
context.oror( context.oror(
context.andand( context.andand(
irCall(builtIns.greaterFunByOperandType[stepKotlinType]!!).apply { irCall(builtIns.greaterFunByOperandType[stepType.classifierOrFail]!!).apply {
putValueArgument(0, irGet(step)) putValueArgument(0, irGet(step))
putValueArgument(1, if (isLong) irLong(0) else irInt(0)) putValueArgument(1, if (isLong) irLong(0) else irInt(0))
}, },
@@ -114,7 +114,7 @@ internal sealed class ForLoopHeader(
putValueArgument(1, lastExpression) putValueArgument(1, lastExpression)
}), }),
context.andand( context.andand(
irCall(builtIns.lessFunByOperandType[stepKotlinType]!!).apply { irCall(builtIns.lessFunByOperandType[stepType.classifierOrFail]!!).apply {
putValueArgument(0, irGet(step)) putValueArgument(0, irGet(step))
putValueArgument(1, if (isLong) irLong(0) else irInt(0)) 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. // We insert this check in the lowered form only if necessary.
val stepType = data.stepType(context.irBuiltIns) 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 zeroStep = if (data == ProgressionType.LONG_PROGRESSION) irLong(0) else irInt(0)
val throwIllegalStepExceptionCall = { val throwIllegalStepExceptionCall = {
irCall(context.irBuiltIns.illegalArgumentExceptionSymbol).apply { 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.declarations.impl.IrExternalPackageFragmentImpl
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.impl.IrExternalPackageFragmentSymbolImpl 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.defaultType
import org.jetbrains.kotlin.ir.types.isLong import org.jetbrains.kotlin.ir.types.isLong
import org.jetbrains.kotlin.ir.util.constructors import org.jetbrains.kotlin.ir.util.constructors
@@ -92,7 +93,7 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
// Type checks: // Type checks:
val jsInstanceOf = binOpBool("jsInstanceOf") val jsInstanceOf = binOpBool("jsInstanceOf")
val jsTypeOf = unOp("jsTypeOf", irBuiltIns.string) val jsTypeOf = unOp("jsTypeOf", irBuiltIns.stringType)
// Number conversions: // Number conversions:
@@ -336,18 +337,18 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
} }
} }
private fun unOp(name: String, returnType: KotlinType = irBuiltIns.anyN) = private fun unOp(name: String, returnType: IrType = irBuiltIns.anyNType) =
irBuiltIns.run { defineOperator(name, returnType, listOf(anyN)) } irBuiltIns.run { defineOperator(name, returnType, listOf(anyNType)) }
private fun unOpBool(name: String) = unOp(name, irBuiltIns.bool) private fun unOpBool(name: String) = unOp(name, irBuiltIns.booleanType)
private fun unOpInt(name: String) = unOp(name, irBuiltIns.int) private fun unOpInt(name: String) = unOp(name, irBuiltIns.intType)
private fun binOp(name: String, returnType: KotlinType = irBuiltIns.anyN) = private fun binOp(name: String, returnType: IrType = irBuiltIns.anyNType) =
irBuiltIns.run { defineOperator(name, returnType, listOf(anyN, anyN)) } irBuiltIns.run { defineOperator(name, returnType, listOf(anyNType, anyNType)) }
private fun tripleOp(name: String, returnType: KotlinType = irBuiltIns.anyN) = private fun tripleOp(name: String, returnType: IrType = irBuiltIns.anyNType) =
irBuiltIns.run { defineOperator(name, returnType, listOf(anyN, anyN, anyN)) } irBuiltIns.run { defineOperator(name, returnType, listOf(anyNType, anyNType, anyNType)) }
private fun binOpBool(name: String) = binOp(name, irBuiltIns.bool) private fun binOpBool(name: String) = binOp(name, irBuiltIns.booleanType)
private fun binOpInt(name: String) = binOp(name, irBuiltIns.int) 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.declarations.IrFunction
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.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.irCall import org.jetbrains.kotlin.ir.util.irCall
@@ -16,13 +17,13 @@ import org.jetbrains.kotlin.types.SimpleType
typealias SymbolToTransformer = MutableMap<IrFunctionSymbol, (IrFunctionAccessExpression) -> IrExpression> 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 -> from.forEach { _, func ->
add(func, to) 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 -> from.forEach { _, func ->
add(func, to) add(func, to)
} }
@@ -34,15 +34,15 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls
add(irBuiltIns.booleanNotSymbol, intrinsics.jsNot) add(irBuiltIns.booleanNotSymbol, intrinsics.jsNot)
add(irBuiltIns.lessFunByOperandType.filterKeys { it != irBuiltIns.long }, intrinsics.jsLt) add(irBuiltIns.lessFunByOperandType.filterKeys { it != irBuiltIns.longClass }, intrinsics.jsLt)
add(irBuiltIns.lessOrEqualFunByOperandType.filterKeys { it != irBuiltIns.long }, intrinsics.jsLtEq) add(irBuiltIns.lessOrEqualFunByOperandType.filterKeys { it != irBuiltIns.longClass }, intrinsics.jsLtEq)
add(irBuiltIns.greaterFunByOperandType.filterKeys { it != irBuiltIns.long }, intrinsics.jsGt) add(irBuiltIns.greaterFunByOperandType.filterKeys { it != irBuiltIns.longClass }, intrinsics.jsGt)
add(irBuiltIns.greaterOrEqualFunByOperandType.filterKeys { it != irBuiltIns.long }, intrinsics.jsGtEq) add(irBuiltIns.greaterOrEqualFunByOperandType.filterKeys { it != irBuiltIns.longClass }, intrinsics.jsGtEq)
add(irBuiltIns.lessFunByOperandType[irBuiltIns.long]!!, transformLongComparison(intrinsics.jsLt)) add(irBuiltIns.lessFunByOperandType[irBuiltIns.longClass]!!, transformLongComparison(intrinsics.jsLt))
add(irBuiltIns.lessOrEqualFunByOperandType[irBuiltIns.long]!!, transformLongComparison(intrinsics.jsLtEq)) add(irBuiltIns.lessOrEqualFunByOperandType[irBuiltIns.longClass]!!, transformLongComparison(intrinsics.jsLtEq))
add(irBuiltIns.greaterFunByOperandType[irBuiltIns.long]!!, transformLongComparison(intrinsics.jsGt)) add(irBuiltIns.greaterFunByOperandType[irBuiltIns.longClass]!!, transformLongComparison(intrinsics.jsGt))
add(irBuiltIns.greaterOrEqualFunByOperandType[irBuiltIns.long]!!, transformLongComparison(intrinsics.jsGtEq)) 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.KtSingleValueToken
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.expressions.OperatorConventions import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.org.objectweb.asm.Opcodes.* import org.jetbrains.org.objectweb.asm.Opcodes.*
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
@@ -81,8 +80,8 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
) to Clone, ) to Clone,
irBuiltIns.eqeqSymbol.toKey()!! to Equals(KtTokens.EQEQ), irBuiltIns.eqeqSymbol.toKey()!! to Equals(KtTokens.EQEQ),
irBuiltIns.eqeqeqSymbol.toKey()!! to Equals(KtTokens.EQEQEQ), irBuiltIns.eqeqeqSymbol.toKey()!! to Equals(KtTokens.EQEQEQ),
irBuiltIns.ieee754equalsFunByOperandType[irBuiltIns.float]!!.toKey()!! to Ieee754Equals(Type.FLOAT_TYPE), irBuiltIns.ieee754equalsFunByOperandType[irBuiltIns.floatClass]!!.toKey()!! to Ieee754Equals(Type.FLOAT_TYPE),
irBuiltIns.ieee754equalsFunByOperandType[irBuiltIns.double]!!.toKey()!! to Ieee754Equals(Type.DOUBLE_TYPE), irBuiltIns.ieee754equalsFunByOperandType[irBuiltIns.doubleClass]!!.toKey()!! to Ieee754Equals(Type.DOUBLE_TYPE),
irBuiltIns.booleanNotSymbol.toKey()!! to Not, irBuiltIns.booleanNotSymbol.toKey()!! to Not,
irBuiltIns.enumValueOfSymbol.toKey()!! to IrEnumValueOf, irBuiltIns.enumValueOfSymbol.toKey()!! to IrEnumValueOf,
irBuiltIns.noWhenBranchMatchedExceptionSymbol.toKey()!! to IrNoWhenBranchMatchedException, irBuiltIns.noWhenBranchMatchedExceptionSymbol.toKey()!! to IrNoWhenBranchMatchedException,
@@ -240,11 +239,11 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
private fun primitiveComparisonIntrinsics( private fun primitiveComparisonIntrinsics(
typeToIrFun: Map<SimpleType, IrSimpleFunctionSymbol>, typeToIrFun: Map<IrClassifierSymbol, IrSimpleFunctionSymbol>,
operator: KtSingleValueToken operator: KtSingleValueToken
): List<Pair<Key, PrimitiveComparison>> = ): List<Pair<Key, PrimitiveComparison>> =
typeToIrFun.map { (type, irFunSymbol) -> 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.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.builders.declarations.addFunction import org.jetbrains.kotlin.ir.builders.declarations.addFunction
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol 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.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -70,13 +72,13 @@ class WasmSymbols(
context.irBuiltIns.doubleType to getInternalFunction("wasm_f64_eq") context.irBuiltIns.doubleType to getInternalFunction("wasm_f64_eq")
) )
private fun wasmString(simpleType: SimpleType): String = with(context.irBuiltIns) { private fun wasmString(classfier: IrClassifierSymbol): String = with(context.irBuiltIns) {
when (simpleType) { when (classfier) {
bool, byte, short, char, int -> "i32" booleanClass, byteClass, shortClass, charClass, intClass -> "i32"
float -> "f32" floatClass -> "f32"
double -> "f64" doubleClass -> "f64"
long -> "i64" longClass -> "i64"
else -> error("Unkonow primitive type") else -> error("Unknown primitive type")
} }
} }
@@ -204,7 +204,7 @@ class DataClassMembersGenerator(
when (val typeConstructorDescriptor = type.constructor.declarationDescriptor) { when (val typeConstructorDescriptor = type.constructor.declarationDescriptor) {
is ClassDescriptor -> is ClassDescriptor ->
if (KotlinBuiltIns.isArrayOrPrimitiveArray(typeConstructorDescriptor)) if (KotlinBuiltIns.isArrayOrPrimitiveArray(typeConstructorDescriptor))
context.irBuiltIns.dataClassArrayMemberHashCodeSymbol.descriptor context.irBuiltIns.dataClassArrayMemberHashCode
else else
type.memberScope.findFirstFunction("hashCode") { it.valueParameters.isEmpty() } 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.*
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol 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.impl.originalKotlinType
import org.jetbrains.kotlin.ir.types.makeNotNull import org.jetbrains.kotlin.ir.types.makeNotNull
import org.jetbrains.kotlin.ir.util.referenceFunction import org.jetbrains.kotlin.ir.util.referenceFunction
@@ -316,7 +319,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
val comparisonInfo = getPrimitiveNumericComparisonInfo(expression) val comparisonInfo = getPrimitiveNumericComparisonInfo(expression)
val comparisonType = comparisonInfo?.comparisonType 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( val irEquals = primitiveOp2(
expression.startOffsetSkippingComments, expression.endOffset, expression.startOffsetSkippingComments, expression.endOffset,
@@ -354,7 +357,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
if (comparisonInfo != null) { if (comparisonInfo != null) {
val comparisonType = comparisonInfo.comparisonType val comparisonType = comparisonInfo.comparisonType
val eqeqSymbol = val eqeqSymbol =
context.irBuiltIns.ieee754equalsFunByOperandType[comparisonType] ?: context.irBuiltIns.eqeqSymbol context.irBuiltIns.ieee754equalsFunByOperandType[kotlinTypeToIrType(comparisonType)?.classifierOrNull] ?: context.irBuiltIns.eqeqSymbol
primitiveOp2( primitiveOp2(
startOffset, endOffset, startOffset, endOffset,
eqeqSymbol, eqeqSymbol,
@@ -432,6 +435,9 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
return memberScope.findSingleFunction(Name.identifier("to$targetTypeName")) 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 { private fun generateComparisonOperator(ktExpression: KtBinaryExpression, origin: IrStatementOrigin): IrExpression {
if (isDynamicBinaryOperator(ktExpression)) return generateDynamicBinaryExpression(ktExpression) 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}") val ktRight = ktExpression.right ?: throw AssertionError("No RHS in ${ktExpression.text}")
return if (comparisonInfo != null) { return if (comparisonInfo != null) {
val comparisonType = comparisonInfo.comparisonType
primitiveOp2( primitiveOp2(
startOffset, endOffset, startOffset, endOffset,
getComparisonOperatorSymbol(origin, comparisonInfo.comparisonType), getComparisonOperatorSymbol(origin, kotlinTypeToIrType(comparisonType) ?: error("$comparisonType expected to be primitive")),
context.irBuiltIns.booleanType, context.irBuiltIns.booleanType,
origin, origin,
ktLeft.generateAsPrimitiveNumericComparisonOperand(comparisonInfo.leftType, comparisonInfo.comparisonType), ktLeft.generateAsPrimitiveNumericComparisonOperand(comparisonInfo.leftType, comparisonInfo.comparisonType),
@@ -458,7 +465,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
primitiveOp2( primitiveOp2(
startOffset, endOffset, startOffset, endOffset,
getComparisonOperatorSymbol(origin, context.irBuiltIns.int), getComparisonOperatorSymbol(origin, context.irBuiltIns.intType),
context.irBuiltIns.booleanType, context.irBuiltIns.booleanType,
origin, origin,
generateCall(resolvedCall, ktExpression, origin), generateCall(resolvedCall, ktExpression, origin),
@@ -474,14 +481,14 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
) = ) =
CallGenerator(statementGenerator).generateCall(ktExpression, statementGenerator.pregenerateCall(resolvedCall), origin) 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) { when (origin) {
IrStatementOrigin.LT -> context.irBuiltIns.lessFunByOperandType IrStatementOrigin.LT -> context.irBuiltIns.lessFunByOperandType
IrStatementOrigin.LTEQ -> context.irBuiltIns.lessOrEqualFunByOperandType IrStatementOrigin.LTEQ -> context.irBuiltIns.lessOrEqualFunByOperandType
IrStatementOrigin.GT -> context.irBuiltIns.greaterFunByOperandType IrStatementOrigin.GT -> context.irBuiltIns.greaterFunByOperandType
IrStatementOrigin.GTEQ -> context.irBuiltIns.greaterOrEqualFunByOperandType IrStatementOrigin.GTEQ -> context.irBuiltIns.greaterOrEqualFunByOperandType
else -> throw AssertionError("Unexpected comparison operator: $origin") else -> throw AssertionError("Unexpected comparison operator: $origin")
}[primitiveNumericType]!! }[primitiveNumericType.classifierOrFail]!!
private fun generateExclExclOperator(expression: KtPostfixExpression, origin: IrStatementOrigin): IrExpression { private fun generateExclExclOperator(expression: KtPostfixExpression, origin: IrStatementOrigin): IrExpression {
val ktArgument = expression.baseExpression!! val ktArgument = expression.baseExpression!!
@@ -5,6 +5,8 @@
package org.jetbrains.kotlin.ir.descriptors 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.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.descriptors.* 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.TypeParameterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.incremental.components.NoLookupLocation 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.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol 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.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.types.withHasQuestionMark
import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.TypeTranslator import org.jetbrains.kotlin.ir.util.TypeTranslator
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.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.makeNullable
class IrBuiltIns( class IrBuiltIns(
val builtIns: KotlinBuiltIns, val builtIns: KotlinBuiltIns,
@@ -35,34 +44,179 @@ class IrBuiltIns(
private val builtInsModule = builtIns.builtInsModule private val builtInsModule = builtIns.builtInsModule
private val packageFragment = IrBuiltinsPackageFragmentDescriptorImpl(builtInsModule, KOTLIN_INTERNAL_IR_FQN) val irBuiltInsSymbols = mutableListOf<IrBuiltinWithMangle>()
val irBuiltInsSymbols = mutableListOf<IrSimpleFunctionSymbol>()
private val symbolTable = outerSymbolTable ?: SymbolTable() 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 ClassDescriptor.toIrSymbol() = symbolTable.referenceClass(this)
private fun KotlinType.toIrType() = typeTranslator.translateType(this) private fun KotlinType.toIrType() = typeTranslator.translateType(this)
fun defineOperator(name: String, returnType: KotlinType, valueParameterTypes: List<KotlinType>): IrSimpleFunctionSymbol { fun defineOperator(name: String, returnType: IrType, valueParameterTypes: List<IrType>): IrSimpleFunctionSymbol {
val operatorDescriptor = IrSimpleBuiltinOperatorDescriptorImpl(packageFragment, Name.identifier(name), returnType) val descriptor = WrappedSimpleFunctionDescriptor()
for ((i, valueParameterType) in valueParameterTypes.withIndex()) { val symbol = symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, BUILTIN_OPERATOR, descriptor) {
operatorDescriptor.addValueParameter( val suffix = valueParameterTypes.joinToString(":", "[", "]") { t -> t.originalKotlinType?.toString() ?: "T" }
IrBuiltinValueParameterDescriptorImpl(operatorDescriptor, Name.identifier("arg$i"), i, valueParameterType) 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 = private fun defineEnumValueOfOperator(): IrSimpleFunctionSymbol {
symbolTable.referenceSimpleFunction(this).also { val name = Name.identifier("enumValueOf")
irBuiltInsSymbols += it 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) = val returnKotlinType = descriptor.returnType
defineOperator(name, bool, listOf(operandType, operandType)) val typeParameterSymbol = IrTypeParameterSymbolImpl(typeParameterDescriptor)
val typeParameter = IrBuiltInOperatorTypeParameter(typeParameterSymbol, Variance.INVARIANT, 0, true).apply {
superTypes += anyNType
}
private fun List<SimpleType>.defineComparisonOperatorForEachType(name: String) = val returnIrType = IrSimpleTypeBuilder().run {
associate { it to defineComparisonOperator(name, it) } 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 any = builtIns.anyType
val anyN = builtIns.nullableAnyType val anyN = builtIns.nullableAnyType
@@ -127,36 +281,6 @@ class IrBuiltIns(
val throwableType = builtIns.throwable.defaultType.toIrType() val throwableType = builtIns.throwable.defaultType.toIrType()
val throwableClass = builtIns.throwable.toIrSymbol() 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 kCallableClass = builtIns.kCallable.toIrSymbol()
val kPropertyClass = builtIns.kProperty.toIrSymbol() val kPropertyClass = builtIns.kProperty.toIrSymbol()
val kDeclarationContainerClass = builtIns.kDeclarationContainer.toIrSymbol() val kDeclarationContainerClass = builtIns.kDeclarationContainer.toIrSymbol()
@@ -177,9 +301,10 @@ class IrBuiltIns(
} }
// TODO switch to IrType // TODO switch to IrType
val primitiveTypes = listOf(bool, char, byte, short, int, long, float, double) val primitiveTypes = listOf(bool, char, byte, short, int, float, long, double)
val primitiveTypesWithComparisons = listOf(char, byte, short, int, long, float, double) val primitiveIrTypes = listOf(booleanType, charType, byteType, shortType, intType, floatType, longType, doubleType)
val primitiveFloatingPointTypes = listOf(float, double) 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 primitiveArrays = PrimitiveType.values().map { builtIns.getPrimitiveArrayClassDescriptor(it).toIrSymbol() }
val primitiveArrayElementTypes = primitiveArrays.zip(primitiveIrTypes).toMap() val primitiveArrayElementTypes = primitiveArrays.zip(primitiveIrTypes).toMap()
val primitiveArrayForType = primitiveArrayElementTypes.asSequence().associate { it.value to it.key } val primitiveArrayForType = primitiveArrayElementTypes.asSequence().associate { it.value to it.key }
@@ -195,96 +320,45 @@ class IrBuiltIns(
PrimitiveType.DOUBLE to doubleType PrimitiveType.DOUBLE to doubleType
) )
val lessFunByOperandType = primitiveTypesWithComparisons.defineComparisonOperatorForEachType(OperatorNames.LESS) val lessFunByOperandType = primitiveIrTypesWithComparisons.defineComparisonOperatorForEachIrType(OperatorNames.LESS)
val lessOrEqualFunByOperandType = primitiveTypesWithComparisons.defineComparisonOperatorForEachType(OperatorNames.LESS_OR_EQUAL) val lessOrEqualFunByOperandType = primitiveIrTypesWithComparisons.defineComparisonOperatorForEachIrType(OperatorNames.LESS_OR_EQUAL)
val greaterOrEqualFunByOperandType = primitiveTypesWithComparisons.defineComparisonOperatorForEachType(OperatorNames.GREATER_OR_EQUAL) val greaterOrEqualFunByOperandType = primitiveIrTypesWithComparisons.defineComparisonOperatorForEachIrType(OperatorNames.GREATER_OR_EQUAL)
val greaterFunByOperandType = primitiveTypesWithComparisons.defineComparisonOperatorForEachType(OperatorNames.GREATER) val greaterFunByOperandType = primitiveIrTypesWithComparisons.defineComparisonOperatorForEachIrType(OperatorNames.GREATER)
val ieee754equalsFunByOperandType = val ieee754equalsFunByOperandType =
primitiveFloatingPointTypes.associateWith { primitiveFloatingPointIrTypes.map {
defineOperator(OperatorNames.IEEE754_EQUALS, bool, listOf(it.makeNullable(), it.makeNullable())) 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 booleanNotSymbol = symbolTable.referenceSimpleFunction(booleanNot)
val eqeqeqSymbol = defineOperator(OperatorNames.EQEQEQ, bool, listOf(anyN, anyN)) val eqeqeqSymbol = defineOperator(OperatorNames.EQEQEQ, booleanType, listOf(anyNType, anyNType))
val eqeqSymbol = defineOperator(OperatorNames.EQEQ, bool, listOf(anyN, anyN)) val eqeqSymbol = defineOperator(OperatorNames.EQEQ, booleanType, listOf(anyNType, anyNType))
val throwCceSymbol = defineOperator(OperatorNames.THROW_CCE, nothing, listOf()) val throwCceSymbol = defineOperator(OperatorNames.THROW_CCE, nothingType, listOf())
val throwIseSymbol = defineOperator(OperatorNames.THROW_ISE, nothing, listOf()) val throwIseSymbol = defineOperator(OperatorNames.THROW_ISE, nothingType, listOf())
val andandSymbol = defineOperator(OperatorNames.ANDAND, bool, listOf(bool, bool)) val andandSymbol = defineOperator(OperatorNames.ANDAND, booleanType, listOf(booleanType, booleanType))
val ororSymbol = defineOperator(OperatorNames.OROR, bool, listOf(bool, bool)) val ororSymbol = defineOperator(OperatorNames.OROR, booleanType, listOf(booleanType, booleanType))
val noWhenBranchMatchedExceptionSymbol = defineOperator(OperatorNames.NO_WHEN_BRANCH_MATCHED_EXCEPTION, nothing, listOf()) val noWhenBranchMatchedExceptionSymbol = defineOperator(OperatorNames.NO_WHEN_BRANCH_MATCHED_EXCEPTION, nothingType, listOf())
val illegalArgumentExceptionSymbol = defineOperator(OperatorNames.ILLEGAL_ARGUMENT_EXCEPTION, nothing, listOf(string)) val illegalArgumentExceptionSymbol = defineOperator(OperatorNames.ILLEGAL_ARGUMENT_EXCEPTION, nothingType, listOf(stringType))
val eqeqeq = eqeqeqSymbol.descriptor val enumValueOfSymbol = defineEnumValueOfOperator()
val eqeq = eqeqSymbol.descriptor val checkNotNullSymbol = defineCheckNotNullOperator()
val throwCce = throwCceSymbol.descriptor
val noWhenBranchMatchedException = noWhenBranchMatchedExceptionSymbol.descriptor
val illegalArgumentException = illegalArgumentExceptionSymbol.descriptor
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 val checkNotNull = checkNotNullSymbol.descriptor
private fun TypeConstructor.makeNonNullType() = KotlinTypeFactory.simpleType(Annotations.EMPTY, this, listOf(), false) private fun TypeConstructor.makeNonNullType() = KotlinTypeFactory.simpleType(Annotations.EMPTY, this, listOf(), false)
private fun TypeConstructor.makeNullableType() = KotlinTypeFactory.simpleType(Annotations.EMPTY, this, listOf(), true) 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 dataClassArrayMemberHashCode = dataClassArrayMemberHashCodeSymbol.descriptor
val dataClassArrayMemberToStringSymbol = defineOperator("dataClassArrayMemberToString", string, listOf(anyN)) val dataClassArrayMemberToStringSymbol = defineOperator("dataClassArrayMemberToString", stringType, listOf(anyNType))
val dataClassArrayMemberToString = dataClassArrayMemberToStringSymbol.descriptor val dataClassArrayMemberToString = dataClassArrayMemberToStringSymbol.descriptor
companion object { companion object {
val KOTLIN_INTERNAL_IR_FQN = FqName("kotlin.internal.ir") val KOTLIN_INTERNAL_IR_FQN = FqName("kotlin.internal.ir")
val BUILTIN_OPERATOR = object : IrDeclarationOriginImpl("OPERATOR") {}
} }
object OperatorNames { 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) constructor(mangler: KotlinMangler) : this(mangler, UniqIdClashTracker.DEFAULT_TRACKER)
protected open fun loadKnownBuiltins(builtIns: IrBuiltIns, startIndex: Long): Long { protected fun loadKnownBuiltins(builtIns: IrBuiltIns) {
var index = startIndex
val mask = 1L shl 63 val mask = 1L shl 63
builtIns.knownBuiltins.forEach { builtIns.knownBuiltins.forEach {
table[it.owner] = UniqId(index or mask).also { id -> clashTracker.commit(it.owner, id) } val index = with(mangler) { it.mangle.hashMangle }
index++ table[it] = UniqId(index or mask).also { id -> clashTracker.commit(it, id) }
} }
return index
} }
open fun computeUniqIdByDeclaration(declaration: IrDeclaration): UniqId { open fun computeUniqIdByDeclaration(declaration: IrDeclaration): UniqId {
@@ -51,7 +51,7 @@ abstract class KotlinIrLinker(
val symbolTable: SymbolTable, val symbolTable: SymbolTable,
private val exportedDependencies: List<ModuleDescriptor>, private val exportedDependencies: List<ModuleDescriptor>,
private val forwardModuleDescriptor: ModuleDescriptor?, private val forwardModuleDescriptor: ModuleDescriptor?,
private val firstKnownBuiltinsIndex: Long mangler: KotlinMangler
) : DescriptorUniqIdAware, IrDeserializer { ) : DescriptorUniqIdAware, IrDeserializer {
@@ -472,18 +472,18 @@ abstract class KotlinIrLinker(
protected abstract val descriptorReferenceDeserializer: DescriptorReferenceDeserializer protected abstract val descriptorReferenceDeserializer: DescriptorReferenceDeserializer
protected val indexAfterKnownBuiltins = loadKnownBuiltinSymbols() private fun loadKnownBuiltinSymbols(mangler: KotlinMangler) {
private fun loadKnownBuiltinSymbols(): Long {
var currentIndex = firstKnownBuiltinsIndex
val mask = 1L shl 63 val mask = 1L shl 63
val globalDeserializedSymbols = globalDeserializationState.deserializedSymbols val globalDeserializedSymbols = globalDeserializationState.deserializedSymbols
builtIns.knownBuiltins.forEach { builtIns.knownBuiltins.forEach {
globalDeserializedSymbols[UniqId(currentIndex or mask)] = it val currentIndex = with(mangler) { it.mangle.hashMangle }
assert(symbolTable.referenceSimpleFunction(it.descriptor) == it) globalDeserializedSymbols[UniqId(currentIndex or mask)] = it.symbol
currentIndex++ assert(symbolTable.referenceSimpleFunction(it.symbol.descriptor as SimpleFunctionDescriptor).owner === it)
} }
return currentIndex }
init {
loadKnownBuiltinSymbols(mangler)
} }
private val ByteArray.codedInputStream: org.jetbrains.kotlin.protobuf.CodedInputStream private val ByteArray.codedInputStream: org.jetbrains.kotlin.protobuf.CodedInputStream
@@ -41,6 +41,6 @@ class JsUniqIdClashTracker : UniqIdClashTracker {
class JsGlobalDeclarationTable(builtIns: IrBuiltIns) : GlobalDeclarationTable(JsMangler, JsUniqIdClashTracker()) { class JsGlobalDeclarationTable(builtIns: IrBuiltIns) : GlobalDeclarationTable(JsMangler, JsUniqIdClashTracker()) {
init { 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, logger: LoggingContext,
builtIns: IrBuiltIns, builtIns: IrBuiltIns,
symbolTable: SymbolTable symbolTable: SymbolTable
) : KotlinIrLinker(logger, builtIns, symbolTable, emptyList(), null, PUBLIC_LOCAL_UNIQ_ID_EDGE), ) : KotlinIrLinker(logger, builtIns, symbolTable, emptyList(), null, mangler),
DescriptorUniqIdAware by DeserializedDescriptorUniqIdAware { DescriptorUniqIdAware by DeserializedDescriptorUniqIdAware {
override val descriptorReferenceDeserializer = override val descriptorReferenceDeserializer =
@@ -3,6 +3,6 @@ FILE fqName:<root> fileName:/dynamicExclExclOperator.kt
VALUE_PARAMETER name:d index:0 type:dynamic VALUE_PARAMETER name:d index:0 type:dynamic
BLOCK_BODY BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test (d: dynamic): dynamic declared in <root>' 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 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
<T>: dynamic <T0>: dynamic
x: GET_VAR 'd: dynamic declared in <root>.test' type=dynamic origin=null 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? VALUE_PARAMETER name:a index:0 type:kotlin.Any?
BLOCK_BODY BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test1 (a: kotlin.Any?): kotlin.Any declared in <root>' 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 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
<T>: kotlin.Any <T0>: kotlin.Any
x: GET_VAR 'a: kotlin.Any? declared in <root>.test1' type=kotlin.Any? origin=null 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 FUN name:test2 visibility:public modality:FINAL <> (a:kotlin.Any?) returnType:kotlin.Int
VALUE_PARAMETER name:a index:0 type:kotlin.Any? VALUE_PARAMETER name:a index:0 type:kotlin.Any?
BLOCK_BODY BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test2 (a: kotlin.Any?): kotlin.Int declared in <root>' 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 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
<T>: kotlin.Int <T0>: kotlin.Int
x: BLOCK type=kotlin.Int? origin=SAFE_CALL arg0: BLOCK type=kotlin.Int? origin=SAFE_CALL
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Any? [val] 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 GET_VAR 'a: kotlin.Any? declared in <root>.test2' type=kotlin.Any? origin=null
WHEN type=kotlin.Int? 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 VALUE_PARAMETER name:a index:0 type:X of <root>.test3
BLOCK_BODY BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test3 <X> (a: X of <root>.test3): X of <root>.test3 declared in <root>' 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 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
<T>: X of <root>.test3 <T0>: X of <root>.test3
x: GET_VAR 'a: X of <root>.test3 declared in <root>.test3' type=X of <root>.test3 origin=null 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 FUN name:useString visibility:public modality:FINAL <> (s:kotlin.String) returnType:kotlin.Unit
VALUE_PARAMETER name:s index:0 type:kotlin.String VALUE_PARAMETER name:s index:0 type:kotlin.String
BLOCK_BODY BLOCK_BODY
@@ -45,15 +45,15 @@ FILE fqName:<root> fileName:/bangbang.kt
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.String? 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 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 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 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
<T>: X of <root>.test4 <T0>: X of <root>.test4
x: GET_VAR 'a: X of <root>.test4 declared in <root>.test4' type=X of <root>.test4 origin=null 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 WHEN type=kotlin.Unit origin=IF
BRANCH BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.String? 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 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 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 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 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
<T>: X of <root>.test4 <T0>: X of <root>.test4
x: GET_VAR 'a: X of <root>.test4 declared in <root>.test4' type=X of <root>.test4 origin=null 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 BRANCH
if: TYPE_OP type=kotlin.Boolean origin=NOT_INSTANCEOF typeOperand=kotlin.Double 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 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 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
<T>: kotlin.Nothing <T0>: kotlin.Nothing
x: CONST Null type=kotlin.Nothing? value=null arg0: CONST Null type=kotlin.Nothing? value=null
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double 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 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 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 <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 $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
<T>: kotlin.collections.MutableList<kotlin.Any> <T0>: kotlin.collections.MutableList<kotlin.Any>
x: BLOCK type=kotlin.collections.MutableList<kotlin.Any>? origin=SAFE_CALL arg0: BLOCK type=kotlin.collections.MutableList<kotlin.Any>? origin=SAFE_CALL
VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:<root>.X? [val] 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 GET_VAR 'nx: <root>.X? declared in <root>.test' type=<root>.X? origin=null
WHEN type=kotlin.collections.MutableList<kotlin.Any>? 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 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 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 <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 $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
<T>: kotlin.collections.MutableList<kotlin.Any> <T0>: kotlin.collections.MutableList<kotlin.Any>
x: BLOCK type=kotlin.collections.MutableList<kotlin.Any>? origin=SAFE_CALL arg0: BLOCK type=kotlin.collections.MutableList<kotlin.Any>? origin=SAFE_CALL
VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:<root>.X? [val] 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 GET_VAR 'nx: <root>.X? declared in <root>.test' type=<root>.X? origin=null
WHEN type=kotlin.collections.MutableList<kotlin.Any>? origin=null WHEN type=kotlin.collections.MutableList<kotlin.Any>? origin=null