我正在尝试使用 ASM 库将字节代码转换为不同的格式,这可以使用 MethodVisitor 来完成,就像这个简单的测试代码一样:
return new MethodVisitor(ASM7) {
@Override
public void visitInsn(int opcode) {
System.out.println(String.format("%02x", opcode));
}
@Override
public void visitMaxs(int maxStack, int maxLocals) {
System.out.println(maxStack);
}
};
一个问题是我只能在实际指令之后看到 maxStack - 我已经测试过它,这就是调用方法的顺序 - 而在翻译指令时获得可用的 maxStack 值会很有帮助。
有什么办法可以先看到 maxStack 吗?
ASM API 不支持在遍历指令之前访问此信息。
一种解决方案是遍历该类两次,在第一次遍历中存储最大值。
另一种方法是暂时存储当前方法信息。 ASM 的 Tree API 可以在这方面为您提供帮助。班上MethodNode
实施MethodVisitor
,存储所有访问过的工件并有一个accept(MethodVisitor)
访问所有存储的工件:
classReader.accept(new ClassVisitor(Opcodes.ASM7) {
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor,
String signature, String[] exceptions) {
MethodVisitor actualVisitor = new MethodVisitor(Opcodes.ASM7) {
@Override
public void visitInsn(int opcode) {
System.out.printf("%02x%n", opcode);
}
@Override
public void visitMaxs(int maxStack, int maxLocals) {
System.out.println("max stack: "+maxStack);
}
};
return new MethodNode(Opcodes.ASM7) {
@Override
public void visitMaxs(int maxStack, int maxLocals) {
actualVisitor.visitMaxs(maxStack, maxLocals);
super.visitMaxs(maxStack, maxLocals);
}
@Override
public void visitEnd() {
accept(actualVisitor);
}
};
}
}, 0);
所以这里我们保留原来的MethodVisitor
按原样但返回实现预期修改的适配器。它是一个子类MethodNode
记录除报告之外的所有工件visitMaxs
立即到actualVisitor
,然后在visitEnd
它会accept(actualVisitor)
访问所有记录的信息。
请注意,因此,actualVisitor
会遇到visitMaxs
两次,一次在所有其他元素之前,然后在标准事件顺序内再次。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)