From 3f7bf8467afcf5f78eaefc037bd8007364d49822 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Tue, 23 May 2017 12:05:12 +0200 Subject: [PATCH] Process non-aload0 outer access in constructor during inline #KT-17972 Fixed --- .../kotlin/codegen/inline/FieldRemapper.kt | 11 ++++- .../kotlin/codegen/inline/MethodInliner.kt | 2 +- .../inline/RegeneratedLambdaFieldRemapper.kt | 4 +- .../boxInline/anonymousObject/kt17972.kt | 33 +++++++++++++ .../boxInline/anonymousObject/kt17972_2.kt | 33 +++++++++++++ .../boxInline/anonymousObject/kt17972_3.kt | 35 ++++++++++++++ .../boxInline/anonymousObject/kt17972_4.kt | 37 ++++++++++++++ .../boxInline/anonymousObject/kt17972_5.kt | 35 ++++++++++++++ .../anonymousObject/kt17972_super.kt | 35 ++++++++++++++ .../anonymousObject/kt17972_super2.kt | 37 ++++++++++++++ .../anonymousObject/kt17972_super3.kt | 39 +++++++++++++++ .../BlackBoxInlineCodegenTestGenerated.java | 48 +++++++++++++++++++ ...otlinAgainstInlineKotlinTestGenerated.java | 48 +++++++++++++++++++ 13 files changed, 392 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/codegen/boxInline/anonymousObject/kt17972.kt create mode 100644 compiler/testData/codegen/boxInline/anonymousObject/kt17972_2.kt create mode 100644 compiler/testData/codegen/boxInline/anonymousObject/kt17972_3.kt create mode 100644 compiler/testData/codegen/boxInline/anonymousObject/kt17972_4.kt create mode 100644 compiler/testData/codegen/boxInline/anonymousObject/kt17972_5.kt create mode 100644 compiler/testData/codegen/boxInline/anonymousObject/kt17972_super.kt create mode 100644 compiler/testData/codegen/boxInline/anonymousObject/kt17972_super2.kt create mode 100644 compiler/testData/codegen/boxInline/anonymousObject/kt17972_super3.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/FieldRemapper.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/FieldRemapper.kt index e502a47090b..52f706cf6f7 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/FieldRemapper.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/FieldRemapper.kt @@ -44,8 +44,15 @@ open class FieldRemapper( else foldFieldAccessChainIfNeeded(capturedFieldAccess, 1, node) - //TODO: seems that this method is redundant but it added from safety purposes before new milestone - open fun processNonAload0FieldAccessChains(isInlinedLambda: Boolean): Boolean = false + /**constructors could access outer not through + * ALOAD 0 //this + * GETFIELD this$0 //outer + * GETFIELD this$0 //outer of outer + * but directly through constructor parameter + * ALOAD X //outer + * GETFIELD this$0 //outer of outer + */ + open fun shouldProcessNonAload0FieldAccessChains(): Boolean = false private fun foldFieldAccessChainIfNeeded( capturedFieldAccess: List, diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt index 2d1f762d4a0..4e1f320fff8 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt @@ -602,7 +602,7 @@ class MethodInliner( while (cur != null) { if (cur is VarInsnNode && cur.opcode == Opcodes.ALOAD) { val varIndex = cur.`var` - if (varIndex == 0 || nodeRemapper.processNonAload0FieldAccessChains(getLambdaIfExists(varIndex) != null)) { + if (varIndex == 0 || nodeRemapper.shouldProcessNonAload0FieldAccessChains()) { val accessChain = getCapturedFieldAccessChain((cur as VarInsnNode?)!!) val insnNode = nodeRemapper.foldFieldAccessChainIfNeeded(accessChain, node) if (insnNode != null) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RegeneratedLambdaFieldRemapper.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RegeneratedLambdaFieldRemapper.kt index 279b44750c6..4eea63ad374 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RegeneratedLambdaFieldRemapper.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RegeneratedLambdaFieldRemapper.kt @@ -46,8 +46,8 @@ class RegeneratedLambdaFieldRemapper( return findFieldInSuper(fieldInsnNode) } - override fun processNonAload0FieldAccessChains(isInlinedLambda: Boolean): Boolean { - return isInlinedLambda && isConstructor + override fun shouldProcessNonAload0FieldAccessChains(): Boolean { + return isConstructor } private fun findFieldInSuper(fieldInsnNode: FieldInsnNode): CapturedParamInfo? { diff --git a/compiler/testData/codegen/boxInline/anonymousObject/kt17972.kt b/compiler/testData/codegen/boxInline/anonymousObject/kt17972.kt new file mode 100644 index 00000000000..42272555489 --- /dev/null +++ b/compiler/testData/codegen/boxInline/anonymousObject/kt17972.kt @@ -0,0 +1,33 @@ +// FILE: 1.kt +package test + +class Test { + + val prop: String = "OK" + + fun test() = + inlineFun { + noInline { + object { + val inflater = prop + }.inflater + } + } +} + +inline fun inlineFun(init: () -> T): T { + return init() +} + +fun noInline(init: () -> T): T { + return init() +} + +// FILE: 2.kt +//NO_CHECK_LAMBDA_INLINING + +import test.* + +fun box(): String { + return Test().test() +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/anonymousObject/kt17972_2.kt b/compiler/testData/codegen/boxInline/anonymousObject/kt17972_2.kt new file mode 100644 index 00000000000..04ac09e1f8e --- /dev/null +++ b/compiler/testData/codegen/boxInline/anonymousObject/kt17972_2.kt @@ -0,0 +1,33 @@ +// FILE: 1.kt +package test + +class Test { + + val prop: String = "OK" + + fun test() = + inlineFun { + inlineFun2 { + object { + val inflater = prop + }.inflater + } + } +} + +inline fun inlineFun(init: () -> T): T { + return init() +} + +inline fun inlineFun2(init: () -> T): T { + return init() +} + +// FILE: 2.kt +//NO_CHECK_LAMBDA_INLINING + +import test.* + +fun box(): String { + return Test().test() +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/anonymousObject/kt17972_3.kt b/compiler/testData/codegen/boxInline/anonymousObject/kt17972_3.kt new file mode 100644 index 00000000000..d5550708d35 --- /dev/null +++ b/compiler/testData/codegen/boxInline/anonymousObject/kt17972_3.kt @@ -0,0 +1,35 @@ +// FILE: 1.kt +package test + +class Test { + + val prop: String = "OK" + + fun test() = + inlineFun { + noInline { + inlineFun { + object { + val inflater = prop + }.inflater + } + } + } +} + +inline fun inlineFun(init: () -> T): T { + return init() +} + +fun noInline(init: () -> T): T { + return init() +} + +// FILE: 2.kt +//NO_CHECK_LAMBDA_INLINING + +import test.* + +fun box(): String { + return Test().test() +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/anonymousObject/kt17972_4.kt b/compiler/testData/codegen/boxInline/anonymousObject/kt17972_4.kt new file mode 100644 index 00000000000..63a24a7a48c --- /dev/null +++ b/compiler/testData/codegen/boxInline/anonymousObject/kt17972_4.kt @@ -0,0 +1,37 @@ +// FILE: 1.kt +package test + +class Test { + + val prop: String = "OK" + + fun test() = + inlineFun { + noInline { + inlineFun { + noInline { + object { + val inflater = prop + }.inflater + } + } + } + } +} + +inline fun inlineFun(init: () -> T): T { + return init() +} + +fun noInline(init: () -> T): T { + return init() +} + +// FILE: 2.kt +//NO_CHECK_LAMBDA_INLINING + +import test.* + +fun box(): String { + return Test().test() +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/anonymousObject/kt17972_5.kt b/compiler/testData/codegen/boxInline/anonymousObject/kt17972_5.kt new file mode 100644 index 00000000000..e244855dd3d --- /dev/null +++ b/compiler/testData/codegen/boxInline/anonymousObject/kt17972_5.kt @@ -0,0 +1,35 @@ +// FILE: 1.kt +package test + +class Test { + + val prop: String = "OK" + + fun test() = + inlineFun { + noInline { + noInline { + object { + val inflater = prop + }.inflater + } + } + } +} + +inline fun inlineFun(init: () -> T): T { + return init() +} + +fun noInline(init: () -> T): T { + return init() +} + +// FILE: 2.kt +//NO_CHECK_LAMBDA_INLINING + +import test.* + +fun box(): String { + return Test().test() +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/anonymousObject/kt17972_super.kt b/compiler/testData/codegen/boxInline/anonymousObject/kt17972_super.kt new file mode 100644 index 00000000000..81121ef7928 --- /dev/null +++ b/compiler/testData/codegen/boxInline/anonymousObject/kt17972_super.kt @@ -0,0 +1,35 @@ +// FILE: 1.kt +package test + +open class A(val value: String) + +class Test { + + val prop: String = "OK" + + fun test() = + inlineFun { + noInline { + object : A(prop) { + + }.value + } + } +} + +inline fun inlineFun(init: () -> T): T { + return init() +} + +fun noInline(init: () -> T): T { + return init() +} + +// FILE: 2.kt +//NO_CHECK_LAMBDA_INLINING + +import test.* + +fun box(): String { + return Test().test() +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/anonymousObject/kt17972_super2.kt b/compiler/testData/codegen/boxInline/anonymousObject/kt17972_super2.kt new file mode 100644 index 00000000000..8f07e0d611e --- /dev/null +++ b/compiler/testData/codegen/boxInline/anonymousObject/kt17972_super2.kt @@ -0,0 +1,37 @@ +// FILE: 1.kt +package test + +open class A(val value: String) + +class Test { + + val prop: String = "OK" + + fun test() = + inlineFun { + noInline { + inlineFun { + object : A(prop) { + + }.value + } + } + } +} + +inline fun inlineFun(init: () -> T): T { + return init() +} + +fun noInline(init: () -> T): T { + return init() +} + +// FILE: 2.kt +//NO_CHECK_LAMBDA_INLINING + +import test.* + +fun box(): String { + return Test().test() +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/anonymousObject/kt17972_super3.kt b/compiler/testData/codegen/boxInline/anonymousObject/kt17972_super3.kt new file mode 100644 index 00000000000..2e6ec71e3f4 --- /dev/null +++ b/compiler/testData/codegen/boxInline/anonymousObject/kt17972_super3.kt @@ -0,0 +1,39 @@ +// FILE: 1.kt +package test + +open class A(val value: String) + +class Test { + + val prop: String = "OK" + + fun test() = + inlineFun { + noInline { + inlineFun { + noInline { + object : A(prop) { + + }.value + } + } + } + } +} + +inline fun inlineFun(init: () -> T): T { + return init() +} + +fun noInline(init: () -> T): T { + return init() +} + +// FILE: 2.kt +//NO_CHECK_LAMBDA_INLINING + +import test.* + +fun box(): String { + return Test().test() +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java index dbdc6027571..9bca40efdcf 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java @@ -164,6 +164,54 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo doTest(fileName); } + @TestMetadata("kt17972.kt") + public void testKt17972() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt17972.kt"); + doTest(fileName); + } + + @TestMetadata("kt17972_2.kt") + public void testKt17972_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt17972_2.kt"); + doTest(fileName); + } + + @TestMetadata("kt17972_3.kt") + public void testKt17972_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt17972_3.kt"); + doTest(fileName); + } + + @TestMetadata("kt17972_4.kt") + public void testKt17972_4() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt17972_4.kt"); + doTest(fileName); + } + + @TestMetadata("kt17972_5.kt") + public void testKt17972_5() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt17972_5.kt"); + doTest(fileName); + } + + @TestMetadata("kt17972_super.kt") + public void testKt17972_super() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt17972_super.kt"); + doTest(fileName); + } + + @TestMetadata("kt17972_super2.kt") + public void testKt17972_super2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt17972_super2.kt"); + doTest(fileName); + } + + @TestMetadata("kt17972_super3.kt") + public void testKt17972_super3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt17972_super3.kt"); + doTest(fileName); + } + @TestMetadata("kt6552.kt") public void testKt6552() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt6552.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java index 9d1ac31d9f0..87314ee4e4f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java @@ -164,6 +164,54 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi doTest(fileName); } + @TestMetadata("kt17972.kt") + public void testKt17972() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt17972.kt"); + doTest(fileName); + } + + @TestMetadata("kt17972_2.kt") + public void testKt17972_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt17972_2.kt"); + doTest(fileName); + } + + @TestMetadata("kt17972_3.kt") + public void testKt17972_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt17972_3.kt"); + doTest(fileName); + } + + @TestMetadata("kt17972_4.kt") + public void testKt17972_4() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt17972_4.kt"); + doTest(fileName); + } + + @TestMetadata("kt17972_5.kt") + public void testKt17972_5() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt17972_5.kt"); + doTest(fileName); + } + + @TestMetadata("kt17972_super.kt") + public void testKt17972_super() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt17972_super.kt"); + doTest(fileName); + } + + @TestMetadata("kt17972_super2.kt") + public void testKt17972_super2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt17972_super2.kt"); + doTest(fileName); + } + + @TestMetadata("kt17972_super3.kt") + public void testKt17972_super3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt17972_super3.kt"); + doTest(fileName); + } + @TestMetadata("kt6552.kt") public void testKt6552() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt6552.kt");