diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java index be35546ba43..0a389e88d3b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java @@ -780,7 +780,7 @@ public class AsmUtil { return typeMapper.mapToCallableMethod(toStringDescriptor, false, OwnerKind.ERASED_INLINE_CLASS); } - static void genHashCode(MethodVisitor mv, InstructionAdapter iv, Type type, JvmTarget jvmTarget) { + public static void genHashCode(MethodVisitor mv, InstructionAdapter iv, Type type, JvmTarget jvmTarget) { if (type.getSort() == Type.ARRAY) { Type elementType = correctElementType(type); if (elementType.getSort() == Type.OBJECT || elementType.getSort() == Type.ARRAY) { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/HashCode.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/HashCode.kt index 03798b2464a..3bd08a5ecb1 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/HashCode.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/HashCode.kt @@ -16,24 +16,39 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics -import org.jetbrains.kotlin.backend.jvm.JvmBackendContext +import org.jetbrains.kotlin.backend.jvm.codegen.* import org.jetbrains.kotlin.codegen.AsmUtil -import org.jetbrains.kotlin.codegen.Callable -import org.jetbrains.kotlin.codegen.CallableMethod -import org.jetbrains.kotlin.ir.expressions.IrCall +import org.jetbrains.kotlin.config.JvmTarget +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression -import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression -import org.jetbrains.kotlin.resolve.jvm.AsmTypes -import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature +import org.jetbrains.kotlin.ir.util.render import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Type -import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter +// TODO Implement hashCode on primitive types as a lowering. object HashCode : IntrinsicMethod() { - - override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction { - return IrIntrinsicFunction.create(expression, signature, context, AsmTypes.OBJECT_TYPE) { - it.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I", false) + override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo) = with(codegen) { + val receiver = expression.dispatchReceiver ?: error("No receiver for hashCode: ${expression.render()}") + val result = receiver.accept(this, data).materialized + val target = context.state.target + when { + irFunction.origin == IrDeclarationOrigin.GENERATED_INLINE_CLASS_MEMBER || irFunction.origin == IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER -> + AsmUtil.genHashCode(mv, mv, result.type, target) + target == JvmTarget.JVM_1_6 -> { + result.coerce(AsmUtil.boxType(result.type)).materialize() + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I", false) + } + else -> { + val boxedType = AsmUtil.boxType(result.type) + mv.visitMethodInsn( + Opcodes.INVOKESTATIC, + boxedType.internalName, + "hashCode", + Type.getMethodDescriptor(Type.INT_TYPE, result.type), + false + ) + } } + MaterialValue(codegen.mv, Type.INT_TYPE) } } diff --git a/compiler/testData/codegen/box/dataClasses/hashCode/boolean.kt b/compiler/testData/codegen/box/dataClasses/hashCode/boolean.kt index d824a5ccf42..e231e75a57b 100644 --- a/compiler/testData/codegen/box/dataClasses/hashCode/boolean.kt +++ b/compiler/testData/codegen/box/dataClasses/hashCode/boolean.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR data class A(val a: Boolean) fun box() : String { diff --git a/compiler/testData/codegen/bytecodeText/jvm8/hashCode/dataClass.kt b/compiler/testData/codegen/bytecodeText/jvm8/hashCode/dataClass.kt index 2dd23679554..b1afb5de8fa 100644 --- a/compiler/testData/codegen/bytecodeText/jvm8/hashCode/dataClass.kt +++ b/compiler/testData/codegen/bytecodeText/jvm8/hashCode/dataClass.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // JVM_TARGET: 1.8 data class Hash( diff --git a/compiler/testData/codegen/bytecodeText/jvm8/hashCode/hashCode.kt b/compiler/testData/codegen/bytecodeText/jvm8/hashCode/hashCode.kt index 04c6424779d..bffb0fbd2fa 100644 --- a/compiler/testData/codegen/bytecodeText/jvm8/hashCode/hashCode.kt +++ b/compiler/testData/codegen/bytecodeText/jvm8/hashCode/hashCode.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // JVM_TARGET: 1.8 fun box(): String {