JVM IR: fix enclosing constructor for lambdas in inner classes

Before this change, we stored the enclosing constructor in a map in
JvmBackendContext before moving lambdas and local classes out of
initializer blocks. However, in case the lambda was declared in an inner
class, we stored a reference to the unlowered constructor of the inner
class, whose JVM signature is "()V" instead of the correct "(LOuter;)V".
Java reflection then threw exception if we tried to call
`getEnclosingConstructor()` on such class at runtime. Proguard finished
with errors for the same reason.

It turns out that we can just store the fact that the class has been
moved, and load the matching constructor in codegen, where everything is
already lowered and guaranteed to match with the signatures of the
actual generated declarations.

 #KT-41668 Fixed
This commit is contained in:
Alexander Udalov
2020-09-03 18:31:06 +02:00
parent 228e329d1f
commit c46c80822c
8 changed files with 63 additions and 18 deletions
@@ -474,6 +474,11 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
runTest("compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/lambdaInInitBlockNoPrimaryConstructor.kt");
}
@TestMetadata("lambdaInInnerClassConstructor.kt")
public void testLambdaInInnerClassConstructor() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/lambdaInInnerClassConstructor.kt");
}
@TestMetadata("transformedConstructor.kt")
public void testTransformedConstructor() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructor.kt");
@@ -444,6 +444,11 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes
runTest("compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/lambdaInInitBlockNoPrimaryConstructor.kt");
}
@TestMetadata("lambdaInInnerClassConstructor.kt")
public void testLambdaInInnerClassConstructor() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/lambdaInInnerClassConstructor.kt");
}
@TestMetadata("transformedConstructor.kt")
public void testTransformedConstructor() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/inline/enclosingInfo/transformedConstructor.kt");