Inline constants in DummyArgTransformer

This is a prerequisite for us to be able to remove the constant
arguments.
pull/48/head
Graham 5 years ago
parent 1216812c8a
commit 7b3ec975d9
  1. 45
      deob/src/main/java/dev/openrs2/deob/transform/DummyArgTransformer.java

@ -13,6 +13,7 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import dev.openrs2.asm.InsnNodeUtils; import dev.openrs2.asm.InsnNodeUtils;
import dev.openrs2.asm.MemberRef; import dev.openrs2.asm.MemberRef;
import dev.openrs2.asm.StackMetadata;
import dev.openrs2.asm.classpath.ClassPath; import dev.openrs2.asm.classpath.ClassPath;
import dev.openrs2.asm.transform.Transformer; import dev.openrs2.asm.transform.Transformer;
import dev.openrs2.deob.analysis.IntInterpreter; import dev.openrs2.deob.analysis.IntInterpreter;
@ -20,6 +21,7 @@ import dev.openrs2.deob.analysis.IntValue;
import dev.openrs2.util.collect.DisjointSet; import dev.openrs2.util.collect.DisjointSet;
import org.objectweb.asm.Opcodes; 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.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.JumpInsnNode; import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodInsnNode;
@ -162,12 +164,13 @@ public final class DummyArgTransformer extends Transformer {
private final Multimap<ArgRef, IntValue> argValues = HashMultimap.create(); private final Multimap<ArgRef, IntValue> argValues = HashMultimap.create();
private final Map<DisjointSet.Partition<MemberRef>, ImmutableSet<Integer>[]> constArgs = new HashMap<>(); private final Map<DisjointSet.Partition<MemberRef>, ImmutableSet<Integer>[]> constArgs = new HashMap<>();
private DisjointSet<MemberRef> inheritedMethodSets; private DisjointSet<MemberRef> inheritedMethodSets;
private int branchesSimplified; private int branchesSimplified, constantsInlined;
@Override @Override
protected void preTransform(ClassPath classPath) { protected void preTransform(ClassPath classPath) {
inheritedMethodSets = classPath.createInheritedMethodSets(); inheritedMethodSets = classPath.createInheritedMethodSets();
branchesSimplified = 0; branchesSimplified = 0;
constantsInlined = 0;
} }
@Override @Override
@ -189,6 +192,7 @@ public final class DummyArgTransformer extends Transformer {
var alwaysTakenBranches = new ArrayList<JumpInsnNode>(); var alwaysTakenBranches = new ArrayList<JumpInsnNode>();
var neverTakenBranches = new ArrayList<JumpInsnNode>(); var neverTakenBranches = new ArrayList<JumpInsnNode>();
var constInsns = new HashMap<AbstractInsnNode, Integer>();
for (var i = 0; i < frames.length; i++) { for (var i = 0; i < frames.length; i++) {
var frame = frames[i]; var frame = frames[i];
@ -256,6 +260,30 @@ public final class DummyArgTransformer extends Transformer {
break; break;
} }
break; break;
default:
if (InsnNodeUtils.hasSideEffects(insn) || InsnNodeUtils.isIntConstant(insn)) {
continue;
}
if (StackMetadata.get(insn).getPushes() != 1) {
continue;
}
var nextInsn = InsnNodeUtils.nextReal(insn);
if (nextInsn == null) {
continue;
}
var nextInsnIndex = method.instructions.indexOf(nextInsn);
var nextFrame = frames[nextInsnIndex];
value = nextFrame.getStack(nextFrame.getStackSize() - 1);
if (!value.isSingleConstant()) {
continue;
}
constInsns.put(insn, value.getIntValue());
break;
} }
} }
@ -273,6 +301,19 @@ public final class DummyArgTransformer extends Transformer {
} }
} }
for (var entry : constInsns.entrySet()) {
var insn = entry.getKey();
if (!method.instructions.contains(insn)) {
continue;
}
var replacement = InsnNodeUtils.createIntConstant(entry.getValue());
if (InsnNodeUtils.replaceSimpleExpression(method.instructions, insn, replacement)) {
constantsInlined++;
changed = true;
}
}
return changed; return changed;
} }
@ -302,6 +343,6 @@ public final class DummyArgTransformer extends Transformer {
@Override @Override
protected void postTransform(ClassPath classPath) { protected void postTransform(ClassPath classPath) {
logger.info("Simplified {} dummy branches", branchesSimplified); logger.info("Simplified {} dummy branches and inlined {} constants", branchesSimplified, constantsInlined);
} }
} }

Loading…
Cancel
Save