|
|
@ -1,5 +1,8 @@ |
|
|
|
package dev.openrs2.deob.analysis |
|
|
|
package dev.openrs2.deob.analysis |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import it.unimi.dsi.fastutil.ints.IntOpenHashSet |
|
|
|
|
|
|
|
import it.unimi.dsi.fastutil.ints.IntSet |
|
|
|
|
|
|
|
import it.unimi.dsi.fastutil.ints.IntSets |
|
|
|
import org.objectweb.asm.Opcodes |
|
|
|
import org.objectweb.asm.Opcodes |
|
|
|
import org.objectweb.asm.tree.AbstractInsnNode |
|
|
|
import org.objectweb.asm.tree.AbstractInsnNode |
|
|
|
import org.objectweb.asm.tree.IincInsnNode |
|
|
|
import org.objectweb.asm.tree.IincInsnNode |
|
|
@ -7,17 +10,17 @@ import org.objectweb.asm.tree.MethodNode |
|
|
|
import org.objectweb.asm.tree.VarInsnNode |
|
|
|
import org.objectweb.asm.tree.VarInsnNode |
|
|
|
|
|
|
|
|
|
|
|
class LiveVariableAnalyzer(owner: String, method: MethodNode) : |
|
|
|
class LiveVariableAnalyzer(owner: String, method: MethodNode) : |
|
|
|
DataFlowAnalyzer<Set<Int>>(owner, method, backwards = true) { |
|
|
|
DataFlowAnalyzer<IntSet>(owner, method, backwards = true) { |
|
|
|
|
|
|
|
|
|
|
|
override fun createInitialSet(): Set<Int> { |
|
|
|
override fun createInitialSet(): IntSet { |
|
|
|
return emptySet() |
|
|
|
return IntSets.EMPTY_SET |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
override fun join(set1: Set<Int>, set2: Set<Int>): Set<Int> { |
|
|
|
override fun join(set1: IntSet, set2: IntSet): IntSet { |
|
|
|
return set1 union set2 |
|
|
|
return set1 union set2 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
override fun transfer(set: Set<Int>, insn: AbstractInsnNode): Set<Int> { |
|
|
|
override fun transfer(set: IntSet, insn: AbstractInsnNode): IntSet { |
|
|
|
return when (insn) { |
|
|
|
return when (insn) { |
|
|
|
is VarInsnNode -> when (insn.opcode) { |
|
|
|
is VarInsnNode -> when (insn.opcode) { |
|
|
|
Opcodes.ILOAD, Opcodes.LLOAD, Opcodes.FLOAD, Opcodes.DLOAD, Opcodes.ALOAD -> set.plus(insn.`var`) |
|
|
|
Opcodes.ILOAD, Opcodes.LLOAD, Opcodes.FLOAD, Opcodes.DLOAD, Opcodes.ALOAD -> set.plus(insn.`var`) |
|
|
@ -28,4 +31,38 @@ class LiveVariableAnalyzer(owner: String, method: MethodNode) : |
|
|
|
else -> set |
|
|
|
else -> set |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private infix fun IntSet.union(other: IntSet): IntSet { |
|
|
|
|
|
|
|
if (this == other || other.isEmpty()) { |
|
|
|
|
|
|
|
return this |
|
|
|
|
|
|
|
} else if (isEmpty()) { |
|
|
|
|
|
|
|
return other |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val set = IntOpenHashSet(this) |
|
|
|
|
|
|
|
set.addAll(other) |
|
|
|
|
|
|
|
return set |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun IntSet.plus(element: Int): IntSet { |
|
|
|
|
|
|
|
if (contains(element)) { |
|
|
|
|
|
|
|
return this |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val newSet = IntOpenHashSet(this) |
|
|
|
|
|
|
|
newSet.add(element) |
|
|
|
|
|
|
|
return newSet |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun IntSet.minus(element: Int): IntSet { |
|
|
|
|
|
|
|
if (!contains(element)) { |
|
|
|
|
|
|
|
return this |
|
|
|
|
|
|
|
} else if (size == 1) { |
|
|
|
|
|
|
|
return IntSets.EMPTY_SET |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val newSet = IntOpenHashSet(this) |
|
|
|
|
|
|
|
newSet.remove(element) |
|
|
|
|
|
|
|
return newSet |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|