[JS IR BE] Support Number.to(Byte|Short|Int|Float|Double|Long)
This commit is contained in:
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.ir.declarations.IrProperty
|
|||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
|
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.getPropertyGetter
|
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
|
||||||
@@ -101,6 +102,7 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
|||||||
val jsNumberToInt = getInternalFunction("numberToInt")
|
val jsNumberToInt = getInternalFunction("numberToInt")
|
||||||
val jsNumberToShort = getInternalFunction("numberToShort")
|
val jsNumberToShort = getInternalFunction("numberToShort")
|
||||||
val jsNumberToLong = getInternalFunction("numberToLong")
|
val jsNumberToLong = getInternalFunction("numberToLong")
|
||||||
|
val jsNumberToChar = getInternalFunction("numberToChar")
|
||||||
val jsToByte = getInternalFunction("toByte")
|
val jsToByte = getInternalFunction("toByte")
|
||||||
val jsToShort = getInternalFunction("toShort")
|
val jsToShort = getInternalFunction("toShort")
|
||||||
val jsToLong = getInternalFunction("toLong")
|
val jsToLong = getInternalFunction("toLong")
|
||||||
@@ -174,6 +176,7 @@ 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 uByteClassSymbol = getInternalClassWithoutPackage("kotlin.UByte")
|
val uByteClassSymbol = getInternalClassWithoutPackage("kotlin.UByte")
|
||||||
val uShortClassSymbol = getInternalClassWithoutPackage("kotlin.UShort")
|
val uShortClassSymbol = getInternalClassWithoutPackage("kotlin.UShort")
|
||||||
|
|||||||
+6
-7
@@ -6,11 +6,10 @@
|
|||||||
package org.jetbrains.kotlin.ir.backend.js.lower.calls
|
package org.jetbrains.kotlin.ir.backend.js.lower.calls
|
||||||
|
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ir.irCall
|
import org.jetbrains.kotlin.ir.backend.js.ir.irCall
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -18,13 +17,13 @@ import org.jetbrains.kotlin.types.SimpleType
|
|||||||
|
|
||||||
typealias SymbolToTransformer = MutableMap<IrFunctionSymbol, (IrCall) -> IrExpression>
|
typealias SymbolToTransformer = MutableMap<IrFunctionSymbol, (IrCall) -> IrExpression>
|
||||||
|
|
||||||
internal fun SymbolToTransformer.add(from: Map<SimpleType, IrSimpleFunction>, to: IrSimpleFunction) {
|
internal fun SymbolToTransformer.add(from: Map<SimpleType, IrFunction>, to: IrFunction) {
|
||||||
from.forEach { _, func ->
|
from.forEach { _, func ->
|
||||||
add(func.symbol, to)
|
add(func.symbol, to)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun SymbolToTransformer.add(from: Map<SimpleType, IrSimpleFunction>, to: (IrCall) -> IrExpression) {
|
internal fun SymbolToTransformer.add(from: Map<SimpleType, IrFunction>, to: (IrCall) -> IrExpression) {
|
||||||
from.forEach { _, func ->
|
from.forEach { _, func ->
|
||||||
add(func.symbol, to)
|
add(func.symbol, to)
|
||||||
}
|
}
|
||||||
@@ -34,7 +33,7 @@ internal fun SymbolToTransformer.add(from: IrFunctionSymbol, to: (IrCall) -> IrE
|
|||||||
put(from, to)
|
put(from, to)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun SymbolToTransformer.add(from: IrFunctionSymbol, to: IrSimpleFunction, dispatchReceiverAsFirstArgument: Boolean = false) {
|
internal fun SymbolToTransformer.add(from: IrFunctionSymbol, to: IrFunction, dispatchReceiverAsFirstArgument: Boolean = false) {
|
||||||
put(from) { call -> irCall(call, to.symbol, dispatchReceiverAsFirstArgument) }
|
put(from) { call -> irCall(call, to.symbol, dispatchReceiverAsFirstArgument) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,11 +47,11 @@ internal fun <K> MutableMap<K, (IrCall) -> IrExpression>.addWithPredicate(
|
|||||||
|
|
||||||
internal typealias MemberToTransformer = HashMap<SimpleMemberKey, (IrCall) -> IrExpression>
|
internal typealias MemberToTransformer = HashMap<SimpleMemberKey, (IrCall) -> IrExpression>
|
||||||
|
|
||||||
internal fun MemberToTransformer.add(type: IrType, name: Name, v: IrSimpleFunctionSymbol) {
|
internal fun MemberToTransformer.add(type: IrType, name: Name, v: IrFunctionSymbol) {
|
||||||
add(type, name) { irCall(it, v, dispatchReceiverAsFirstArgument = true) }
|
add(type, name) { irCall(it, v, dispatchReceiverAsFirstArgument = true) }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun MemberToTransformer.add(type: IrType, name: Name, v: IrSimpleFunction) {
|
internal fun MemberToTransformer.add(type: IrType, name: Name, v: IrFunction) {
|
||||||
add(type, name, v.symbol)
|
add(type, name, v.symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+15
-11
@@ -64,21 +64,25 @@ class NumberConversionCallsTransformer(context: JsIrBackendContext) : CallsTrans
|
|||||||
add(it, ConversionNames.TO_LONG, intrinsics.jsToLong)
|
add(it, ConversionNames.TO_LONG, intrinsics.jsToLong)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (type in arrayOf(irBuiltIns.byteType, irBuiltIns.intType)) {
|
|
||||||
add(type, ConversionNames.TO_CHAR) {
|
irBuiltIns.numberType.let {
|
||||||
irCall(it, intrinsics.charClassSymbol.constructors.single(), dispatchReceiverAsFirstArgument = true)
|
add(it, ConversionNames.TO_BYTE, intrinsics.jsNumberToByte)
|
||||||
}
|
add(it, ConversionNames.TO_DOUBLE, intrinsics.jsNumberToDouble)
|
||||||
|
add(it, ConversionNames.TO_FLOAT, intrinsics.jsNumberToDouble)
|
||||||
|
add(it, ConversionNames.TO_INT, intrinsics.jsNumberToInt)
|
||||||
|
add(it, ConversionNames.TO_SHORT, intrinsics.jsNumberToShort)
|
||||||
|
add(it, ConversionNames.TO_LONG, intrinsics.jsNumberToLong)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (type in arrayOf(irBuiltIns.floatType, irBuiltIns.doubleType)) {
|
for (type in arrayOf(irBuiltIns.byteType, irBuiltIns.shortType, irBuiltIns.intType)) {
|
||||||
add(type, ConversionNames.TO_CHAR) {
|
add(type, ConversionNames.TO_CHAR, intrinsics.charConstructor)
|
||||||
JsIrBuilder.buildCall(intrinsics.charClassSymbol.constructors.single()).apply {
|
|
||||||
putValueArgument(0, irCall(it, intrinsics.jsNumberToInt, dispatchReceiverAsFirstArgument = true))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
add(irBuiltIns.charType, ConversionNames.TO_CHAR) { it.dispatchReceiver!! }
|
for (type in arrayOf(irBuiltIns.floatType, irBuiltIns.doubleType, irBuiltIns.numberType)) {
|
||||||
|
add(type, ConversionNames.TO_CHAR, intrinsics.jsNumberToChar)
|
||||||
|
}
|
||||||
|
|
||||||
|
add(irBuiltIns.charType, ConversionNames.TO_CHAR, ::useDispatchReceiver)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformCall(call: IrCall): IrExpression {
|
override fun transformCall(call: IrCall): IrExpression {
|
||||||
|
|||||||
@@ -86,6 +86,10 @@ class IrBuiltIns(
|
|||||||
val charType = char.toIrType()
|
val charType = char.toIrType()
|
||||||
val charClass = builtIns.char.toIrSymbol()
|
val charClass = builtIns.char.toIrSymbol()
|
||||||
|
|
||||||
|
val number = builtIns.number.defaultType
|
||||||
|
val numberType = number.toIrType()
|
||||||
|
val numberClass = builtIns.number.toIrSymbol()
|
||||||
|
|
||||||
val byte = builtIns.byteType
|
val byte = builtIns.byteType
|
||||||
val byteType = byte.toIrType()
|
val byteType = byte.toIrType()
|
||||||
val byteClass = builtIns.byte.toIrSymbol()
|
val byteClass = builtIns.byte.toIrSymbol()
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ fun numberToByte(a: dynamic): Byte = toByte(numberToInt(a))
|
|||||||
|
|
||||||
fun numberToDouble(a: dynamic): Double = js("+a").unsafeCast<Double>()
|
fun numberToDouble(a: dynamic): Double = js("+a").unsafeCast<Double>()
|
||||||
|
|
||||||
fun numberToInt(a: dynamic): Int = doubleToInt(a)
|
fun numberToInt(a: dynamic): Int = if (a is Long) a.toInt() else doubleToInt(a)
|
||||||
|
|
||||||
fun numberToShort(a: dynamic): Short = toShort(numberToInt(a))
|
fun numberToShort(a: dynamic): Short = toShort(numberToInt(a))
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ fun numberToShort(a: dynamic): Short = toShort(numberToInt(a))
|
|||||||
fun toByte(a: dynamic): Byte = js("a << 24 >> 24").unsafeCast<Byte>()
|
fun toByte(a: dynamic): Byte = js("a << 24 >> 24").unsafeCast<Byte>()
|
||||||
fun toShort(a: dynamic): Short = js("a << 16 >> 16").unsafeCast<Short>()
|
fun toShort(a: dynamic): Short = js("a << 16 >> 16").unsafeCast<Short>()
|
||||||
|
|
||||||
fun numberToLong(a: dynamic): Long = fromNumber(a)
|
fun numberToLong(a: dynamic): Long = if (a is Long) a else fromNumber(a)
|
||||||
|
|
||||||
fun toLong(a: dynamic): Long = fromInt(a)
|
fun toLong(a: dynamic): Long = fromInt(a)
|
||||||
|
|
||||||
@@ -25,4 +25,6 @@ fun doubleToInt(a: dynamic) = js("""
|
|||||||
if (a > 2147483647) return 2147483647;
|
if (a > 2147483647) return 2147483647;
|
||||||
if (a < -2147483648) return -2147483648;
|
if (a < -2147483648) return -2147483648;
|
||||||
return a | 0;
|
return a | 0;
|
||||||
""").unsafeCast<Int>()
|
""").unsafeCast<Int>()
|
||||||
|
|
||||||
|
fun numberToChar(a: dynamic) = Char(numberToInt(a))
|
||||||
Reference in New Issue
Block a user