How to copy InsnList

拜拜、爱过 提交于 2019-12-11 06:06:21

问题


InsnList has no method for copy self.

I tried to iterate list and add each node to new list. But iterating copy of list perform npe

private static InsnList copy(InsnList insnList) {
        InsnList r = new InsnList();

        for (int i = 0; i < insnList.size(); i++)
            r.add(insnList.get(i));

        return r;
}
InsnList copy = copy(someList);

for (int i = 0; i < copy.size(); i++)
    System.out.println(copy.get(i));

I expected that copy will be, but iterating of copy produce follow error

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
    at org.objectweb.asm.tree.InsnList.toArray(InsnList.java:199)
    at org.objectweb.asm.tree.InsnList.get(InsnList.java:110)

回答1:


While I can’t reproduce your specific exception, it seems to be just another symptom of the fundamental problem with your approach. As the documentation of AbstractInsnNode states:

A node that represents a bytecode instruction. An instruction can appear at most once in at most one InsnList at a time.

So you can’t copy an InsnList, at least not by inserting the same nodes into the other list. This is also the reason why the add(InsnList) and insert(InsnList) methods of InsnList remove the nodes from the source list.

When you truly want a copy of the InsnList, you also have to create copies of the node objects, which is done easiest via the Visitor API:

private static InsnList copy(InsnList insnList) {
    MethodNode mv = new MethodNode();
    insnList.accept(mv);
    return mv.instructions;
}

But whenever the task allows it, you should rather use ASM’s Visitor API to write the instructions directly to the target class file rather than creating copies of the instruction list. See also this answer regarding your actual task.



来源:https://stackoverflow.com/questions/57537240/how-to-copy-insnlist

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!