[K/JS] Prevent Char boxing on value or reference equals call
This commit is contained in:
+7
-17
@@ -14,7 +14,10 @@ import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsCommonBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.realOverrideTarget
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrReturnTargetSymbol
|
||||
@@ -227,25 +230,12 @@ class AutoboxingTransformer(context: JsCommonBackendContext) : AbstractValueUsag
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
return if (
|
||||
expression.symbol != irBuiltIns.eqeqeqSymbol ||
|
||||
!expression.allArgumentsHaveType(irBuiltIns.charType) &&
|
||||
expression.origin != IrStatementOrigin.SYNTHETIC_NOT_AUTOBOXED_CHECK
|
||||
) {
|
||||
super.visitCall(expression)
|
||||
} else {
|
||||
return if (expression.origin == IrStatementOrigin.SYNTHETIC_NOT_AUTOBOXED_CHECK) {
|
||||
expression.apply { transformChildrenVoid() }
|
||||
} else {
|
||||
super.visitCall(expression)
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrCall.allArgumentsHaveType(type: IrType): Boolean {
|
||||
for (i in 0 until valueArgumentsCount) {
|
||||
if (getValueArgument(i)?.type != type) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
private tailrec fun IrExpression.isGetUnit(irBuiltIns: IrBuiltIns): Boolean =
|
||||
|
||||
+18
-4
@@ -5,7 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower.calls
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.InlineClassRepresentation
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.isEqualsInheritedFromAny
|
||||
@@ -28,7 +27,7 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls
|
||||
|
||||
init {
|
||||
symbolToTransformer.run {
|
||||
add(irBuiltIns.eqeqeqSymbol, intrinsics.jsEqeqeq)
|
||||
add(irBuiltIns.eqeqeqSymbol, ::transformEqeqeqOperator)
|
||||
add(irBuiltIns.eqeqSymbol, ::transformEqeqOperator)
|
||||
// ieee754equals can only be applied in between statically known Floats, Doubles, null or undefined
|
||||
add(irBuiltIns.ieee754equalsFunByOperandType, ::chooseEqualityOperatorForPrimitiveTypes)
|
||||
@@ -74,6 +73,21 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls
|
||||
}
|
||||
}
|
||||
|
||||
private fun transformEqeqeqOperator(call: IrFunctionAccessExpression): IrExpression {
|
||||
val lhs = call.getValueArgument(0)!!
|
||||
val rhs = call.getValueArgument(1)!!
|
||||
|
||||
return if (lhs.isCharBoxing() && rhs.isCharBoxing()) {
|
||||
optimizeInlineClassEquality(call, lhs, rhs)
|
||||
} else {
|
||||
irCall(call, intrinsics.jsEqeqeq)
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrExpression.isCharBoxing(): Boolean {
|
||||
return this is IrCall && symbol == intrinsics.jsBoxIntrinsic && getValueArgument(0)!!.type.isChar()
|
||||
}
|
||||
|
||||
private fun transformEqeqOperator(call: IrFunctionAccessExpression): IrExpression {
|
||||
val lhs = call.getValueArgument(0)!!
|
||||
val rhs = call.getValueArgument(1)!!
|
||||
@@ -186,7 +200,7 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls
|
||||
isBuiltin() && this != PrimitiveType.FLOATING_POINT_NUMBER
|
||||
|
||||
private fun IrType.isDefaultEqualsMethod() =
|
||||
findEqualsMethod()?.origin === IrDeclarationOrigin.GENERATED_SINGLE_FIELD_VALUE_CLASS_MEMBER
|
||||
isChar() || findEqualsMethod()?.origin === IrDeclarationOrigin.GENERATED_SINGLE_FIELD_VALUE_CLASS_MEMBER
|
||||
|
||||
private fun IrExpression.isBoxIntrinsic() =
|
||||
this is IrCall && symbol == icUtils.boxIntrinsic
|
||||
@@ -204,7 +218,7 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls
|
||||
call.putValueArgument(0, lhsUnboxed)
|
||||
call.putValueArgument(1, rhsUnboxed)
|
||||
|
||||
if (lhsUnboxed.type.getLowestUnderlyingType().getPrimitiveType().canBeUsedWithJsEq()) {
|
||||
if (lhsUnboxed.type.isChar() || lhsUnboxed.type.getLowestUnderlyingType().getPrimitiveType().canBeUsedWithJsEq()) {
|
||||
return chooseEqualityOperatorForPrimitiveTypes(call)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user