Skip to content

Commit

Permalink
Process non-aload0 outer access in constructor during inline
Browse files Browse the repository at this point in the history
  #KT-17972 Fixed
  • Loading branch information
Mikhael Bogdanov committed May 26, 2017
1 parent 5e265b3 commit 3f7bf84
Show file tree
Hide file tree
Showing 13 changed files with 392 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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? {
Expand Down
33 changes: 33 additions & 0 deletions compiler/testData/codegen/boxInline/anonymousObject/kt17972.kt
Original file line number Diff line number Diff line change
@@ -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()
}
33 changes: 33 additions & 0 deletions compiler/testData/codegen/boxInline/anonymousObject/kt17972_2.kt
Original file line number Diff line number Diff line change
@@ -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()
}
35 changes: 35 additions & 0 deletions compiler/testData/codegen/boxInline/anonymousObject/kt17972_3.kt
Original file line number Diff line number Diff line change
@@ -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()
}
37 changes: 37 additions & 0 deletions compiler/testData/codegen/boxInline/anonymousObject/kt17972_4.kt
Original file line number Diff line number Diff line change
@@ -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()
}
35 changes: 35 additions & 0 deletions compiler/testData/codegen/boxInline/anonymousObject/kt17972_5.kt
Original file line number Diff line number Diff line change
@@ -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()
}
Original file line number Diff line number Diff line change
@@ -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()
}
Original file line number Diff line number Diff line change
@@ -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()
}
Original file line number Diff line number Diff line change
@@ -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()
}
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,54 @@ public void testKt16193() throws Exception {
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");
Expand Down
Loading

0 comments on commit 3f7bf84

Please sign in to comment.