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
@@ -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)) }
}