From 70ccdfa5260f61e49379bef0f27a22273aff4ae4 Mon Sep 17 00:00:00 2001 From: Graham Date: Mon, 30 Sep 2019 11:33:13 +0100 Subject: [PATCH] Add removeDeadCode method --- .../java/dev/openrs2/asm/MethodNodeUtils.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/asm/src/main/java/dev/openrs2/asm/MethodNodeUtils.java b/asm/src/main/java/dev/openrs2/asm/MethodNodeUtils.java index 9e96bb0554..e42d4b3073 100644 --- a/asm/src/main/java/dev/openrs2/asm/MethodNodeUtils.java +++ b/asm/src/main/java/dev/openrs2/asm/MethodNodeUtils.java @@ -2,6 +2,7 @@ package dev.openrs2.asm; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.List; import java.util.stream.Collectors; @@ -11,8 +12,12 @@ import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.AnnotationNode; import org.objectweb.asm.tree.FrameNode; import org.objectweb.asm.tree.IincInsnNode; +import org.objectweb.asm.tree.LabelNode; import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.VarInsnNode; +import org.objectweb.asm.tree.analysis.Analyzer; +import org.objectweb.asm.tree.analysis.AnalyzerException; +import org.objectweb.asm.tree.analysis.BasicInterpreter; public final class MethodNodeUtils { private static int localIndex(int access, List argTypes, int argIndex) { @@ -129,6 +134,36 @@ public final class MethodNodeUtils { } } + public static void removeDeadCode(String owner, MethodNode method) throws AnalyzerException { + boolean changed; + do { + changed = false; + + var analyzer = new Analyzer<>(new BasicInterpreter()); + var frames = analyzer.analyze(owner, method); + + var deadLabels = new HashSet(); + var i = 0; + for (var it = method.instructions.iterator(); it.hasNext(); ) { + var insn = it.next(); + if (frames[i++] != null) { + continue; + } + + if (insn.getType() == AbstractInsnNode.LABEL) { + deadLabels.add((LabelNode) insn); + } else { + it.remove(); + changed = true; + } + } + + if (method.tryCatchBlocks.removeIf(tryCatch -> deadLabels.contains(tryCatch.start) && deadLabels.contains(tryCatch.end))) { + changed = true; + } + } while (changed); + } + private MethodNodeUtils() { /* empty */ }