JS_IR: remove stub generator from IrBuiltins

This commit is contained in:
Anton Bannykh
2019-03-19 17:40:54 +03:00
parent ed440fc060
commit b3f1908026
23 changed files with 125 additions and 144 deletions
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrAnonymousInitializerImpl
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.IrSymbol
class DescriptorTable {
private val descriptors = mutableMapOf<DeclarationDescriptor, Long>()
@@ -21,18 +22,19 @@ class DescriptorTable {
// TODO: We don't manage id clashes anyhow now.
abstract class DeclarationTable(val builtIns: IrBuiltIns, val descriptorTable: DescriptorTable, mangler: KotlinMangler): KotlinMangler by mangler {
private val builtInsTable = mutableMapOf<IrSymbol, UniqId>()
private val table = mutableMapOf<IrDeclaration, UniqId>()
val descriptors = descriptorTable
protected abstract var currentIndex: Long
open fun loadKnownBuiltins(): Long {
builtIns.knownBuiltins.forEach {
table.put(it, UniqId(currentIndex++, false))
builtInsTable[it] = UniqId(currentIndex++, false)
}
return currentIndex
}
fun uniqIdByDeclaration(value: IrDeclaration) = table.getOrPut(value) {
fun uniqIdByDeclaration(value: IrDeclaration) = (value as? IrSymbolOwner)?.let { builtInsTable[it.symbol] } ?: table.getOrPut(value) {
computeUniqIdByDeclaration(value)
}
@@ -55,4 +57,4 @@ abstract class DeclarationTable(val builtIns: IrBuiltIns, val descriptorTable: D
// This is what we pre-populate tables with
val IrBuiltIns.knownBuiltins
get() = irBuiltInsExternalPackageFragment.declarations
get() = irBuiltInsSymbols
@@ -258,9 +258,8 @@ abstract class KotlinIrLinker(
private fun loadKnownBuiltinSymbols(): Long {
var currentIndex = firstKnownBuiltinsIndex
builtIns.knownBuiltins.forEach {
require(it is IrFunction)
deserializedSymbols[UniqIdKey(null, UniqId(currentIndex, isLocal = false))] = it.symbol
assert(symbolTable.referenceSimpleFunction(it.descriptor) == it.symbol)
deserializedSymbols[UniqIdKey(null, UniqId(currentIndex, isLocal = false))] = it
assert(symbolTable.referenceSimpleFunction(it.descriptor) == it)
currentIndex++
}
return currentIndex
@@ -214,7 +214,7 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
val jsPrimitiveArrayIteratorFunctions =
PrimitiveType.values().associate { it to getInternalFunction("${it.typeName.asString().toLowerCase()}ArrayIterator") }
val arrayLiteral = unOp("arrayLiteral").symbol
val arrayLiteral = unOp("arrayLiteral")
val primitiveToTypedArrayMap = EnumMap(
mapOf(
@@ -229,14 +229,14 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
val primitiveToSizeConstructor =
PrimitiveType.values().associate { type ->
type to (primitiveToTypedArrayMap[type]?.let {
unOp("${it.toLowerCase()}Array").symbol
unOp("${it.toLowerCase()}Array")
} ?: getInternalFunction("${type.typeName.asString().toLowerCase()}Array"))
}
val primitiveToLiteralConstructor =
PrimitiveType.values().associate { type ->
type to (primitiveToTypedArrayMap[type]?.let {
unOp("${it.toLowerCase()}ArrayOf").symbol
unOp("${it.toLowerCase()}ArrayOf")
} ?: getInternalFunction("${type.typeName.asString().toLowerCase()}ArrayOf"))
}
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.backend.js.lower.inline.replaceUnboundSymbols
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsDeclarationTable
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrModuleSerializer
@@ -276,7 +276,7 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
val declaration = propertyReference.delegate.owner
val factoryName = createPropertyFactoryName(declaration)
val factoryFunction = buildFactoryFunction(propertyReference.getter.owner, propertyReference, factoryName)
val closureFunction = buildClosureFunction(context.irBuiltIns.throwIseFun, factoryFunction, propertyReference, arity)
val closureFunction = buildClosureFunction(context.irBuiltIns.throwIseSymbol.owner, factoryFunction, propertyReference, arity)
val additionalDeclarations = generateFactoryBodyWithGuard(factoryFunction) {
val statements = mutableListOf<IrStatement>(closureFunction)
@@ -45,8 +45,8 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
// private val isCharSymbol get() = context.intrinsics.isCharSymbol
private val isObjectSymbol get() = context.intrinsics.isObjectSymbol
private val instanceOfIntrinsicSymbol = context.intrinsics.jsInstanceOf.symbol
private val typeOfIntrinsicSymbol = context.intrinsics.jsTypeOf.symbol
private val instanceOfIntrinsicSymbol = context.intrinsics.jsInstanceOf
private val typeOfIntrinsicSymbol = context.intrinsics.jsTypeOf
private val jsClassIntrinsicSymbol = context.intrinsics.jsClass
private val stringMarker get() = JsIrBuilder.buildString(context.irBuiltIns.stringType, "string")
@@ -128,7 +128,7 @@ private class VarargTransformer(
expression.startOffset,
expression.endOffset,
expression.type,
context.intrinsics.jsArraySlice.symbol
context.intrinsics.jsArraySlice
).apply {
putValueArgument(0, segments.first())
}
@@ -16,15 +16,15 @@ import org.jetbrains.kotlin.types.SimpleType
typealias SymbolToTransformer = MutableMap<IrFunctionSymbol, (IrCall) -> IrExpression>
internal fun SymbolToTransformer.add(from: Map<SimpleType, IrFunction>, to: IrFunction) {
internal fun SymbolToTransformer.add(from: Map<SimpleType, IrFunctionSymbol>, to: IrFunctionSymbol) {
from.forEach { _, func ->
add(func.symbol, to)
add(func, to)
}
}
internal fun SymbolToTransformer.add(from: Map<SimpleType, IrFunction>, to: (IrCall) -> IrExpression) {
internal fun SymbolToTransformer.add(from: Map<SimpleType, IrFunctionSymbol>, to: (IrCall) -> IrExpression) {
from.forEach { _, func ->
add(func.symbol, to)
add(func, to)
}
}
@@ -32,8 +32,8 @@ internal fun SymbolToTransformer.add(from: IrFunctionSymbol, to: (IrCall) -> IrE
put(from, to)
}
internal fun SymbolToTransformer.add(from: IrFunctionSymbol, to: IrFunction, dispatchReceiverAsFirstArgument: Boolean = false) {
put(from) { call -> irCall(call, to.symbol, dispatchReceiverAsFirstArgument) }
internal fun SymbolToTransformer.add(from: IrFunctionSymbol, to: IrFunctionSymbol, dispatchReceiverAsFirstArgument: Boolean = false) {
put(from) { call -> irCall(call, to, dispatchReceiverAsFirstArgument) }
}
internal fun <K> MutableMap<K, (IrCall) -> IrExpression>.addWithPredicate(
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.Name
@@ -37,19 +38,19 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls
add(irBuiltIns.greaterFunByOperandType.filterKeys { it != irBuiltIns.long }, intrinsics.jsGt)
add(irBuiltIns.greaterOrEqualFunByOperandType.filterKeys { it != irBuiltIns.long }, intrinsics.jsGtEq)
add(irBuiltIns.lessFunByOperandType[irBuiltIns.long]!!.symbol, transformLongComparison(intrinsics.jsLt))
add(irBuiltIns.lessOrEqualFunByOperandType[irBuiltIns.long]!!.symbol, transformLongComparison(intrinsics.jsLtEq))
add(irBuiltIns.greaterFunByOperandType[irBuiltIns.long]!!.symbol, transformLongComparison(intrinsics.jsGt))
add(irBuiltIns.greaterOrEqualFunByOperandType[irBuiltIns.long]!!.symbol, transformLongComparison(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))
}
}
private fun transformLongComparison(comparator: IrSimpleFunction): (IrCall) -> IrExpression = { call ->
private fun transformLongComparison(comparator: IrSimpleFunctionSymbol): (IrCall) -> IrExpression = { call ->
IrCallImpl(
call.startOffset,
call.endOffset,
comparator.returnType,
comparator.symbol
comparator.owner.returnType,
comparator
).apply {
putValueArgument(0, irCall(call, intrinsics.longCompareToLong, firstArgumentAsDispatchReceiver = true))
putValueArgument(1, JsIrBuilder.buildInt(irBuiltIns.intType, 0))
@@ -82,11 +83,11 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls
return when {
lhs.type is IrDynamicType ->
irCall(call, intrinsics.jsEqeq.symbol)
irCall(call, intrinsics.jsEqeq)
// Special optimization for "<expression> == null"
lhs.isNullConst() || rhs.isNullConst() ->
irCall(call, intrinsics.jsEqeq.symbol)
irCall(call, intrinsics.jsEqeq)
// For non-float primitives of the same type use JS `==`
isLhsPrimitive && lhsJsType == rhsJsType && lhsJsType != PrimitiveType.FLOATING_POINT_NUMBER ->
@@ -102,9 +103,9 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls
private fun chooseEqualityOperatorForPrimitiveTypes(call: IrCall): IrExpression = when {
call.allValueArgumentsAreNullable() ->
irCall(call, intrinsics.jsEqeq.symbol)
irCall(call, intrinsics.jsEqeq)
else ->
irCall(call, intrinsics.jsEqeqeq.symbol)
irCall(call, intrinsics.jsEqeqeq)
}
private fun IrCall.allValueArgumentsAreNullable() =
@@ -142,7 +143,7 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls
// `Any.equals` works as identity operator
call.isSuperToAny() ->
irCall(call, intrinsics.jsEqeqeq.symbol, dispatchReceiverAsFirstArgument = true)
irCall(call, intrinsics.jsEqeqeq, dispatchReceiverAsFirstArgument = true)
// Use runtime function call in case when receiverType is a primitive JS type that doesn't have `equals` method,
// or has a potential to be primitive type (being fake overridden from `Any`)
@@ -97,7 +97,7 @@ class NumberOperatorCallsTransformer(context: JsIrBackendContext) : CallsTransfo
private fun irBinaryOp(
call: IrCall,
intrinsic: IrFunction,
intrinsic: IrFunctionSymbol,
toInt32: Boolean = false
): IrExpression {
val newCall = irCall(call, intrinsic, dispatchReceiverAsFirstArgument = true)
@@ -128,7 +128,7 @@ class NumberOperatorCallsTransformer(context: JsIrBackendContext) : CallsTransfo
result.isInt() -> when {
lhs.isInt() && rhs.isInt() ->
irBinaryOp(call, intrinsics.jsImul.owner)
irBinaryOp(call, intrinsics.jsImul)
else ->
irBinaryOp(call, intrinsics.jsMult, toInt32 = true)
@@ -150,8 +150,8 @@ class NumberOperatorCallsTransformer(context: JsIrBackendContext) : CallsTransfo
private fun transformDecrement(call: IrCall) =
transformCrement(call, intrinsics.jsMinus)
private fun transformCrement(call: IrCall, correspondingBinaryOp: IrFunction): IrExpression {
val operation = irCall(call, correspondingBinaryOp.symbol, dispatchReceiverAsFirstArgument = true).apply {
private fun transformCrement(call: IrCall, correspondingBinaryOp: IrFunctionSymbol): IrExpression {
val operation = irCall(call, correspondingBinaryOp, dispatchReceiverAsFirstArgument = true).apply {
putValueArgument(1, buildInt(1))
}
@@ -231,7 +231,7 @@ class NumberOperatorCallsTransformer(context: JsIrBackendContext) : CallsTransfo
}
private fun toInt32(e: IrExpression) =
JsIrBuilder.buildCall(intrinsics.jsBitOr.symbol, irBuiltIns.intType).apply {
JsIrBuilder.buildCall(intrinsics.jsBitOr, irBuiltIns.intType).apply {
putValueArgument(0, e)
putValueArgument(1, buildInt(0))
}
@@ -25,12 +25,12 @@ class PrimitiveContainerMemberCallTransformer(private val context: JsIrBackendCo
add(context.intrinsics.array.sizeProperty, context.intrinsics.jsArrayLength, true)
add(context.intrinsics.array.getFunction, context.intrinsics.jsArrayGet, true)
add(context.intrinsics.array.setFunction, context.intrinsics.jsArraySet, true)
add(context.intrinsics.array.iterator, context.intrinsics.jsArrayIteratorFunction.owner, true)
add(context.intrinsics.array.iterator, context.intrinsics.jsArrayIteratorFunction, true)
for ((key, elementType) in context.intrinsics.primitiveArrays) {
add(key.sizeProperty, context.intrinsics.jsArrayLength, true)
add(key.getFunction, context.intrinsics.jsArrayGet, true)
add(key.setFunction, context.intrinsics.jsArraySet, true)
add(key.iterator, context.intrinsics.jsPrimitiveArrayIteratorFunctions[elementType]!!.owner, true)
add(key.iterator, context.intrinsics.jsPrimitiveArrayIteratorFunctions[elementType]!!, true)
// TODO irCall?
add(key.sizeConstructor) { call ->
@@ -46,11 +46,11 @@ class PrimitiveContainerMemberCallTransformer(private val context: JsIrBackendCo
}
add(context.irBuiltIns.stringClass.lengthProperty, context.intrinsics.jsArrayLength, true)
add(context.irBuiltIns.stringClass.getFunction, intrinsics.jsCharSequenceGet.owner, true)
add(context.irBuiltIns.stringClass.subSequence, intrinsics.jsCharSequenceSubSequence.owner, true)
add(intrinsics.charSequenceLengthPropertyGetterSymbol, intrinsics.jsCharSequenceLength.owner, true)
add(intrinsics.charSequenceGetFunctionSymbol, intrinsics.jsCharSequenceGet.owner, true)
add(intrinsics.charSequenceSubSequenceFunctionSymbol, intrinsics.jsCharSequenceSubSequence.owner, true)
add(context.irBuiltIns.stringClass.getFunction, intrinsics.jsCharSequenceGet, true)
add(context.irBuiltIns.stringClass.subSequence, intrinsics.jsCharSequenceSubSequence, true)
add(intrinsics.charSequenceLengthPropertyGetterSymbol, intrinsics.jsCharSequenceLength, true)
add(intrinsics.charSequenceGetFunctionSymbol, intrinsics.jsCharSequenceGet, true)
add(intrinsics.charSequenceSubSequenceFunctionSymbol, intrinsics.jsCharSequenceSubSequence, true)
}
}
@@ -25,14 +25,14 @@ class ReflectionCallsTransformer(private val context: JsIrBackendContext) : Call
{ call ->
call.symbol.owner.dispatchReceiverParameter?.run { type.isSubtypeOfClass(context.irBuiltIns.kCallableClass) } ?: false
},
{ call -> irCall(call, context.intrinsics.jsName.symbol, dispatchReceiverAsFirstArgument = true) })
{ call -> irCall(call, context.intrinsics.jsName, dispatchReceiverAsFirstArgument = true) })
addWithPredicate(
Name.identifier(Namer.KPROPERTY_GET),
{ call ->
call.symbol.owner.dispatchReceiverParameter?.run { type.isSubtypeOfClass(context.irBuiltIns.kPropertyClass) } ?: false
},
{ call -> irCall(call, context.intrinsics.jsPropertyGet.symbol, dispatchReceiverAsFirstArgument = true) }
{ call -> irCall(call, context.intrinsics.jsPropertyGet, dispatchReceiverAsFirstArgument = true) }
)
addWithPredicate(
@@ -40,7 +40,7 @@ class ReflectionCallsTransformer(private val context: JsIrBackendContext) : Call
{ call ->
call.symbol.owner.dispatchReceiverParameter?.run { type.isSubtypeOfClass(context.irBuiltIns.kPropertyClass) } ?: false
},
{ call -> irCall(call, context.intrinsics.jsPropertySet.symbol, dispatchReceiverAsFirstArgument = true) }
{ call -> irCall(call, context.intrinsics.jsPropertySet, dispatchReceiverAsFirstArgument = true) }
)
}
}
@@ -22,15 +22,13 @@ class JsDescriptorReferenceDeserializer(
DescriptorReferenceDeserializer(currentModule, mutableMapOf<UniqIdKey, UniqIdKey>()),
DescriptorUniqIdAware by JsDescriptorUniqIdAware {
val knownBuiltInsDescriptors = mutableMapOf<DeclarationDescriptor, UniqId>()
override fun resolveSpecialDescriptor(fqn: FqName) = builtIns.builtIns.getBuiltInClassByFqName(fqn)
override fun checkIfSpecialDescriptorId(id: Long) =
(FUNCTION_INDEX_START + BUILT_IN_UNIQ_ID_CLASS_OFFSET) <= id && id < (FUNCTION_INDEX_START + BUILT_IN_UNIQ_ID_GAP)
override fun getDescriptorIdOrNull(descriptor: DeclarationDescriptor) =
knownBuiltInsDescriptors[descriptor]?.index ?: if (isBuiltInFunction(descriptor))
if (isBuiltInFunction(descriptor))
FUNCTION_INDEX_START + builtInFunctionId(descriptor)
else null
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.util.getInlineClassBackingField
@@ -235,21 +236,21 @@ private fun MutableMap<IrSymbol, IrCallTransformer>.addIfNotNull(symbol: IrSymbo
put(symbol, t)
}
private fun MutableMap<IrSymbol, IrCallTransformer>.binOp(function: IrFunction, op: JsBinaryOperator) {
private fun MutableMap<IrSymbol, IrCallTransformer>.binOp(function: IrFunctionSymbol, op: JsBinaryOperator) {
withTranslatedArgs(function) { JsBinaryOperation(op, it[0], it[1]) }
}
private fun MutableMap<IrSymbol, IrCallTransformer>.prefixOp(function: IrFunction, op: JsUnaryOperator) {
private fun MutableMap<IrSymbol, IrCallTransformer>.prefixOp(function: IrFunctionSymbol, op: JsUnaryOperator) {
withTranslatedArgs(function) { JsPrefixOperation(op, it[0]) }
}
private fun MutableMap<IrSymbol, IrCallTransformer>.postfixOp(function: IrFunction, op: JsUnaryOperator) {
private fun MutableMap<IrSymbol, IrCallTransformer>.postfixOp(function: IrFunctionSymbol, op: JsUnaryOperator) {
withTranslatedArgs(function) { JsPostfixOperation(op, it[0]) }
}
private inline fun MutableMap<IrSymbol, IrCallTransformer>.withTranslatedArgs(
function: IrFunction,
function: IrFunctionSymbol,
crossinline t: (List<JsExpression>) -> JsExpression
) {
put(function.symbol) { call, context -> t(translateCallArguments(call, context)) }
put(function) { call, context -> t(translateCallArguments(call, context)) }
}
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.lexer.KtSingleValueToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.resolve.DescriptorUtils
@@ -32,9 +33,9 @@ class IrIntrinsicMethods(irBuiltIns: IrBuiltIns) {
private val irMapping = hashMapOf<CallableMemberDescriptor, IntrinsicMethod>()
private fun createPrimitiveComparisonIntrinsics(typeToIrFun: Map<SimpleType, IrSimpleFunction>, operator: KtSingleValueToken) {
for ((type, irFun) in typeToIrFun) {
irMapping[irFun.descriptor] = PrimitiveComparison(type, operator)
private fun createPrimitiveComparisonIntrinsics(typeToIrFun: Map<SimpleType, IrSimpleFunctionSymbol>, operator: KtSingleValueToken) {
for ((type, irFunSymbol) in typeToIrFun) {
irMapping[irFunSymbol.descriptor] = PrimitiveComparison(type, operator)
}
}
@@ -379,7 +379,7 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
},
irInt(unboundCalleeParameters.size)
),
irCall(context.irBuiltIns.illegalArgumentExceptionFun).apply {
irCall(context.irBuiltIns.illegalArgumentExceptionSymbol).apply {
putValueArgument(0, irString("Expected ${unboundCalleeParameters.size} arguments"))
}
)
@@ -410,7 +410,7 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
)
+irIfThen(
irNotIs(irGet(argValue), type),
irCall(context.irBuiltIns.illegalArgumentExceptionFun).apply {
irCall(context.irBuiltIns.illegalArgumentExceptionSymbol).apply {
putValueArgument(0, irString("Wrong type, expected $type"))
}
)
@@ -494,7 +494,7 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
}
private fun createEnumValueOfBody(): IrBody {
val enumValueOf = context.irBuiltIns.enumValueOfFun
val enumValueOf = context.irBuiltIns.enumValueOfSymbol
val returnType = irClass.defaultType
val unsubstitutedValueOfDescriptor = enumValueOf.descriptor
@@ -508,9 +508,9 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
UNDEFINED_OFFSET,
UNDEFINED_OFFSET,
returnType,
enumValueOf.symbol,
enumValueOf,
substitutedValueOfDescriptor,
enumValueOf.typeParameters.size
enumValueOf.owner.typeParameters.size
)
irValueOfCall.putTypeArgument(0, irClass.defaultType)
irValueOfCall.putValueArgument(
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.expressions.IrCall
@@ -16,6 +15,7 @@ import org.jetbrains.kotlin.ir.expressions.IrConst
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.resolve.constants.evaluate.evaluateBinary
@@ -146,7 +146,7 @@ class FoldConstantLowering(private val context: JvmBackendContext) : IrElementTr
private fun tryFoldingBuiltinBinaryOps(call: IrCall): IrExpression {
// Make sure that this is a IrBuiltIn
if (call.symbol.owner.origin != IrDeclarationOrigin.IR_BUILTINS_STUB)
if (call.symbol.owner.fqNameWhenAvailable?.parent() != IrBuiltIns.KOTLIN_INTERNAL_IR_FQN)
return call
val lhs = call.getValueArgument(0) as? IrConst<*> ?: return call
@@ -124,7 +124,7 @@ private class FunctionNVarargInvokeLowering(var context: JvmBackendContext) : Cl
)
+irIfThen(
irNotIs(irGet(argValue), type),
irCall(context.irBuiltIns.illegalArgumentExceptionFun).apply {
irCall(context.irBuiltIns.illegalArgumentExceptionSymbol).apply {
putValueArgument(0, irString("Wrong type, expected $type"))
}
)
@@ -143,7 +143,7 @@ private class FunctionNVarargInvokeLowering(var context: JvmBackendContext) : Cl
separator = " or ",
postfix = " arguments to invoke call"
)
+irCall(context.irBuiltIns.illegalArgumentExceptionFun.symbol).apply {
+irCall(context.irBuiltIns.illegalArgumentExceptionSymbol).apply {
putValueArgument(0, irString(throwMessage))
}
}
@@ -298,8 +298,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
val comparisonInfo = getPrimitiveNumericComparisonInfo(expression)
val comparisonType = comparisonInfo?.comparisonType
val eqeqSymbol = context.irBuiltIns.ieee754equalsFunByOperandType[comparisonType]?.symbol
?: context.irBuiltIns.eqeqSymbol
val eqeqSymbol = context.irBuiltIns.ieee754equalsFunByOperandType[comparisonType] ?: context.irBuiltIns.eqeqSymbol
val irEquals = IrBinaryPrimitiveImpl(
expression.startOffsetSkippingComments, expression.endOffset,
@@ -337,8 +336,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
if (comparisonInfo != null) {
val comparisonType = comparisonInfo.comparisonType
val eqeqSymbol =
context.irBuiltIns.ieee754equalsFunByOperandType[comparisonType]?.symbol
?: context.irBuiltIns.eqeqSymbol
context.irBuiltIns.ieee754equalsFunByOperandType[comparisonType] ?: context.irBuiltIns.eqeqSymbol
IrBinaryPrimitiveImpl(
startOffset, endOffset,
context.irBuiltIns.booleanType,
@@ -463,7 +461,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
IrStatementOrigin.GT -> context.irBuiltIns.greaterFunByOperandType
IrStatementOrigin.GTEQ -> context.irBuiltIns.greaterOrEqualFunByOperandType
else -> throw AssertionError("Unexpected comparison operator: $origin")
}[primitiveNumericType]!!.symbol
}[primitiveNumericType]!!
private fun generateExclExclOperator(expression: KtPostfixExpression, origin: IrStatementOrigin): IrExpression {
val ktArgument = expression.baseExpression!!
@@ -183,13 +183,13 @@ fun IrBuilderWithScope.irNull() =
fun IrBuilderWithScope.irEqualsNull(argument: IrExpression) =
primitiveOp2(
startOffset, endOffset, context.irBuiltIns.eqeqSymbol, IrStatementOrigin.EQEQ,
startOffset, endOffset, context.irBuiltIns.eqeqSymbol, context.irBuiltIns.booleanType, IrStatementOrigin.EQEQ,
argument, irNull()
)
fun IrBuilderWithScope.irEquals(arg1: IrExpression, arg2: IrExpression, origin: IrStatementOrigin = IrStatementOrigin.EQEQ) =
primitiveOp2(
startOffset, endOffset, context.irBuiltIns.eqeqSymbol, origin,
startOffset, endOffset, context.irBuiltIns.eqeqSymbol, context.irBuiltIns.booleanType, origin,
arg1, arg2
)
@@ -40,22 +40,23 @@ fun primitiveOp1(
fun primitiveOp2(
startOffset: Int, endOffset: Int,
primitiveOpSymbol: IrSimpleFunctionSymbol,
primitiveOpReturnType: IrType,
origin: IrStatementOrigin,
argument1: IrExpression, argument2: IrExpression
): IrExpression =
IrBinaryPrimitiveImpl(startOffset, endOffset, primitiveOpSymbol.owner.returnType, origin, primitiveOpSymbol, argument1, argument2)
IrBinaryPrimitiveImpl(startOffset, endOffset, primitiveOpReturnType, origin, primitiveOpSymbol, argument1, argument2)
fun IrGeneratorContext.constNull(startOffset: Int, endOffset: Int): IrExpression =
IrConstImpl.constNull(startOffset, endOffset, irBuiltIns.nothingNType)
fun IrGeneratorContext.equalsNull(startOffset: Int, endOffset: Int, argument: IrExpression): IrExpression =
primitiveOp2(
startOffset, endOffset, irBuiltIns.eqeqSymbol, IrStatementOrigin.EQEQ,
startOffset, endOffset, irBuiltIns.eqeqSymbol, irBuiltIns.booleanType, IrStatementOrigin.EQEQ,
argument, constNull(startOffset, endOffset)
)
fun IrGeneratorContext.eqeqeq(startOffset: Int, endOffset: Int, argument1: IrExpression, argument2: IrExpression): IrExpression =
primitiveOp2(startOffset, endOffset, irBuiltIns.eqeqeqSymbol, IrStatementOrigin.EQEQEQ, argument1, argument2)
primitiveOp2(startOffset, endOffset, irBuiltIns.eqeqeqSymbol, irBuiltIns.booleanType, IrStatementOrigin.EQEQEQ, argument1, argument2)
fun IrGeneratorContext.throwNpe(startOffset: Int, endOffset: Int, origin: IrStatementOrigin): IrExpression =
IrNullaryPrimitiveImpl(startOffset, endOffset, irBuiltIns.nothingType, origin, irBuiltIns.throwNpeSymbol)
@@ -15,13 +15,12 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrExternalPackageFragmentSymbolImpl
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.toIrType
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.types.withHasQuestionMark
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.TypeTranslator
import org.jetbrains.kotlin.name.FqName
@@ -42,35 +41,27 @@ class IrBuiltIns(
private val builtInsModule = builtIns.builtInsModule
private val packageFragment = IrBuiltinsPackageFragmentDescriptorImpl(builtInsModule, KOTLIN_INTERNAL_IR_FQN)
val irBuiltInsExternalPackageFragment = IrExternalPackageFragmentImpl(IrExternalPackageFragmentSymbolImpl(packageFragment))
val irBuiltInsSymbols = mutableListOf<IrSimpleFunctionSymbol>()
private val symbolTable = outerSymbolTable ?: SymbolTable()
private val stubBuilder = DeclarationStubGenerator(
builtInsModule, symbolTable, languageVersionSettings, externalDeclarationOrigin = { IrDeclarationOrigin.IR_BUILTINS_STUB }
)
private fun ClassDescriptor.toIrSymbol() = symbolTable.referenceClass(this)
private fun KotlinType.toIrType() = typeTranslator.translateType(this)
fun defineOperator(name: String, returnType: KotlinType, valueParameterTypes: List<KotlinType>): IrSimpleFunction {
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)
)
}
return addStubToPackageFragment(operatorDescriptor)
return operatorDescriptor.addStub()
}
private fun addStubToPackageFragment(descriptor: SimpleFunctionDescriptor): IrSimpleFunction {
val irSimpleFunction = stubBuilder.generateFunctionStub(descriptor)
irBuiltInsExternalPackageFragment.declarations.add(irSimpleFunction)
irSimpleFunction.parent = irBuiltInsExternalPackageFragment
return irSimpleFunction
}
private fun <T : SimpleFunctionDescriptor> T.addStub(): IrSimpleFunction =
addStubToPackageFragment(this)
private fun <T : SimpleFunctionDescriptor> T.addStub(): IrSimpleFunctionSymbol =
symbolTable.referenceSimpleFunction(this).also {
irBuiltInsSymbols += it
}
private fun defineComparisonOperator(name: String, operandType: KotlinType) =
defineOperator(name, bool, listOf(operandType, operandType))
@@ -142,27 +133,27 @@ class IrBuiltIns(
val throwableType = builtIns.throwable.defaultType.toIrType()
val throwableClass = builtIns.throwable.toIrSymbol()
private class IrTypeMapper(val type: IrType, val nType: IrType)
private fun buildNullableType(irType: IrType) = with(irType as IrSimpleType) {
IrSimpleTypeImpl(classifier, true, arguments, annotations)
private class IrTypeMapper(val type: IrType) {
val nType: IrType = with(type as IrSimpleType) {
IrSimpleTypeImpl(classifier, true, arguments, annotations)
}
}
private val primitiveTypesMapping = mapOf(
builtIns.any to IrTypeMapper(anyType, anyNType),
builtIns.boolean to IrTypeMapper(booleanType, buildNullableType(booleanType)),
builtIns.char to IrTypeMapper(charType, buildNullableType(charType)),
builtIns.number to IrTypeMapper(numberType, buildNullableType(numberType)),
builtIns.byte to IrTypeMapper(byteType, buildNullableType(byteType)),
builtIns.short to IrTypeMapper(shortType, buildNullableType(shortType)),
builtIns.int to IrTypeMapper(intType, buildNullableType(intType)),
builtIns.long to IrTypeMapper(longType, buildNullableType(longType)),
builtIns.float to IrTypeMapper(floatType, buildNullableType(floatType)),
builtIns.double to IrTypeMapper(doubleType, buildNullableType(doubleType)),
builtIns.nothing to IrTypeMapper(nothingType, nothingNType),
builtIns.unit to IrTypeMapper(unitType, buildNullableType(unitType)),
builtIns.string to IrTypeMapper(stringType, buildNullableType(stringType)),
builtIns.throwable to IrTypeMapper(throwableType, buildNullableType(throwableType))
builtIns.any to IrTypeMapper(anyType),
builtIns.boolean to IrTypeMapper(booleanType),
builtIns.char to IrTypeMapper(charType),
builtIns.number to IrTypeMapper(numberType),
builtIns.byte to IrTypeMapper(byteType),
builtIns.short to IrTypeMapper(shortType),
builtIns.int to IrTypeMapper(intType),
builtIns.long to IrTypeMapper(longType),
builtIns.float to IrTypeMapper(floatType),
builtIns.double to IrTypeMapper(doubleType),
builtIns.nothing to IrTypeMapper(nothingType),
builtIns.unit to IrTypeMapper(unitType),
builtIns.string to IrTypeMapper(stringType),
builtIns.throwable to IrTypeMapper(throwableType)
)
fun getPrimitiveTypeOrNullByDescriptor(descriptor: ClassifierDescriptor, isNullable: Boolean) =
@@ -190,36 +181,28 @@ class IrBuiltIns(
it to defineOperator(OperatorNames.IEEE754_EQUALS, bool, listOf(it.makeNullable(), it.makeNullable()))
}
val eqeqeqFun = defineOperator(OperatorNames.EQEQEQ, bool, listOf(anyN, anyN))
val eqeqFun = defineOperator(OperatorNames.EQEQ, bool, listOf(anyN, anyN))
val throwNpeFun = defineOperator(OperatorNames.THROW_NPE, nothing, listOf())
val throwCceFun = defineOperator(OperatorNames.THROW_CCE, nothing, listOf())
val throwIseFun = defineOperator(OperatorNames.THROW_ISE, nothing, listOf())
val noWhenBranchMatchedExceptionFun = defineOperator(OperatorNames.NO_WHEN_BRANCH_MATCHED_EXCEPTION, nothing, listOf())
val illegalArgumentExceptionFun = defineOperator(OperatorNames.ILLEGAL_ARGUMENT_EXCEPTION, nothing, listOf(string))
val eqeqeq = eqeqeqFun.descriptor
val eqeq = eqeqFun.descriptor
val throwNpe = throwNpeFun.descriptor
val throwCce = throwCceFun.descriptor
val booleanNot = builtIns.boolean.unsubstitutedMemberScope.getContributedFunctions(Name.identifier("not"), NoLookupLocation.FROM_BACKEND).single()
val noWhenBranchMatchedException = noWhenBranchMatchedExceptionFun.descriptor
val illegalArgumentException = illegalArgumentExceptionFun.descriptor
val eqeqeqSymbol = eqeqeqFun.symbol
val eqeqSymbol = eqeqFun.symbol
val throwNpeSymbol = throwNpeFun.symbol
val throwCceSymbol = throwCceFun.symbol
val throwIseSymbol = throwIseFun.symbol
val booleanNotSymbol = symbolTable.referenceSimpleFunction(booleanNot)
val noWhenBranchMatchedExceptionSymbol = noWhenBranchMatchedExceptionFun.symbol
val illegalArgumentExceptionSymbol = illegalArgumentExceptionFun.symbol
val enumValueOfFun = createEnumValueOfFun()
val enumValueOf = enumValueOfFun.descriptor
val enumValueOfSymbol = enumValueOfFun.symbol
val eqeqeqSymbol = defineOperator(OperatorNames.EQEQEQ, bool, listOf(anyN, anyN))
val eqeqSymbol = defineOperator(OperatorNames.EQEQ, bool, listOf(anyN, anyN))
val throwNpeSymbol = defineOperator(OperatorNames.THROW_NPE, nothing, listOf())
val throwCceSymbol = defineOperator(OperatorNames.THROW_CCE, nothing, listOf())
val throwIseSymbol = defineOperator(OperatorNames.THROW_ISE, nothing, listOf())
val noWhenBranchMatchedExceptionSymbol = defineOperator(OperatorNames.NO_WHEN_BRANCH_MATCHED_EXCEPTION, nothing, listOf())
val illegalArgumentExceptionSymbol = defineOperator(OperatorNames.ILLEGAL_ARGUMENT_EXCEPTION, nothing, listOf(string))
private fun createEnumValueOfFun(): IrSimpleFunction =
val eqeqeq = eqeqeqSymbol.descriptor
val eqeq = eqeqSymbol.descriptor
val throwNpe = throwNpeSymbol.descriptor
val throwCce = throwCceSymbol.descriptor
val noWhenBranchMatchedException = noWhenBranchMatchedExceptionSymbol.descriptor
val illegalArgumentException = illegalArgumentExceptionSymbol.descriptor
val enumValueOfSymbol = createEnumValueOfFun()
val enumValueOf = enumValueOfSymbol.descriptor
private fun createEnumValueOfFun(): IrSimpleFunctionSymbol =
SimpleFunctionDescriptorImpl.create(
packageFragment,
Annotations.EMPTY,
@@ -241,13 +224,11 @@ class IrBuiltIns(
initialize(null, null, listOf(typeParameterT), listOf(valueParameterName), returnType, Modality.FINAL, Visibilities.PUBLIC)
}.addStub()
val dataClassArrayMemberHashCodeFun = defineOperator("dataClassArrayMemberHashCode", int, listOf(any))
val dataClassArrayMemberHashCode = dataClassArrayMemberHashCodeFun.descriptor
val dataClassArrayMemberHashCodeSymbol = dataClassArrayMemberHashCodeFun.symbol
val dataClassArrayMemberHashCodeSymbol = defineOperator("dataClassArrayMemberHashCode", int, listOf(any))
val dataClassArrayMemberHashCode = dataClassArrayMemberHashCodeSymbol.descriptor
val dataClassArrayMemberToStringFun = defineOperator("dataClassArrayMemberToString", string, listOf(anyN))
val dataClassArrayMemberToString = dataClassArrayMemberToStringFun.descriptor
val dataClassArrayMemberToStringSymbol = dataClassArrayMemberToStringFun.symbol
val dataClassArrayMemberToStringSymbol = defineOperator("dataClassArrayMemberToString", string, listOf(anyN))
val dataClassArrayMemberToString = dataClassArrayMemberToStringSymbol.descriptor
companion object {
val KOTLIN_INTERNAL_IR_FQN = FqName("kotlin.internal.ir")