Process non-aload0 outer access in constructor during inline

#KT-17972 Fixed
This commit is contained in:
Mikhael Bogdanov
2017-05-23 12:05:12 +02:00
committed by Michael Bogdanov
parent 5e265b3d17
commit 3f7bf8467a
13 changed files with 392 additions and 5 deletions
@@ -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<AbstractInsnNode>,
@@ -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) {
@@ -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? {
@@ -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 <T> inlineFun(init: () -> T): T {
return init()
}
fun <T> noInline(init: () -> T): T {
return init()
}
// FILE: 2.kt
//NO_CHECK_LAMBDA_INLINING
import test.*
fun box(): String {
return Test().test()
}
@@ -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 <T> inlineFun(init: () -> T): T {
return init()
}
inline fun <T> inlineFun2(init: () -> T): T {
return init()
}
// FILE: 2.kt
//NO_CHECK_LAMBDA_INLINING
import test.*
fun box(): String {
return Test().test()
}
@@ -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 <T> inlineFun(init: () -> T): T {
return init()
}
fun <T> noInline(init: () -> T): T {
return init()
}
// FILE: 2.kt
//NO_CHECK_LAMBDA_INLINING
import test.*
fun box(): String {
return Test().test()
}
@@ -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 <T> inlineFun(init: () -> T): T {
return init()
}
fun <T> noInline(init: () -> T): T {
return init()
}
// FILE: 2.kt
//NO_CHECK_LAMBDA_INLINING
import test.*
fun box(): String {
return Test().test()
}
@@ -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 <T> inlineFun(init: () -> T): T {
return init()
}
fun <T> noInline(init: () -> T): T {
return init()
}
// FILE: 2.kt
//NO_CHECK_LAMBDA_INLINING
import test.*
fun box(): String {
return Test().test()
}
@@ -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 <T> inlineFun(init: () -> T): T {
return init()
}
fun <T> noInline(init: () -> T): T {
return init()
}
// FILE: 2.kt
//NO_CHECK_LAMBDA_INLINING
import test.*
fun box(): String {
return Test().test()
}
@@ -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 <T> inlineFun(init: () -> T): T {
return init()
}
fun <T> noInline(init: () -> T): T {
return init()
}
// FILE: 2.kt
//NO_CHECK_LAMBDA_INLINING
import test.*
fun box(): String {
return Test().test()
}
@@ -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 <T> inlineFun(init: () -> T): T {
return init()
}
fun <T> noInline(init: () -> T): T {
return init()
}
// FILE: 2.kt
//NO_CHECK_LAMBDA_INLINING
import test.*
fun box(): String {
return Test().test()
}
@@ -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");
@@ -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");