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) 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 { override fun newOperation(insn: AbstractInsnNode): ConstSourceValue {
val basicValue = basicInterpreter.newOperation(insn) val basicValue = basicInterpreter.newOperation(insn)
return if (insn.intConstant != null) { return if (insn.intConstant != null) {
ConstSourceValue.Single(basicValue, insn) ConstSourceValue.Insn(basicValue, insn)
} else { } else {
ConstSourceValue.Unknown(basicValue) ConstSourceValue.Unknown(basicValue)
} }
@ -74,10 +79,10 @@ class ConstSourceInterpreter : Interpreter<ConstSourceValue>(Opcodes.ASM8) {
override fun merge(value1: ConstSourceValue, value2: ConstSourceValue): ConstSourceValue { override fun merge(value1: ConstSourceValue, value2: ConstSourceValue): ConstSourceValue {
val basicValue = basicInterpreter.merge(value1.basicValue, value2.basicValue) val basicValue = basicInterpreter.merge(value1.basicValue, value2.basicValue)
return if (value1 is ConstSourceValue.Single && value1 == value2) { return when {
value1 value1 is ConstSourceValue.Arg || value2 is ConstSourceValue.Arg -> ConstSourceValue.Arg(basicValue)
} else { value1 == value2 -> value1
ConstSourceValue.Unknown(basicValue) else -> ConstSourceValue.Unknown(basicValue)
} }
} }
} }

@ -6,7 +6,8 @@ import org.objectweb.asm.tree.analysis.Value
sealed class ConstSourceValue : Value { sealed class ConstSourceValue : Value {
data class Unknown(override val basicValue: BasicValue) : ConstSourceValue() 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 abstract val basicValue: BasicValue

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

Loading…
Cancel
Save