[JS IR BE] Use unsigned types lowering lazily

This commit is contained in:
Svyatoslav Kuzmich
2019-01-22 19:18:38 +03:00
parent eea7e85d3a
commit a40448aebc
4 changed files with 31 additions and 21 deletions
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.ir.util package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.builtins.UnsignedTypes
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrDeclaration
@@ -75,13 +76,18 @@ fun IrType.isNullable(): Boolean = DFS.ifAny(listOf(this), { it.typeParameterSup
}) })
fun IrType.isThrowable(): Boolean { fun IrType.isThrowable(): Boolean = isTypeFromKotlinPackage { name -> name.asString() == "Throwable" }
fun IrType.isThrowableTypeOrSubtype() = DFS.ifAny(listOf(this), IrType::superTypes, IrType::isThrowable)
fun IrType.isUnsigned(): Boolean = isTypeFromKotlinPackage { name -> UnsignedTypes.isShortNameOfUnsignedType(name) }
private inline fun IrType.isTypeFromKotlinPackage(namePredicate: (Name) -> Boolean): Boolean {
if (this is IrSimpleType) { if (this is IrSimpleType) {
val classClassifier = classifier as? IrClassSymbol ?: return false val classClassifier = classifier as? IrClassSymbol ?: return false
if (classClassifier.owner.name.asString() != "Throwable") return false if (!namePredicate(classClassifier.owner.name)) return false
val parent = classClassifier.owner.parent as? IrPackageFragment ?: return false val parent = classClassifier.owner.parent as? IrPackageFragment ?: return false
return parent.fqName == kotlinPackageFqn return parent.fqName == kotlinPackageFqn
} else return false } else return false
} }
fun IrType.isThrowableTypeOrSubtype() = DFS.ifAny(listOf(this), IrType::superTypes, IrType::isThrowable)
@@ -15,7 +15,6 @@ 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.util.constructors import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.ir.util.getPropertyGetter
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.psi2ir.findSingleFunction import org.jetbrains.kotlin.psi2ir.findSingleFunction
@@ -181,10 +180,10 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
val charClassSymbol = getInternalClassWithoutPackage("kotlin.Char") val charClassSymbol = getInternalClassWithoutPackage("kotlin.Char")
val charConstructor = charClassSymbol.constructors.single().owner val charConstructor = charClassSymbol.constructors.single().owner
val uByteClassSymbol = getInternalClassWithoutPackage("kotlin.UByte") val uByteClassSymbol by lazy { getInternalClassWithoutPackage("kotlin.UByte") }
val uShortClassSymbol = getInternalClassWithoutPackage("kotlin.UShort") val uShortClassSymbol by lazy { getInternalClassWithoutPackage("kotlin.UShort") }
val uIntClassSymbol = getInternalClassWithoutPackage("kotlin.UInt") val uIntClassSymbol by lazy { getInternalClassWithoutPackage("kotlin.UInt") }
val uLongClassSymbol = getInternalClassWithoutPackage("kotlin.ULong") val uLongClassSymbol by lazy { getInternalClassWithoutPackage("kotlin.ULong") }
val unreachable = defineUnreachableIntrinsic() val unreachable = defineUnreachableIntrinsic()
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classifierOrNull import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.ir.util.constructors import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.ir.util.isUnsigned
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
@@ -42,25 +43,28 @@ class ConstTransformer(private val context: JsIrBackendContext) : IrElementTrans
override fun <T> visitConst(expression: IrConst<T>): IrExpression { override fun <T> visitConst(expression: IrConst<T>): IrExpression {
with(context.intrinsics) { with(context.intrinsics) {
return when (expression.type.classifierOrNull) { if (expression.type.isUnsigned()) {
uByteClassSymbol -> lowerConst(uByteClassSymbol, IrConstImpl<*>::byte, IrConstKind.Byte.valueOf(expression)) return when (expression.type.classifierOrNull) {
uByteClassSymbol -> lowerConst(uByteClassSymbol, IrConstImpl<*>::byte, IrConstKind.Byte.valueOf(expression))
uShortClassSymbol -> lowerConst(uShortClassSymbol, IrConstImpl<*>::short, IrConstKind.Short.valueOf(expression)) uShortClassSymbol -> lowerConst(uShortClassSymbol, IrConstImpl<*>::short, IrConstKind.Short.valueOf(expression))
uIntClassSymbol -> lowerConst(uIntClassSymbol, IrConstImpl<*>::int, IrConstKind.Int.valueOf(expression)) uIntClassSymbol -> lowerConst(uIntClassSymbol, IrConstImpl<*>::int, IrConstKind.Int.valueOf(expression))
uLongClassSymbol -> lowerConst(uLongClassSymbol, { _, _, _, v -> createLong(v) }, IrConstKind.Long.valueOf(expression)) uLongClassSymbol -> lowerConst(uLongClassSymbol, { _, _, _, v -> createLong(v) }, IrConstKind.Long.valueOf(expression))
else -> when { else -> error("Unknown unsigned type")
expression.kind is IrConstKind.Char ->
lowerConst(charClassSymbol, IrConstImpl<*>::int, IrConstKind.Char.valueOf(expression).toInt())
expression.kind is IrConstKind.Long ->
createLong(IrConstKind.Long.valueOf(expression))
else -> super.visitConst(expression)
} }
} }
return when {
expression.kind is IrConstKind.Char ->
lowerConst(charClassSymbol, IrConstImpl<*>::int, IrConstKind.Char.valueOf(expression).toInt())
expression.kind is IrConstKind.Long ->
createLong(IrConstKind.Long.valueOf(expression))
else -> super.visitConst(expression)
}
} }
} }
} }
@@ -38,6 +38,7 @@ object UnsignedTypes {
} }
fun isShortNameOfUnsignedArray(name: Name) = name in arrayClassesShortNames fun isShortNameOfUnsignedArray(name: Name) = name in arrayClassesShortNames
fun isShortNameOfUnsignedType(name: Name) = name in unsignedTypeNames
fun getUnsignedClassIdByArrayClassId(arrayClassId: ClassId): ClassId? = arrayClassIdToUnsignedClassId[arrayClassId] fun getUnsignedClassIdByArrayClassId(arrayClassId: ClassId): ClassId? = arrayClassIdToUnsignedClassId[arrayClassId]
fun getUnsignedArrayClassIdByUnsignedClassId(arrayClassId: ClassId): ClassId? = unsignedClassIdToArrayClassId[arrayClassId] fun getUnsignedArrayClassIdByUnsignedClassId(arrayClassId: ClassId): ClassId? = unsignedClassIdToArrayClassId[arrayClassId]