Hi,
The problem happens in ASM 3.1 and 3.0 (I worked with 3.1 sources).
After ASM works on it, the class cannot be loaded (see details later).
BCEL handles the class without a problem.
The code is the following:
cr = new ClassReader(bytes);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cr.accept(cw, 0);
return cw.toByteArray();
After this code works on the attached class, the class cannot be loaded with
the exception saying there is invalid length in LocalVariableTable in this
class.
The problematic method is newDataStoreId(javax.jdo.spi.PersistenceCapable,
kodo.meta.ClassMetaData);
Here is the information obtained using javap before and after the ASM
regarding this method:
Before:
LineNumberTable:
line 667: 95
line 668: 100
line 669: 107
LocalVariableTable:
Start Length Slot Name Signature
95 20 0 this Lkodo/jdbc/runtime/JDBCStoreManager;
95 20 1 pc Ljavax/jdo/spi/PersistenceCapable;
95 20 2 meta Lkodo/meta/ClassMetaData;
100 15 3 mapping Lkodo/jdbc/meta/ClassMapping;
107 8 4 id J
Code:
Stack=7, Locals=12, Args_size=3
After:
LineNumberTable:
line 667: 95
line 668: 100
line 669: 107
LocalVariableTable:
Start Length Slot Name Signature
95 -95 0 this Lkodo/jdbc/runtime/JDBCStoreManager;
95 -95 1 pc Ljavax/jdo/spi/PersistenceCapable;
95 -95 2 meta Lkodo/meta/ClassMetaData;
100 -100 3 mapping Lkodo/jdbc/meta/ClassMapping;
107 -107 4 id J
Code:
Stack=5, Locals=12, Args_size=3
The problem is that when the mv.visitLocalVariable(readUTF8(w + 4, c),
readUTF8(w + 6, c),
vsignature,
labels[start],
labels[start + length],
index);
is called from the ClassReader.accept(), the position of the labels
[start+lenght] is 0 in case of this particular method. Start is 95 , lenght is
20. The problematic labels[115] has position 0. Inside the
MethodWriter.visitLocalVariable the lenght is calculates as end.position -
start.position. Start's position is 95, end's position is 0, so the lenght is -
95.
It seems like the root cause is that the current code skips
MethodWriter.visitLabel() called from the line 1143 (in the beginning of the
while loop).
It skips label 115 because it points into the middle of the instruction:
114: astore 11
116: jsr 130
After label 114 is handled in the case ClassWriter.VAR_INSN (line 1340) for
the astore instruction, 2 is added to local var v that points into the byte[],
so next label that is handled is 116. 115 is skipped.
Hence the problem.
Also, I noticed that MaxStack is less then the original...
Thank you,
Lena.