Open-source multiplayer game server compatible with the RuneScape client https://www.openrs2.org/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
openrs2/deob-bytecode/src/main/kotlin/org/openrs2/deob/bytecode/analysis/CopyPropagationAnalyzer.kt

80 lines
2.5 KiB

package org.openrs2.deob.bytecode.analysis
import org.objectweb.asm.Opcodes
import org.objectweb.asm.tree.AbstractInsnNode
import org.objectweb.asm.tree.IincInsnNode
import org.objectweb.asm.tree.MethodNode
import org.objectweb.asm.tree.VarInsnNode
import java.util.Collections
public class CopyPropagationAnalyzer(owner: String, method: MethodNode) :
DataFlowAnalyzer<Set<CopyAssignment>>(owner, method) {
private val allAssignments = mutableSetOf<CopyAssignment>()
init {
for (insn in method.instructions) {
if (insn !is VarInsnNode || !STORE_OPCODES.contains(insn.opcode)) {
continue
}
val previous = insn.previous
if (previous !is VarInsnNode || !LOAD_OPCODES.contains(previous.opcode)) {
continue
}
allAssignments += CopyAssignment(insn.`var`, previous.`var`)
}
}
override fun createEntrySet(): Set<CopyAssignment> {
return Collections.emptySet()
}
override fun createInitialSet(): Set<CopyAssignment> {
return allAssignments
}
override fun join(set1: Set<CopyAssignment>, set2: Set<CopyAssignment>): Set<CopyAssignment> {
return set1 intersect set2
}
override fun transfer(set: Set<CopyAssignment>, insn: AbstractInsnNode): Set<CopyAssignment> {
return when {
insn is VarInsnNode && STORE_OPCODES.contains(insn.opcode) -> {
val newSet = set.minusKilledByAssignmentTo(insn.`var`)
val previous = insn.previous
if (previous is VarInsnNode && LOAD_OPCODES.contains(previous.opcode)) {
newSet.plus(CopyAssignment(insn.`var`, previous.`var`))
} else {
newSet
}
}
insn is IincInsnNode -> set.minusKilledByAssignmentTo(insn.`var`)
else -> set
}
}
private fun Set<CopyAssignment>.minusKilledByAssignmentTo(index: Int): Set<CopyAssignment> {
return filterTo(mutableSetOf()) { it.source != index && it.destination != index }
}
private companion object {
private val LOAD_OPCODES = setOf(
Opcodes.ILOAD,
Opcodes.LSTORE,
Opcodes.FLOAD,
Opcodes.DLOAD,
Opcodes.ALOAD
)
private val STORE_OPCODES = setOf(
Opcodes.ISTORE,
Opcodes.LSTORE,
Opcodes.FSTORE,
Opcodes.DSTORE,
Opcodes.ASTORE
)
}
}