forked from openrs2/openrs2
parent
4ad8606b97
commit
7747fe457a
@ -0,0 +1,83 @@ |
|||||||
|
package dev.openrs2.deob.transform; |
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet; |
||||||
|
import dev.openrs2.asm.InsnNodeUtils; |
||||||
|
import dev.openrs2.asm.classpath.ClassPath; |
||||||
|
import dev.openrs2.asm.transform.Transformer; |
||||||
|
import org.objectweb.asm.Opcodes; |
||||||
|
import org.objectweb.asm.tree.ClassNode; |
||||||
|
import org.objectweb.asm.tree.MethodNode; |
||||||
|
import org.objectweb.asm.tree.VarInsnNode; |
||||||
|
import org.objectweb.asm.tree.analysis.AnalyzerException; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
public final class DummyLocalTransformer extends Transformer { |
||||||
|
private static final Logger logger = LoggerFactory.getLogger(DummyLocalTransformer.class); |
||||||
|
|
||||||
|
private static final ImmutableSet<Integer> LOAD_OPCODES = ImmutableSet.of( |
||||||
|
Opcodes.ILOAD, |
||||||
|
Opcodes.LLOAD, |
||||||
|
Opcodes.FLOAD, |
||||||
|
Opcodes.DLOAD, |
||||||
|
Opcodes.ALOAD |
||||||
|
); |
||||||
|
|
||||||
|
private static final ImmutableSet<Integer> STORE_OPCODES = ImmutableSet.of( |
||||||
|
Opcodes.ISTORE, |
||||||
|
Opcodes.LSTORE, |
||||||
|
Opcodes.FSTORE, |
||||||
|
Opcodes.DSTORE, |
||||||
|
Opcodes.ASTORE |
||||||
|
); |
||||||
|
|
||||||
|
private int localsRemoved; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void preTransform(ClassPath classPath) throws AnalyzerException { |
||||||
|
localsRemoved = 0; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected boolean transformCode(ClassNode clazz, MethodNode method) throws AnalyzerException { |
||||||
|
/* |
||||||
|
* XXX(gpe): this is primitive (ideally we'd do a proper data flow |
||||||
|
* analysis, but we'd need to do it in reverse and ASM only supports |
||||||
|
* forward data flow), however, it seems to be good enough to catch |
||||||
|
* everything. |
||||||
|
*/ |
||||||
|
var loads = new boolean[method.maxLocals]; |
||||||
|
|
||||||
|
for (var it = method.instructions.iterator(); it.hasNext(); ) { |
||||||
|
var insn = it.next(); |
||||||
|
if (LOAD_OPCODES.contains(insn.getOpcode())) { |
||||||
|
var load = (VarInsnNode) insn; |
||||||
|
loads[load.var] = true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
for (var it = method.instructions.iterator(); it.hasNext(); ) { |
||||||
|
var insn = it.next(); |
||||||
|
var opcode = insn.getOpcode(); |
||||||
|
if (!STORE_OPCODES.contains(opcode)) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
var store = (VarInsnNode) insn; |
||||||
|
if (loads[store.var]) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
if (InsnNodeUtils.deleteSimpleExpression(method.instructions, insn)) { |
||||||
|
localsRemoved++; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void postTransform(ClassPath classPath) throws AnalyzerException { |
||||||
|
logger.info("Removed {} dummy local variables", localsRemoved); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue