问题
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