Fix removal of unused arguments whose local variable slot is re-used

Signed-off-by: Graham <gpe@openrs2.dev>
pull/132/head
Graham 4 years ago
parent 1eb423fbf6
commit 47325edb72
  1. 15
      deob/src/main/java/dev/openrs2/deob/analysis/ConstSourceInterpreter.kt
  2. 3
      deob/src/main/java/dev/openrs2/deob/analysis/ConstSourceValue.kt
  3. 33
      deob/src/main/java/dev/openrs2/deob/transform/UnusedArgTransformer.kt

@ -15,10 +15,15 @@ class ConstSourceInterpreter : Interpreter<ConstSourceValue>(Opcodes.ASM8) {
return ConstSourceValue.Unknown(basicValue)
}
override fun newParameterValue(isInstanceMethod: Boolean, local: Int, type: Type): ConstSourceValue {
val basicValue = basicInterpreter.newParameterValue(isInstanceMethod, local, type)
return ConstSourceValue.Arg(basicValue)
}
override fun newOperation(insn: AbstractInsnNode): ConstSourceValue {
val basicValue = basicInterpreter.newOperation(insn)
return if (insn.intConstant != null) {
ConstSourceValue.Single(basicValue, insn)
ConstSourceValue.Insn(basicValue, insn)
} else {
ConstSourceValue.Unknown(basicValue)
}
@ -74,10 +79,10 @@ class ConstSourceInterpreter : Interpreter<ConstSourceValue>(Opcodes.ASM8) {
override fun merge(value1: ConstSourceValue, value2: ConstSourceValue): ConstSourceValue {
val basicValue = basicInterpreter.merge(value1.basicValue, value2.basicValue)
return if (value1 is ConstSourceValue.Single && value1 == value2) {
value1
} else {
ConstSourceValue.Unknown(basicValue)
return when {
value1 is ConstSourceValue.Arg || value2 is ConstSourceValue.Arg -> ConstSourceValue.Arg(basicValue)
value1 == value2 -> value1
else -> ConstSourceValue.Unknown(basicValue)
}
}
}

@ -6,7 +6,8 @@ import org.objectweb.asm.tree.analysis.Value
sealed class ConstSourceValue : Value {
data class Unknown(override val basicValue: BasicValue) : ConstSourceValue()
data class Single(override val basicValue: BasicValue, val source: AbstractInsnNode) : ConstSourceValue()
data class Insn(override val basicValue: BasicValue, val source: AbstractInsnNode) : ConstSourceValue()
data class Arg(override val basicValue: BasicValue) : ConstSourceValue()
abstract val basicValue: BasicValue

@ -17,10 +17,12 @@ import org.objectweb.asm.Opcodes
import org.objectweb.asm.Type
import org.objectweb.asm.tree.AbstractInsnNode
import org.objectweb.asm.tree.ClassNode
import org.objectweb.asm.tree.IincInsnNode
import org.objectweb.asm.tree.MethodInsnNode
import org.objectweb.asm.tree.MethodNode
import org.objectweb.asm.tree.VarInsnNode
import org.objectweb.asm.tree.analysis.Analyzer
import org.objectweb.asm.tree.analysis.Frame
import javax.inject.Inject
import javax.inject.Singleton
@ -46,6 +48,23 @@ class UnusedArgTransformer @Inject constructor(private val profile: Profile) : T
}
}
private fun retainArg(
partition: DisjointSet.Partition<MemberRef>,
localToArgMap: Map<Int, Int>,
frame: Frame<ConstSourceValue>,
local: Int
) {
val source = frame.getLocal(local)
if (source !is ConstSourceValue.Arg) {
return
}
val arg = localToArgMap[local]
if (arg != null) {
retainedArgs.add(ArgPartition(partition, arg))
}
}
private fun populateRetainedArgs(classPath: ClassPath, clazz: ClassNode, method: MethodNode) {
val partition = inheritedMethodSets[MemberRef(clazz, method)]!!
val localToArgMap = createLocalToArgMap(method)
@ -62,15 +81,11 @@ class UnusedArgTransformer @Inject constructor(private val profile: Profile) : T
when (val insn = method.instructions[i]) {
is VarInsnNode -> {
if (insn.opcode != Opcodes.ILOAD) {
continue@frame
}
val arg = localToArgMap[insn.`var`]
if (arg != null) {
retainedArgs.add(ArgPartition(partition, arg))
if (insn.opcode == Opcodes.ILOAD) {
retainArg(partition, localToArgMap, frame, insn.`var`)
}
}
is IincInsnNode -> retainArg(partition, localToArgMap, frame, insn.`var`)
is MethodInsnNode -> {
val invokePartition = inheritedMethodSets[MemberRef(insn)]
if (invokePartition == null) {
@ -84,7 +99,7 @@ class UnusedArgTransformer @Inject constructor(private val profile: Profile) : T
val args = Type.getArgumentTypes(insn.desc).size
for (j in 0 until args) {
val source = frame.getStack(stackSize - args + j)
if (source !is ConstSourceValue.Single) {
if (source !is ConstSourceValue.Insn) {
retainedArgs.add(ArgPartition(invokePartition, j))
}
}
@ -133,7 +148,7 @@ class UnusedArgTransformer @Inject constructor(private val profile: Profile) : T
for ((j, argType) in argTypes.withIndex()) {
if (argType.sort in INT_SORTS && ArgPartition(partition, j) !in retainedArgs) {
val value = frame.getStack(stackSize - argTypes.size + j) as ConstSourceValue.Single
val value = frame.getStack(stackSize - argTypes.size + j) as ConstSourceValue.Insn
deadInsns.add(value.source)
} else {
newArgTypes.add(argType)

Loading…
Cancel
Save