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.
master
Graham 4 years ago
parent 400a10f8d2
commit 29e55df5a4
  1. 24
      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.classpath.Library
import dev.openrs2.asm.deleteSimpleExpression import dev.openrs2.asm.deleteSimpleExpression
import dev.openrs2.asm.transform.Transformer import dev.openrs2.asm.transform.Transformer
import dev.openrs2.deob.analysis.LiveVariableAnalyzer
import org.objectweb.asm.Opcodes import org.objectweb.asm.Opcodes
import org.objectweb.asm.tree.AbstractInsnNode
import org.objectweb.asm.tree.ClassNode import org.objectweb.asm.tree.ClassNode
import org.objectweb.asm.tree.MethodNode import org.objectweb.asm.tree.MethodNode
import org.objectweb.asm.tree.VarInsnNode 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 { override fun transformCode(classPath: ClassPath, library: Library, clazz: ClassNode, method: MethodNode): Boolean {
/* val analyzer = LiveVariableAnalyzer(clazz.name, method)
* XXX(gpe): this is primitive (ideally we'd do a proper data flow analyzer.analyze()
* 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)
for (insn in method.instructions) { val deadStores = mutableListOf<AbstractInsnNode>()
if (insn is VarInsnNode && insn.opcode == Opcodes.ILOAD) {
loads[insn.`var`] = true
}
}
for (insn in method.instructions) { for (insn in method.instructions) {
if (insn !is VarInsnNode || insn.opcode != Opcodes.ISTORE) { if (insn !is VarInsnNode || insn.opcode != Opcodes.ISTORE) {
continue continue
} }
if (loads[insn.`var`]) { val live = analyzer.getInSet(insn)?.contains(insn.`var`) ?: false
if (live) {
continue continue
} }
deadStores += insn
}
for (insn in deadStores) {
if (method.instructions.deleteSimpleExpression(insn)) { if (method.instructions.deleteSimpleExpression(insn)) {
localsRemoved++ localsRemoved++
} }

Loading…
Cancel
Save