From 29e55df5a4904cc2363bd6569e6345d7348f2ea7 Mon Sep 17 00:00:00 2001 From: Graham Date: Mon, 27 Jan 2020 21:25:55 +0000 Subject: [PATCH] Use live variable analysis in DummyLocalTransformer This allows us to catch a few extra locals, which in turn allows us to remove a few more dummy arguments. --- .../deob/transform/DummyLocalTransformer.kt | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/deob/src/main/java/dev/openrs2/deob/transform/DummyLocalTransformer.kt b/deob/src/main/java/dev/openrs2/deob/transform/DummyLocalTransformer.kt index cdd14db9..df806579 100644 --- a/deob/src/main/java/dev/openrs2/deob/transform/DummyLocalTransformer.kt +++ b/deob/src/main/java/dev/openrs2/deob/transform/DummyLocalTransformer.kt @@ -5,7 +5,9 @@ import dev.openrs2.asm.classpath.ClassPath import dev.openrs2.asm.classpath.Library import dev.openrs2.asm.deleteSimpleExpression import dev.openrs2.asm.transform.Transformer +import dev.openrs2.deob.analysis.LiveVariableAnalyzer import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.AbstractInsnNode import org.objectweb.asm.tree.ClassNode import org.objectweb.asm.tree.MethodNode import org.objectweb.asm.tree.VarInsnNode @@ -18,29 +20,25 @@ class DummyLocalTransformer : Transformer() { } override fun transformCode(classPath: ClassPath, library: Library, clazz: ClassNode, method: MethodNode): Boolean { - /* - * XXX(gpe): this is primitive (ideally we'd do a proper data flow - * analysis, but we'd need to do it in reverse and ASM only supports - * forward data flow), however, it seems to be good enough to catch - * most dummy locals. - */ - val loads = BooleanArray(method.maxLocals) + val analyzer = LiveVariableAnalyzer(clazz.name, method) + analyzer.analyze() - for (insn in method.instructions) { - if (insn is VarInsnNode && insn.opcode == Opcodes.ILOAD) { - loads[insn.`var`] = true - } - } + val deadStores = mutableListOf() for (insn in method.instructions) { if (insn !is VarInsnNode || insn.opcode != Opcodes.ISTORE) { continue } - if (loads[insn.`var`]) { + val live = analyzer.getInSet(insn)?.contains(insn.`var`) ?: false + if (live) { continue } + deadStores += insn + } + + for (insn in deadStores) { if (method.instructions.deleteSimpleExpression(insn)) { localsRemoved++ }