如何复制 InsnList



InsnList 没有复制自我的方法。

我尝试迭代列表并将每个节点添加到新列表中。但是迭代列表的副本执行 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));

我预计副本会,但是迭代副本会产生错误

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)

虽然我无法重现您的特定异常,但这似乎只是您的方法存在根本问题的另一个症状。正如AbstractInsnNode的文件所述:

表示字节码指令的节点。一条指令最多可以出现一次,一次最多出现一次InsnList

所以你不能复制一个InsnList,至少不能通过将相同的节点插入到另一个列表中。这也是InsnListadd(InsnList)insert(InsnList)方法从源列表中删除节点的原因。

当你真的想要一个InsnList的副本时,你还必须创建节点对象的副本,这可以通过访问者API最简单的方式完成:

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

但是,只要任务允许,您就应该使用ASM的访问者API将指令直接写入目标类文件,而不是创建指令列表的副本。另请参阅有关您的实际任务的答案。

相关内容

  • 没有找到相关文章

最新更新