gpt4 book ai didi

java - 获取方法中当前解释的字节码指令的索引

转载 作者:行者123 更新时间:2023-12-02 04:28:24 25 4
gpt4 key购买 nike

我想在访问某个字节码时获取该方法中该字节码的索引号。例如,给定下面的字节码序列,invokevirtual 的索引号为 7(使用 SKIP_DEBUG 访问方法体)。

public calculate(IILjava/lang/String;J)J
L0
LINENUMBER 17 L0
ICONST_3 //0
ISTORE 6 //1
L1
LINENUMBER 18 L1
LDC 10.0 //2
DSTORE 7 //3
L2
LINENUMBER 19 L2
ALOAD 0 //4
GETFIELD code/sxu/asm/Callee._call2 : Lcode/sxu/asm/Callee2; //5
LDC "xushijie" //6
INVOKEVIRTUAL code/sxu/asm/Callee2.sayHello (Ljava/lang/String;)I //7
ISTORE 9

}

我的代码是这样的:

ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);

cr.accept(new SomeMethodVisitor(api, owner, access, name, desc, cw.visitMethod(access, name, desc, owner, null)), SKIP_DEBUG);

class SomeMethodVisitor extends MethodVisitor{
@Override
public void visitMethodInsn(final int opcode, final String owner,
final String name, final String desc, final boolean itf) {
int index = ??? //Get the current bytecode index number here.
super.visitMethodInsn(opcode, owner, name, desc, itf);
}
}

使用基于树的 ASM API 相对容易,我们可以使用:

 class MethodNode{
public InsnList instructions;
}

但是我在基于事件的模式中没有好的解决方案。另外,重写 MethodVisitor 的所有 visitXXX 方法并计算所有已经过去的字节码也不是一个好的解决方案。

最佳答案

这实际上对于 ASM 来说非常棘手,以至于几乎值得使用 Javassist 来代替此功能。

MethodVisitor 有一个名为 CodeSizeEvaluator 的子类。如果您对其进行子类化,则可以获取字节码大小的运行总计(以及字节码的偏移量)。为什么是“有点”?

某些字节码操作的大小可能有所不同。例如,如果要将整数常量压入堆栈,可以使用一、二或三个字节的指令代码来完成此操作,具体取决于整数的大小。 ASM 拥有字节码的操作抽象。换句话说,对于该指令,它将维护一个节点,该节点表示“将一个整数压入值 X 的堆栈中”。 Classwriter 将决定如何在实际字节码中执行此操作。因此,CodeSizeEvaluator 并不真正知道该指令是 1、2 还是 3 个字节。这就是为什么它保持“最小值”或“最大值”。

您可以通过查看 X 的值并确定将使用哪个实际指令并选择“实际”大小来增强逻辑。有几种情况是很棘手的。这些是当你有表跳转(即 case 语句)时。这些被填充,以便它们与 4 字节边界对齐。了解对齐方式需要了解它们开始的字节码计数(您应该知道)。更难的是跳转和跳转。 Classwriter 通过插入带有长 goto 的代码来处理跳转偏移量超过 +/-32K 的情况。除非你正在做一些疯狂的事情,否则这种情况几乎永远不会发生。尽管如此,CodeSizeEvaluator 将允许分支最多使用 7 个字节。您可能必须假设一个典型情况并计算 3 个字节。

我希望这会有所帮助。

附注这是凭内存写的,所以我可能忘记了其他一些边缘情况。

关于java - 获取方法中当前解释的字节码指令的索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31840994/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com