ASM:有状态转型

som*_*guy 7 java bytecode java-bytecode-asm

我想编写一个MethodVisitor来转换用于乘法的LDC指令.

字节码示例:

ldc #26
imul
Run Code Online (Sandbox Code Playgroud)

这基本上推动了一个常数然后乘以它.

它必须是有状态的转换,因为我首先必须检查它是否为乘法,如果是,我需要返回到ldc指令并修改常量.我不完全确定我会怎么做,我不知道如何修改常量(当我尝试传递一个不同的值时,旧的值仍然保留在常量池中).

编辑:

public class AdditionTransformer extends MethodAdapter {
    boolean replace = false;
    int operand = 0;

    AdditionTransformer(MethodVisitor mv) {
        super(mv);
    }

    @Override
    public void visitInsn(int opcode) {
        if (opcode == IMUL && replace) {
            operand *= 2;
            visitLdcInsn(operand);
            replace = false;
        }
        mv.visitInsn(opcode);
    }

    @Override
    public void visitLdcInsn(Object cst) {
        if (cst instanceof Integer && !replace) {
            operand = (Integer) cst;
            replace = true;
        } else {
            mv.visitLdcInsn(cst);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这就是我所拥有的,但它不会删除常量池中的旧值,并且可能存在错误.

old*_*inb 1

如果您有兴趣以这种方式修改字节码,您可能需要查看ASM 树 API。您可以通过更舒适的 DOM 样式树界面(而不是您尝试使用的 SAX 样式访问者界面)轻松替换 LdcInsnNode.cst。