From 080610c2083829e515bfa4a8d8900f2cc3a01112 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Fri, 21 Nov 2014 11:45:38 +0400 Subject: [PATCH] Wrap parentCodegen before generating from inline --- .../jetbrains/jet/codegen/MemberCodegen.java | 4 ++ .../jet/codegen/inline/InlineCodegen.java | 50 ++++++++++++++++--- .../reifiedInlineIntoNonInlineableLambda.kt | 28 +++++++++++ ...lackBoxWithStdlibCodegenTestGenerated.java | 6 +++ 4 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 compiler/testData/codegen/boxWithStdlib/reified/reifiedInlineIntoNonInlineableLambda.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java index e8fc2cf7c5e..a646a80b185 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java @@ -86,6 +86,10 @@ public abstract class MemberCodegen wrapped) { + this(wrapped.state, wrapped.getParentCodegen(), wrapped.getContext(), wrapped.element, wrapped.v); + } + public void generate() { generateDeclaration(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlineCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlineCodegen.java index 0d715f965ff..9ac3e68e656 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlineCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlineCodegen.java @@ -192,11 +192,7 @@ public class InlineCodegen implements CallGenerator { ); } else { - FunctionCodegen.generateMethodBody( - maxCalcAdapter, functionDescriptor, methodContext, jvmSignature, - new FunctionGenerationStrategy.FunctionDefault(state, functionDescriptor, (JetDeclarationWithBody) element), - parentCodegen - ); + generateMethodBody(maxCalcAdapter, functionDescriptor, methodContext, (JetDeclarationWithBody) element, jvmSignature); } maxCalcAdapter.visitMaxs(-1, -1); maxCalcAdapter.visitEnd(); @@ -277,13 +273,55 @@ public class InlineCodegen implements CallGenerator { MethodVisitor adapter = InlineCodegenUtil.wrapWithMaxLocalCalc(methodNode); - FunctionCodegen.generateMethodBody(adapter, descriptor, context, jvmMethodSignature, new FunctionGenerationStrategy.FunctionDefault(state, descriptor, declaration), codegen.getParentCodegen()); + generateMethodBody(adapter, descriptor, context, declaration, jvmMethodSignature); adapter.visitMaxs(-1, -1); return methodNode; } + private void generateMethodBody( + @NotNull MethodVisitor adapter, + @NotNull FunctionDescriptor descriptor, + @NotNull MethodContext context, + @NotNull JetDeclarationWithBody declaration, + @NotNull JvmMethodSignature jvmMethodSignature + ) { + FunctionCodegen.generateMethodBody( + adapter, descriptor, context, jvmMethodSignature, + new FunctionGenerationStrategy.FunctionDefault(state, descriptor, declaration), + // Wrapping for preventing marking actual parent codegen as containing reifier markers + new FakeMemberCodegen(codegen.getParentCodegen()) + ); + } + private static class FakeMemberCodegen extends MemberCodegen { + private final MemberCodegen delegate; + public FakeMemberCodegen(@NotNull MemberCodegen wrapped) { + super(wrapped); + delegate = wrapped; + } + + @Override + protected void generateDeclaration() { + throw new IllegalStateException(); + } + + @Override + protected void generateBody() { + throw new IllegalStateException(); + } + + @Override + protected void generateKotlinAnnotation() { + throw new IllegalStateException(); + } + + @NotNull + @Override + public NameGenerator getInlineNameGenerator() { + return delegate.getInlineNameGenerator(); + } + } @Override public void afterParameterPut(@NotNull Type type, @Nullable StackValue stackValue, @Nullable ValueParameterDescriptor valueParameterDescriptor) { diff --git a/compiler/testData/codegen/boxWithStdlib/reified/reifiedInlineIntoNonInlineableLambda.kt b/compiler/testData/codegen/boxWithStdlib/reified/reifiedInlineIntoNonInlineableLambda.kt new file mode 100644 index 00000000000..ce25ba54f75 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reified/reifiedInlineIntoNonInlineableLambda.kt @@ -0,0 +1,28 @@ +import kotlin.test.assertEquals + +fun foo(block: () -> String) = block() + +inline fun className(): String = javaClass().getName() + +trait A { + fun f(): String + fun g(): String +} + +fun box(): String { + val x = foo() { + className() + } + + assertEquals("java.lang.String", x) + + val y: A = object : A { + override fun f(): String = foo { className() } + override fun g(): String = foo { className() } + } + + assertEquals("java.lang.String", y.f()) + assertEquals("java.lang.Integer", y.g()) + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index c4cc4736f2b..58d5972e836 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -2718,6 +2718,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib(fileName); } + @TestMetadata("reifiedInlineIntoNonInlineableLambda.kt") + public void testReifiedInlineIntoNonInlineableLambda() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/reifiedInlineIntoNonInlineableLambda.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("safecast.kt") public void testSafecast() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/safecast.kt");