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.isPrimitiveNumberOrNullableType
|
||||||
import org.jetbrains.kotlin.types.typeUtil.upperBoundedByPrimitiveNumberOrNullableType
|
import org.jetbrains.kotlin.types.typeUtil.upperBoundedByPrimitiveNumberOrNullableType
|
||||||
import org.jetbrains.org.objectweb.asm.Label
|
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.Type
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
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() {
|
class Equals(val operator: IElementType) : IntrinsicMethod() {
|
||||||
private class BooleanConstantFalseCheck(val value: PromisedValue) : BooleanValue(value.codegen) {
|
private class BooleanConstantFalseCheck(val value: PromisedValue) : BooleanValue(value.codegen) {
|
||||||
override fun materialize() = value.discard().let { mv.iconst(0) }
|
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("inc", INC) +
|
||||||
unaryFunForPrimitives("dec", DEC) +
|
unaryFunForPrimitives("dec", DEC) +
|
||||||
unaryFunForPrimitives("hashCode", HashCode) +
|
unaryFunForPrimitives("hashCode", HashCode) +
|
||||||
binaryFunForPrimitives("equals", EQUALS, irBuiltIns.anyClass) +
|
binaryFunForPrimitives("equals", EXPLICIT_EQUALS, irBuiltIns.anyClass) +
|
||||||
binaryFunForPrimitivesAcrossPrimitives("rangeTo", RangeTo) +
|
binaryFunForPrimitivesAcrossPrimitives("rangeTo", RangeTo) +
|
||||||
binaryOp("plus", IADD) +
|
binaryOp("plus", IADD) +
|
||||||
binaryOp("minus", ISUB) +
|
binaryOp("minus", ISUB) +
|
||||||
@@ -193,7 +193,7 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
|
|||||||
private val INC = Increment(1)
|
private val INC = Increment(1)
|
||||||
|
|
||||||
private val DEC = Increment(-1)
|
private val DEC = Increment(-1)
|
||||||
private val EQUALS = Equals(KtTokens.EQEQ)
|
private val EXPLICIT_EQUALS = ExplicitEquals()
|
||||||
|
|
||||||
private fun IrFunctionSymbol.toKey(): Key? {
|
private fun IrFunctionSymbol.toKey(): Key? {
|
||||||
val parent = owner.parent
|
val parent = owner.parent
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// FILE: equalsNull_lv12.kt
|
// FILE: equalsNull.kt
|
||||||
|
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// ^ TODO: fix intrinsic for 'equals' for boxed primitives
|
|
||||||
|
|
||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -4,8 +4,7 @@
|
|||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// FILE: equalsNull_withExplicitFlag.kt
|
// FILE: equalsNull_withExplicitFlag.kt
|
||||||
|
|
||||||
// Should be ignored on JVM IR.
|
// IGNORE_BACKEND: JVM_IR
|
||||||
// ^ TODO: fix intrinsic for 'equals' for boxed primitives
|
|
||||||
// JVM_IR supports behavior since Kotlin 1.3,
|
// 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.
|
// and '-Xno-exception-on-explicit-equals-for-boxed-null' is a fallback flag introduced in 1.2.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user