我需要编写将指令插入指定位置的方法的代码。我指定位置的方式是提供紧接在它之前的指令的编号。想法是访问所有指令,直到指令的编号等于指定的编号(因此第一条指令是第0条指令,下一条指令是第一条指令,等等),此时,我想要的指令注射将被注射。问题是没有通用的访问指令" MethodVisitor
类中的方法;它只有访问特定类型指令的方法,所以我无法找到一种访问 nth 指令的优雅方式。这就是我提出的(为简洁起见省略的部分):
private int counter = 0;
@Override
public void visitIincInsn(int arg0, int arg1) {
super.visitIincInsn(arg0, arg1);
if (checkInstruction()) {
insertInstructions();
}
}
@Override
public void visitInsn(int arg0) {
super.visitInsn(arg0);
if (checkInstruction()) {
insertInstructions();
}
}
@Override
public void visitIntInsn(int arg0, int arg1) {
super.visitIntInsn(arg0, arg1);
if (checkInstruction()) {
insertInstructions();
}
}
/* And continue, implementing every method
which visits a specific type of instruction. */
private boolean checkInstruction() {
return counter++ == instructionNumber;
}
我对这个解决方案的问题是它重复了很多代码,并且要求我实现一堆我无意修改的方法。另外,如果添加了新类型的指令,我将不得不再次修改此代码以实现该特定类型的指令。
有没有人有更好的解决方案?
答案 0 :(得分:1)
在ASM的树API中,您可以找到一个实用程序类,收集所有简化此类工作的指令:
import org.objectweb.asm.*;
import org.objectweb.asm.tree.*;
public class AsmFirstFiveOnly extends MethodVisitor {
private final MethodNode methodNode;
/** pass in the values provided in ClassVisitor.visitMethod */
public AsmFirstFiveOnly(
int access, String name, String desc, String signature, String[] exceptions){
this(new MethodNode(access, signature, signature, signature, exceptions));
}
private AsmFirstFiveOnly(MethodNode mn) {
super(Opcodes.ASM5, mn);
methodNode=mn;
}
// exemplary for the visit methods you are interested in,
// no need to override the others
@Override
public void visitInsn(int opcode) {
super.visitInsn(opcode);
if(methodNode.instructions.size()<5) {
// do your action
}
}
}