Add support for impure expressions to InsnListUtils

master
Graham 4 years ago
parent f8acce846b
commit 3f2335859d
  1. 25
      asm/src/main/java/dev/openrs2/asm/InsnListUtils.kt
  2. 11
      deob/src/main/java/dev/openrs2/deob/transform/DummyArgTransformer.kt
  3. 5
      deob/src/main/java/dev/openrs2/deob/transform/DummyLocalTransformer.kt

@ -3,7 +3,13 @@ package dev.openrs2.asm
import org.objectweb.asm.tree.AbstractInsnNode import org.objectweb.asm.tree.AbstractInsnNode
import org.objectweb.asm.tree.InsnList import org.objectweb.asm.tree.InsnList
fun getSimpleExpression(last: AbstractInsnNode): List<AbstractInsnNode>? { private val ANY_INSN = { _: AbstractInsnNode -> true }
private val JUMP_OR_LABEL = listOf(AbstractInsnNode.LABEL, AbstractInsnNode.JUMP_INSN)
fun getExpression(
last: AbstractInsnNode,
filter: (AbstractInsnNode) -> Boolean = ANY_INSN
): List<AbstractInsnNode>? {
val expr = mutableListOf<AbstractInsnNode>() val expr = mutableListOf<AbstractInsnNode>()
var height = 0 var height = 0
@ -21,20 +27,27 @@ fun getSimpleExpression(last: AbstractInsnNode): List<AbstractInsnNode>? {
} }
insn = insn.previous insn = insn.previous
} while (insn != null && insn.type != AbstractInsnNode.LABEL && insn.pure) } while (insn != null && insn.type !in JUMP_OR_LABEL && filter(insn))
return null return null
} }
fun InsnList.replaceSimpleExpression(last: AbstractInsnNode, replacement: AbstractInsnNode): Boolean { fun InsnList.replaceExpression(
val expr = getSimpleExpression(last) ?: return false last: AbstractInsnNode,
replacement: AbstractInsnNode,
filter: (AbstractInsnNode) -> Boolean = ANY_INSN
): Boolean {
val expr = getExpression(last, filter) ?: return false
expr.forEach(this::remove) expr.forEach(this::remove)
this[last] = replacement this[last] = replacement
return true return true
} }
fun InsnList.deleteSimpleExpression(last: AbstractInsnNode): Boolean { fun InsnList.deleteExpression(
val expr = getSimpleExpression(last) ?: return false last: AbstractInsnNode,
filter: (AbstractInsnNode) -> Boolean = ANY_INSN
): Boolean {
val expr = getExpression(last, filter) ?: return false
expr.forEach(this::remove) expr.forEach(this::remove)
remove(last) remove(last)
return true return true

@ -8,11 +8,11 @@ import dev.openrs2.asm.MemberRef
import dev.openrs2.asm.classpath.ClassPath import dev.openrs2.asm.classpath.ClassPath
import dev.openrs2.asm.classpath.Library import dev.openrs2.asm.classpath.Library
import dev.openrs2.asm.createIntConstant import dev.openrs2.asm.createIntConstant
import dev.openrs2.asm.deleteSimpleExpression import dev.openrs2.asm.deleteExpression
import dev.openrs2.asm.intConstant import dev.openrs2.asm.intConstant
import dev.openrs2.asm.nextReal import dev.openrs2.asm.nextReal
import dev.openrs2.asm.pure import dev.openrs2.asm.pure
import dev.openrs2.asm.replaceSimpleExpression import dev.openrs2.asm.replaceExpression
import dev.openrs2.asm.stackMetadata import dev.openrs2.asm.stackMetadata
import dev.openrs2.asm.transform.Transformer import dev.openrs2.asm.transform.Transformer
import dev.openrs2.common.collect.DisjointSet import dev.openrs2.common.collect.DisjointSet
@ -297,14 +297,15 @@ class DummyArgTransformer : Transformer() {
} }
for (insn in alwaysTakenBranches) { for (insn in alwaysTakenBranches) {
if (method.instructions.replaceSimpleExpression(insn, JumpInsnNode(Opcodes.GOTO, insn.label))) { val replacement = JumpInsnNode(Opcodes.GOTO, insn.label)
if (method.instructions.replaceExpression(insn, replacement, AbstractInsnNode::pure)) {
branchesSimplified++ branchesSimplified++
changed = true changed = true
} }
} }
for (insn in neverTakenBranches) { for (insn in neverTakenBranches) {
if (method.instructions.deleteSimpleExpression(insn)) { if (method.instructions.deleteExpression(insn, AbstractInsnNode::pure)) {
branchesSimplified++ branchesSimplified++
changed = true changed = true
} }
@ -316,7 +317,7 @@ class DummyArgTransformer : Transformer() {
} }
val replacement = createIntConstant(value) val replacement = createIntConstant(value)
if (method.instructions.replaceSimpleExpression(insn, replacement)) { if (method.instructions.replaceExpression(insn, replacement, AbstractInsnNode::pure)) {
constantsInlined++ constantsInlined++
changed = true changed = true
} }

@ -3,7 +3,8 @@ package dev.openrs2.deob.transform
import com.github.michaelbull.logging.InlineLogger import com.github.michaelbull.logging.InlineLogger
import dev.openrs2.asm.classpath.ClassPath 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.deleteExpression
import dev.openrs2.asm.pure
import dev.openrs2.asm.transform.Transformer import dev.openrs2.asm.transform.Transformer
import dev.openrs2.deob.analysis.LiveVariableAnalyzer import dev.openrs2.deob.analysis.LiveVariableAnalyzer
import org.objectweb.asm.Opcodes import org.objectweb.asm.Opcodes
@ -39,7 +40,7 @@ class DummyLocalTransformer : Transformer() {
} }
for (insn in deadStores) { for (insn in deadStores) {
if (method.instructions.deleteSimpleExpression(insn)) { if (method.instructions.deleteExpression(insn, AbstractInsnNode::pure)) {
localsRemoved++ localsRemoved++
} }
} }

Loading…
Cancel
Save