From 5c40892c5784484fd37c86829e53008e6e7f4f32 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Wed, 25 Apr 2018 23:38:57 +0300 Subject: [PATCH] [JS IR BE] Right support for `inc` and `dec` on primitive numbers --- .../kotlin/ir/backend/js/compiler.kt | 4 +- ...wering.kt => IntrinsicifyCallsLowering.kt} | 49 +++++++++++++------ .../evaluationOrder/dangerousInline.kt | 1 - .../testData/box/expression/misc/KT-740-2.kt | 1 - .../testData/box/expression/misc/intRange.kt | 1 - .../testData/box/number/numberIncDec.kt | 1 - 6 files changed, 37 insertions(+), 20 deletions(-) rename compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/{IntrinsicifyBuiltinOperationsLowering.kt => IntrinsicifyCallsLowering.kt} (76%) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt index e2455bbc88a..80c32d2ce95 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt @@ -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) } \ No newline at end of file diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyBuiltinOperationsLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyCallsLowering.kt similarity index 76% rename from compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyBuiltinOperationsLowering.kt rename to compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyCallsLowering.kt index 5b5031c2b2d..434ce4de6dd 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyBuiltinOperationsLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyCallsLowering.kt @@ -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 - private val comparisonIntrinsics: Map + private val memberToTransformer: Map IrCall> + private val memberToIrFunction: Map + private val symbolToIrFunction: Map 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) + } } } diff --git a/js/js.translator/testData/box/expression/evaluationOrder/dangerousInline.kt b/js/js.translator/testData/box/expression/evaluationOrder/dangerousInline.kt index 19400a719a2..7312503ccff 100644 --- a/js/js.translator/testData/box/expression/evaluationOrder/dangerousInline.kt +++ b/js/js.translator/testData/box/expression/evaluationOrder/dangerousInline.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR // EXPECTED_REACHABLE_NODES: 1110 package foo diff --git a/js/js.translator/testData/box/expression/misc/KT-740-2.kt b/js/js.translator/testData/box/expression/misc/KT-740-2.kt index 2dca9263221..57611d613fe 100644 --- a/js/js.translator/testData/box/expression/misc/KT-740-2.kt +++ b/js/js.translator/testData/box/expression/misc/KT-740-2.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR // EXPECTED_REACHABLE_NODES: 1122 package foo diff --git a/js/js.translator/testData/box/expression/misc/intRange.kt b/js/js.translator/testData/box/expression/misc/intRange.kt index c687b02999c..a83e1fcddac 100644 --- a/js/js.translator/testData/box/expression/misc/intRange.kt +++ b/js/js.translator/testData/box/expression/misc/intRange.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR // EXPECTED_REACHABLE_NODES: 1121 package foo diff --git a/js/js.translator/testData/box/number/numberIncDec.kt b/js/js.translator/testData/box/number/numberIncDec.kt index 3806631644d..eaab2b783a6 100644 --- a/js/js.translator/testData/box/number/numberIncDec.kt +++ b/js/js.translator/testData/box/number/numberIncDec.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR // EXPECTED_REACHABLE_NODES: 1112 package foo