1 /***
2  * ASM: a very small and fast Java bytecode manipulation framework
3  * Copyright (c) 2000-2011 INRIA, France Telecom
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of its
15  *    contributors may be used to endorse or promote products derived from
16  *    this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 package org.objectweb.asm;
31 
32 import java.io.IOException;
33 import java.io.InputStream;
34 
35 /**
36  * A Java class parser to make a {@link ClassVisitor} visit an existing class.
37  * This class parses a byte array conforming to the Java class file format and
38  * calls the appropriate visit methods of a given class visitor for each field,
39  * method and bytecode instruction encountered.
40  *
41  * @author Eric Bruneton
42  * @author Eugene Kuleshov
43  */
44 public class ClassReader {
45 
46     /**
47      * True to enable signatures support.
48      */
49     static final boolean SIGNATURES = true;
50 
51     /**
52      * True to enable annotations support.
53      */
54     static final boolean ANNOTATIONS = true;
55 
56     /**
57      * True to enable stack map frames support.
58      */
59     static final boolean FRAMES = true;
60 
61     /**
62      * True to enable bytecode writing support.
63      */
64     static final boolean WRITER = true;
65 
66     /**
67      * True to enable JSR_W and GOTO_W support.
68      */
69     static final boolean RESIZE = true;
70 
71     /**
72      * Flag to skip method code. If this class is set <code>CODE</code>
73      * attribute won't be visited. This can be used, for example, to retrieve
74      * annotations for methods and method parameters.
75      */
76     public static final int SKIP_CODE = 1;
77 
78     /**
79      * Flag to skip the debug information in the class. If this flag is set the
80      * debug information of the class is not visited, i.e. the
81      * {@link MethodVisitor#visitLocalVariable visitLocalVariable} and
82      * {@link MethodVisitor#visitLineNumber visitLineNumber} methods will not be
83      * called.
84      */
85     public static final int SKIP_DEBUG = 2;
86 
87     /**
88      * Flag to skip the stack map frames in the class. If this flag is set the
89      * stack map frames of the class is not visited, i.e. the
90      * {@link MethodVisitor#visitFrame visitFrame} method will not be called.
91      * This flag is useful when the {@link ClassWriter#COMPUTE_FRAMES} option is
92      * used: it avoids visiting frames that will be ignored and recomputed from
93      * scratch in the class writer.
94      */
95     public static final int SKIP_FRAMES = 4;
96 
97     /**
98      * Flag to expand the stack map frames. By default stack map frames are
99      * visited in their original format (i.e. "expanded" for classes whose
100      * version is less than V1_6, and "compressed" for the other classes). If
101      * this flag is set, stack map frames are always visited in expanded format
102      * (this option adds a decompression/recompression step in ClassReader and
103      * ClassWriter which degrades performances quite a lot).
104      */
105     public static final int EXPAND_FRAMES = 8;
106 
107     /**
108      * The class to be parsed. <i>The content of this array must not be
109      * modified. This field is intended for {@link Attribute} sub classes, and
110      * is normally not needed by class generators or adapters.</i>
111      */
112     public final byte[] b;
113 
114     /**
115      * The start index of each constant pool item in {@link #b b}, plus one. The
116      * one byte offset skips the constant pool item tag that indicates its type.
117      */
118     private final int[] items;
119 
120     /**
121      * The String objects corresponding to the CONSTANT_Utf8 items. This cache
122      * avoids multiple parsing of a given CONSTANT_Utf8 constant pool item,
123      * which GREATLY improves performances (by a factor 2 to 3). This caching
124      * strategy could be extended to all constant pool items, but its benefit
125      * would not be so great for these items (because they are much less
126      * expensive to parse than CONSTANT_Utf8 items).
127      */
128     private final String[] strings;
129 
130     /**
131      * Maximum length of the strings contained in the constant pool of the
132      * class.
133      */
134     private final int maxStringLength;
135 
136     /**
137      * Start index of the class header information (access, name...) in
138      * {@link #b b}.
139      */
140     public final int header;
141 
142     // ------------------------------------------------------------------------
143     // Constructors
144     // ------------------------------------------------------------------------
145 
146     /**
147      * Constructs a new {@link ClassReader} object.
148      *
149      * @param b
150      *            the bytecode of the class to be read.
151      */
ClassReader(final byte[] b)152     public ClassReader(final byte[] b) {
153         this(b, 0, b.length);
154     }
155 
156     /**
157      * Constructs a new {@link ClassReader} object.
158      *
159      * @param b
160      *            the bytecode of the class to be read.
161      * @param off
162      *            the start offset of the class data.
163      * @param len
164      *            the length of the class data.
165      */
ClassReader(final byte[] b, final int off, final int len)166     public ClassReader(final byte[] b, final int off, final int len) {
167         this.b = b;
168         // checks the class version
169         if (readShort(off + 6) > Opcodes.V1_8) {
170             throw new IllegalArgumentException();
171         }
172         // parses the constant pool
173         items = new int[readUnsignedShort(off + 8)];
174         int n = items.length;
175         strings = new String[n];
176         int max = 0;
177         int index = off + 10;
178         for (int i = 1; i < n; ++i) {
179             items[i] = index + 1;
180             int size;
181             switch (b[index]) {
182             case ClassWriter.FIELD:
183             case ClassWriter.METH:
184             case ClassWriter.IMETH:
185             case ClassWriter.INT:
186             case ClassWriter.FLOAT:
187             case ClassWriter.NAME_TYPE:
188             case ClassWriter.INDY:
189                 size = 5;
190                 break;
191             case ClassWriter.LONG:
192             case ClassWriter.DOUBLE:
193                 size = 9;
194                 ++i;
195                 break;
196             case ClassWriter.UTF8:
197                 size = 3 + readUnsignedShort(index + 1);
198                 if (size > max) {
199                     max = size;
200                 }
201                 break;
202             case ClassWriter.HANDLE:
203                 size = 4;
204                 break;
205             // case ClassWriter.CLASS:
206             // case ClassWriter.STR:
207             // case ClassWriter.MTYPE
208             default:
209                 size = 3;
210                 break;
211             }
212             index += size;
213         }
214         maxStringLength = max;
215         // the class header information starts just after the constant pool
216         header = index;
217     }
218 
219     /**
220      * Returns the class's access flags (see {@link Opcodes}). This value may
221      * not reflect Deprecated and Synthetic flags when bytecode is before 1.5
222      * and those flags are represented by attributes.
223      *
224      * @return the class access flags
225      *
226      * @see ClassVisitor#visit(int, int, String, String, String, String[])
227      */
getAccess()228     public int getAccess() {
229         return readUnsignedShort(header);
230     }
231 
232     /**
233      * Returns the internal name of the class (see
234      * {@link Type#getInternalName() getInternalName}).
235      *
236      * @return the internal class name
237      *
238      * @see ClassVisitor#visit(int, int, String, String, String, String[])
239      */
getClassName()240     public String getClassName() {
241         return readClass(header + 2, new char[maxStringLength]);
242     }
243 
244     /**
245      * Returns the internal of name of the super class (see
246      * {@link Type#getInternalName() getInternalName}). For interfaces, the
247      * super class is {@link Object}.
248      *
249      * @return the internal name of super class, or <tt>null</tt> for
250      *         {@link Object} class.
251      *
252      * @see ClassVisitor#visit(int, int, String, String, String, String[])
253      */
getSuperName()254     public String getSuperName() {
255         return readClass(header + 4, new char[maxStringLength]);
256     }
257 
258     /**
259      * Returns the internal names of the class's interfaces (see
260      * {@link Type#getInternalName() getInternalName}).
261      *
262      * @return the array of internal names for all implemented interfaces or
263      *         <tt>null</tt>.
264      *
265      * @see ClassVisitor#visit(int, int, String, String, String, String[])
266      */
getInterfaces()267     public String[] getInterfaces() {
268         int index = header + 6;
269         int n = readUnsignedShort(index);
270         String[] interfaces = new String[n];
271         if (n > 0) {
272             char[] buf = new char[maxStringLength];
273             for (int i = 0; i < n; ++i) {
274                 index += 2;
275                 interfaces[i] = readClass(index, buf);
276             }
277         }
278         return interfaces;
279     }
280 
281     /**
282      * Copies the constant pool data into the given {@link ClassWriter}. Should
283      * be called before the {@link #accept(ClassVisitor,int)} method.
284      *
285      * @param classWriter
286      *            the {@link ClassWriter} to copy constant pool into.
287      */
copyPool(final ClassWriter classWriter)288     void copyPool(final ClassWriter classWriter) {
289         char[] buf = new char[maxStringLength];
290         int ll = items.length;
291         Item[] items2 = new Item[ll];
292         for (int i = 1; i < ll; i++) {
293             int index = items[i];
294             int tag = b[index - 1];
295             Item item = new Item(i);
296             int nameType;
297             switch (tag) {
298             case ClassWriter.FIELD:
299             case ClassWriter.METH:
300             case ClassWriter.IMETH:
301                 nameType = items[readUnsignedShort(index + 2)];
302                 item.set(tag, readClass(index, buf), readUTF8(nameType, buf),
303                         readUTF8(nameType + 2, buf));
304                 break;
305             case ClassWriter.INT:
306                 item.set(readInt(index));
307                 break;
308             case ClassWriter.FLOAT:
309                 item.set(Float.intBitsToFloat(readInt(index)));
310                 break;
311             case ClassWriter.NAME_TYPE:
312                 item.set(tag, readUTF8(index, buf), readUTF8(index + 2, buf),
313                         null);
314                 break;
315             case ClassWriter.LONG:
316                 item.set(readLong(index));
317                 ++i;
318                 break;
319             case ClassWriter.DOUBLE:
320                 item.set(Double.longBitsToDouble(readLong(index)));
321                 ++i;
322                 break;
323             case ClassWriter.UTF8: {
324                 String s = strings[i];
325                 if (s == null) {
326                     index = items[i];
327                     s = strings[i] = readUTF(index + 2,
328                             readUnsignedShort(index), buf);
329                 }
330                 item.set(tag, s, null, null);
331                 break;
332             }
333             case ClassWriter.HANDLE: {
334                 int fieldOrMethodRef = items[readUnsignedShort(index + 1)];
335                 nameType = items[readUnsignedShort(fieldOrMethodRef + 2)];
336                 item.set(ClassWriter.HANDLE_BASE + readByte(index),
337                         readClass(fieldOrMethodRef, buf),
338                         readUTF8(nameType, buf), readUTF8(nameType + 2, buf));
339                 break;
340             }
341             case ClassWriter.INDY:
342                 if (classWriter.bootstrapMethods == null) {
343                     copyBootstrapMethods(classWriter, items2, buf);
344                 }
345                 nameType = items[readUnsignedShort(index + 2)];
346                 item.set(readUTF8(nameType, buf), readUTF8(nameType + 2, buf),
347                         readUnsignedShort(index));
348                 break;
349             // case ClassWriter.STR:
350             // case ClassWriter.CLASS:
351             // case ClassWriter.MTYPE
352             default:
353                 item.set(tag, readUTF8(index, buf), null, null);
354                 break;
355             }
356 
357             int index2 = item.hashCode % items2.length;
358             item.next = items2[index2];
359             items2[index2] = item;
360         }
361 
362         int off = items[1] - 1;
363         classWriter.pool.putByteArray(b, off, header - off);
364         classWriter.items = items2;
365         classWriter.threshold = (int) (0.75d * ll);
366         classWriter.index = ll;
367     }
368 
369     /**
370      * Copies the bootstrap method data into the given {@link ClassWriter}.
371      * Should be called before the {@link #accept(ClassVisitor,int)} method.
372      *
373      * @param classWriter
374      *            the {@link ClassWriter} to copy bootstrap methods into.
375      */
copyBootstrapMethods(final ClassWriter classWriter, final Item[] items, final char[] c)376     private void copyBootstrapMethods(final ClassWriter classWriter,
377             final Item[] items, final char[] c) {
378         // finds the "BootstrapMethods" attribute
379         int u = getAttributes();
380         boolean found = false;
381         for (int i = readUnsignedShort(u); i > 0; --i) {
382             String attrName = readUTF8(u + 2, c);
383             if ("BootstrapMethods".equals(attrName)) {
384                 found = true;
385                 break;
386             }
387             u += 6 + readInt(u + 4);
388         }
389         if (!found) {
390             return;
391         }
392         // copies the bootstrap methods in the class writer
393         int boostrapMethodCount = readUnsignedShort(u + 8);
394         for (int j = 0, v = u + 10; j < boostrapMethodCount; j++) {
395             int position = v - u - 10;
396             int hashCode = readConst(readUnsignedShort(v), c).hashCode();
397             for (int k = readUnsignedShort(v + 2); k > 0; --k) {
398                 hashCode ^= readConst(readUnsignedShort(v + 4), c).hashCode();
399                 v += 2;
400             }
401             v += 4;
402             Item item = new Item(j);
403             item.set(position, hashCode & 0x7FFFFFFF);
404             int index = item.hashCode % items.length;
405             item.next = items[index];
406             items[index] = item;
407         }
408         int attrSize = readInt(u + 4);
409         ByteVector bootstrapMethods = new ByteVector(attrSize + 62);
410         bootstrapMethods.putByteArray(b, u + 10, attrSize - 2);
411         classWriter.bootstrapMethodsCount = boostrapMethodCount;
412         classWriter.bootstrapMethods = bootstrapMethods;
413     }
414 
415     /**
416      * Constructs a new {@link ClassReader} object.
417      *
418      * @param is
419      *            an input stream from which to read the class.
420      * @throws IOException
421      *             if a problem occurs during reading.
422      */
ClassReader(final InputStream is)423     public ClassReader(final InputStream is) throws IOException {
424         this(readClass(is, false));
425     }
426 
427     /**
428      * Constructs a new {@link ClassReader} object.
429      *
430      * @param name
431      *            the binary qualified name of the class to be read.
432      * @throws IOException
433      *             if an exception occurs during reading.
434      */
ClassReader(final String name)435     public ClassReader(final String name) throws IOException {
436         this(readClass(
437                 ClassLoader.getSystemResourceAsStream(name.replace('.', '/')
438                         + ".class"), true));
439     }
440 
441     /**
442      * Reads the bytecode of a class.
443      *
444      * @param is
445      *            an input stream from which to read the class.
446      * @param close
447      *            true to close the input stream after reading.
448      * @return the bytecode read from the given input stream.
449      * @throws IOException
450      *             if a problem occurs during reading.
451      */
readClass(final InputStream is, boolean close)452     private static byte[] readClass(final InputStream is, boolean close)
453             throws IOException {
454         if (is == null) {
455             throw new IOException("Class not found");
456         }
457         try {
458             byte[] b = new byte[is.available()];
459             int len = 0;
460             while (true) {
461                 int n = is.read(b, len, b.length - len);
462                 if (n == -1) {
463                     if (len < b.length) {
464                         byte[] c = new byte[len];
465                         System.arraycopy(b, 0, c, 0, len);
466                         b = c;
467                     }
468                     return b;
469                 }
470                 len += n;
471                 if (len == b.length) {
472                     int last = is.read();
473                     if (last < 0) {
474                         return b;
475                     }
476                     byte[] c = new byte[b.length + 1000];
477                     System.arraycopy(b, 0, c, 0, len);
478                     c[len++] = (byte) last;
479                     b = c;
480                 }
481             }
482         } finally {
483             if (close) {
484                 is.close();
485             }
486         }
487     }
488 
489     // ------------------------------------------------------------------------
490     // Public methods
491     // ------------------------------------------------------------------------
492 
493     /**
494      * Makes the given visitor visit the Java class of this {@link ClassReader}
495      * . This class is the one specified in the constructor (see
496      * {@link #ClassReader(byte[]) ClassReader}).
497      *
498      * @param classVisitor
499      *            the visitor that must visit this class.
500      * @param flags
501      *            option flags that can be used to modify the default behavior
502      *            of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES}
503      *            , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
504      */
accept(final ClassVisitor classVisitor, final int flags)505     public void accept(final ClassVisitor classVisitor, final int flags) {
506         accept(classVisitor, new Attribute[0], flags);
507     }
508 
509     /**
510      * Makes the given visitor visit the Java class of this {@link ClassReader}.
511      * This class is the one specified in the constructor (see
512      * {@link #ClassReader(byte[]) ClassReader}).
513      *
514      * @param classVisitor
515      *            the visitor that must visit this class.
516      * @param attrs
517      *            prototypes of the attributes that must be parsed during the
518      *            visit of the class. Any attribute whose type is not equal to
519      *            the type of one the prototypes will not be parsed: its byte
520      *            array value will be passed unchanged to the ClassWriter.
521      *            <i>This may corrupt it if this value contains references to
522      *            the constant pool, or has syntactic or semantic links with a
523      *            class element that has been transformed by a class adapter
524      *            between the reader and the writer</i>.
525      * @param flags
526      *            option flags that can be used to modify the default behavior
527      *            of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES}
528      *            , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
529      */
accept(final ClassVisitor classVisitor, final Attribute[] attrs, final int flags)530     public void accept(final ClassVisitor classVisitor,
531             final Attribute[] attrs, final int flags) {
532         int u = header; // current offset in the class file
533         char[] c = new char[maxStringLength]; // buffer used to read strings
534 
535         Context context = new Context();
536         context.attrs = attrs;
537         context.flags = flags;
538         context.buffer = c;
539 
540         // reads the class declaration
541         int access = readUnsignedShort(u);
542         String name = readClass(u + 2, c);
543         String superClass = readClass(u + 4, c);
544         String[] interfaces = new String[readUnsignedShort(u + 6)];
545         u += 8;
546         for (int i = 0; i < interfaces.length; ++i) {
547             interfaces[i] = readClass(u, c);
548             u += 2;
549         }
550 
551         // reads the class attributes
552         String signature = null;
553         String sourceFile = null;
554         String sourceDebug = null;
555         String enclosingOwner = null;
556         String enclosingName = null;
557         String enclosingDesc = null;
558         int anns = 0;
559         int ianns = 0;
560         int tanns = 0;
561         int itanns = 0;
562         int innerClasses = 0;
563         Attribute attributes = null;
564 
565         u = getAttributes();
566         for (int i = readUnsignedShort(u); i > 0; --i) {
567             String attrName = readUTF8(u + 2, c);
568             // tests are sorted in decreasing frequency order
569             // (based on frequencies observed on typical classes)
570             if ("SourceFile".equals(attrName)) {
571                 sourceFile = readUTF8(u + 8, c);
572             } else if ("InnerClasses".equals(attrName)) {
573                 innerClasses = u + 8;
574             } else if ("EnclosingMethod".equals(attrName)) {
575                 enclosingOwner = readClass(u + 8, c);
576                 int item = readUnsignedShort(u + 10);
577                 if (item != 0) {
578                     enclosingName = readUTF8(items[item], c);
579                     enclosingDesc = readUTF8(items[item] + 2, c);
580                 }
581             } else if (SIGNATURES && "Signature".equals(attrName)) {
582                 signature = readUTF8(u + 8, c);
583             } else if (ANNOTATIONS
584                     && "RuntimeVisibleAnnotations".equals(attrName)) {
585                 anns = u + 8;
586             } else if (ANNOTATIONS
587                     && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
588                 tanns = u + 8;
589             } else if ("Deprecated".equals(attrName)) {
590                 access |= Opcodes.ACC_DEPRECATED;
591             } else if ("Synthetic".equals(attrName)) {
592                 access |= Opcodes.ACC_SYNTHETIC
593                         | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
594             } else if ("SourceDebugExtension".equals(attrName)) {
595                 int len = readInt(u + 4);
596                 sourceDebug = readUTF(u + 8, len, new char[len]);
597             } else if (ANNOTATIONS
598                     && "RuntimeInvisibleAnnotations".equals(attrName)) {
599                 ianns = u + 8;
600             } else if (ANNOTATIONS
601                     && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
602                 itanns = u + 8;
603             } else if ("BootstrapMethods".equals(attrName)) {
604                 int[] bootstrapMethods = new int[readUnsignedShort(u + 8)];
605                 for (int j = 0, v = u + 10; j < bootstrapMethods.length; j++) {
606                     bootstrapMethods[j] = v;
607                     v += 2 + readUnsignedShort(v + 2) << 1;
608                 }
609                 context.bootstrapMethods = bootstrapMethods;
610             } else {
611                 Attribute attr = readAttribute(attrs, attrName, u + 8,
612                         readInt(u + 4), c, -1, null);
613                 if (attr != null) {
614                     attr.next = attributes;
615                     attributes = attr;
616                 }
617             }
618             u += 6 + readInt(u + 4);
619         }
620 
621         // visits the class declaration
622         classVisitor.visit(readInt(items[1] - 7), access, name, signature,
623                 superClass, interfaces);
624 
625         // visits the source and debug info
626         if ((flags & SKIP_DEBUG) == 0
627                 && (sourceFile != null || sourceDebug != null)) {
628             classVisitor.visitSource(sourceFile, sourceDebug);
629         }
630 
631         // visits the outer class
632         if (enclosingOwner != null) {
633             classVisitor.visitOuterClass(enclosingOwner, enclosingName,
634                     enclosingDesc);
635         }
636 
637         // visits the class annotations and type annotations
638         if (ANNOTATIONS && anns != 0) {
639             for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
640                 v = readAnnotationValues(v + 2, c, true,
641                         classVisitor.visitAnnotation(readUTF8(v, c), true));
642             }
643         }
644         if (ANNOTATIONS && ianns != 0) {
645             for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
646                 v = readAnnotationValues(v + 2, c, true,
647                         classVisitor.visitAnnotation(readUTF8(v, c), false));
648             }
649         }
650         if (ANNOTATIONS && tanns != 0) {
651             for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
652                 v = readAnnotationTarget(context, v);
653                 v = readAnnotationValues(v + 2, c, true,
654                         classVisitor.visitTypeAnnotation(context.typeRef,
655                                 context.typePath, readUTF8(v, c), true));
656             }
657         }
658         if (ANNOTATIONS && itanns != 0) {
659             for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
660                 v = readAnnotationTarget(context, v);
661                 v = readAnnotationValues(v + 2, c, true,
662                         classVisitor.visitTypeAnnotation(context.typeRef,
663                                 context.typePath, readUTF8(v, c), false));
664             }
665         }
666 
667         // visits the attributes
668         while (attributes != null) {
669             Attribute attr = attributes.next;
670             attributes.next = null;
671             classVisitor.visitAttribute(attributes);
672             attributes = attr;
673         }
674 
675         // visits the inner classes
676         if (innerClasses != 0) {
677             int v = innerClasses + 2;
678             for (int i = readUnsignedShort(innerClasses); i > 0; --i) {
679                 classVisitor.visitInnerClass(readClass(v, c),
680                         readClass(v + 2, c), readUTF8(v + 4, c),
681                         readUnsignedShort(v + 6));
682                 v += 8;
683             }
684         }
685 
686         // visits the fields and methods
687         u = header + 10 + 2 * interfaces.length;
688         for (int i = readUnsignedShort(u - 2); i > 0; --i) {
689             u = readField(classVisitor, context, u);
690         }
691         u += 2;
692         for (int i = readUnsignedShort(u - 2); i > 0; --i) {
693             u = readMethod(classVisitor, context, u);
694         }
695 
696         // visits the end of the class
697         classVisitor.visitEnd();
698     }
699 
700     /**
701      * Reads a field and makes the given visitor visit it.
702      *
703      * @param classVisitor
704      *            the visitor that must visit the field.
705      * @param context
706      *            information about the class being parsed.
707      * @param u
708      *            the start offset of the field in the class file.
709      * @return the offset of the first byte following the field in the class.
710      */
readField(final ClassVisitor classVisitor, final Context context, int u)711     private int readField(final ClassVisitor classVisitor,
712             final Context context, int u) {
713         // reads the field declaration
714         char[] c = context.buffer;
715         int access = readUnsignedShort(u);
716         String name = readUTF8(u + 2, c);
717         String desc = readUTF8(u + 4, c);
718         u += 6;
719 
720         // reads the field attributes
721         String signature = null;
722         int anns = 0;
723         int ianns = 0;
724         int tanns = 0;
725         int itanns = 0;
726         Object value = null;
727         Attribute attributes = null;
728 
729         for (int i = readUnsignedShort(u); i > 0; --i) {
730             String attrName = readUTF8(u + 2, c);
731             // tests are sorted in decreasing frequency order
732             // (based on frequencies observed on typical classes)
733             if ("ConstantValue".equals(attrName)) {
734                 int item = readUnsignedShort(u + 8);
735                 value = item == 0 ? null : readConst(item, c);
736             } else if (SIGNATURES && "Signature".equals(attrName)) {
737                 signature = readUTF8(u + 8, c);
738             } else if ("Deprecated".equals(attrName)) {
739                 access |= Opcodes.ACC_DEPRECATED;
740             } else if ("Synthetic".equals(attrName)) {
741                 access |= Opcodes.ACC_SYNTHETIC
742                         | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
743             } else if (ANNOTATIONS
744                     && "RuntimeVisibleAnnotations".equals(attrName)) {
745                 anns = u + 8;
746             } else if (ANNOTATIONS
747                     && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
748                 tanns = u + 8;
749             } else if (ANNOTATIONS
750                     && "RuntimeInvisibleAnnotations".equals(attrName)) {
751                 ianns = u + 8;
752             } else if (ANNOTATIONS
753                     && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
754                 itanns = u + 8;
755             } else {
756                 Attribute attr = readAttribute(context.attrs, attrName, u + 8,
757                         readInt(u + 4), c, -1, null);
758                 if (attr != null) {
759                     attr.next = attributes;
760                     attributes = attr;
761                 }
762             }
763             u += 6 + readInt(u + 4);
764         }
765         u += 2;
766 
767         // visits the field declaration
768         FieldVisitor fv = classVisitor.visitField(access, name, desc,
769                 signature, value);
770         if (fv == null) {
771             return u;
772         }
773 
774         // visits the field annotations and type annotations
775         if (ANNOTATIONS && anns != 0) {
776             for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
777                 v = readAnnotationValues(v + 2, c, true,
778                         fv.visitAnnotation(readUTF8(v, c), true));
779             }
780         }
781         if (ANNOTATIONS && ianns != 0) {
782             for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
783                 v = readAnnotationValues(v + 2, c, true,
784                         fv.visitAnnotation(readUTF8(v, c), false));
785             }
786         }
787         if (ANNOTATIONS && tanns != 0) {
788             for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
789                 v = readAnnotationTarget(context, v);
790                 v = readAnnotationValues(v + 2, c, true,
791                         fv.visitTypeAnnotation(context.typeRef,
792                                 context.typePath, readUTF8(v, c), true));
793             }
794         }
795         if (ANNOTATIONS && itanns != 0) {
796             for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
797                 v = readAnnotationTarget(context, v);
798                 v = readAnnotationValues(v + 2, c, true,
799                         fv.visitTypeAnnotation(context.typeRef,
800                                 context.typePath, readUTF8(v, c), false));
801             }
802         }
803 
804         // visits the field attributes
805         while (attributes != null) {
806             Attribute attr = attributes.next;
807             attributes.next = null;
808             fv.visitAttribute(attributes);
809             attributes = attr;
810         }
811 
812         // visits the end of the field
813         fv.visitEnd();
814 
815         return u;
816     }
817 
818     /**
819      * Reads a method and makes the given visitor visit it.
820      *
821      * @param classVisitor
822      *            the visitor that must visit the method.
823      * @param context
824      *            information about the class being parsed.
825      * @param u
826      *            the start offset of the method in the class file.
827      * @return the offset of the first byte following the method in the class.
828      */
readMethod(final ClassVisitor classVisitor, final Context context, int u)829     private int readMethod(final ClassVisitor classVisitor,
830             final Context context, int u) {
831         // reads the method declaration
832         char[] c = context.buffer;
833         context.access = readUnsignedShort(u);
834         context.name = readUTF8(u + 2, c);
835         context.desc = readUTF8(u + 4, c);
836         u += 6;
837 
838         // reads the method attributes
839         int code = 0;
840         int exception = 0;
841         String[] exceptions = null;
842         String signature = null;
843         int methodParameters = 0;
844         int anns = 0;
845         int ianns = 0;
846         int tanns = 0;
847         int itanns = 0;
848         int dann = 0;
849         int mpanns = 0;
850         int impanns = 0;
851         int firstAttribute = u;
852         Attribute attributes = null;
853 
854         for (int i = readUnsignedShort(u); i > 0; --i) {
855             String attrName = readUTF8(u + 2, c);
856             // tests are sorted in decreasing frequency order
857             // (based on frequencies observed on typical classes)
858             if ("Code".equals(attrName)) {
859                 if ((context.flags & SKIP_CODE) == 0) {
860                     code = u + 8;
861                 }
862             } else if ("Exceptions".equals(attrName)) {
863                 exceptions = new String[readUnsignedShort(u + 8)];
864                 exception = u + 10;
865                 for (int j = 0; j < exceptions.length; ++j) {
866                     exceptions[j] = readClass(exception, c);
867                     exception += 2;
868                 }
869             } else if (SIGNATURES && "Signature".equals(attrName)) {
870                 signature = readUTF8(u + 8, c);
871             } else if ("Deprecated".equals(attrName)) {
872                 context.access |= Opcodes.ACC_DEPRECATED;
873             } else if (ANNOTATIONS
874                     && "RuntimeVisibleAnnotations".equals(attrName)) {
875                 anns = u + 8;
876             } else if (ANNOTATIONS
877                     && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
878                 tanns = u + 8;
879             } else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) {
880                 dann = u + 8;
881             } else if ("Synthetic".equals(attrName)) {
882                 context.access |= Opcodes.ACC_SYNTHETIC
883                         | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
884             } else if (ANNOTATIONS
885                     && "RuntimeInvisibleAnnotations".equals(attrName)) {
886                 ianns = u + 8;
887             } else if (ANNOTATIONS
888                     && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
889                 itanns = u + 8;
890             } else if (ANNOTATIONS
891                     && "RuntimeVisibleParameterAnnotations".equals(attrName)) {
892                 mpanns = u + 8;
893             } else if (ANNOTATIONS
894                     && "RuntimeInvisibleParameterAnnotations".equals(attrName)) {
895                 impanns = u + 8;
896             } else if ("MethodParameters".equals(attrName)) {
897                 methodParameters = u + 8;
898             } else {
899                 Attribute attr = readAttribute(context.attrs, attrName, u + 8,
900                         readInt(u + 4), c, -1, null);
901                 if (attr != null) {
902                     attr.next = attributes;
903                     attributes = attr;
904                 }
905             }
906             u += 6 + readInt(u + 4);
907         }
908         u += 2;
909 
910         // visits the method declaration
911         MethodVisitor mv = classVisitor.visitMethod(context.access,
912                 context.name, context.desc, signature, exceptions);
913         if (mv == null) {
914             return u;
915         }
916 
917         /*
918          * if the returned MethodVisitor is in fact a MethodWriter, it means
919          * there is no method adapter between the reader and the writer. If, in
920          * addition, the writer's constant pool was copied from this reader
921          * (mw.cw.cr == this), and the signature and exceptions of the method
922          * have not been changed, then it is possible to skip all visit events
923          * and just copy the original code of the method to the writer (the
924          * access, name and descriptor can have been changed, this is not
925          * important since they are not copied as is from the reader).
926          */
927         if (WRITER && mv instanceof MethodWriter) {
928             MethodWriter mw = (MethodWriter) mv;
929             if (mw.cw.cr == this && signature == mw.signature) {
930                 boolean sameExceptions = false;
931                 if (exceptions == null) {
932                     sameExceptions = mw.exceptionCount == 0;
933                 } else if (exceptions.length == mw.exceptionCount) {
934                     sameExceptions = true;
935                     for (int j = exceptions.length - 1; j >= 0; --j) {
936                         exception -= 2;
937                         if (mw.exceptions[j] != readUnsignedShort(exception)) {
938                             sameExceptions = false;
939                             break;
940                         }
941                     }
942                 }
943                 if (sameExceptions) {
944                     /*
945                      * we do not copy directly the code into MethodWriter to
946                      * save a byte array copy operation. The real copy will be
947                      * done in ClassWriter.toByteArray().
948                      */
949                     mw.classReaderOffset = firstAttribute;
950                     mw.classReaderLength = u - firstAttribute;
951                     return u;
952                 }
953             }
954         }
955 
956         // visit the method parameters
957         if (methodParameters != 0) {
958             for (int i = b[methodParameters] & 0xFF, v = methodParameters + 1; i > 0; --i, v = v + 4) {
959                 mv.visitParameter(readUTF8(v, c), readUnsignedShort(v + 2));
960             }
961         }
962 
963         // visits the method annotations
964         if (ANNOTATIONS && dann != 0) {
965             AnnotationVisitor dv = mv.visitAnnotationDefault();
966             readAnnotationValue(dann, c, null, dv);
967             if (dv != null) {
968                 dv.visitEnd();
969             }
970         }
971         if (ANNOTATIONS && anns != 0) {
972             for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
973                 v = readAnnotationValues(v + 2, c, true,
974                         mv.visitAnnotation(readUTF8(v, c), true));
975             }
976         }
977         if (ANNOTATIONS && ianns != 0) {
978             for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
979                 v = readAnnotationValues(v + 2, c, true,
980                         mv.visitAnnotation(readUTF8(v, c), false));
981             }
982         }
983         if (ANNOTATIONS && tanns != 0) {
984             for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
985                 v = readAnnotationTarget(context, v);
986                 v = readAnnotationValues(v + 2, c, true,
987                         mv.visitTypeAnnotation(context.typeRef,
988                                 context.typePath, readUTF8(v, c), true));
989             }
990         }
991         if (ANNOTATIONS && itanns != 0) {
992             for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
993                 v = readAnnotationTarget(context, v);
994                 v = readAnnotationValues(v + 2, c, true,
995                         mv.visitTypeAnnotation(context.typeRef,
996                                 context.typePath, readUTF8(v, c), false));
997             }
998         }
999         if (ANNOTATIONS && mpanns != 0) {
1000             readParameterAnnotations(mv, context, mpanns, true);
1001         }
1002         if (ANNOTATIONS && impanns != 0) {
1003             readParameterAnnotations(mv, context, impanns, false);
1004         }
1005 
1006         // visits the method attributes
1007         while (attributes != null) {
1008             Attribute attr = attributes.next;
1009             attributes.next = null;
1010             mv.visitAttribute(attributes);
1011             attributes = attr;
1012         }
1013 
1014         // visits the method code
1015         if (code != 0) {
1016             mv.visitCode();
1017             readCode(mv, context, code);
1018         }
1019 
1020         // visits the end of the method
1021         mv.visitEnd();
1022 
1023         return u;
1024     }
1025 
1026     /**
1027      * Reads the bytecode of a method and makes the given visitor visit it.
1028      *
1029      * @param mv
1030      *            the visitor that must visit the method's code.
1031      * @param context
1032      *            information about the class being parsed.
1033      * @param u
1034      *            the start offset of the code attribute in the class file.
1035      */
readCode(final MethodVisitor mv, final Context context, int u)1036     private void readCode(final MethodVisitor mv, final Context context, int u) {
1037         // reads the header
1038         byte[] b = this.b;
1039         char[] c = context.buffer;
1040         int maxStack = readUnsignedShort(u);
1041         int maxLocals = readUnsignedShort(u + 2);
1042         int codeLength = readInt(u + 4);
1043         u += 8;
1044 
1045         // reads the bytecode to find the labels
1046         int codeStart = u;
1047         int codeEnd = u + codeLength;
1048         Label[] labels = context.labels = new Label[codeLength + 2];
1049         readLabel(codeLength + 1, labels);
1050         while (u < codeEnd) {
1051             int offset = u - codeStart;
1052             int opcode = b[u] & 0xFF;
1053             switch (ClassWriter.TYPE[opcode]) {
1054             case ClassWriter.NOARG_INSN:
1055             case ClassWriter.IMPLVAR_INSN:
1056                 u += 1;
1057                 break;
1058             case ClassWriter.LABEL_INSN:
1059                 readLabel(offset + readShort(u + 1), labels);
1060                 u += 3;
1061                 break;
1062             case ClassWriter.LABELW_INSN:
1063                 readLabel(offset + readInt(u + 1), labels);
1064                 u += 5;
1065                 break;
1066             case ClassWriter.WIDE_INSN:
1067                 opcode = b[u + 1] & 0xFF;
1068                 if (opcode == Opcodes.IINC) {
1069                     u += 6;
1070                 } else {
1071                     u += 4;
1072                 }
1073                 break;
1074             case ClassWriter.TABL_INSN:
1075                 // skips 0 to 3 padding bytes
1076                 u = u + 4 - (offset & 3);
1077                 // reads instruction
1078                 readLabel(offset + readInt(u), labels);
1079                 for (int i = readInt(u + 8) - readInt(u + 4) + 1; i > 0; --i) {
1080                     readLabel(offset + readInt(u + 12), labels);
1081                     u += 4;
1082                 }
1083                 u += 12;
1084                 break;
1085             case ClassWriter.LOOK_INSN:
1086                 // skips 0 to 3 padding bytes
1087                 u = u + 4 - (offset & 3);
1088                 // reads instruction
1089                 readLabel(offset + readInt(u), labels);
1090                 for (int i = readInt(u + 4); i > 0; --i) {
1091                     readLabel(offset + readInt(u + 12), labels);
1092                     u += 8;
1093                 }
1094                 u += 8;
1095                 break;
1096             case ClassWriter.VAR_INSN:
1097             case ClassWriter.SBYTE_INSN:
1098             case ClassWriter.LDC_INSN:
1099                 u += 2;
1100                 break;
1101             case ClassWriter.SHORT_INSN:
1102             case ClassWriter.LDCW_INSN:
1103             case ClassWriter.FIELDORMETH_INSN:
1104             case ClassWriter.TYPE_INSN:
1105             case ClassWriter.IINC_INSN:
1106                 u += 3;
1107                 break;
1108             case ClassWriter.ITFMETH_INSN:
1109             case ClassWriter.INDYMETH_INSN:
1110                 u += 5;
1111                 break;
1112             // case MANA_INSN:
1113             default:
1114                 u += 4;
1115                 break;
1116             }
1117         }
1118 
1119         // reads the try catch entries to find the labels, and also visits them
1120         for (int i = readUnsignedShort(u); i > 0; --i) {
1121             Label start = readLabel(readUnsignedShort(u + 2), labels);
1122             Label end = readLabel(readUnsignedShort(u + 4), labels);
1123             Label handler = readLabel(readUnsignedShort(u + 6), labels);
1124             String type = readUTF8(items[readUnsignedShort(u + 8)], c);
1125             mv.visitTryCatchBlock(start, end, handler, type);
1126             u += 8;
1127         }
1128         u += 2;
1129 
1130         // reads the code attributes
1131         int[] tanns = null; // start index of each visible type annotation
1132         int[] itanns = null; // start index of each invisible type annotation
1133         int tann = 0; // current index in tanns array
1134         int itann = 0; // current index in itanns array
1135         int ntoff = -1; // next visible type annotation code offset
1136         int nitoff = -1; // next invisible type annotation code offset
1137         int varTable = 0;
1138         int varTypeTable = 0;
1139         boolean zip = true;
1140         boolean unzip = (context.flags & EXPAND_FRAMES) != 0;
1141         int stackMap = 0;
1142         int stackMapSize = 0;
1143         int frameCount = 0;
1144         Context frame = null;
1145         Attribute attributes = null;
1146 
1147         for (int i = readUnsignedShort(u); i > 0; --i) {
1148             String attrName = readUTF8(u + 2, c);
1149             if ("LocalVariableTable".equals(attrName)) {
1150                 if ((context.flags & SKIP_DEBUG) == 0) {
1151                     varTable = u + 8;
1152                     for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
1153                         int label = readUnsignedShort(v + 10);
1154                         if (labels[label] == null) {
1155                             readLabel(label, labels).status |= Label.DEBUG;
1156                         }
1157                         label += readUnsignedShort(v + 12);
1158                         if (labels[label] == null) {
1159                             readLabel(label, labels).status |= Label.DEBUG;
1160                         }
1161                         v += 10;
1162                     }
1163                 }
1164             } else if ("LocalVariableTypeTable".equals(attrName)) {
1165                 varTypeTable = u + 8;
1166             } else if ("LineNumberTable".equals(attrName)) {
1167                 if ((context.flags & SKIP_DEBUG) == 0) {
1168                     for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
1169                         int label = readUnsignedShort(v + 10);
1170                         if (labels[label] == null) {
1171                             readLabel(label, labels).status |= Label.DEBUG;
1172                         }
1173                         Label l = labels[label];
1174                         while (l.line > 0) {
1175                             if (l.next == null) {
1176                                 l.next = new Label();
1177                             }
1178                             l = l.next;
1179                         }
1180                         l.line = readUnsignedShort(v + 12);
1181                         v += 4;
1182                     }
1183                 }
1184             } else if (ANNOTATIONS
1185                     && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
1186                 tanns = readTypeAnnotations(mv, context, u + 8, true);
1187                 ntoff = tanns.length == 0 || readByte(tanns[0]) < 0x43 ? -1
1188                         : readUnsignedShort(tanns[0] + 1);
1189             } else if (ANNOTATIONS
1190                     && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
1191                 itanns = readTypeAnnotations(mv, context, u + 8, false);
1192                 nitoff = itanns.length == 0 || readByte(itanns[0]) < 0x43 ? -1
1193                         : readUnsignedShort(itanns[0] + 1);
1194             } else if (FRAMES && "StackMapTable".equals(attrName)) {
1195                 if ((context.flags & SKIP_FRAMES) == 0) {
1196                     stackMap = u + 10;
1197                     stackMapSize = readInt(u + 4);
1198                     frameCount = readUnsignedShort(u + 8);
1199                 }
1200                 /*
1201                  * here we do not extract the labels corresponding to the
1202                  * attribute content. This would require a full parsing of the
1203                  * attribute, which would need to be repeated in the second
1204                  * phase (see below). Instead the content of the attribute is
1205                  * read one frame at a time (i.e. after a frame has been
1206                  * visited, the next frame is read), and the labels it contains
1207                  * are also extracted one frame at a time. Thanks to the
1208                  * ordering of frames, having only a "one frame lookahead" is
1209                  * not a problem, i.e. it is not possible to see an offset
1210                  * smaller than the offset of the current insn and for which no
1211                  * Label exist.
1212                  */
1213                 /*
1214                  * This is not true for UNINITIALIZED type offsets. We solve
1215                  * this by parsing the stack map table without a full decoding
1216                  * (see below).
1217                  */
1218             } else if (FRAMES && "StackMap".equals(attrName)) {
1219                 if ((context.flags & SKIP_FRAMES) == 0) {
1220                     zip = false;
1221                     stackMap = u + 10;
1222                     stackMapSize = readInt(u + 4);
1223                     frameCount = readUnsignedShort(u + 8);
1224                 }
1225                 /*
1226                  * IMPORTANT! here we assume that the frames are ordered, as in
1227                  * the StackMapTable attribute, although this is not guaranteed
1228                  * by the attribute format.
1229                  */
1230             } else {
1231                 for (int j = 0; j < context.attrs.length; ++j) {
1232                     if (context.attrs[j].type.equals(attrName)) {
1233                         Attribute attr = context.attrs[j].read(this, u + 8,
1234                                 readInt(u + 4), c, codeStart - 8, labels);
1235                         if (attr != null) {
1236                             attr.next = attributes;
1237                             attributes = attr;
1238                         }
1239                     }
1240                 }
1241             }
1242             u += 6 + readInt(u + 4);
1243         }
1244         u += 2;
1245 
1246         // generates the first (implicit) stack map frame
1247         if (FRAMES && stackMap != 0) {
1248             /*
1249              * for the first explicit frame the offset is not offset_delta + 1
1250              * but only offset_delta; setting the implicit frame offset to -1
1251              * allow the use of the "offset_delta + 1" rule in all cases
1252              */
1253             frame = context;
1254             frame.offset = -1;
1255             frame.mode = 0;
1256             frame.localCount = 0;
1257             frame.localDiff = 0;
1258             frame.stackCount = 0;
1259             frame.local = new Object[maxLocals];
1260             frame.stack = new Object[maxStack];
1261             if (unzip) {
1262                 getImplicitFrame(context);
1263             }
1264             /*
1265              * Finds labels for UNINITIALIZED frame types. Instead of decoding
1266              * each element of the stack map table, we look for 3 consecutive
1267              * bytes that "look like" an UNINITIALIZED type (tag 8, offset
1268              * within code bounds, NEW instruction at this offset). We may find
1269              * false positives (i.e. not real UNINITIALIZED types), but this
1270              * should be rare, and the only consequence will be the creation of
1271              * an unneeded label. This is better than creating a label for each
1272              * NEW instruction, and faster than fully decoding the whole stack
1273              * map table.
1274              */
1275             for (int i = stackMap; i < stackMap + stackMapSize - 2; ++i) {
1276                 if (b[i] == 8) { // UNINITIALIZED FRAME TYPE
1277                     int v = readUnsignedShort(i + 1);
1278                     if (v >= 0 && v < codeLength) {
1279                         if ((b[codeStart + v] & 0xFF) == Opcodes.NEW) {
1280                             readLabel(v, labels);
1281                         }
1282                     }
1283                 }
1284             }
1285         }
1286 
1287         // visits the instructions
1288         u = codeStart;
1289         while (u < codeEnd) {
1290             int offset = u - codeStart;
1291 
1292             // visits the label and line number for this offset, if any
1293             Label l = labels[offset];
1294             if (l != null) {
1295                 Label next = l.next;
1296                 l.next = null;
1297                 mv.visitLabel(l);
1298                 if ((context.flags & SKIP_DEBUG) == 0 && l.line > 0) {
1299                     mv.visitLineNumber(l.line, l);
1300                     while (next != null) {
1301                         mv.visitLineNumber(next.line, l);
1302                         next = next.next;
1303                     }
1304                 }
1305             }
1306 
1307             // visits the frame for this offset, if any
1308             while (FRAMES && frame != null
1309                     && (frame.offset == offset || frame.offset == -1)) {
1310                 // if there is a frame for this offset, makes the visitor visit
1311                 // it, and reads the next frame if there is one.
1312                 if (frame.offset != -1) {
1313                     if (!zip || unzip) {
1314                         mv.visitFrame(Opcodes.F_NEW, frame.localCount,
1315                                 frame.local, frame.stackCount, frame.stack);
1316                     } else {
1317                         mv.visitFrame(frame.mode, frame.localDiff, frame.local,
1318                                 frame.stackCount, frame.stack);
1319                     }
1320                 }
1321                 if (frameCount > 0) {
1322                     stackMap = readFrame(stackMap, zip, unzip, frame);
1323                     --frameCount;
1324                 } else {
1325                     frame = null;
1326                 }
1327             }
1328 
1329             // visits the instruction at this offset
1330             int opcode = b[u] & 0xFF;
1331             switch (ClassWriter.TYPE[opcode]) {
1332             case ClassWriter.NOARG_INSN:
1333                 mv.visitInsn(opcode);
1334                 u += 1;
1335                 break;
1336             case ClassWriter.IMPLVAR_INSN:
1337                 if (opcode > Opcodes.ISTORE) {
1338                     opcode -= 59; // ISTORE_0
1339                     mv.visitVarInsn(Opcodes.ISTORE + (opcode >> 2),
1340                             opcode & 0x3);
1341                 } else {
1342                     opcode -= 26; // ILOAD_0
1343                     mv.visitVarInsn(Opcodes.ILOAD + (opcode >> 2), opcode & 0x3);
1344                 }
1345                 u += 1;
1346                 break;
1347             case ClassWriter.LABEL_INSN:
1348                 mv.visitJumpInsn(opcode, labels[offset + readShort(u + 1)]);
1349                 u += 3;
1350                 break;
1351             case ClassWriter.LABELW_INSN:
1352                 mv.visitJumpInsn(opcode - 33, labels[offset + readInt(u + 1)]);
1353                 u += 5;
1354                 break;
1355             case ClassWriter.WIDE_INSN:
1356                 opcode = b[u + 1] & 0xFF;
1357                 if (opcode == Opcodes.IINC) {
1358                     mv.visitIincInsn(readUnsignedShort(u + 2), readShort(u + 4));
1359                     u += 6;
1360                 } else {
1361                     mv.visitVarInsn(opcode, readUnsignedShort(u + 2));
1362                     u += 4;
1363                 }
1364                 break;
1365             case ClassWriter.TABL_INSN: {
1366                 // skips 0 to 3 padding bytes
1367                 u = u + 4 - (offset & 3);
1368                 // reads instruction
1369                 int label = offset + readInt(u);
1370                 int min = readInt(u + 4);
1371                 int max = readInt(u + 8);
1372                 Label[] table = new Label[max - min + 1];
1373                 u += 12;
1374                 for (int i = 0; i < table.length; ++i) {
1375                     table[i] = labels[offset + readInt(u)];
1376                     u += 4;
1377                 }
1378                 mv.visitTableSwitchInsn(min, max, labels[label], table);
1379                 break;
1380             }
1381             case ClassWriter.LOOK_INSN: {
1382                 // skips 0 to 3 padding bytes
1383                 u = u + 4 - (offset & 3);
1384                 // reads instruction
1385                 int label = offset + readInt(u);
1386                 int len = readInt(u + 4);
1387                 int[] keys = new int[len];
1388                 Label[] values = new Label[len];
1389                 u += 8;
1390                 for (int i = 0; i < len; ++i) {
1391                     keys[i] = readInt(u);
1392                     values[i] = labels[offset + readInt(u + 4)];
1393                     u += 8;
1394                 }
1395                 mv.visitLookupSwitchInsn(labels[label], keys, values);
1396                 break;
1397             }
1398             case ClassWriter.VAR_INSN:
1399                 mv.visitVarInsn(opcode, b[u + 1] & 0xFF);
1400                 u += 2;
1401                 break;
1402             case ClassWriter.SBYTE_INSN:
1403                 mv.visitIntInsn(opcode, b[u + 1]);
1404                 u += 2;
1405                 break;
1406             case ClassWriter.SHORT_INSN:
1407                 mv.visitIntInsn(opcode, readShort(u + 1));
1408                 u += 3;
1409                 break;
1410             case ClassWriter.LDC_INSN:
1411                 mv.visitLdcInsn(readConst(b[u + 1] & 0xFF, c));
1412                 u += 2;
1413                 break;
1414             case ClassWriter.LDCW_INSN:
1415                 mv.visitLdcInsn(readConst(readUnsignedShort(u + 1), c));
1416                 u += 3;
1417                 break;
1418             case ClassWriter.FIELDORMETH_INSN:
1419             case ClassWriter.ITFMETH_INSN: {
1420                 int cpIndex = items[readUnsignedShort(u + 1)];
1421                 boolean itf = b[cpIndex - 1] == ClassWriter.IMETH;
1422                 String iowner = readClass(cpIndex, c);
1423                 cpIndex = items[readUnsignedShort(cpIndex + 2)];
1424                 String iname = readUTF8(cpIndex, c);
1425                 String idesc = readUTF8(cpIndex + 2, c);
1426                 if (opcode < Opcodes.INVOKEVIRTUAL) {
1427                     mv.visitFieldInsn(opcode, iowner, iname, idesc);
1428                 } else {
1429                     mv.visitMethodInsn(opcode, iowner, iname, idesc, itf);
1430                 }
1431                 if (opcode == Opcodes.INVOKEINTERFACE) {
1432                     u += 5;
1433                 } else {
1434                     u += 3;
1435                 }
1436                 break;
1437             }
1438             case ClassWriter.INDYMETH_INSN: {
1439                 int cpIndex = items[readUnsignedShort(u + 1)];
1440                 int bsmIndex = context.bootstrapMethods[readUnsignedShort(cpIndex)];
1441                 Handle bsm = (Handle) readConst(readUnsignedShort(bsmIndex), c);
1442                 int bsmArgCount = readUnsignedShort(bsmIndex + 2);
1443                 Object[] bsmArgs = new Object[bsmArgCount];
1444                 bsmIndex += 4;
1445                 for (int i = 0; i < bsmArgCount; i++) {
1446                     bsmArgs[i] = readConst(readUnsignedShort(bsmIndex), c);
1447                     bsmIndex += 2;
1448                 }
1449                 cpIndex = items[readUnsignedShort(cpIndex + 2)];
1450                 String iname = readUTF8(cpIndex, c);
1451                 String idesc = readUTF8(cpIndex + 2, c);
1452                 mv.visitInvokeDynamicInsn(iname, idesc, bsm, bsmArgs);
1453                 u += 5;
1454                 break;
1455             }
1456             case ClassWriter.TYPE_INSN:
1457                 mv.visitTypeInsn(opcode, readClass(u + 1, c));
1458                 u += 3;
1459                 break;
1460             case ClassWriter.IINC_INSN:
1461                 mv.visitIincInsn(b[u + 1] & 0xFF, b[u + 2]);
1462                 u += 3;
1463                 break;
1464             // case MANA_INSN:
1465             default:
1466                 mv.visitMultiANewArrayInsn(readClass(u + 1, c), b[u + 3] & 0xFF);
1467                 u += 4;
1468                 break;
1469             }
1470 
1471             // visit the instruction annotations, if any
1472             while (tanns != null && tann < tanns.length && ntoff <= offset) {
1473                 if (ntoff == offset) {
1474                     int v = readAnnotationTarget(context, tanns[tann]);
1475                     readAnnotationValues(v + 2, c, true,
1476                             mv.visitInsnAnnotation(context.typeRef,
1477                                     context.typePath, readUTF8(v, c), true));
1478                 }
1479                 ntoff = ++tann >= tanns.length || readByte(tanns[tann]) < 0x43 ? -1
1480                         : readUnsignedShort(tanns[tann] + 1);
1481             }
1482             while (itanns != null && itann < itanns.length && nitoff <= offset) {
1483                 if (nitoff == offset) {
1484                     int v = readAnnotationTarget(context, itanns[itann]);
1485                     readAnnotationValues(v + 2, c, true,
1486                             mv.visitInsnAnnotation(context.typeRef,
1487                                     context.typePath, readUTF8(v, c), false));
1488                 }
1489                 nitoff = ++itann >= itanns.length
1490                         || readByte(itanns[itann]) < 0x43 ? -1
1491                         : readUnsignedShort(itanns[itann] + 1);
1492             }
1493         }
1494         if (labels[codeLength] != null) {
1495             mv.visitLabel(labels[codeLength]);
1496         }
1497 
1498         // visits the local variable tables
1499         if ((context.flags & SKIP_DEBUG) == 0 && varTable != 0) {
1500             int[] typeTable = null;
1501             if (varTypeTable != 0) {
1502                 u = varTypeTable + 2;
1503                 typeTable = new int[readUnsignedShort(varTypeTable) * 3];
1504                 for (int i = typeTable.length; i > 0;) {
1505                     typeTable[--i] = u + 6; // signature
1506                     typeTable[--i] = readUnsignedShort(u + 8); // index
1507                     typeTable[--i] = readUnsignedShort(u); // start
1508                     u += 10;
1509                 }
1510             }
1511             u = varTable + 2;
1512             for (int i = readUnsignedShort(varTable); i > 0; --i) {
1513                 int start = readUnsignedShort(u);
1514                 int length = readUnsignedShort(u + 2);
1515                 int index = readUnsignedShort(u + 8);
1516                 String vsignature = null;
1517                 if (typeTable != null) {
1518                     for (int j = 0; j < typeTable.length; j += 3) {
1519                         if (typeTable[j] == start && typeTable[j + 1] == index) {
1520                             vsignature = readUTF8(typeTable[j + 2], c);
1521                             break;
1522                         }
1523                     }
1524                 }
1525                 mv.visitLocalVariable(readUTF8(u + 4, c), readUTF8(u + 6, c),
1526                         vsignature, labels[start], labels[start + length],
1527                         index);
1528                 u += 10;
1529             }
1530         }
1531 
1532         // visits the local variables type annotations
1533         if (tanns != null) {
1534             for (int i = 0; i < tanns.length; ++i) {
1535                 if ((readByte(tanns[i]) >> 1) == (0x40 >> 1)) {
1536                     int v = readAnnotationTarget(context, tanns[i]);
1537                     v = readAnnotationValues(v + 2, c, true,
1538                             mv.visitLocalVariableAnnotation(context.typeRef,
1539                                     context.typePath, context.start,
1540                                     context.end, context.index, readUTF8(v, c),
1541                                     true));
1542                 }
1543             }
1544         }
1545         if (itanns != null) {
1546             for (int i = 0; i < itanns.length; ++i) {
1547                 if ((readByte(itanns[i]) >> 1) == (0x40 >> 1)) {
1548                     int v = readAnnotationTarget(context, itanns[i]);
1549                     v = readAnnotationValues(v + 2, c, true,
1550                             mv.visitLocalVariableAnnotation(context.typeRef,
1551                                     context.typePath, context.start,
1552                                     context.end, context.index, readUTF8(v, c),
1553                                     false));
1554                 }
1555             }
1556         }
1557 
1558         // visits the code attributes
1559         while (attributes != null) {
1560             Attribute attr = attributes.next;
1561             attributes.next = null;
1562             mv.visitAttribute(attributes);
1563             attributes = attr;
1564         }
1565 
1566         // visits the max stack and max locals values
1567         mv.visitMaxs(maxStack, maxLocals);
1568     }
1569 
1570     /**
1571      * Parses a type annotation table to find the labels, and to visit the try
1572      * catch block annotations.
1573      *
1574      * @param u
1575      *            the start offset of a type annotation table.
1576      * @param mv
1577      *            the method visitor to be used to visit the try catch block
1578      *            annotations.
1579      * @param context
1580      *            information about the class being parsed.
1581      * @param visible
1582      *            if the type annotation table to parse contains runtime visible
1583      *            annotations.
1584      * @return the start offset of each type annotation in the parsed table.
1585      */
readTypeAnnotations(final MethodVisitor mv, final Context context, int u, boolean visible)1586     private int[] readTypeAnnotations(final MethodVisitor mv,
1587             final Context context, int u, boolean visible) {
1588         char[] c = context.buffer;
1589         int[] offsets = new int[readUnsignedShort(u)];
1590         u += 2;
1591         for (int i = 0; i < offsets.length; ++i) {
1592             offsets[i] = u;
1593             int target = readInt(u);
1594             switch (target >>> 24) {
1595             case 0x00: // CLASS_TYPE_PARAMETER
1596             case 0x01: // METHOD_TYPE_PARAMETER
1597             case 0x16: // METHOD_FORMAL_PARAMETER
1598                 u += 2;
1599                 break;
1600             case 0x13: // FIELD
1601             case 0x14: // METHOD_RETURN
1602             case 0x15: // METHOD_RECEIVER
1603                 u += 1;
1604                 break;
1605             case 0x40: // LOCAL_VARIABLE
1606             case 0x41: // RESOURCE_VARIABLE
1607                 for (int j = readUnsignedShort(u + 1); j > 0; --j) {
1608                     int start = readUnsignedShort(u + 3);
1609                     int length = readUnsignedShort(u + 5);
1610                     readLabel(start, context.labels);
1611                     readLabel(start + length, context.labels);
1612                     u += 6;
1613                 }
1614                 u += 3;
1615                 break;
1616             case 0x47: // CAST
1617             case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
1618             case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT
1619             case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
1620             case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT
1621                 u += 4;
1622                 break;
1623             // case 0x10: // CLASS_EXTENDS
1624             // case 0x11: // CLASS_TYPE_PARAMETER_BOUND
1625             // case 0x12: // METHOD_TYPE_PARAMETER_BOUND
1626             // case 0x17: // THROWS
1627             // case 0x42: // EXCEPTION_PARAMETER
1628             // case 0x43: // INSTANCEOF
1629             // case 0x44: // NEW
1630             // case 0x45: // CONSTRUCTOR_REFERENCE
1631             // case 0x46: // METHOD_REFERENCE
1632             default:
1633                 u += 3;
1634                 break;
1635             }
1636             int pathLength = readByte(u);
1637             if ((target >>> 24) == 0x42) {
1638                 TypePath path = pathLength == 0 ? null : new TypePath(b, u);
1639                 u += 1 + 2 * pathLength;
1640                 u = readAnnotationValues(u + 2, c, true,
1641                         mv.visitTryCatchAnnotation(target, path,
1642                                 readUTF8(u, c), visible));
1643             } else {
1644                 u = readAnnotationValues(u + 3 + 2 * pathLength, c, true, null);
1645             }
1646         }
1647         return offsets;
1648     }
1649 
1650     /**
1651      * Parses the header of a type annotation to extract its target_type and
1652      * target_path (the result is stored in the given context), and returns the
1653      * start offset of the rest of the type_annotation structure (i.e. the
1654      * offset to the type_index field, which is followed by
1655      * num_element_value_pairs and then the name,value pairs).
1656      *
1657      * @param context
1658      *            information about the class being parsed. This is where the
1659      *            extracted target_type and target_path must be stored.
1660      * @param u
1661      *            the start offset of a type_annotation structure.
1662      * @return the start offset of the rest of the type_annotation structure.
1663      */
readAnnotationTarget(final Context context, int u)1664     private int readAnnotationTarget(final Context context, int u) {
1665         int target = readInt(u);
1666         switch (target >>> 24) {
1667         case 0x00: // CLASS_TYPE_PARAMETER
1668         case 0x01: // METHOD_TYPE_PARAMETER
1669         case 0x16: // METHOD_FORMAL_PARAMETER
1670             target &= 0xFFFF0000;
1671             u += 2;
1672             break;
1673         case 0x13: // FIELD
1674         case 0x14: // METHOD_RETURN
1675         case 0x15: // METHOD_RECEIVER
1676             target &= 0xFF000000;
1677             u += 1;
1678             break;
1679         case 0x40: // LOCAL_VARIABLE
1680         case 0x41: { // RESOURCE_VARIABLE
1681             target &= 0xFF000000;
1682             int n = readUnsignedShort(u + 1);
1683             context.start = new Label[n];
1684             context.end = new Label[n];
1685             context.index = new int[n];
1686             u += 3;
1687             for (int i = 0; i < n; ++i) {
1688                 int start = readUnsignedShort(u);
1689                 int length = readUnsignedShort(u + 2);
1690                 context.start[i] = readLabel(start, context.labels);
1691                 context.end[i] = readLabel(start + length, context.labels);
1692                 context.index[i] = readUnsignedShort(u + 4);
1693                 u += 6;
1694             }
1695             break;
1696         }
1697         case 0x47: // CAST
1698         case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
1699         case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT
1700         case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
1701         case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT
1702             target &= 0xFF0000FF;
1703             u += 4;
1704             break;
1705         // case 0x10: // CLASS_EXTENDS
1706         // case 0x11: // CLASS_TYPE_PARAMETER_BOUND
1707         // case 0x12: // METHOD_TYPE_PARAMETER_BOUND
1708         // case 0x17: // THROWS
1709         // case 0x42: // EXCEPTION_PARAMETER
1710         // case 0x43: // INSTANCEOF
1711         // case 0x44: // NEW
1712         // case 0x45: // CONSTRUCTOR_REFERENCE
1713         // case 0x46: // METHOD_REFERENCE
1714         default:
1715             target &= (target >>> 24) < 0x43 ? 0xFFFFFF00 : 0xFF000000;
1716             u += 3;
1717             break;
1718         }
1719         int pathLength = readByte(u);
1720         context.typeRef = target;
1721         context.typePath = pathLength == 0 ? null : new TypePath(b, u);
1722         return u + 1 + 2 * pathLength;
1723     }
1724 
1725     /**
1726      * Reads parameter annotations and makes the given visitor visit them.
1727      *
1728      * @param mv
1729      *            the visitor that must visit the annotations.
1730      * @param context
1731      *            information about the class being parsed.
1732      * @param v
1733      *            start offset in {@link #b b} of the annotations to be read.
1734      * @param visible
1735      *            <tt>true</tt> if the annotations to be read are visible at
1736      *            runtime.
1737      */
1738     private void readParameterAnnotations(final MethodVisitor mv,
1739             final Context context, int v, final boolean visible) {
1740         int i;
1741         int n = b[v++] & 0xFF;
1742         // workaround for a bug in javac (javac compiler generates a parameter
1743         // annotation array whose size is equal to the number of parameters in
1744         // the Java source file, while it should generate an array whose size is
1745         // equal to the number of parameters in the method descriptor - which
1746         // includes the synthetic parameters added by the compiler). This work-
1747         // around supposes that the synthetic parameters are the first ones.
1748         int synthetics = Type.getArgumentTypes(context.desc).length - n;
1749         AnnotationVisitor av;
1750         for (i = 0; i < synthetics; ++i) {
1751             // virtual annotation to detect synthetic parameters in MethodWriter
1752             av = mv.visitParameterAnnotation(i, "Ljava/lang/Synthetic;", false);
1753             if (av != null) {
1754                 av.visitEnd();
1755             }
1756         }
1757         char[] c = context.buffer;
1758         for (; i < n + synthetics; ++i) {
1759             int j = readUnsignedShort(v);
1760             v += 2;
1761             for (; j > 0; --j) {
1762                 av = mv.visitParameterAnnotation(i, readUTF8(v, c), visible);
1763                 v = readAnnotationValues(v + 2, c, true, av);
1764             }
1765         }
1766     }
1767 
1768     /**
1769      * Reads the values of an annotation and makes the given visitor visit them.
1770      *
1771      * @param v
1772      *            the start offset in {@link #b b} of the values to be read
1773      *            (including the unsigned short that gives the number of
1774      *            values).
1775      * @param buf
1776      *            buffer to be used to call {@link #readUTF8 readUTF8},
1777      *            {@link #readClass(int,char[]) readClass} or {@link #readConst
1778      *            readConst}.
1779      * @param named
1780      *            if the annotation values are named or not.
1781      * @param av
1782      *            the visitor that must visit the values.
1783      * @return the end offset of the annotation values.
1784      */
1785     private int readAnnotationValues(int v, final char[] buf,
1786             final boolean named, final AnnotationVisitor av) {
1787         int i = readUnsignedShort(v);
1788         v += 2;
1789         if (named) {
1790             for (; i > 0; --i) {
1791                 v = readAnnotationValue(v + 2, buf, readUTF8(v, buf), av);
1792             }
1793         } else {
1794             for (; i > 0; --i) {
1795                 v = readAnnotationValue(v, buf, null, av);
1796             }
1797         }
1798         if (av != null) {
1799             av.visitEnd();
1800         }
1801         return v;
1802     }
1803 
1804     /**
1805      * Reads a value of an annotation and makes the given visitor visit it.
1806      *
1807      * @param v
1808      *            the start offset in {@link #b b} of the value to be read
1809      *            (<i>not including the value name constant pool index</i>).
1810      * @param buf
1811      *            buffer to be used to call {@link #readUTF8 readUTF8},
1812      *            {@link #readClass(int,char[]) readClass} or {@link #readConst
1813      *            readConst}.
1814      * @param name
1815      *            the name of the value to be read.
1816      * @param av
1817      *            the visitor that must visit the value.
1818      * @return the end offset of the annotation value.
1819      */
readAnnotationValue(int v, final char[] buf, final String name, final AnnotationVisitor av)1820     private int readAnnotationValue(int v, final char[] buf, final String name,
1821             final AnnotationVisitor av) {
1822         int i;
1823         if (av == null) {
1824             switch (b[v] & 0xFF) {
1825             case 'e': // enum_const_value
1826                 return v + 5;
1827             case '@': // annotation_value
1828                 return readAnnotationValues(v + 3, buf, true, null);
1829             case '[': // array_value
1830                 return readAnnotationValues(v + 1, buf, false, null);
1831             default:
1832                 return v + 3;
1833             }
1834         }
1835         switch (b[v++] & 0xFF) {
1836         case 'I': // pointer to CONSTANT_Integer
1837         case 'J': // pointer to CONSTANT_Long
1838         case 'F': // pointer to CONSTANT_Float
1839         case 'D': // pointer to CONSTANT_Double
1840             av.visit(name, readConst(readUnsignedShort(v), buf));
1841             v += 2;
1842             break;
1843         case 'B': // pointer to CONSTANT_Byte
1844             av.visit(name, (byte) readInt(items[readUnsignedShort(v)]));
1845             v += 2;
1846             break;
1847         case 'Z': // pointer to CONSTANT_Boolean
1848             av.visit(name,
1849                     readInt(items[readUnsignedShort(v)]) == 0 ? Boolean.FALSE
1850                             : Boolean.TRUE);
1851             v += 2;
1852             break;
1853         case 'S': // pointer to CONSTANT_Short
1854             av.visit(name, (short) readInt(items[readUnsignedShort(v)]));
1855             v += 2;
1856             break;
1857         case 'C': // pointer to CONSTANT_Char
1858             av.visit(name, (char) readInt(items[readUnsignedShort(v)]));
1859             v += 2;
1860             break;
1861         case 's': // pointer to CONSTANT_Utf8
1862             av.visit(name, readUTF8(v, buf));
1863             v += 2;
1864             break;
1865         case 'e': // enum_const_value
1866             av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf));
1867             v += 4;
1868             break;
1869         case 'c': // class_info
1870             av.visit(name, Type.getType(readUTF8(v, buf)));
1871             v += 2;
1872             break;
1873         case '@': // annotation_value
1874             v = readAnnotationValues(v + 2, buf, true,
1875                     av.visitAnnotation(name, readUTF8(v, buf)));
1876             break;
1877         case '[': // array_value
1878             int size = readUnsignedShort(v);
1879             v += 2;
1880             if (size == 0) {
1881                 return readAnnotationValues(v - 2, buf, false,
1882                         av.visitArray(name));
1883             }
1884             switch (this.b[v++] & 0xFF) {
1885             case 'B':
1886                 byte[] bv = new byte[size];
1887                 for (i = 0; i < size; i++) {
1888                     bv[i] = (byte) readInt(items[readUnsignedShort(v)]);
1889                     v += 3;
1890                 }
1891                 av.visit(name, bv);
1892                 --v;
1893                 break;
1894             case 'Z':
1895                 boolean[] zv = new boolean[size];
1896                 for (i = 0; i < size; i++) {
1897                     zv[i] = readInt(items[readUnsignedShort(v)]) != 0;
1898                     v += 3;
1899                 }
1900                 av.visit(name, zv);
1901                 --v;
1902                 break;
1903             case 'S':
1904                 short[] sv = new short[size];
1905                 for (i = 0; i < size; i++) {
1906                     sv[i] = (short) readInt(items[readUnsignedShort(v)]);
1907                     v += 3;
1908                 }
1909                 av.visit(name, sv);
1910                 --v;
1911                 break;
1912             case 'C':
1913                 char[] cv = new char[size];
1914                 for (i = 0; i < size; i++) {
1915                     cv[i] = (char) readInt(items[readUnsignedShort(v)]);
1916                     v += 3;
1917                 }
1918                 av.visit(name, cv);
1919                 --v;
1920                 break;
1921             case 'I':
1922                 int[] iv = new int[size];
1923                 for (i = 0; i < size; i++) {
1924                     iv[i] = readInt(items[readUnsignedShort(v)]);
1925                     v += 3;
1926                 }
1927                 av.visit(name, iv);
1928                 --v;
1929                 break;
1930             case 'J':
1931                 long[] lv = new long[size];
1932                 for (i = 0; i < size; i++) {
1933                     lv[i] = readLong(items[readUnsignedShort(v)]);
1934                     v += 3;
1935                 }
1936                 av.visit(name, lv);
1937                 --v;
1938                 break;
1939             case 'F':
1940                 float[] fv = new float[size];
1941                 for (i = 0; i < size; i++) {
1942                     fv[i] = Float
1943                             .intBitsToFloat(readInt(items[readUnsignedShort(v)]));
1944                     v += 3;
1945                 }
1946                 av.visit(name, fv);
1947                 --v;
1948                 break;
1949             case 'D':
1950                 double[] dv = new double[size];
1951                 for (i = 0; i < size; i++) {
1952                     dv[i] = Double
1953                             .longBitsToDouble(readLong(items[readUnsignedShort(v)]));
1954                     v += 3;
1955                 }
1956                 av.visit(name, dv);
1957                 --v;
1958                 break;
1959             default:
1960                 v = readAnnotationValues(v - 3, buf, false, av.visitArray(name));
1961             }
1962         }
1963         return v;
1964     }
1965 
1966     /**
1967      * Computes the implicit frame of the method currently being parsed (as
1968      * defined in the given {@link Context}) and stores it in the given context.
1969      *
1970      * @param frame
1971      *            information about the class being parsed.
1972      */
getImplicitFrame(final Context frame)1973     private void getImplicitFrame(final Context frame) {
1974         String desc = frame.desc;
1975         Object[] locals = frame.local;
1976         int local = 0;
1977         if ((frame.access & Opcodes.ACC_STATIC) == 0) {
1978             if ("<init>".equals(frame.name)) {
1979                 locals[local++] = Opcodes.UNINITIALIZED_THIS;
1980             } else {
1981                 locals[local++] = readClass(header + 2, frame.buffer);
1982             }
1983         }
1984         int i = 1;
1985         loop: while (true) {
1986             int j = i;
1987             switch (desc.charAt(i++)) {
1988             case 'Z':
1989             case 'C':
1990             case 'B':
1991             case 'S':
1992             case 'I':
1993                 locals[local++] = Opcodes.INTEGER;
1994                 break;
1995             case 'F':
1996                 locals[local++] = Opcodes.FLOAT;
1997                 break;
1998             case 'J':
1999                 locals[local++] = Opcodes.LONG;
2000                 break;
2001             case 'D':
2002                 locals[local++] = Opcodes.DOUBLE;
2003                 break;
2004             case '[':
2005                 while (desc.charAt(i) == '[') {
2006                     ++i;
2007                 }
2008                 if (desc.charAt(i) == 'L') {
2009                     ++i;
2010                     while (desc.charAt(i) != ';') {
2011                         ++i;
2012                     }
2013                 }
2014                 locals[local++] = desc.substring(j, ++i);
2015                 break;
2016             case 'L':
2017                 while (desc.charAt(i) != ';') {
2018                     ++i;
2019                 }
2020                 locals[local++] = desc.substring(j + 1, i++);
2021                 break;
2022             default:
2023                 break loop;
2024             }
2025         }
2026         frame.localCount = local;
2027     }
2028 
2029     /**
2030      * Reads a stack map frame and stores the result in the given
2031      * {@link Context} object.
2032      *
2033      * @param stackMap
2034      *            the start offset of a stack map frame in the class file.
2035      * @param zip
2036      *            if the stack map frame at stackMap is compressed or not.
2037      * @param unzip
2038      *            if the stack map frame must be uncompressed.
2039      * @param frame
2040      *            where the parsed stack map frame must be stored.
2041      * @return the offset of the first byte following the parsed frame.
2042      */
readFrame(int stackMap, boolean zip, boolean unzip, Context frame)2043     private int readFrame(int stackMap, boolean zip, boolean unzip,
2044             Context frame) {
2045         char[] c = frame.buffer;
2046         Label[] labels = frame.labels;
2047         int tag;
2048         int delta;
2049         if (zip) {
2050             tag = b[stackMap++] & 0xFF;
2051         } else {
2052             tag = MethodWriter.FULL_FRAME;
2053             frame.offset = -1;
2054         }
2055         frame.localDiff = 0;
2056         if (tag < MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME) {
2057             delta = tag;
2058             frame.mode = Opcodes.F_SAME;
2059             frame.stackCount = 0;
2060         } else if (tag < MethodWriter.RESERVED) {
2061             delta = tag - MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME;
2062             stackMap = readFrameType(frame.stack, 0, stackMap, c, labels);
2063             frame.mode = Opcodes.F_SAME1;
2064             frame.stackCount = 1;
2065         } else {
2066             delta = readUnsignedShort(stackMap);
2067             stackMap += 2;
2068             if (tag == MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) {
2069                 stackMap = readFrameType(frame.stack, 0, stackMap, c, labels);
2070                 frame.mode = Opcodes.F_SAME1;
2071                 frame.stackCount = 1;
2072             } else if (tag >= MethodWriter.CHOP_FRAME
2073                     && tag < MethodWriter.SAME_FRAME_EXTENDED) {
2074                 frame.mode = Opcodes.F_CHOP;
2075                 frame.localDiff = MethodWriter.SAME_FRAME_EXTENDED - tag;
2076                 frame.localCount -= frame.localDiff;
2077                 frame.stackCount = 0;
2078             } else if (tag == MethodWriter.SAME_FRAME_EXTENDED) {
2079                 frame.mode = Opcodes.F_SAME;
2080                 frame.stackCount = 0;
2081             } else if (tag < MethodWriter.FULL_FRAME) {
2082                 int local = unzip ? frame.localCount : 0;
2083                 for (int i = tag - MethodWriter.SAME_FRAME_EXTENDED; i > 0; i--) {
2084                     stackMap = readFrameType(frame.local, local++, stackMap, c,
2085                             labels);
2086                 }
2087                 frame.mode = Opcodes.F_APPEND;
2088                 frame.localDiff = tag - MethodWriter.SAME_FRAME_EXTENDED;
2089                 frame.localCount += frame.localDiff;
2090                 frame.stackCount = 0;
2091             } else { // if (tag == FULL_FRAME) {
2092                 frame.mode = Opcodes.F_FULL;
2093                 int n = readUnsignedShort(stackMap);
2094                 stackMap += 2;
2095                 frame.localDiff = n;
2096                 frame.localCount = n;
2097                 for (int local = 0; n > 0; n--) {
2098                     stackMap = readFrameType(frame.local, local++, stackMap, c,
2099                             labels);
2100                 }
2101                 n = readUnsignedShort(stackMap);
2102                 stackMap += 2;
2103                 frame.stackCount = n;
2104                 for (int stack = 0; n > 0; n--) {
2105                     stackMap = readFrameType(frame.stack, stack++, stackMap, c,
2106                             labels);
2107                 }
2108             }
2109         }
2110         frame.offset += delta + 1;
2111         readLabel(frame.offset, labels);
2112         return stackMap;
2113     }
2114 
2115     /**
2116      * Reads a stack map frame type and stores it at the given index in the
2117      * given array.
2118      *
2119      * @param frame
2120      *            the array where the parsed type must be stored.
2121      * @param index
2122      *            the index in 'frame' where the parsed type must be stored.
2123      * @param v
2124      *            the start offset of the stack map frame type to read.
2125      * @param buf
2126      *            a buffer to read strings.
2127      * @param labels
2128      *            the labels of the method currently being parsed, indexed by
2129      *            their offset. If the parsed type is an Uninitialized type, a
2130      *            new label for the corresponding NEW instruction is stored in
2131      *            this array if it does not already exist.
2132      * @return the offset of the first byte after the parsed type.
2133      */
readFrameType(final Object[] frame, final int index, int v, final char[] buf, final Label[] labels)2134     private int readFrameType(final Object[] frame, final int index, int v,
2135             final char[] buf, final Label[] labels) {
2136         int type = b[v++] & 0xFF;
2137         switch (type) {
2138         case 0:
2139             frame[index] = Opcodes.TOP;
2140             break;
2141         case 1:
2142             frame[index] = Opcodes.INTEGER;
2143             break;
2144         case 2:
2145             frame[index] = Opcodes.FLOAT;
2146             break;
2147         case 3:
2148             frame[index] = Opcodes.DOUBLE;
2149             break;
2150         case 4:
2151             frame[index] = Opcodes.LONG;
2152             break;
2153         case 5:
2154             frame[index] = Opcodes.NULL;
2155             break;
2156         case 6:
2157             frame[index] = Opcodes.UNINITIALIZED_THIS;
2158             break;
2159         case 7: // Object
2160             frame[index] = readClass(v, buf);
2161             v += 2;
2162             break;
2163         default: // Uninitialized
2164             frame[index] = readLabel(readUnsignedShort(v), labels);
2165             v += 2;
2166         }
2167         return v;
2168     }
2169 
2170     /**
2171      * Returns the label corresponding to the given offset. The default
2172      * implementation of this method creates a label for the given offset if it
2173      * has not been already created.
2174      *
2175      * @param offset
2176      *            a bytecode offset in a method.
2177      * @param labels
2178      *            the already created labels, indexed by their offset. If a
2179      *            label already exists for offset this method must not create a
2180      *            new one. Otherwise it must store the new label in this array.
2181      * @return a non null Label, which must be equal to labels[offset].
2182      */
readLabel(int offset, Label[] labels)2183     protected Label readLabel(int offset, Label[] labels) {
2184         if (labels[offset] == null) {
2185             labels[offset] = new Label();
2186         }
2187         return labels[offset];
2188     }
2189 
2190     /**
2191      * Returns the start index of the attribute_info structure of this class.
2192      *
2193      * @return the start index of the attribute_info structure of this class.
2194      */
getAttributes()2195     private int getAttributes() {
2196         // skips the header
2197         int u = header + 8 + readUnsignedShort(header + 6) * 2;
2198         // skips fields and methods
2199         for (int i = readUnsignedShort(u); i > 0; --i) {
2200             for (int j = readUnsignedShort(u + 8); j > 0; --j) {
2201                 u += 6 + readInt(u + 12);
2202             }
2203             u += 8;
2204         }
2205         u += 2;
2206         for (int i = readUnsignedShort(u); i > 0; --i) {
2207             for (int j = readUnsignedShort(u + 8); j > 0; --j) {
2208                 u += 6 + readInt(u + 12);
2209             }
2210             u += 8;
2211         }
2212         // the attribute_info structure starts just after the methods
2213         return u + 2;
2214     }
2215 
2216     /**
2217      * Reads an attribute in {@link #b b}.
2218      *
2219      * @param attrs
2220      *            prototypes of the attributes that must be parsed during the
2221      *            visit of the class. Any attribute whose type is not equal to
2222      *            the type of one the prototypes is ignored (i.e. an empty
2223      *            {@link Attribute} instance is returned).
2224      * @param type
2225      *            the type of the attribute.
2226      * @param off
2227      *            index of the first byte of the attribute's content in
2228      *            {@link #b b}. The 6 attribute header bytes, containing the
2229      *            type and the length of the attribute, are not taken into
2230      *            account here (they have already been read).
2231      * @param len
2232      *            the length of the attribute's content.
2233      * @param buf
2234      *            buffer to be used to call {@link #readUTF8 readUTF8},
2235      *            {@link #readClass(int,char[]) readClass} or {@link #readConst
2236      *            readConst}.
2237      * @param codeOff
2238      *            index of the first byte of code's attribute content in
2239      *            {@link #b b}, or -1 if the attribute to be read is not a code
2240      *            attribute. The 6 attribute header bytes, containing the type
2241      *            and the length of the attribute, are not taken into account
2242      *            here.
2243      * @param labels
2244      *            the labels of the method's code, or <tt>null</tt> if the
2245      *            attribute to be read is not a code attribute.
2246      * @return the attribute that has been read, or <tt>null</tt> to skip this
2247      *         attribute.
2248      */
readAttribute(final Attribute[] attrs, final String type, final int off, final int len, final char[] buf, final int codeOff, final Label[] labels)2249     private Attribute readAttribute(final Attribute[] attrs, final String type,
2250             final int off, final int len, final char[] buf, final int codeOff,
2251             final Label[] labels) {
2252         for (int i = 0; i < attrs.length; ++i) {
2253             if (attrs[i].type.equals(type)) {
2254                 return attrs[i].read(this, off, len, buf, codeOff, labels);
2255             }
2256         }
2257         return new Attribute(type).read(this, off, len, null, -1, null);
2258     }
2259 
2260     // ------------------------------------------------------------------------
2261     // Utility methods: low level parsing
2262     // ------------------------------------------------------------------------
2263 
2264     /**
2265      * Returns the number of constant pool items in {@link #b b}.
2266      *
2267      * @return the number of constant pool items in {@link #b b}.
2268      */
getItemCount()2269     public int getItemCount() {
2270         return items.length;
2271     }
2272 
2273     /**
2274      * Returns the start index of the constant pool item in {@link #b b}, plus
2275      * one. <i>This method is intended for {@link Attribute} sub classes, and is
2276      * normally not needed by class generators or adapters.</i>
2277      *
2278      * @param item
2279      *            the index a constant pool item.
2280      * @return the start index of the constant pool item in {@link #b b}, plus
2281      *         one.
2282      */
getItem(final int item)2283     public int getItem(final int item) {
2284         return items[item];
2285     }
2286 
2287     /**
2288      * Returns the maximum length of the strings contained in the constant pool
2289      * of the class.
2290      *
2291      * @return the maximum length of the strings contained in the constant pool
2292      *         of the class.
2293      */
getMaxStringLength()2294     public int getMaxStringLength() {
2295         return maxStringLength;
2296     }
2297 
2298     /**
2299      * Reads a byte value in {@link #b b}. <i>This method is intended for
2300      * {@link Attribute} sub classes, and is normally not needed by class
2301      * generators or adapters.</i>
2302      *
2303      * @param index
2304      *            the start index of the value to be read in {@link #b b}.
2305      * @return the read value.
2306      */
readByte(final int index)2307     public int readByte(final int index) {
2308         return b[index] & 0xFF;
2309     }
2310 
2311     /**
2312      * Reads an unsigned short value in {@link #b b}. <i>This method is intended
2313      * for {@link Attribute} sub classes, and is normally not needed by class
2314      * generators or adapters.</i>
2315      *
2316      * @param index
2317      *            the start index of the value to be read in {@link #b b}.
2318      * @return the read value.
2319      */
readUnsignedShort(final int index)2320     public int readUnsignedShort(final int index) {
2321         byte[] b = this.b;
2322         return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF);
2323     }
2324 
2325     /**
2326      * Reads a signed short value in {@link #b b}. <i>This method is intended
2327      * for {@link Attribute} sub classes, and is normally not needed by class
2328      * generators or adapters.</i>
2329      *
2330      * @param index
2331      *            the start index of the value to be read in {@link #b b}.
2332      * @return the read value.
2333      */
readShort(final int index)2334     public short readShort(final int index) {
2335         byte[] b = this.b;
2336         return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF));
2337     }
2338 
2339     /**
2340      * Reads a signed int value in {@link #b b}. <i>This method is intended for
2341      * {@link Attribute} sub classes, and is normally not needed by class
2342      * generators or adapters.</i>
2343      *
2344      * @param index
2345      *            the start index of the value to be read in {@link #b b}.
2346      * @return the read value.
2347      */
readInt(final int index)2348     public int readInt(final int index) {
2349         byte[] b = this.b;
2350         return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16)
2351                 | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF);
2352     }
2353 
2354     /**
2355      * Reads a signed long value in {@link #b b}. <i>This method is intended for
2356      * {@link Attribute} sub classes, and is normally not needed by class
2357      * generators or adapters.</i>
2358      *
2359      * @param index
2360      *            the start index of the value to be read in {@link #b b}.
2361      * @return the read value.
2362      */
readLong(final int index)2363     public long readLong(final int index) {
2364         long l1 = readInt(index);
2365         long l0 = readInt(index + 4) & 0xFFFFFFFFL;
2366         return (l1 << 32) | l0;
2367     }
2368 
2369     /**
2370      * Reads an UTF8 string constant pool item in {@link #b b}. <i>This method
2371      * is intended for {@link Attribute} sub classes, and is normally not needed
2372      * by class generators or adapters.</i>
2373      *
2374      * @param index
2375      *            the start index of an unsigned short value in {@link #b b},
2376      *            whose value is the index of an UTF8 constant pool item.
2377      * @param buf
2378      *            buffer to be used to read the item. This buffer must be
2379      *            sufficiently large. It is not automatically resized.
2380      * @return the String corresponding to the specified UTF8 item.
2381      */
readUTF8(int index, final char[] buf)2382     public String readUTF8(int index, final char[] buf) {
2383         int item = readUnsignedShort(index);
2384         if (index == 0 || item == 0) {
2385             return null;
2386         }
2387         String s = strings[item];
2388         if (s != null) {
2389             return s;
2390         }
2391         index = items[item];
2392         return strings[item] = readUTF(index + 2, readUnsignedShort(index), buf);
2393     }
2394 
2395     /**
2396      * Reads UTF8 string in {@link #b b}.
2397      *
2398      * @param index
2399      *            start offset of the UTF8 string to be read.
2400      * @param utfLen
2401      *            length of the UTF8 string to be read.
2402      * @param buf
2403      *            buffer to be used to read the string. This buffer must be
2404      *            sufficiently large. It is not automatically resized.
2405      * @return the String corresponding to the specified UTF8 string.
2406      */
readUTF(int index, final int utfLen, final char[] buf)2407     private String readUTF(int index, final int utfLen, final char[] buf) {
2408         int endIndex = index + utfLen;
2409         byte[] b = this.b;
2410         int strLen = 0;
2411         int c;
2412         int st = 0;
2413         char cc = 0;
2414         while (index < endIndex) {
2415             c = b[index++];
2416             switch (st) {
2417             case 0:
2418                 c = c & 0xFF;
2419                 if (c < 0x80) { // 0xxxxxxx
2420                     buf[strLen++] = (char) c;
2421                 } else if (c < 0xE0 && c > 0xBF) { // 110x xxxx 10xx xxxx
2422                     cc = (char) (c & 0x1F);
2423                     st = 1;
2424                 } else { // 1110 xxxx 10xx xxxx 10xx xxxx
2425                     cc = (char) (c & 0x0F);
2426                     st = 2;
2427                 }
2428                 break;
2429 
2430             case 1: // byte 2 of 2-byte char or byte 3 of 3-byte char
2431                 buf[strLen++] = (char) ((cc << 6) | (c & 0x3F));
2432                 st = 0;
2433                 break;
2434 
2435             case 2: // byte 2 of 3-byte char
2436                 cc = (char) ((cc << 6) | (c & 0x3F));
2437                 st = 1;
2438                 break;
2439             }
2440         }
2441         return new String(buf, 0, strLen);
2442     }
2443 
2444     /**
2445      * Reads a class constant pool item in {@link #b b}. <i>This method is
2446      * intended for {@link Attribute} sub classes, and is normally not needed by
2447      * class generators or adapters.</i>
2448      *
2449      * @param index
2450      *            the start index of an unsigned short value in {@link #b b},
2451      *            whose value is the index of a class constant pool item.
2452      * @param buf
2453      *            buffer to be used to read the item. This buffer must be
2454      *            sufficiently large. It is not automatically resized.
2455      * @return the String corresponding to the specified class item.
2456      */
readClass(final int index, final char[] buf)2457     public String readClass(final int index, final char[] buf) {
2458         // computes the start index of the CONSTANT_Class item in b
2459         // and reads the CONSTANT_Utf8 item designated by
2460         // the first two bytes of this CONSTANT_Class item
2461         return readUTF8(items[readUnsignedShort(index)], buf);
2462     }
2463 
2464     /**
2465      * Reads a numeric or string constant pool item in {@link #b b}. <i>This
2466      * method is intended for {@link Attribute} sub classes, and is normally not
2467      * needed by class generators or adapters.</i>
2468      *
2469      * @param item
2470      *            the index of a constant pool item.
2471      * @param buf
2472      *            buffer to be used to read the item. This buffer must be
2473      *            sufficiently large. It is not automatically resized.
2474      * @return the {@link Integer}, {@link Float}, {@link Long}, {@link Double},
2475      *         {@link String}, {@link Type} or {@link Handle} corresponding to
2476      *         the given constant pool item.
2477      */
readConst(final int item, final char[] buf)2478     public Object readConst(final int item, final char[] buf) {
2479         int index = items[item];
2480         switch (b[index - 1]) {
2481         case ClassWriter.INT:
2482             return readInt(index);
2483         case ClassWriter.FLOAT:
2484             return Float.intBitsToFloat(readInt(index));
2485         case ClassWriter.LONG:
2486             return readLong(index);
2487         case ClassWriter.DOUBLE:
2488             return Double.longBitsToDouble(readLong(index));
2489         case ClassWriter.CLASS:
2490             return Type.getObjectType(readUTF8(index, buf));
2491         case ClassWriter.STR:
2492             return readUTF8(index, buf);
2493         case ClassWriter.MTYPE:
2494             return Type.getMethodType(readUTF8(index, buf));
2495         default: // case ClassWriter.HANDLE_BASE + [1..9]:
2496             int tag = readByte(index);
2497             int[] items = this.items;
2498             int cpIndex = items[readUnsignedShort(index + 1)];
2499             String owner = readClass(cpIndex, buf);
2500             cpIndex = items[readUnsignedShort(cpIndex + 2)];
2501             String name = readUTF8(cpIndex, buf);
2502             String desc = readUTF8(cpIndex + 2, buf);
2503             return new Handle(tag, owner, name, desc);
2504         }
2505     }
2506 }
2507