I am using ASM (tree and util as well) and have faced a weird exception
Exception in thread "main" java.lang.ClassFormatError: Invalid length 65526 in LocalVariableTable in class file
I am trying to edit the bytecode of a .class file, to generate a new one. I have a for loop with some if branches inside and I try to modify it. I am posting below the code of the two for loops the initial one and the desired generated.
Initial
int[] ar = new int[]{1,2,3,4,5};
int[] ar2 = new int[]{8,9,9,94,3,2};
MyClass myar = new MyClass(ar);
MyClass myar2 = new MyClass(ar2);
int sum=0;
for(int i=0; i<ar.length; i++)
if(ar[i]>3) {
if(ar2[i]>8) {
sum+=(ar[i]+ar2[i]);
}
}
}
Desired
int[] ar = new int[]{1,2,3,4,5};
int[] ar2 = new int[]{8,9,9,94,3,2};
MyClass myar = new MyClass(ar);
MyClass myar2 = new MyClass(ar2);
int sum=0;
for(int i=0; i<ar.length; i++)
int[] temp = callAFunctionToDoSthing(myar, myar2);
if(temp[0]>3) {
if(temp[1]>8) {
sum+=(temp[0]+temp[1]);
}else i+=1;
}else i+=2;
}
In order to do that, I use the ASM tree ListIterator, to detect the for loop (I am doing that by checking if some commands are occurring the one after the other). I use the ASM bytecode extension for intellj, to compare the initial and the desired bytecode. Then, using ASM tree I remove and add in the bytecode list the instructions I want. (I have tried both ASM5 and ASM8) The problem is that after this operation when I run the generated .class file I get the Exception above. The point is I don't manually edit the LocalVariableTable and don't really know how to edit it. If I run the javap -v command in the desired code I cannot even see the LocalVariableTable, whereas if I run the javap -v in the generated .class file I see it.
I have tried another modification to see that my idea with ASM tree works in a simpler for loop without if and a unique array and everything worked fine there.
Also, I have tried using SKIP_DEBUG, but I cannot see the Label and LineNumber -Nodes and in my case I need to remove some of the LabelNode and LineNumberNode instructions.
EDIT:
I am giving a simple example of the way I am doing the transformation. I use a diff checker of the initial and the desired ASM bytecode and it produces something like the image below
So the code in order to manipulate that is
IntInsnNode bp7 = (IntInsnNode) aload17.getNext();
instructions.remove(bp7.getNext());
instructions.remove(bp7.getNext());
instructions.remove(bp7.getNext());
instructions.remove(bp7.getNext());
instructions.remove(bp7.getNext());
InsnList l4 = new InsnList();
LabelNode l45Ins = new LabelNode();
l4.add(new JumpInsnNode(Opcodes.IF_ICMPGT, l45Ins));
LabelNode l46Ins = new LabelNode();
l4.add(l46Ins);
l4.add(new LineNumberNode(178, l46Ins));
l4.add(new VarInsnNode(Opcodes.ALOAD, 20));
l4.add(new InsnNode(Opcodes.ICONST_0));
instructions.insert(bp7, l4);