Java 字节码 - ASM - 获取标签偏移量

Java Bytecode - ASM - Get Label Offset

我正在尝试获取方法中所有标签的偏移量。

我尝试使用以下代码:

private static ArrayList<Integer> GetLabelOffsets(MethodNode methodNode) {
    ArrayList<Integer> labelOffsets = new ArrayList<>();

    for (AbstractInsnNode instruction : methodNode.instructions.toArray()) {
        if (instruction instanceof JumpInsnNode) {
            JumpInsnNode jumpInsnNode = (JumpInsnNode) instruction;
            labelOffsets.add(jumpInsnNode.label.getLabel().getOffset());.
        }
    }

    return labelOffsets;
}

但是 getOffset() 方法抛出 Exception:

java.lang.IllegalStateException: Label offset position has not been resolved yet

如何解决这些偏移位置?或者实现这一目标的正确方法是什么?

编辑

MethodNode 是来自 Java ASM 库的 org.objectweb.asm.tree.MethodNode 对象

根据要求添加了更多代码:

public static HashMap<String, ClassNode> ParseJar(JarFile jar) {
    HashMap<String, ClassNode> classes = new HashMap<>();

    try {
        Enumeration<?> enumeration = jar.entries();
        while (enumeration.hasMoreElements()) {
            JarEntry entry = (JarEntry) enumeration.nextElement();

            if (entry.getName().endsWith(".class")) {
                ClassReader classReader = new ClassReader(jar.getInputStream(entry));
                ClassNode classNode = new ClassNode();
                classReader.accept(classNode, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
                classes.put(classNode.name, classNode);
            }

        }
        jar.close();
        return classes;
    } catch (Exception ex) {
        return null;
    }
}

public static void main(String[] args) {
    JarFile jar = new JarFile(fileName);
    HashMap<String, ClassNode> classes = JarUtils.ParseJar(jar);
    for (ClassNode classNode : classes.values()) {
        for (MethodNode methodNode : classNode.methods) {
            ArrayList<Integer> offsets = GetLabelOffsets(methodNode);
            // do more stuff with offsets
        }
    }
}

来自documentation of getOffset()

This method is intended for Attribute sub classes, and is normally not needed by class generators or adapters.

由于此偏移量是根据 字节 定义的,因此在处理 指令 列表时不会很有帮助,尤其是因为 ASM 抽象出不同形式的指令,这些指令的字节码长度可能不同。

大意是这个指令列表是可以改变的,所以Labels代表逻辑位置,在写一个方法的结果字节码时会计算偏移量,实际数字是已知的。

在指令列表中,应该有一个相应的 LabelNode 引用与指令相同的 Label