[JS IR BE] Right support for inc and dec on primitive numbers
This commit is contained in:
@@ -9,7 +9,7 @@ import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.backend.common.lower.*
|
||||
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.IntrinsicifyBuiltinOperationsLowering
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.IntrinsicifyCallsLowering
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.SecondaryCtorLowering
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
@@ -62,5 +62,5 @@ fun JsIrBackendContext.lower(file: IrFile) {
|
||||
InitializersLowering(this, JsLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER, false).runOnFilePostfix(file)
|
||||
SecondaryCtorLowering(this).lower(file)
|
||||
|
||||
IntrinsicifyBuiltinOperationsLowering(this).lower(file)
|
||||
IntrinsicifyCallsLowering(this).lower(file)
|
||||
}
|
||||
+35
-14
@@ -6,15 +6,18 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.name
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.copyTypeArgumentsFrom
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -22,27 +25,25 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.SimpleType
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
class IntrinsicifyBuiltinOperationsLowering(private val context: JsIrBackendContext) : FileLoweringPass {
|
||||
class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileLoweringPass {
|
||||
|
||||
// TODO: should/can we unify these maps?
|
||||
private val primitiveNumberIntrinsics: Map<SimpleMemberKey, IrSimpleFunction>
|
||||
private val comparisonIntrinsics: Map<IrFunctionSymbol, IrSimpleFunction>
|
||||
private val memberToTransformer: Map<SimpleMemberKey, (IrCall) -> IrCall>
|
||||
private val memberToIrFunction: Map<SimpleMemberKey, IrSimpleFunction>
|
||||
private val symbolToIrFunction: Map<IrFunctionSymbol, IrSimpleFunction>
|
||||
|
||||
init {
|
||||
primitiveNumberIntrinsics = mutableMapOf()
|
||||
comparisonIntrinsics = mutableMapOf()
|
||||
memberToIrFunction = mutableMapOf()
|
||||
symbolToIrFunction = mutableMapOf()
|
||||
memberToTransformer = mutableMapOf()
|
||||
|
||||
primitiveNumberIntrinsics.run {
|
||||
val primitiveNumbers = context.irBuiltIns.run { listOf(int, short, byte, float, double) }
|
||||
val primitiveNumbers = context.irBuiltIns.run { listOf(int, short, byte, float, double) }
|
||||
|
||||
memberToIrFunction.run {
|
||||
for (type in primitiveNumbers) {
|
||||
op(type, OperatorNameConventions.UNARY_PLUS, context.intrinsics.jsUnaryPlus)
|
||||
op(type, OperatorNameConventions.UNARY_MINUS, context.intrinsics.jsUnaryMinus)
|
||||
|
||||
// TODO: inc & dec are mapped wrongly
|
||||
op(type, OperatorNameConventions.INC, context.intrinsics.jsPrefixInc)
|
||||
op(type, OperatorNameConventions.DEC, context.intrinsics.jsPrefixDec)
|
||||
|
||||
op(type, OperatorNameConventions.PLUS, context.intrinsics.jsPlus)
|
||||
op(type, OperatorNameConventions.MINUS, context.intrinsics.jsMinus)
|
||||
op(type, OperatorNameConventions.TIMES, context.intrinsics.jsMult)
|
||||
@@ -69,7 +70,7 @@ class IntrinsicifyBuiltinOperationsLowering(private val context: JsIrBackendCont
|
||||
}
|
||||
}
|
||||
|
||||
comparisonIntrinsics.run {
|
||||
symbolToIrFunction.run {
|
||||
add(context.irBuiltIns.eqeqeqSymbol, context.intrinsics.jsEqeqeq)
|
||||
// TODO: implement it a right way
|
||||
add(context.irBuiltIns.eqeqSymbol, context.intrinsics.jsEqeq)
|
||||
@@ -83,6 +84,22 @@ class IntrinsicifyBuiltinOperationsLowering(private val context: JsIrBackendCont
|
||||
add(context.irBuiltIns.greaterFunByOperandType, context.intrinsics.jsGt)
|
||||
add(context.irBuiltIns.greaterOrEqualFunByOperandType, context.intrinsics.jsGtEq)
|
||||
}
|
||||
|
||||
memberToTransformer.run {
|
||||
for (type in primitiveNumbers) {
|
||||
// TODO: use increment and decrement when it's possible
|
||||
op(type, OperatorNameConventions.INC) {
|
||||
irCall(it, context.intrinsics.jsPlus.symbol, dispatchReceiverAsFirstArgument = true).apply {
|
||||
putValueArgument(1, IrConstImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.int, IrConstKind.Int, 1))
|
||||
}
|
||||
}
|
||||
op(type, OperatorNameConventions.DEC) {
|
||||
irCall(it, context.intrinsics.jsMinus.symbol, dispatchReceiverAsFirstArgument = true).apply {
|
||||
putValueArgument(1, IrConstImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.int, IrConstKind.Int, 1))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun lower(irFile: IrFile) {
|
||||
@@ -93,17 +110,21 @@ class IntrinsicifyBuiltinOperationsLowering(private val context: JsIrBackendCont
|
||||
if (call is IrCall) {
|
||||
val symbol = call.symbol
|
||||
|
||||
comparisonIntrinsics[symbol]?.let {
|
||||
symbolToIrFunction[symbol]?.let {
|
||||
return irCall(call, it.symbol)
|
||||
}
|
||||
|
||||
(symbol.owner as? IrFunction)?.dispatchReceiverParameter?.let {
|
||||
val key = SimpleMemberKey(it.type, symbol.name)
|
||||
|
||||
primitiveNumberIntrinsics[key]?.let {
|
||||
memberToIrFunction[key]?.let {
|
||||
// TODO: don't apply intrinsics when type of receiver or argument is Long
|
||||
return irCall(call, it.symbol, dispatchReceiverAsFirstArgument = true)
|
||||
}
|
||||
|
||||
memberToTransformer[key]?.let {
|
||||
return it(call)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user