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
This commit is contained in:
Nikolay Krasko
2018-10-19 18:50:37 +03:00
parent 3b5dfba73a
commit 5fdb0df3fa
7 changed files with 36 additions and 3 deletions
@@ -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;
}
}
}
}
}
@@ -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
@@ -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)
}
}
@@ -290,6 +290,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
removeFinallyMarkers(adapter)
}
AsmUtil.resetLabelInfos(adapter)
adapter.accept(MethodBodyVisitor(codegen.v))
if (shouldSpillStack) {
@@ -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))
}
@@ -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
@@ -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
}
}