When MethodGen read LDC_W whose index is less than 256 and dumps it, the size of its operand becomes incorrect. LDC_W's setIndex method can change both the opcode and the length. But after the invocation initFromFile method change the opcode OR the length. And its dump method determines the operand's size by the length. As a result that can make a mismatch b/w an opcode and an operand. LDC_W.java 1.1.1.1 and 1.3 has this problem. A scenario(in case of LDC_W.java 1.3): 1. Suppose a LDC_W whose index is less than 256 2. initFromFile method sets the opcode to LDC_W and the length to 2. 3. dump method writes a LDC_W but it writes a byte as the operand. I think that 1.2 has no problem. Another solution is as follows. --- LDC_W.java.1.1.1.1 Sat Dec 15 21:40:41 2001 +++ LDC_W.java Wed Mar 26 00:36:01 2003 @@ -82,6 +82,6 @@ throws IOException { setIndex(bytes.readUnsignedShort()); - length = 3; + //length = 3; } }
Created attachment 6777 [details] patch against 1.4 to fix the length issue
One example is the JDK 1.4 compiled java.math.BigInteger. If you run: `javap -c java.math.BigInteger | grep ldc_w` you will find several examples of LDC_W operands with sub-256 indices: 401: ldc_w #268; //int 2147483647 1835: ldc_w #435; //String 0000000[..] 2691: ldc_w #259; //int 1162261467 2702: ldc_w #260; //int 1220703125 2709: ldc_w #247; //int 362797056 2716: ldc_w #267; //int 1977326743 2729: ldc_w #248; //int 387420489 2736: ldc_w #258; //int 1000000000 ... Without the above patch, a BCEL lifted and regenerated BigInteger will generate the following broken classfile: 434: ldc_w #268; //int 2147483647 1868: ldc_w #435; //String 0000000[..] 2724: ldc_w #259; //int 1162261467 2735: ldc_w #260; //int 1220703125 2742: ldc_w #63311; //BOGUS_TAG:100 <Incorrect CP index:63311> 2748: ldc_w #267; //int 1977326743 2761: ldc_w #63567; //BOGUS_TAG:100 <Incorrect CP index:63567> 2767: ldc_w #258; //int 1000000000 ... Note that 63311 = 247*256 + 79, and the instruction following the ldc_w is an iastore (opcode 79).
Related to 29903 and 29275
The patch to Bug 29275 seems to have addressed this issue, in at least one example. Please repost if the problem still exists.