From 80a67477db0443b8623d5bc7a0c0678b58b896ca Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Thu, 30 Aug 2018 12:29:41 +0300 Subject: [PATCH] Generate method calls for inline classes through IC, not IC$Erased IC extends IC$Erased, so it should be fine. --- .../codegen/state/KotlinTypeMapper.java | 2 +- .../callMemberMethodsInsideInlineClass.kt | 6 +++--- .../equalsIsCalledByInlineClass.kt | 14 +++++++++++++ .../hashCodeIsCalledByInlineClass.kt | 13 ++++++++++++ .../inlineClasses/isCheckForInlineClass.kt | 4 ++-- ...tualCallsOfInlineFunctionsOfInlineClass.kt | 4 ++-- ...OverridingMethodsAreCalledByInlineClass.kt | 12 +++++++++++ ...overridingMethodsAreCalledByInlineClass.kt | 20 +++++++++++++++++++ .../toStringIsCalledByInlineClass.kt | 13 ++++++++++++ .../codegen/BytecodeTextTestGenerated.java | 20 +++++++++++++++++++ 10 files changed, 100 insertions(+), 8 deletions(-) create mode 100644 compiler/testData/codegen/bytecodeText/inlineClasses/equalsIsCalledByInlineClass.kt create mode 100644 compiler/testData/codegen/bytecodeText/inlineClasses/hashCodeIsCalledByInlineClass.kt create mode 100644 compiler/testData/codegen/bytecodeText/inlineClasses/nonOverridingMethodsAreCalledByInlineClass.kt create mode 100644 compiler/testData/codegen/bytecodeText/inlineClasses/overridingMethodsAreCalledByInlineClass.kt create mode 100644 compiler/testData/codegen/bytecodeText/inlineClasses/toStringIsCalledByInlineClass.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java index 825c020bff8..6a78395dafa 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java @@ -910,7 +910,7 @@ public class KotlinTypeMapper { ClassDescriptor receiver = (currentIsInterface && !originalIsInterface) || currentOwner instanceof FunctionClassDescriptor ? declarationOwner : currentOwner; - owner = toInlinedErasedClass ? mapErasedInlineClass(receiver) : mapClass(receiver); + owner = mapClass(receiver); thisClass = owner; dispatchReceiverKotlinType = receiver.getDefaultType(); } diff --git a/compiler/testData/codegen/bytecodeText/inlineClasses/callMemberMethodsInsideInlineClass.kt b/compiler/testData/codegen/bytecodeText/inlineClasses/callMemberMethodsInsideInlineClass.kt index 2d7384edf31..7f61cfc51d3 100644 --- a/compiler/testData/codegen/bytecodeText/inlineClasses/callMemberMethodsInsideInlineClass.kt +++ b/compiler/testData/codegen/bytecodeText/inlineClasses/callMemberMethodsInsideInlineClass.kt @@ -12,7 +12,7 @@ inline class Foo(val x: Int) { } } -// 1 INVOKESTATIC Foo\$Erased.empty \(I\)V -// 1 INVOKESTATIC Foo\$Erased.withParam \(ILjava/lang/String;\)V -// 1 INVOKESTATIC Foo\$Erased.withInlineClassParam-1e4ch6lh \(II\)V +// 1 INVOKESTATIC Foo\.empty \(I\)V +// 1 INVOKESTATIC Foo\.withParam \(ILjava/lang/String;\)V +// 1 INVOKESTATIC Foo\.withInlineClassParam-1e4ch6lh \(II\)V // 5 INVOKEVIRTUAL \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/inlineClasses/equalsIsCalledByInlineClass.kt b/compiler/testData/codegen/bytecodeText/inlineClasses/equalsIsCalledByInlineClass.kt new file mode 100644 index 00000000000..6c1ff170558 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/inlineClasses/equalsIsCalledByInlineClass.kt @@ -0,0 +1,14 @@ +// !LANGUAGE: +InlineClasses + +// FILE: Z.kt +inline class Z(val x: Int) + +// FILE: test.kt +fun testZ(z: Z) = z.equals(z) +fun testZ(z: Z, a: Any?) = z.equals(a) +fun testNZ(z: Z?) = z?.equals(z) + +// @TestKt.class: +// 0 INVOKESTATIC Z\$Erased\.equals +// 0 INVOKESTATIC Z\-Erased\.equals +// 3 INVOKESTATIC Z\.equals \(ILjava/lang/Object;\)Z \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/inlineClasses/hashCodeIsCalledByInlineClass.kt b/compiler/testData/codegen/bytecodeText/inlineClasses/hashCodeIsCalledByInlineClass.kt new file mode 100644 index 00000000000..cd015f12fca --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/inlineClasses/hashCodeIsCalledByInlineClass.kt @@ -0,0 +1,13 @@ +// !LANGUAGE: +InlineClasses + +// FILE: Z.kt +inline class Z(val x: Int) + +// FILE: Test.kt +fun testZ(z: Z) = z.hashCode() +fun testNZ(z: Z?) = z?.hashCode() + +// @TestKt.class: +// 0 INVOKESTATIC Z\$Erased\.hashCode +// 0 INVOKESTATIC Z\-Erased\.hashCode +// 2 INVOKESTATIC Z\.hashCode \(I\)I diff --git a/compiler/testData/codegen/bytecodeText/inlineClasses/isCheckForInlineClass.kt b/compiler/testData/codegen/bytecodeText/inlineClasses/isCheckForInlineClass.kt index f3929b20080..1f78152eb9f 100644 --- a/compiler/testData/codegen/bytecodeText/inlineClasses/isCheckForInlineClass.kt +++ b/compiler/testData/codegen/bytecodeText/inlineClasses/isCheckForInlineClass.kt @@ -24,7 +24,7 @@ fun test(a: Any, b: Any?) { // 2 INSTANCEOF UInt // 2 CHECKCAST UInt -// 1 INVOKEVIRTUAL UInt.unbox -// 1 INVOKESTATIC UInt\$Erased.member +// 1 INVOKEVIRTUAL UInt\.unbox +// 1 INVOKESTATIC UInt\.member // 0 intValue \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/inlineClasses/noActualCallsOfInlineFunctionsOfInlineClass.kt b/compiler/testData/codegen/bytecodeText/inlineClasses/noActualCallsOfInlineFunctionsOfInlineClass.kt index 7613aa5572a..b2127dba123 100644 --- a/compiler/testData/codegen/bytecodeText/inlineClasses/noActualCallsOfInlineFunctionsOfInlineClass.kt +++ b/compiler/testData/codegen/bytecodeText/inlineClasses/noActualCallsOfInlineFunctionsOfInlineClass.kt @@ -14,5 +14,5 @@ fun test(f: Foo) { f.notInlineInc() // one here } -// 0 INVOKESTATIC Foo\$Erased.inlineInc -// 1 INVOKESTATIC Foo\$Erased.notInlineInc +// 0 INVOKESTATIC Foo\.inlineInc +// 1 INVOKESTATIC Foo\.notInlineInc diff --git a/compiler/testData/codegen/bytecodeText/inlineClasses/nonOverridingMethodsAreCalledByInlineClass.kt b/compiler/testData/codegen/bytecodeText/inlineClasses/nonOverridingMethodsAreCalledByInlineClass.kt new file mode 100644 index 00000000000..cf23b9fd51e --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/inlineClasses/nonOverridingMethodsAreCalledByInlineClass.kt @@ -0,0 +1,12 @@ +// !LANGUAGE: +InlineClasses + +inline class Z(val x: Int) { + fun foo() {} +} + +fun testZ(z: Z) = z.foo() +fun testNZ(z: Z?) = z?.foo() + +// 0 INVOKESTATIC Z\$Erased\.foo +// 0 INVOKESTATIC Z\-Erased\.foo +// 2 INVOKESTATIC Z\.foo \(I\)V diff --git a/compiler/testData/codegen/bytecodeText/inlineClasses/overridingMethodsAreCalledByInlineClass.kt b/compiler/testData/codegen/bytecodeText/inlineClasses/overridingMethodsAreCalledByInlineClass.kt new file mode 100644 index 00000000000..db011795844 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/inlineClasses/overridingMethodsAreCalledByInlineClass.kt @@ -0,0 +1,20 @@ +// !LANGUAGE: +InlineClasses + +// FILE: Z.kt +interface IFoo { + fun foo() +} + +inline class Z(val x: Int) : IFoo { + override fun foo() {} +} + +// FILE: test.kt +fun testZ(z: Z) = z.foo() + +fun testNZ(z: Z?) = z?.foo() + +// @TestKt.class: +// 0 INVOKESTATIC Z\$Erased\.foo +// 0 INVOKESTATIC Z\-Erased\.foo +// 2 INVOKESTATIC Z\.foo \(I\)V \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/inlineClasses/toStringIsCalledByInlineClass.kt b/compiler/testData/codegen/bytecodeText/inlineClasses/toStringIsCalledByInlineClass.kt new file mode 100644 index 00000000000..e8d0117f32e --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/inlineClasses/toStringIsCalledByInlineClass.kt @@ -0,0 +1,13 @@ +// !LANGUAGE: +InlineClasses + +// FILE: Z.kt +inline class Z(val x: Int) + +// FILE: test.kt +fun testZ(z: Z) = z.toString() +fun testNZ(z: Z?) = z?.toString() + +// @TestKt.class: +// 0 INVOKESTATIC Z\$Erased\.toString +// 0 INVOKESTATIC Z\-Erased\.toString +// 2 INVOKESTATIC Z\.toString \(I\)Ljava/lang/String; diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index b4c87f2ab6c..db8a7021b23 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -2073,6 +2073,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/inlineClasses/generationOfAccessorToUnderlyingValue.kt"); } + @TestMetadata("hashCodeIsCalledByInlineClass.kt") + public void testHashCodeIsCalledByInlineClass() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/inlineClasses/hashCodeIsCalledByInlineClass.kt"); + } + @TestMetadata("inlineClassBoxingOnAssignment.kt") public void testInlineClassBoxingOnAssignment() throws Exception { runTest("compiler/testData/codegen/bytecodeText/inlineClasses/inlineClassBoxingOnAssignment.kt"); @@ -2123,6 +2128,16 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/inlineClasses/noBoxingOperationsOnNonTrivialSpread.kt"); } + @TestMetadata("nonOverridingMethodsAreCalledByInlineClass.kt") + public void testNonOverridingMethodsAreCalledByInlineClass() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/inlineClasses/nonOverridingMethodsAreCalledByInlineClass.kt"); + } + + @TestMetadata("overridingMethodsAreCalledByInlineClass.kt") + public void testOverridingMethodsAreCalledByInlineClass() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/inlineClasses/overridingMethodsAreCalledByInlineClass.kt"); + } + @TestMetadata("passInlineClassesWithSpreadOperatorToVarargs.kt") public void testPassInlineClassesWithSpreadOperatorToVarargs() throws Exception { runTest("compiler/testData/codegen/bytecodeText/inlineClasses/passInlineClassesWithSpreadOperatorToVarargs.kt"); @@ -2143,6 +2158,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/inlineClasses/synthesizedBoxMethodIsNotMangled.kt"); } + @TestMetadata("toStringIsCalledByInlineClass.kt") + public void testToStringIsCalledByInlineClass() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/inlineClasses/toStringIsCalledByInlineClass.kt"); + } + @TestMetadata("uIntArrayIteratorWithoutBoxing.kt") public void testUIntArrayIteratorWithoutBoxing() throws Exception { runTest("compiler/testData/codegen/bytecodeText/inlineClasses/uIntArrayIteratorWithoutBoxing.kt");