From 5fdb0df3fa050f46718dfdcefe23527cbe937806 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Fri, 19 Oct 2018 18:50:37 +0300 Subject: [PATCH] Fix backend for working with asm-7.0 beta (KT-27540, KT-27774) Reset labels infos before moving instructions, otherwise list of instructions is corrupted. For more information: https://gitlab.ow2.org/asm/asm/issues/317858 https://gitlab.ow2.org/asm/asm/commit/dc8acb48450bbb4aa461fb103916378cd226a6f6#5e3df072b61d74b2fd71d97a1d99188ccc46c1da_235_233 #KT-27540 Fixed --- .../org/jetbrains/kotlin/codegen/AsmUtil.java | 21 +++++++++++++++++++ .../inline/AnonymousObjectTransformer.kt | 1 + .../codegen/inline/DeferredMethodVisitor.kt | 2 ++ .../kotlin/codegen/inline/InlineCodegen.kt | 1 + .../inline/InlineCodegenForDefaultBody.kt | 2 ++ .../kotlin/codegen/inline/MethodInliner.kt | 3 +++ .../LabelNormalizationMethodTransformer.kt | 9 +++++--- 7 files changed, 36 insertions(+), 3 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java index 96cc1037c8d..bed92d14eaf 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java @@ -51,6 +51,10 @@ import org.jetbrains.kotlin.types.SimpleType; import org.jetbrains.org.objectweb.asm.*; import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; import org.jetbrains.org.objectweb.asm.commons.Method; +import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode; +import org.jetbrains.org.objectweb.asm.tree.InsnList; +import org.jetbrains.org.objectweb.asm.tree.LabelNode; +import org.jetbrains.org.objectweb.asm.tree.MethodNode; import java.util.ArrayList; import java.util.List; @@ -1229,4 +1233,21 @@ public class AsmUtil { //Trait always should have this descriptor return kind != OwnerKind.DEFAULT_IMPLS && isStaticMethod(kind, descriptor) ? 0 : 1; } + + public static void resetLabelInfos(@NotNull MethodNode methodNode) { + //noinspection ConstantConditions + if (Opcodes.API_VERSION <= Opcodes.ASM6) { + return; + } + + InsnList instructions = methodNode.instructions; + for (AbstractInsnNode inst = instructions.getFirst(); inst != null; inst = inst.getNext()) { + if (inst instanceof LabelNode) { + Label label = ((LabelNode) inst).getLabel(); + if (label != null) { + label.info = null; + } + } + } + } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt index ecbbc732ab4..bae6bb8f40d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt @@ -407,6 +407,7 @@ class AnonymousObjectTransformer( val first = intermediateMethodNode.instructions.first val oldStartLabel = (first as? LabelNode)?.label + AsmUtil.resetLabelInfos(intermediateMethodNode) intermediateMethodNode.accept(object : MethodBodyVisitor(capturedFieldInitializer) { override fun visitLocalVariable( name: String, desc: String, signature: String?, start: Label, end: Label, index: Int diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/DeferredMethodVisitor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/DeferredMethodVisitor.kt index 6ff841d43c2..3a2447adcd1 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/DeferredMethodVisitor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/DeferredMethodVisitor.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.codegen.inline +import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.org.objectweb.asm.MethodVisitor import org.jetbrains.org.objectweb.asm.tree.MethodNode @@ -27,6 +28,7 @@ class DeferredMethodVisitor( override fun visitEnd() { super.visitEnd() val resultVisitor = resultNode() + AsmUtil.resetLabelInfos(intermediate) intermediate.accept(resultVisitor) } } \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt index 232d86c5b25..a0751726c4c 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt @@ -290,6 +290,7 @@ abstract class InlineCodegen( removeFinallyMarkers(adapter) } + AsmUtil.resetLabelInfos(adapter) adapter.accept(MethodBodyVisitor(codegen.v)) if (shouldSpillStack) { 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 5146af98fb6..afcc3398f13 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenForDefaultBody.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenForDefaultBody.kt @@ -70,6 +70,7 @@ class InlineCodegenForDefaultBody( val argsSize = (Type.getArgumentsAndReturnSizes(jvmSignature.asmMethod.descriptor) ushr 2) - if (callableMethod.isStaticCall()) 1 else 0 + AsmUtil.resetLabelInfos(node) 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 @@ -77,6 +78,7 @@ class InlineCodegenForDefaultBody( } }) + AsmUtil.resetLabelInfos(transformedMethod) transformedMethod.accept(MethodBodyVisitor(codegen.visitor)) } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt index 3adc87a9f67..df2e14fb5de 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt @@ -130,7 +130,9 @@ class MethodInliner( } processReturns(resultNode, labelOwner, remapReturn, end) + //flush transformed node to output + AsmUtil.resetLabelInfos(resultNode) resultNode.accept(MethodBodyVisitor(adapter, true)) sourceMapper.endMapping() @@ -383,6 +385,7 @@ class MethodInliner( } } + AsmUtil.resetLabelInfos(node) node.accept(lambdaInliner) return resultNode diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/LabelNormalizationMethodTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/LabelNormalizationMethodTransformer.kt index e896ca7d047..02da4ce1cf7 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/LabelNormalizationMethodTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/LabelNormalizationMethodTransformer.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.codegen.optimization.common.removeEmptyCatchBlocks import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.tree.* +import java.lang.IllegalStateException class LabelNormalizationMethodTransformer : MethodTransformer() { override fun transform(internalClassName: String, methodNode: MethodNode) { @@ -142,8 +143,10 @@ class LabelNormalizationMethodTransformer : MethodTransformer() { return frameNode } - private fun getNew(oldLabelNode: LabelNode): LabelNode = - newLabelNodes[oldLabelNode.label]!! + private fun getNew(oldLabelNode: LabelNode): LabelNode { + return newLabelNodes[oldLabelNode.label] + ?: throw IllegalStateException("Label wasn't found during iterating through instructions") + } private fun getNewOrOld(oldLabelNode: LabelNode): LabelNode = newLabelNodes[oldLabelNode.label] ?: oldLabelNode @@ -160,4 +163,4 @@ fun InsnList.removeNodeGetNext(oldNode: AbstractInsnNode): AbstractInsnNode? { val next = oldNode.next remove(oldNode) return next -} +} \ No newline at end of file