From be999ca4cb575fb5ae8c25401bec27cfb8c624c7 Mon Sep 17 00:00:00 2001 From: Michael Bogdanov Date: Sat, 9 Apr 2016 12:21:37 +0300 Subject: [PATCH] Write proper start label for parameters of inline function default implementation --- .../inline/InlineCodegenForDefaultBody.kt | 14 +++++++- .../jackAndJill/inlineDefaultBody.kt | 13 ++++++++ .../jackAndJill/inlineDefaultBodyInClass.kt | 16 +++++++++ .../codegen/BytecodeTextTestGenerated.java | 33 +++++++++++++++++++ 4 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/codegen/bytecodeText/jackAndJill/inlineDefaultBody.kt create mode 100644 compiler/testData/codegen/bytecodeText/jackAndJill/inlineDefaultBodyInClass.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenForDefaultBody.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenForDefaultBody.kt index 0d2430dbceb..72694078215 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenForDefaultBody.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenForDefaultBody.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.inline.InlineUtil +import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.tree.MethodNode @@ -51,11 +52,16 @@ class InlineCodegenForDefaultBody( private val jvmSignature = state.typeMapper.mapSignatureWithGeneric(functionDescriptor, context.contextKind) + private val methodStartLabel = Label() + init { assert(InlineUtil.isInline(function)) { "InlineCodegen can inline only inline functions and array constructors: " + function } InlineCodegen.reportIncrementalInfo(functionDescriptor, codegen.context.functionDescriptor.original, jvmSignature, state) + + //InlineCodegenForDefaultBody created just after visitCode call + codegen.v.visitLabel(methodStartLabel) } override fun genCallInner(callableMethod: Callable, resolvedCall: ResolvedCall<*>?, callDefault: Boolean, codegen: ExpressionCodegen) { @@ -70,7 +76,13 @@ class InlineCodegenForDefaultBody( node.signature, node.exceptions.toTypedArray()) - node.accept(InlineAdapter(transformedMethod, 0, childSourceMapper)) + val argsSize = (Type.getArgumentsAndReturnSizes(jvmSignature.asmMethod.descriptor) ushr 2) - if (callableMethod.isStaticCall()) 1 else 0 + node.accept(object : InlineAdapter(transformedMethod, 0, childSourceMapper) { + override fun visitLocalVariable(name: String, desc: String, signature: String?, start: Label, end: Label, index: Int) { + val startLabel = if (index < argsSize) methodStartLabel else start + super.visitLocalVariable(name, desc, signature, startLabel, end, index) + } + }) transformedMethod.accept(MethodBodyVisitor(codegen.v)) } diff --git a/compiler/testData/codegen/bytecodeText/jackAndJill/inlineDefaultBody.kt b/compiler/testData/codegen/bytecodeText/jackAndJill/inlineDefaultBody.kt new file mode 100644 index 00000000000..3799f94a720 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/jackAndJill/inlineDefaultBody.kt @@ -0,0 +1,13 @@ +inline fun test(a: Int = 1, b: Long = 1L, c: String = "123") { + val d = 1 +} + +// +// 1 test\$default\(IJLjava/lang/String;ILjava/lang/Object;\)V\s+L0 +// 1 LOCALVARIABLE a I L0 L8 0 +// 1 LOCALVARIABLE b J L0 L8 1 +// 1 LOCALVARIABLE c Ljava/lang/String; L0 L8 3 +// 1 LOCALVARIABLE \$i\$f\$test I L5 L8 4 +// 1 LOCALVARIABLE d I L7 L8 5 + + diff --git a/compiler/testData/codegen/bytecodeText/jackAndJill/inlineDefaultBodyInClass.kt b/compiler/testData/codegen/bytecodeText/jackAndJill/inlineDefaultBodyInClass.kt new file mode 100644 index 00000000000..e787c21516e --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/jackAndJill/inlineDefaultBodyInClass.kt @@ -0,0 +1,16 @@ +class A { + inline fun test(a: Int = 1, b: Long = 1L, c: String = "123") { + val d = 1 + } +} + +// +// 1 test\$default\(LA;IJLjava/lang/String;ILjava/lang/Object;\)V\s+L0 +// 1 LOCALVARIABLE this LA; L0 L8 0 +// 1 LOCALVARIABLE a I L0 L8 1 +// 1 LOCALVARIABLE b J L0 L8 2 +// 1 LOCALVARIABLE c Ljava/lang/String; L0 L8 4 +// 1 LOCALVARIABLE \$i\$f\$test I L5 L8 5 +// 1 LOCALVARIABLE d I L7 L8 6 + + diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index ef648a75a94..aaf8bc96b87 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -980,6 +980,39 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { } } + @TestMetadata("compiler/testData/codegen/bytecodeText/jackAndJill") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class JackAndJill extends AbstractBytecodeTextTest { + public void testAllFilesPresentInJackAndJill() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/jackAndJill"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("inlineDefaultBody.kt") + public void testInlineDefaultBody() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/jackAndJill/inlineDefaultBody.kt"); + doTest(fileName); + } + + @TestMetadata("inlineDefaultBodyInClass.kt") + public void testInlineDefaultBodyInClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/jackAndJill/inlineDefaultBodyInClass.kt"); + doTest(fileName); + } + + @TestMetadata("inlinedConstuctor.kt") + public void testInlinedConstuctor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/jackAndJill/inlinedConstuctor.kt"); + doTest(fileName); + } + + @TestMetadata("inlinedConstuctorWithSuperCallParams.kt") + public void testInlinedConstuctorWithSuperCallParams() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/jackAndJill/inlinedConstuctorWithSuperCallParams.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/bytecodeText/lazyCodegen") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)