From a40448aebccfdcb4af85eabac51463ec9bf86033 Mon Sep 17 00:00:00 2001 From: Svyatoslav Kuzmich Date: Tue, 22 Jan 2019 19:18:38 +0300 Subject: [PATCH] [JS IR BE] Use unsigned types lowering lazily --- .../jetbrains/kotlin/ir/util/IrTypeUtils.kt | 12 ++++++-- .../kotlin/ir/backend/js/JsIntrinsics.kt | 9 +++--- .../ir/backend/js/lower/ConstLowering.kt | 30 +++++++++++-------- .../jetbrains/kotlin/builtins/UnsignedType.kt | 1 + 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/util/IrTypeUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/util/IrTypeUtils.kt index 1f43f76c472..2715b03630d 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/util/IrTypeUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/util/IrTypeUtils.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.ir.util +import org.jetbrains.kotlin.builtins.UnsignedTypes import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.ir.declarations.IrClass 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) { 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 return parent.fqName == kotlinPackageFqn } else return false } -fun IrType.isThrowableTypeOrSubtype() = DFS.ifAny(listOf(this), IrType::superTypes, IrType::isThrowable) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt index f5e21281edb..d36da88e126 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt @@ -15,7 +15,6 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.symbols.impl.IrExternalPackageFragmentSymbolImpl import org.jetbrains.kotlin.ir.util.constructors -import org.jetbrains.kotlin.ir.util.getPropertyGetter import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name 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 charConstructor = charClassSymbol.constructors.single().owner - val uByteClassSymbol = getInternalClassWithoutPackage("kotlin.UByte") - val uShortClassSymbol = getInternalClassWithoutPackage("kotlin.UShort") - val uIntClassSymbol = getInternalClassWithoutPackage("kotlin.UInt") - val uLongClassSymbol = getInternalClassWithoutPackage("kotlin.ULong") + val uByteClassSymbol by lazy { getInternalClassWithoutPackage("kotlin.UByte") } + val uShortClassSymbol by lazy { getInternalClassWithoutPackage("kotlin.UShort") } + val uIntClassSymbol by lazy { getInternalClassWithoutPackage("kotlin.UInt") } + val uLongClassSymbol by lazy { getInternalClassWithoutPackage("kotlin.ULong") } val unreachable = defineUnreachableIntrinsic() diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ConstLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ConstLowering.kt index 1d50cf08342..3b0d4bc96b6 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ConstLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ConstLowering.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.classifierOrNull 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.transformChildrenVoid @@ -42,25 +43,28 @@ class ConstTransformer(private val context: JsIrBackendContext) : IrElementTrans override fun visitConst(expression: IrConst): IrExpression { with(context.intrinsics) { - return when (expression.type.classifierOrNull) { - uByteClassSymbol -> lowerConst(uByteClassSymbol, IrConstImpl<*>::byte, IrConstKind.Byte.valueOf(expression)) + if (expression.type.isUnsigned()) { + 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 { - 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) + else -> error("Unknown unsigned type") } } + 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) + } } } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/UnsignedType.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/UnsignedType.kt index e6e0360ec01..f2d90cb0e53 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/UnsignedType.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/UnsignedType.kt @@ -38,6 +38,7 @@ object UnsignedTypes { } fun isShortNameOfUnsignedArray(name: Name) = name in arrayClassesShortNames + fun isShortNameOfUnsignedType(name: Name) = name in unsignedTypeNames fun getUnsignedClassIdByArrayClassId(arrayClassId: ClassId): ClassId? = arrayClassIdToUnsignedClassId[arrayClassId] fun getUnsignedArrayClassIdByUnsignedClassId(arrayClassId: ClassId): ClassId? = unsignedClassIdToArrayClassId[arrayClassId]