Fix explicit 'equals' for primitive types
This commit is contained in:
@@ -30,9 +30,29 @@ import org.jetbrains.kotlin.types.isNullable
|
||||
import org.jetbrains.kotlin.types.typeUtil.isPrimitiveNumberOrNullableType
|
||||
import org.jetbrains.kotlin.types.typeUtil.upperBoundedByPrimitiveNumberOrNullableType
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
class ExplicitEquals : IntrinsicMethod() {
|
||||
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? {
|
||||
val (a, b) = expression.receiverAndArgs()
|
||||
|
||||
// TODO use specialized boxed type - this might require types like 'java.lang.Integer' in IR
|
||||
a.accept(codegen, data).coerce(AsmTypes.OBJECT_TYPE, codegen.context.irBuiltIns.anyNType).materialize()
|
||||
b.accept(codegen, data).coerce(AsmTypes.OBJECT_TYPE, codegen.context.irBuiltIns.anyNType).materialize()
|
||||
codegen.mv.visitMethodInsn(
|
||||
Opcodes.INVOKEVIRTUAL,
|
||||
AsmTypes.OBJECT_TYPE.internalName,
|
||||
"equals",
|
||||
Type.getMethodDescriptor(Type.BOOLEAN_TYPE, AsmTypes.OBJECT_TYPE),
|
||||
false
|
||||
)
|
||||
|
||||
return MaterialValue(codegen, Type.BOOLEAN_TYPE, codegen.context.irBuiltIns.booleanType)
|
||||
}
|
||||
}
|
||||
|
||||
class Equals(val operator: IElementType) : IntrinsicMethod() {
|
||||
private class BooleanConstantFalseCheck(val value: PromisedValue) : BooleanValue(value.codegen) {
|
||||
override fun materialize() = value.discard().let { mv.iconst(0) }
|
||||
|
||||
+2
-2
@@ -103,7 +103,7 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
|
||||
unaryFunForPrimitives("inc", INC) +
|
||||
unaryFunForPrimitives("dec", DEC) +
|
||||
unaryFunForPrimitives("hashCode", HashCode) +
|
||||
binaryFunForPrimitives("equals", EQUALS, irBuiltIns.anyClass) +
|
||||
binaryFunForPrimitives("equals", EXPLICIT_EQUALS, irBuiltIns.anyClass) +
|
||||
binaryFunForPrimitivesAcrossPrimitives("rangeTo", RangeTo) +
|
||||
binaryOp("plus", IADD) +
|
||||
binaryOp("minus", ISUB) +
|
||||
@@ -193,7 +193,7 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
|
||||
private val INC = Increment(1)
|
||||
|
||||
private val DEC = Increment(-1)
|
||||
private val EQUALS = Equals(KtTokens.EQEQ)
|
||||
private val EXPLICIT_EQUALS = ExplicitEquals()
|
||||
|
||||
private fun IrFunctionSymbol.toKey(): Key? {
|
||||
val parent = owner.parent
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
// FILE: equalsNull_lv12.kt
|
||||
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// ^ TODO: fix intrinsic for 'equals' for boxed primitives
|
||||
// FILE: equalsNull.kt
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
|
||||
+1
-2
@@ -4,8 +4,7 @@
|
||||
// WITH_RUNTIME
|
||||
// FILE: equalsNull_withExplicitFlag.kt
|
||||
|
||||
// Should be ignored on JVM IR.
|
||||
// ^ TODO: fix intrinsic for 'equals' for boxed primitives
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// JVM_IR supports behavior since Kotlin 1.3,
|
||||
// and '-Xno-exception-on-explicit-equals-for-boxed-null' is a fallback flag introduced in 1.2.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user