[JS IR BE] unsigned literal support
This commit is contained in:
@@ -148,8 +148,8 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
||||
val jsNumberRangeToNumber = getInternalFunction("numberRangeToNumber")
|
||||
val jsNumberRangeToLong = getInternalFunction("numberRangeToLong")
|
||||
|
||||
val longConstructor =
|
||||
context.symbolTable.referenceConstructor(context.getClass(FqName("kotlin.Long")).constructors.single())
|
||||
val longClassSymbol = getInternalClassWithoutPackage("kotlin.Long")
|
||||
|
||||
val longToDouble = context.symbolTable.referenceSimpleFunction(
|
||||
context.getClass(FqName("kotlin.Long")).unsubstitutedMemberScope.findSingleFunction(
|
||||
Name.identifier("toDouble")
|
||||
@@ -161,7 +161,12 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
||||
)
|
||||
)
|
||||
|
||||
val charConstructor = context.symbolTable.referenceConstructor(context.getClass(KotlinBuiltIns.FQ_NAMES._char.toSafe()).constructors.single())
|
||||
val charClassSymbol = getInternalClassWithoutPackage("kotlin.Char")
|
||||
|
||||
val uByteClassSymbol = getInternalClassWithoutPackage("kotlin.UByte")
|
||||
val uShortClassSymbol = getInternalClassWithoutPackage("kotlin.UShort")
|
||||
val uIntClassSymbol = getInternalClassWithoutPackage("kotlin.UInt")
|
||||
val uLongClassSymbol = getInternalClassWithoutPackage("kotlin.ULong")
|
||||
|
||||
val unreachable = defineUnreachableIntrinsic()
|
||||
|
||||
@@ -222,6 +227,9 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
||||
private fun getInternalWithoutPackage(name: String) =
|
||||
context.symbolTable.referenceSimpleFunction(context.getFunctions(FqName(name)).single())
|
||||
|
||||
private fun getInternalClassWithoutPackage(fqName: String) =
|
||||
context.symbolTable.referenceClass(context.getClass(FqName(fqName)))
|
||||
|
||||
// TODO: unify how we create intrinsic symbols
|
||||
private fun defineObjectCreateIntrinsic() =
|
||||
JsIrBuilder.buildFunction("Object\$create", isInline = true, origin = JsLoweredDeclarationOrigin.JS_INTRINSICS_STUB).also {
|
||||
|
||||
+38
-37
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
@@ -189,18 +190,13 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
|
||||
|
||||
for (type in arrayOf(irBuiltIns.byteType, irBuiltIns.intType)) {
|
||||
op(type, ConversionNames.TO_CHAR) {
|
||||
irCall(it, intrinsics.charConstructor, dispatchReceiverAsFirstArgument = true)
|
||||
irCall(it, intrinsics.charClassSymbol.constructors.single(), dispatchReceiverAsFirstArgument = true)
|
||||
}
|
||||
}
|
||||
|
||||
for (type in arrayOf(irBuiltIns.floatType, irBuiltIns.doubleType)) {
|
||||
op(type, ConversionNames.TO_CHAR) {
|
||||
IrCallImpl(
|
||||
it.startOffset,
|
||||
it.endOffset,
|
||||
irBuiltIns.charType,
|
||||
intrinsics.charConstructor
|
||||
).apply {
|
||||
JsIrBuilder.buildCall(intrinsics.charClassSymbol.constructors.single()).apply {
|
||||
putValueArgument(0, irCall(it, intrinsics.jsNumberToInt, dispatchReceiverAsFirstArgument = true))
|
||||
}
|
||||
}
|
||||
@@ -306,42 +302,47 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
|
||||
}
|
||||
}
|
||||
|
||||
private fun lowerLongConst(value: Long, startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET): IrExpression {
|
||||
val high = (value shr 32).toInt()
|
||||
val low = value.toInt()
|
||||
return IrCallImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
irBuiltIns.longType,
|
||||
context.intrinsics.longConstructor
|
||||
).apply {
|
||||
putValueArgument(0, JsIrBuilder.buildInt(context.irBuiltIns.intType, low))
|
||||
putValueArgument(1, JsIrBuilder.buildInt(context.irBuiltIns.intType, high))
|
||||
}
|
||||
}
|
||||
|
||||
private fun lowerCharConst(value: Char, startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET): IrExpression {
|
||||
return IrCallImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
irBuiltIns.charType,
|
||||
context.intrinsics.charConstructor
|
||||
).apply {
|
||||
putValueArgument(0, JsIrBuilder.buildInt(context.irBuiltIns.intType, value.toInt()))
|
||||
}
|
||||
}
|
||||
|
||||
override fun lower(irFile: IrFile) {
|
||||
irFile.transform(object : IrElementTransformerVoid() {
|
||||
private fun <C> lowerConst(
|
||||
irClass: IrClassSymbol,
|
||||
carrierFactory: (Int, Int, IrType, C) -> IrExpression,
|
||||
vararg args: C
|
||||
): IrExpression {
|
||||
val constructor = irClass.constructors.single()
|
||||
val argType = constructor.owner.valueParameters.first().type
|
||||
return JsIrBuilder.buildCall(constructor).apply {
|
||||
for (i in args.indices) {
|
||||
putValueArgument(i, carrierFactory(UNDEFINED_OFFSET, UNDEFINED_OFFSET, argType, args[i]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createLong(v: Long): IrExpression = lowerConst(context.intrinsics.longClassSymbol, IrConstImpl<*>::int, v.toInt(), (v shr 32).toInt())
|
||||
|
||||
// TODO should this be a separate lowering?
|
||||
override fun <T> visitConst(expression: IrConst<T>): IrExpression {
|
||||
if (expression.kind is IrConstKind.Long) {
|
||||
return lowerLongConst(IrConstKind.Long.valueOf(expression), expression.startOffset, expression.endOffset)
|
||||
} else if (expression.kind is IrConstKind.Char) {
|
||||
return lowerCharConst(IrConstKind.Char.valueOf(expression), expression.startOffset, expression.endOffset)
|
||||
with(context.intrinsics) {
|
||||
return when (expression.type.classifierOrNull) {
|
||||
uByteClassSymbol -> lowerConst(uByteClassSymbol, IrConstImpl<*>::byte, IrConstKind.Byte.valueOf(expression))
|
||||
|
||||
uShortClassSymbol -> lowerConst(uShortClassSymbol, IrConstImpl<*>::short, IrConstKind.Short.valueOf(expression))
|
||||
|
||||
uIntClassSymbol -> lowerConst(uIntClassSymbol, IrConstImpl<*>::int, IrConstKind.Int.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)
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.visitConst(expression)
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
|
||||
Reference in New Issue
Block a user