View Javadoc
1   /*
2    * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  /*
27   * This file is available under and governed by the GNU General Public
28   * License version 2 only, as published by the Free Software Foundation.
29   * However, the following notice accompanied the original version of this
30   * file:
31   *
32   * ASM: a very small and fast Java bytecode manipulation framework
33   * Copyright (c) 2000-2007 INRIA, France Telecom
34   * All rights reserved.
35   *
36   * Redistribution and use in source and binary forms, with or without
37   * modification, are permitted provided that the following conditions
38   * are met:
39   * 1. Redistributions of source code must retain the above copyright
40   *    notice, this list of conditions and the following disclaimer.
41   * 2. Redistributions in binary form must reproduce the above copyright
42   *    notice, this list of conditions and the following disclaimer in the
43   *    documentation and/or other materials provided with the distribution.
44   * 3. Neither the name of the copyright holders nor the names of its
45   *    contributors may be used to endorse or promote products derived from
46   *    this software without specific prior written permission.
47   *
48   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
49   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
52   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
53   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
54   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
55   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
56   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
57   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
58   * THE POSSIBILITY OF SUCH DAMAGE.
59   */
60  package com.sun.xml.internal.ws.org.objectweb.asm;
61  
62  import java.io.InputStream;
63  import java.io.IOException;
64  
65  /**
66   * A Java class parser to make a {@link ClassVisitor} visit an existing class.
67   * This class parses a byte array conforming to the Java class file format and
68   * calls the appropriate visit methods of a given class visitor for each field,
69   * method and bytecode instruction encountered.
70   *
71   * @author Eric Bruneton
72   * @author Eugene Kuleshov
73   */
74  public class ClassReader {
75  
76      /**
77       * True to enable signatures support.
78       */
79      static final boolean SIGNATURES = true;
80  
81      /**
82       * True to enable annotations support.
83       */
84      static final boolean ANNOTATIONS = true;
85  
86      /**
87       * True to enable stack map frames support.
88       */
89      static final boolean FRAMES = true;
90  
91      /**
92       * True to enable bytecode writing support.
93       */
94      static final boolean WRITER = true;
95  
96      /**
97       * True to enable JSR_W and GOTO_W support.
98       */
99      static final boolean RESIZE = true;
100 
101     /**
102      * Flag to skip method code. If this class is set <code>CODE</code>
103      * attribute won't be visited. This can be used, for example, to retrieve
104      * annotations for methods and method parameters.
105      */
106     public static final int SKIP_CODE = 1;
107 
108     /**
109      * Flag to skip the debug information in the class. If this flag is set the
110      * debug information of the class is not visited, i.e. the
111      * {@link MethodVisitor#visitLocalVariable visitLocalVariable} and
112      * {@link MethodVisitor#visitLineNumber visitLineNumber} methods will not be
113      * called.
114      */
115     public static final int SKIP_DEBUG = 2;
116 
117     /**
118      * Flag to skip the stack map frames in the class. If this flag is set the
119      * stack map frames of the class is not visited, i.e. the
120      * {@link MethodVisitor#visitFrame visitFrame} method will not be called.
121      * This flag is useful when the {@link ClassWriter#COMPUTE_FRAMES} option is
122      * used: it avoids visiting frames that will be ignored and recomputed from
123      * scratch in the class writer.
124      */
125     public static final int SKIP_FRAMES = 4;
126 
127     /**
128      * Flag to expand the stack map frames. By default stack map frames are
129      * visited in their original format (i.e. "expanded" for classes whose
130      * version is less than V1_6, and "compressed" for the other classes). If
131      * this flag is set, stack map frames are always visited in expanded format
132      * (this option adds a decompression/recompression step in ClassReader and
133      * ClassWriter which degrades performances quite a lot).
134      */
135     public static final int EXPAND_FRAMES = 8;
136 
137     /**
138      * The class to be parsed. <i>The content of this array must not be
139      * modified. This field is intended for {@link Attribute} sub classes, and
140      * is normally not needed by class generators or adapters.</i>
141      */
142     public final byte[] b;
143 
144     /**
145      * The start index of each constant pool item in {@link #b b}, plus one.
146      * The one byte offset skips the constant pool item tag that indicates its
147      * type.
148      */
149     private final int[] items;
150 
151     /**
152      * The String objects corresponding to the CONSTANT_Utf8 items. This cache
153      * avoids multiple parsing of a given CONSTANT_Utf8 constant pool item,
154      * which GREATLY improves performances (by a factor 2 to 3). This caching
155      * strategy could be extended to all constant pool items, but its benefit
156      * would not be so great for these items (because they are much less
157      * expensive to parse than CONSTANT_Utf8 items).
158      */
159     private final String[] strings;
160 
161     /**
162      * Maximum length of the strings contained in the constant pool of the
163      * class.
164      */
165     private final int maxStringLength;
166 
167     /**
168      * Start index of the class header information (access, name...) in
169      * {@link #b b}.
170      */
171     public final int header;
172 
173     // ------------------------------------------------------------------------
174     // Constructors
175     // ------------------------------------------------------------------------
176 
177     /**
178      * Constructs a new {@link ClassReader} object.
179      *
180      * @param b the bytecode of the class to be read.
181      */
182     public ClassReader(final byte[] b) {
183         this(b, 0, b.length);
184     }
185 
186     /**
187      * Constructs a new {@link ClassReader} object.
188      *
189      * @param b the bytecode of the class to be read.
190      * @param off the start offset of the class data.
191      * @param len the length of the class data.
192      */
193     public ClassReader(final byte[] b, final int off, final int len) {
194         this.b = b;
195         // parses the constant pool
196         items = new int[readUnsignedShort(off + 8)];
197         int n = items.length;
198         strings = new String[n];
199         int max = 0;
200         int index = off + 10;
201         for (int i = 1; i < n; ++i) {
202             items[i] = index + 1;
203             int size;
204             switch (b[index]) {
205                 case ClassWriter.FIELD:
206                 case ClassWriter.METH:
207                 case ClassWriter.IMETH:
208                 case ClassWriter.INT:
209                 case ClassWriter.FLOAT:
210                 case ClassWriter.NAME_TYPE:
211                     size = 5;
212                     break;
213                 case ClassWriter.LONG:
214                 case ClassWriter.DOUBLE:
215                     size = 9;
216                     ++i;
217                     break;
218                 case ClassWriter.UTF8:
219                     size = 3 + readUnsignedShort(index + 1);
220                     if (size > max) {
221                         max = size;
222                     }
223                     break;
224                 // case ClassWriter.CLASS:
225                 // case ClassWriter.STR:
226                 default:
227                     size = 3;
228                     break;
229             }
230             index += size;
231         }
232         maxStringLength = max;
233         // the class header information starts just after the constant pool
234         header = index;
235     }
236 
237     /**
238      * Returns the class's access flags (see {@link Opcodes}). This value may
239      * not reflect Deprecated and Synthetic flags when bytecode is before 1.5
240      * and those flags are represented by attributes.
241      *
242      * @return the class access flags
243      *
244      * @see ClassVisitor#visit(int, int, String, String, String, String[])
245      */
246     public int getAccess() {
247         return readUnsignedShort(header);
248     }
249 
250     /**
251      * Returns the internal name of the class (see
252      * {@link Type#getInternalName() getInternalName}).
253      *
254      * @return the internal class name
255      *
256      * @see ClassVisitor#visit(int, int, String, String, String, String[])
257      */
258     public String getClassName() {
259         return readClass(header + 2, new char[maxStringLength]);
260     }
261 
262     /**
263      * Returns the internal of name of the super class (see
264      * {@link Type#getInternalName() getInternalName}). For interfaces, the
265      * super class is {@link Object}.
266      *
267      * @return the internal name of super class, or <tt>null</tt> for
268      *         {@link Object} class.
269      *
270      * @see ClassVisitor#visit(int, int, String, String, String, String[])
271      */
272     public String getSuperName() {
273         int n = items[readUnsignedShort(header + 4)];
274         return n == 0 ? null : readUTF8(n, new char[maxStringLength]);
275     }
276 
277     /**
278      * Returns the internal names of the class's interfaces (see
279      * {@link Type#getInternalName() getInternalName}).
280      *
281      * @return the array of internal names for all implemented interfaces or
282      *         <tt>null</tt>.
283      *
284      * @see ClassVisitor#visit(int, int, String, String, String, String[])
285      */
286     public String[] getInterfaces() {
287         int index = header + 6;
288         int n = readUnsignedShort(index);
289         String[] interfaces = new String[n];
290         if (n > 0) {
291             char[] buf = new char[maxStringLength];
292             for (int i = 0; i < n; ++i) {
293                 index += 2;
294                 interfaces[i] = readClass(index, buf);
295             }
296         }
297         return interfaces;
298     }
299 
300     /**
301      * Copies the constant pool data into the given {@link ClassWriter}. Should
302      * be called before the {@link #accept(ClassVisitor,int)} method.
303      *
304      * @param classWriter the {@link ClassWriter} to copy constant pool into.
305      */
306     void copyPool(final ClassWriter classWriter) {
307         char[] buf = new char[maxStringLength];
308         int ll = items.length;
309         Item[] items2 = new Item[ll];
310         for (int i = 1; i < ll; i++) {
311             int index = items[i];
312             int tag = b[index - 1];
313             Item item = new Item(i);
314             int nameType;
315             switch (tag) {
316                 case ClassWriter.FIELD:
317                 case ClassWriter.METH:
318                 case ClassWriter.IMETH:
319                     nameType = items[readUnsignedShort(index + 2)];
320                     item.set(tag,
321                             readClass(index, buf),
322                             readUTF8(nameType, buf),
323                             readUTF8(nameType + 2, buf));
324                     break;
325 
326                 case ClassWriter.INT:
327                     item.set(readInt(index));
328                     break;
329 
330                 case ClassWriter.FLOAT:
331                     item.set(Float.intBitsToFloat(readInt(index)));
332                     break;
333 
334                 case ClassWriter.NAME_TYPE:
335                     item.set(tag,
336                             readUTF8(index, buf),
337                             readUTF8(index + 2, buf),
338                             null);
339                     break;
340 
341                 case ClassWriter.LONG:
342                     item.set(readLong(index));
343                     ++i;
344                     break;
345 
346                 case ClassWriter.DOUBLE:
347                     item.set(Double.longBitsToDouble(readLong(index)));
348                     ++i;
349                     break;
350 
351                 case ClassWriter.UTF8: {
352                     String s = strings[i];
353                     if (s == null) {
354                         index = items[i];
355                         s = strings[i] = readUTF(index + 2,
356                                 readUnsignedShort(index),
357                                 buf);
358                     }
359                     item.set(tag, s, null, null);
360                 }
361                     break;
362 
363                 // case ClassWriter.STR:
364                 // case ClassWriter.CLASS:
365                 default:
366                     item.set(tag, readUTF8(index, buf), null, null);
367                     break;
368             }
369 
370             int index2 = item.hashCode % items2.length;
371             item.next = items2[index2];
372             items2[index2] = item;
373         }
374 
375         int off = items[1] - 1;
376         classWriter.pool.putByteArray(b, off, header - off);
377         classWriter.items = items2;
378         classWriter.threshold = (int) (0.75d * ll);
379         classWriter.index = ll;
380     }
381 
382     /**
383      * Constructs a new {@link ClassReader} object.
384      *
385      * @param is an input stream from which to read the class.
386      * @throws IOException if a problem occurs during reading.
387      */
388     public ClassReader(final InputStream is) throws IOException {
389         this(readClass(is));
390     }
391 
392     /**
393      * Constructs a new {@link ClassReader} object.
394      *
395      * @param name the fully qualified name of the class to be read.
396      * @throws IOException if an exception occurs during reading.
397      */
398     public ClassReader(final String name) throws IOException {
399         this(ClassLoader.getSystemResourceAsStream(name.replace('.', '/')
400                 + ".class"));
401     }
402 
403     /**
404      * Reads the bytecode of a class.
405      *
406      * @param is an input stream from which to read the class.
407      * @return the bytecode read from the given input stream.
408      * @throws IOException if a problem occurs during reading.
409      */
410     private static byte[] readClass(final InputStream is) throws IOException {
411         if (is == null) {
412             throw new IOException("Class not found");
413         }
414         byte[] b = new byte[is.available()];
415         int len = 0;
416         while (true) {
417             int n = is.read(b, len, b.length - len);
418             if (n == -1) {
419                 if (len < b.length) {
420                     byte[] c = new byte[len];
421                     System.arraycopy(b, 0, c, 0, len);
422                     b = c;
423                 }
424                 return b;
425             }
426             len += n;
427             if (len == b.length) {
428                 byte[] c = new byte[b.length + 1000];
429                 System.arraycopy(b, 0, c, 0, len);
430                 b = c;
431             }
432         }
433     }
434 
435     // ------------------------------------------------------------------------
436     // Public methods
437     // ------------------------------------------------------------------------
438 
439     /**
440      * Makes the given visitor visit the Java class of this {@link ClassReader}.
441      * This class is the one specified in the constructor (see
442      * {@link #ClassReader(byte[]) ClassReader}).
443      *
444      * @param classVisitor the visitor that must visit this class.
445      * @param flags option flags that can be used to modify the default behavior
446      *        of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES},
447      *        {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
448      */
449     public void accept(final ClassVisitor classVisitor, final int flags) {
450         accept(classVisitor, new Attribute[0], flags);
451     }
452 
453     /**
454      * Makes the given visitor visit the Java class of this {@link ClassReader}.
455      * This class is the one specified in the constructor (see
456      * {@link #ClassReader(byte[]) ClassReader}).
457      *
458      * @param classVisitor the visitor that must visit this class.
459      * @param attrs prototypes of the attributes that must be parsed during the
460      *        visit of the class. Any attribute whose type is not equal to the
461      *        type of one the prototypes will not be parsed: its byte array
462      *        value will be passed unchanged to the ClassWriter. <i>This may
463      *        corrupt it if this value contains references to the constant pool,
464      *        or has syntactic or semantic links with a class element that has
465      *        been transformed by a class adapter between the reader and the
466      *        writer</i>.
467      * @param flags option flags that can be used to modify the default behavior
468      *        of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES},
469      *        {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
470      */
471     public void accept(
472         final ClassVisitor classVisitor,
473         final Attribute[] attrs,
474         final int flags)
475     {
476         byte[] b = this.b; // the bytecode array
477         char[] c = new char[maxStringLength]; // buffer used to read strings
478         int i, j, k; // loop variables
479         int u, v, w; // indexes in b
480         Attribute attr;
481 
482         int access;
483         String name;
484         String desc;
485         String attrName;
486         String signature;
487         int anns = 0;
488         int ianns = 0;
489         Attribute cattrs = null;
490 
491         // visits the header
492         u = header;
493         access = readUnsignedShort(u);
494         name = readClass(u + 2, c);
495         v = items[readUnsignedShort(u + 4)];
496         String superClassName = v == 0 ? null : readUTF8(v, c);
497         String[] implementedItfs = new String[readUnsignedShort(u + 6)];
498         w = 0;
499         u += 8;
500         for (i = 0; i < implementedItfs.length; ++i) {
501             implementedItfs[i] = readClass(u, c);
502             u += 2;
503         }
504 
505         boolean skipCode = (flags & SKIP_CODE) != 0;
506         boolean skipDebug = (flags & SKIP_DEBUG) != 0;
507         boolean unzip = (flags & EXPAND_FRAMES) != 0;
508 
509         // skips fields and methods
510         v = u;
511         i = readUnsignedShort(v);
512         v += 2;
513         for (; i > 0; --i) {
514             j = readUnsignedShort(v + 6);
515             v += 8;
516             for (; j > 0; --j) {
517                 v += 6 + readInt(v + 2);
518             }
519         }
520         i = readUnsignedShort(v);
521         v += 2;
522         for (; i > 0; --i) {
523             j = readUnsignedShort(v + 6);
524             v += 8;
525             for (; j > 0; --j) {
526                 v += 6 + readInt(v + 2);
527             }
528         }
529         // reads the class's attributes
530         signature = null;
531         String sourceFile = null;
532         String sourceDebug = null;
533         String enclosingOwner = null;
534         String enclosingName = null;
535         String enclosingDesc = null;
536 
537         i = readUnsignedShort(v);
538         v += 2;
539         for (; i > 0; --i) {
540             attrName = readUTF8(v, c);
541             // tests are sorted in decreasing frequency order
542             // (based on frequencies observed on typical classes)
543             if ("SourceFile".equals(attrName)) {
544                 sourceFile = readUTF8(v + 6, c);
545             } else if ("InnerClasses".equals(attrName)) {
546                 w = v + 6;
547             } else if ("EnclosingMethod".equals(attrName)) {
548                 enclosingOwner = readClass(v + 6, c);
549                 int item = readUnsignedShort(v + 8);
550                 if (item != 0) {
551                     enclosingName = readUTF8(items[item], c);
552                     enclosingDesc = readUTF8(items[item] + 2, c);
553                 }
554             } else if (SIGNATURES && "Signature".equals(attrName)) {
555                 signature = readUTF8(v + 6, c);
556             } else if (ANNOTATIONS && "RuntimeVisibleAnnotations".equals(attrName)) {
557                 anns = v + 6;
558             } else if ("Deprecated".equals(attrName)) {
559                 access |= Opcodes.ACC_DEPRECATED;
560             } else if ("Synthetic".equals(attrName)) {
561                 access |= Opcodes.ACC_SYNTHETIC;
562             } else if ("SourceDebugExtension".equals(attrName)) {
563                 int len = readInt(v + 2);
564                 sourceDebug = readUTF(v + 6, len, new char[len]);
565             } else if (ANNOTATIONS && "RuntimeInvisibleAnnotations".equals(attrName)) {
566                 ianns = v + 6;
567             } else {
568                 attr = readAttribute(attrs,
569                         attrName,
570                         v + 6,
571                         readInt(v + 2),
572                         c,
573                         -1,
574                         null);
575                 if (attr != null) {
576                     attr.next = cattrs;
577                     cattrs = attr;
578                 }
579             }
580             v += 6 + readInt(v + 2);
581         }
582         // calls the visit method
583         classVisitor.visit(readInt(4),
584                 access,
585                 name,
586                 signature,
587                 superClassName,
588                 implementedItfs);
589 
590         // calls the visitSource method
591         if (!skipDebug && (sourceFile != null || sourceDebug != null)) {
592             classVisitor.visitSource(sourceFile, sourceDebug);
593         }
594 
595         // calls the visitOuterClass method
596         if (enclosingOwner != null) {
597             classVisitor.visitOuterClass(enclosingOwner,
598                     enclosingName,
599                     enclosingDesc);
600         }
601 
602         // visits the class annotations
603         if (ANNOTATIONS) {
604             for (i = 1; i >= 0; --i) {
605                 v = i == 0 ? ianns : anns;
606                 if (v != 0) {
607                     j = readUnsignedShort(v);
608                     v += 2;
609                     for (; j > 0; --j) {
610                         v = readAnnotationValues(v + 2,
611                                 c,
612                                 true,
613                                 classVisitor.visitAnnotation(readUTF8(v, c), i != 0));
614                     }
615                 }
616             }
617         }
618 
619         // visits the class attributes
620         while (cattrs != null) {
621             attr = cattrs.next;
622             cattrs.next = null;
623             classVisitor.visitAttribute(cattrs);
624             cattrs = attr;
625         }
626 
627         // calls the visitInnerClass method
628         if (w != 0) {
629             i = readUnsignedShort(w);
630             w += 2;
631             for (; i > 0; --i) {
632                 classVisitor.visitInnerClass(readUnsignedShort(w) == 0
633                         ? null
634                         : readClass(w, c), readUnsignedShort(w + 2) == 0
635                         ? null
636                         : readClass(w + 2, c), readUnsignedShort(w + 4) == 0
637                         ? null
638                         : readUTF8(w + 4, c), readUnsignedShort(w + 6));
639                 w += 8;
640             }
641         }
642 
643         // visits the fields
644         i = readUnsignedShort(u);
645         u += 2;
646         for (; i > 0; --i) {
647             access = readUnsignedShort(u);
648             name = readUTF8(u + 2, c);
649             desc = readUTF8(u + 4, c);
650             // visits the field's attributes and looks for a ConstantValue
651             // attribute
652             int fieldValueItem = 0;
653             signature = null;
654             anns = 0;
655             ianns = 0;
656             cattrs = null;
657 
658             j = readUnsignedShort(u + 6);
659             u += 8;
660             for (; j > 0; --j) {
661                 attrName = readUTF8(u, c);
662                 // tests are sorted in decreasing frequency order
663                 // (based on frequencies observed on typical classes)
664                 if ("ConstantValue".equals(attrName)) {
665                     fieldValueItem = readUnsignedShort(u + 6);
666                 } else if (SIGNATURES && "Signature".equals(attrName)) {
667                     signature = readUTF8(u + 6, c);
668                 } else if ("Deprecated".equals(attrName)) {
669                     access |= Opcodes.ACC_DEPRECATED;
670                 } else if ("Synthetic".equals(attrName)) {
671                     access |= Opcodes.ACC_SYNTHETIC;
672                 } else if (ANNOTATIONS && "RuntimeVisibleAnnotations".equals(attrName)) {
673                     anns = u + 6;
674                 } else if (ANNOTATIONS && "RuntimeInvisibleAnnotations".equals(attrName)) {
675                     ianns = u + 6;
676                 } else {
677                     attr = readAttribute(attrs,
678                             attrName,
679                             u + 6,
680                             readInt(u + 2),
681                             c,
682                             -1,
683                             null);
684                     if (attr != null) {
685                         attr.next = cattrs;
686                         cattrs = attr;
687                     }
688                 }
689                 u += 6 + readInt(u + 2);
690             }
691             // visits the field
692             FieldVisitor fv = classVisitor.visitField(access,
693                     name,
694                     desc,
695                     signature,
696                     fieldValueItem == 0 ? null : readConst(fieldValueItem, c));
697             // visits the field annotations and attributes
698             if (fv != null) {
699                 if (ANNOTATIONS) {
700                     for (j = 1; j >= 0; --j) {
701                         v = j == 0 ? ianns : anns;
702                         if (v != 0) {
703                             k = readUnsignedShort(v);
704                             v += 2;
705                             for (; k > 0; --k) {
706                                 v = readAnnotationValues(v + 2,
707                                         c,
708                                         true,
709                                         fv.visitAnnotation(readUTF8(v, c), j != 0));
710                             }
711                         }
712                     }
713                 }
714                 while (cattrs != null) {
715                     attr = cattrs.next;
716                     cattrs.next = null;
717                     fv.visitAttribute(cattrs);
718                     cattrs = attr;
719                 }
720                 fv.visitEnd();
721             }
722         }
723 
724         // visits the methods
725         i = readUnsignedShort(u);
726         u += 2;
727         for (; i > 0; --i) {
728             int u0 = u + 6;
729             access = readUnsignedShort(u);
730             name = readUTF8(u + 2, c);
731             desc = readUTF8(u + 4, c);
732             signature = null;
733             anns = 0;
734             ianns = 0;
735             int dann = 0;
736             int mpanns = 0;
737             int impanns = 0;
738             cattrs = null;
739             v = 0;
740             w = 0;
741 
742             // looks for Code and Exceptions attributes
743             j = readUnsignedShort(u + 6);
744             u += 8;
745             for (; j > 0; --j) {
746                 attrName = readUTF8(u, c);
747                 int attrSize = readInt(u + 2);
748                 u += 6;
749                 // tests are sorted in decreasing frequency order
750                 // (based on frequencies observed on typical classes)
751                 if ("Code".equals(attrName)) {
752                     if (!skipCode) {
753                         v = u;
754                     }
755                 } else if ("Exceptions".equals(attrName)) {
756                     w = u;
757                 } else if (SIGNATURES && "Signature".equals(attrName)) {
758                     signature = readUTF8(u, c);
759                 } else if ("Deprecated".equals(attrName)) {
760                     access |= Opcodes.ACC_DEPRECATED;
761                 } else if (ANNOTATIONS && "RuntimeVisibleAnnotations".equals(attrName)) {
762                     anns = u;
763                 } else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) {
764                     dann = u;
765                 } else if ("Synthetic".equals(attrName)) {
766                     access |= Opcodes.ACC_SYNTHETIC;
767                 } else if (ANNOTATIONS && "RuntimeInvisibleAnnotations".equals(attrName)) {
768                     ianns = u;
769                 } else if (ANNOTATIONS && "RuntimeVisibleParameterAnnotations".equals(attrName))
770                 {
771                     mpanns = u;
772                 } else if (ANNOTATIONS && "RuntimeInvisibleParameterAnnotations".equals(attrName))
773                 {
774                     impanns = u;
775                 } else {
776                     attr = readAttribute(attrs,
777                             attrName,
778                             u,
779                             attrSize,
780                             c,
781                             -1,
782                             null);
783                     if (attr != null) {
784                         attr.next = cattrs;
785                         cattrs = attr;
786                     }
787                 }
788                 u += attrSize;
789             }
790             // reads declared exceptions
791             String[] exceptions;
792             if (w == 0) {
793                 exceptions = null;
794             } else {
795                 exceptions = new String[readUnsignedShort(w)];
796                 w += 2;
797                 for (j = 0; j < exceptions.length; ++j) {
798                     exceptions[j] = readClass(w, c);
799                     w += 2;
800                 }
801             }
802 
803             // visits the method's code, if any
804             MethodVisitor mv = classVisitor.visitMethod(access,
805                     name,
806                     desc,
807                     signature,
808                     exceptions);
809 
810             if (mv != null) {
811                 /*
812                  * if the returned MethodVisitor is in fact a MethodWriter, it
813                  * means there is no method adapter between the reader and the
814                  * writer. If, in addition, the writer's constant pool was
815                  * copied from this reader (mw.cw.cr == this), and the signature
816                  * and exceptions of the method have not been changed, then it
817                  * is possible to skip all visit events and just copy the
818                  * original code of the method to the writer (the access, name
819                  * and descriptor can have been changed, this is not important
820                  * since they are not copied as is from the reader).
821                  */
822                 if (WRITER && mv instanceof MethodWriter) {
823                     MethodWriter mw = (MethodWriter) mv;
824                     if (mw.cw.cr == this) {
825                         if (signature == mw.signature) {
826                             boolean sameExceptions = false;
827                             if (exceptions == null) {
828                                 sameExceptions = mw.exceptionCount == 0;
829                             } else {
830                                 if (exceptions.length == mw.exceptionCount) {
831                                     sameExceptions = true;
832                                     for (j = exceptions.length - 1; j >= 0; --j)
833                                     {
834                                         w -= 2;
835                                         if (mw.exceptions[j] != readUnsignedShort(w))
836                                         {
837                                             sameExceptions = false;
838                                             break;
839                                         }
840                                     }
841                                 }
842                             }
843                             if (sameExceptions) {
844                                 /*
845                                  * we do not copy directly the code into
846                                  * MethodWriter to save a byte array copy
847                                  * operation. The real copy will be done in
848                                  * ClassWriter.toByteArray().
849                                  */
850                                 mw.classReaderOffset = u0;
851                                 mw.classReaderLength = u - u0;
852                                 continue;
853                             }
854                         }
855                     }
856                 }
857 
858                 if (ANNOTATIONS && dann != 0) {
859                     AnnotationVisitor dv = mv.visitAnnotationDefault();
860                     readAnnotationValue(dann, c, null, dv);
861                     if (dv != null) {
862                         dv.visitEnd();
863                     }
864                 }
865                 if (ANNOTATIONS) {
866                     for (j = 1; j >= 0; --j) {
867                         w = j == 0 ? ianns : anns;
868                         if (w != 0) {
869                             k = readUnsignedShort(w);
870                             w += 2;
871                             for (; k > 0; --k) {
872                                 w = readAnnotationValues(w + 2,
873                                         c,
874                                         true,
875                                         mv.visitAnnotation(readUTF8(w, c), j != 0));
876                             }
877                         }
878                     }
879                 }
880                 if (ANNOTATIONS && mpanns != 0) {
881                     readParameterAnnotations(mpanns, desc, c, true, mv);
882                 }
883                 if (ANNOTATIONS && impanns != 0) {
884                     readParameterAnnotations(impanns, desc, c, false, mv);
885                 }
886                 while (cattrs != null) {
887                     attr = cattrs.next;
888                     cattrs.next = null;
889                     mv.visitAttribute(cattrs);
890                     cattrs = attr;
891                 }
892             }
893 
894             if (mv != null && v != 0) {
895                 int maxStack = readUnsignedShort(v);
896                 int maxLocals = readUnsignedShort(v + 2);
897                 int codeLength = readInt(v + 4);
898                 v += 8;
899 
900                 int codeStart = v;
901                 int codeEnd = v + codeLength;
902 
903                 mv.visitCode();
904 
905                 // 1st phase: finds the labels
906                 int label;
907                 Label[] labels = new Label[codeLength + 2];
908                 readLabel(codeLength + 1, labels);
909                 while (v < codeEnd) {
910                     w = v - codeStart;
911                     int opcode = b[v] & 0xFF;
912                     switch (ClassWriter.TYPE[opcode]) {
913                         case ClassWriter.NOARG_INSN:
914                         case ClassWriter.IMPLVAR_INSN:
915                             v += 1;
916                             break;
917                         case ClassWriter.LABEL_INSN:
918                             readLabel(w + readShort(v + 1), labels);
919                             v += 3;
920                             break;
921                         case ClassWriter.LABELW_INSN:
922                             readLabel(w + readInt(v + 1), labels);
923                             v += 5;
924                             break;
925                         case ClassWriter.WIDE_INSN:
926                             opcode = b[v + 1] & 0xFF;
927                             if (opcode == Opcodes.IINC) {
928                                 v += 6;
929                             } else {
930                                 v += 4;
931                             }
932                             break;
933                         case ClassWriter.TABL_INSN:
934                             // skips 0 to 3 padding bytes*
935                             v = v + 4 - (w & 3);
936                             // reads instruction
937                             readLabel(w + readInt(v), labels);
938                             j = readInt(v + 8) - readInt(v + 4) + 1;
939                             v += 12;
940                             for (; j > 0; --j) {
941                                 readLabel(w + readInt(v), labels);
942                                 v += 4;
943                             }
944                             break;
945                         case ClassWriter.LOOK_INSN:
946                             // skips 0 to 3 padding bytes*
947                             v = v + 4 - (w & 3);
948                             // reads instruction
949                             readLabel(w + readInt(v), labels);
950                             j = readInt(v + 4);
951                             v += 8;
952                             for (; j > 0; --j) {
953                                 readLabel(w + readInt(v + 4), labels);
954                                 v += 8;
955                             }
956                             break;
957                         case ClassWriter.VAR_INSN:
958                         case ClassWriter.SBYTE_INSN:
959                         case ClassWriter.LDC_INSN:
960                             v += 2;
961                             break;
962                         case ClassWriter.SHORT_INSN:
963                         case ClassWriter.LDCW_INSN:
964                         case ClassWriter.FIELDORMETH_INSN:
965                         case ClassWriter.TYPE_INSN:
966                         case ClassWriter.IINC_INSN:
967                             v += 3;
968                             break;
969                         case ClassWriter.ITFMETH_INSN:
970                             v += 5;
971                             break;
972                         // case MANA_INSN:
973                         default:
974                             v += 4;
975                             break;
976                     }
977                 }
978                 // parses the try catch entries
979                 j = readUnsignedShort(v);
980                 v += 2;
981                 for (; j > 0; --j) {
982                     Label start = readLabel(readUnsignedShort(v), labels);
983                     Label end = readLabel(readUnsignedShort(v + 2), labels);
984                     Label handler = readLabel(readUnsignedShort(v + 4), labels);
985                     int type = readUnsignedShort(v + 6);
986                     if (type == 0) {
987                         mv.visitTryCatchBlock(start, end, handler, null);
988                     } else {
989                         mv.visitTryCatchBlock(start,
990                                 end,
991                                 handler,
992                                 readUTF8(items[type], c));
993                     }
994                     v += 8;
995                 }
996                 // parses the local variable, line number tables, and code
997                 // attributes
998                 int varTable = 0;
999                 int varTypeTable = 0;
1000                 int stackMap = 0;
1001                 int frameCount = 0;
1002                 int frameMode = 0;
1003                 int frameOffset = 0;
1004                 int frameLocalCount = 0;
1005                 int frameLocalDiff = 0;
1006                 int frameStackCount = 0;
1007                 Object[] frameLocal = null;
1008                 Object[] frameStack = null;
1009                 boolean zip = true;
1010                 cattrs = null;
1011                 j = readUnsignedShort(v);
1012                 v += 2;
1013                 for (; j > 0; --j) {
1014                     attrName = readUTF8(v, c);
1015                     if ("LocalVariableTable".equals(attrName)) {
1016                         if (!skipDebug) {
1017                             varTable = v + 6;
1018                             k = readUnsignedShort(v + 6);
1019                             w = v + 8;
1020                             for (; k > 0; --k) {
1021                                 label = readUnsignedShort(w);
1022                                 if (labels[label] == null) {
1023                                     readLabel(label, labels).status |= Label.DEBUG;
1024                                 }
1025                                 label += readUnsignedShort(w + 2);
1026                                 if (labels[label] == null) {
1027                                     readLabel(label, labels).status |= Label.DEBUG;
1028                                 }
1029                                 w += 10;
1030                             }
1031                         }
1032                     } else if ("LocalVariableTypeTable".equals(attrName)) {
1033                         varTypeTable = v + 6;
1034                     } else if ("LineNumberTable".equals(attrName)) {
1035                         if (!skipDebug) {
1036                             k = readUnsignedShort(v + 6);
1037                             w = v + 8;
1038                             for (; k > 0; --k) {
1039                                 label = readUnsignedShort(w);
1040                                 if (labels[label] == null) {
1041                                     readLabel(label, labels).status |= Label.DEBUG;
1042                                 }
1043                                 labels[label].line = readUnsignedShort(w + 2);
1044                                 w += 4;
1045                             }
1046                         }
1047                     } else if (FRAMES && "StackMapTable".equals(attrName)) {
1048                         if ((flags & SKIP_FRAMES) == 0) {
1049                             stackMap = v + 8;
1050                             frameCount = readUnsignedShort(v + 6);
1051                         }
1052                         /*
1053                          * here we do not extract the labels corresponding to
1054                          * the attribute content. This would require a full
1055                          * parsing of the attribute, which would need to be
1056                          * repeated in the second phase (see below). Instead the
1057                          * content of the attribute is read one frame at a time
1058                          * (i.e. after a frame has been visited, the next frame
1059                          * is read), and the labels it contains are also
1060                          * extracted one frame at a time. Thanks to the ordering
1061                          * of frames, having only a "one frame lookahead" is not
1062                          * a problem, i.e. it is not possible to see an offset
1063                          * smaller than the offset of the current insn and for
1064                          * which no Label exist.
1065                          */
1066                         // TODO true for frame offsets,
1067                         // but for UNINITIALIZED type offsets?
1068                     } else if (FRAMES && "StackMap".equals(attrName)) {
1069                         if ((flags & SKIP_FRAMES) == 0) {
1070                             stackMap = v + 8;
1071                             frameCount = readUnsignedShort(v + 6);
1072                             zip = false;
1073                         }
1074                         /*
1075                          * IMPORTANT! here we assume that the frames are
1076                          * ordered, as in the StackMapTable attribute, although
1077                          * this is not guaranteed by the attribute format.
1078                          */
1079                     } else {
1080                         for (k = 0; k < attrs.length; ++k) {
1081                             if (attrs[k].type.equals(attrName)) {
1082                                 attr = attrs[k].read(this,
1083                                         v + 6,
1084                                         readInt(v + 2),
1085                                         c,
1086                                         codeStart - 8,
1087                                         labels);
1088                                 if (attr != null) {
1089                                     attr.next = cattrs;
1090                                     cattrs = attr;
1091                                 }
1092                             }
1093                         }
1094                     }
1095                     v += 6 + readInt(v + 2);
1096                 }
1097 
1098                 // 2nd phase: visits each instruction
1099                 if (FRAMES && stackMap != 0) {
1100                     // creates the very first (implicit) frame from the method
1101                     // descriptor
1102                     frameLocal = new Object[maxLocals];
1103                     frameStack = new Object[maxStack];
1104                     if (unzip) {
1105                         int local = 0;
1106                         if ((access & Opcodes.ACC_STATIC) == 0) {
1107                             if ("<init>".equals(name)) {
1108                                 frameLocal[local++] = Opcodes.UNINITIALIZED_THIS;
1109                             } else {
1110                                 frameLocal[local++] = readClass(header + 2, c);
1111                             }
1112                         }
1113                         j = 1;
1114                         loop: while (true) {
1115                             k = j;
1116                             switch (desc.charAt(j++)) {
1117                                 case 'Z':
1118                                 case 'C':
1119                                 case 'B':
1120                                 case 'S':
1121                                 case 'I':
1122                                     frameLocal[local++] = Opcodes.INTEGER;
1123                                     break;
1124                                 case 'F':
1125                                     frameLocal[local++] = Opcodes.FLOAT;
1126                                     break;
1127                                 case 'J':
1128                                     frameLocal[local++] = Opcodes.LONG;
1129                                     break;
1130                                 case 'D':
1131                                     frameLocal[local++] = Opcodes.DOUBLE;
1132                                     break;
1133                                 case '[':
1134                                     while (desc.charAt(j) == '[') {
1135                                         ++j;
1136                                     }
1137                                     if (desc.charAt(j) == 'L') {
1138                                         ++j;
1139                                         while (desc.charAt(j) != ';') {
1140                                             ++j;
1141                                         }
1142                                     }
1143                                     frameLocal[local++] = desc.substring(k, ++j);
1144                                     break;
1145                                 case 'L':
1146                                     while (desc.charAt(j) != ';') {
1147                                         ++j;
1148                                     }
1149                                     frameLocal[local++] = desc.substring(k + 1,
1150                                             j++);
1151                                     break;
1152                                 default:
1153                                     break loop;
1154                             }
1155                         }
1156                         frameLocalCount = local;
1157                     }
1158                     /*
1159                      * for the first explicit frame the offset is not
1160                      * offset_delta + 1 but only offset_delta; setting the
1161                      * implicit frame offset to -1 allow the use of the
1162                      * "offset_delta + 1" rule in all cases
1163                      */
1164                     frameOffset = -1;
1165                 }
1166                 v = codeStart;
1167                 Label l;
1168                 while (v < codeEnd) {
1169                     w = v - codeStart;
1170 
1171                     l = labels[w];
1172                     if (l != null) {
1173                         mv.visitLabel(l);
1174                         if (!skipDebug && l.line > 0) {
1175                             mv.visitLineNumber(l.line, l);
1176                         }
1177                     }
1178 
1179                     while (FRAMES && frameLocal != null
1180                             && (frameOffset == w || frameOffset == -1))
1181                     {
1182                         // if there is a frame for this offset,
1183                         // makes the visitor visit it,
1184                         // and reads the next frame if there is one.
1185                         if (!zip || unzip) {
1186                             mv.visitFrame(Opcodes.F_NEW,
1187                                     frameLocalCount,
1188                                     frameLocal,
1189                                     frameStackCount,
1190                                     frameStack);
1191                         } else if (frameOffset != -1) {
1192                             mv.visitFrame(frameMode,
1193                                     frameLocalDiff,
1194                                     frameLocal,
1195                                     frameStackCount,
1196                                     frameStack);
1197                         }
1198 
1199                         if (frameCount > 0) {
1200                             int tag, delta, n;
1201                             if (zip) {
1202                                 tag = b[stackMap++] & 0xFF;
1203                             } else {
1204                                 tag = MethodWriter.FULL_FRAME;
1205                                 frameOffset = -1;
1206                             }
1207                             frameLocalDiff = 0;
1208                             if (tag < MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME)
1209                             {
1210                                 delta = tag;
1211                                 frameMode = Opcodes.F_SAME;
1212                                 frameStackCount = 0;
1213                             } else if (tag < MethodWriter.RESERVED) {
1214                                 delta = tag
1215                                         - MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME;
1216                                 stackMap = readFrameType(frameStack,
1217                                         0,
1218                                         stackMap,
1219                                         c,
1220                                         labels);
1221                                 frameMode = Opcodes.F_SAME1;
1222                                 frameStackCount = 1;
1223                             } else {
1224                                 delta = readUnsignedShort(stackMap);
1225                                 stackMap += 2;
1226                                 if (tag == MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
1227                                 {
1228                                     stackMap = readFrameType(frameStack,
1229                                             0,
1230                                             stackMap,
1231                                             c,
1232                                             labels);
1233                                     frameMode = Opcodes.F_SAME1;
1234                                     frameStackCount = 1;
1235                                 } else if (tag >= MethodWriter.CHOP_FRAME
1236                                         && tag < MethodWriter.SAME_FRAME_EXTENDED)
1237                                 {
1238                                     frameMode = Opcodes.F_CHOP;
1239                                     frameLocalDiff = MethodWriter.SAME_FRAME_EXTENDED
1240                                             - tag;
1241                                     frameLocalCount -= frameLocalDiff;
1242                                     frameStackCount = 0;
1243                                 } else if (tag == MethodWriter.SAME_FRAME_EXTENDED)
1244                                 {
1245                                     frameMode = Opcodes.F_SAME;
1246                                     frameStackCount = 0;
1247                                 } else if (tag < MethodWriter.FULL_FRAME) {
1248                                     j = unzip ? frameLocalCount : 0;
1249                                     for (k = tag
1250                                             - MethodWriter.SAME_FRAME_EXTENDED; k > 0; k--)
1251                                     {
1252                                         stackMap = readFrameType(frameLocal,
1253                                                 j++,
1254                                                 stackMap,
1255                                                 c,
1256                                                 labels);
1257                                     }
1258                                     frameMode = Opcodes.F_APPEND;
1259                                     frameLocalDiff = tag
1260                                             - MethodWriter.SAME_FRAME_EXTENDED;
1261                                     frameLocalCount += frameLocalDiff;
1262                                     frameStackCount = 0;
1263                                 } else { // if (tag == FULL_FRAME) {
1264                                     frameMode = Opcodes.F_FULL;
1265                                     n = frameLocalDiff = frameLocalCount = readUnsignedShort(stackMap);
1266                                     stackMap += 2;
1267                                     for (j = 0; n > 0; n--) {
1268                                         stackMap = readFrameType(frameLocal,
1269                                                 j++,
1270                                                 stackMap,
1271                                                 c,
1272                                                 labels);
1273                                     }
1274                                     n = frameStackCount = readUnsignedShort(stackMap);
1275                                     stackMap += 2;
1276                                     for (j = 0; n > 0; n--) {
1277                                         stackMap = readFrameType(frameStack,
1278                                                 j++,
1279                                                 stackMap,
1280                                                 c,
1281                                                 labels);
1282                                     }
1283                                 }
1284                             }
1285                             frameOffset += delta + 1;
1286                             readLabel(frameOffset, labels);
1287 
1288                             --frameCount;
1289                         } else {
1290                             frameLocal = null;
1291                         }
1292                     }
1293 
1294                     int opcode = b[v] & 0xFF;
1295                     switch (ClassWriter.TYPE[opcode]) {
1296                         case ClassWriter.NOARG_INSN:
1297                             mv.visitInsn(opcode);
1298                             v += 1;
1299                             break;
1300                         case ClassWriter.IMPLVAR_INSN:
1301                             if (opcode > Opcodes.ISTORE) {
1302                                 opcode -= 59; // ISTORE_0
1303                                 mv.visitVarInsn(Opcodes.ISTORE + (opcode >> 2),
1304                                         opcode & 0x3);
1305                             } else {
1306                                 opcode -= 26; // ILOAD_0
1307                                 mv.visitVarInsn(Opcodes.ILOAD + (opcode >> 2),
1308                                         opcode & 0x3);
1309                             }
1310                             v += 1;
1311                             break;
1312                         case ClassWriter.LABEL_INSN:
1313                             mv.visitJumpInsn(opcode, labels[w
1314                                     + readShort(v + 1)]);
1315                             v += 3;
1316                             break;
1317                         case ClassWriter.LABELW_INSN:
1318                             mv.visitJumpInsn(opcode - 33, labels[w
1319                                     + readInt(v + 1)]);
1320                             v += 5;
1321                             break;
1322                         case ClassWriter.WIDE_INSN:
1323                             opcode = b[v + 1] & 0xFF;
1324                             if (opcode == Opcodes.IINC) {
1325                                 mv.visitIincInsn(readUnsignedShort(v + 2),
1326                                         readShort(v + 4));
1327                                 v += 6;
1328                             } else {
1329                                 mv.visitVarInsn(opcode,
1330                                         readUnsignedShort(v + 2));
1331                                 v += 4;
1332                             }
1333                             break;
1334                         case ClassWriter.TABL_INSN:
1335                             // skips 0 to 3 padding bytes
1336                             v = v + 4 - (w & 3);
1337                             // reads instruction
1338                             label = w + readInt(v);
1339                             int min = readInt(v + 4);
1340                             int max = readInt(v + 8);
1341                             v += 12;
1342                             Label[] table = new Label[max - min + 1];
1343                             for (j = 0; j < table.length; ++j) {
1344                                 table[j] = labels[w + readInt(v)];
1345                                 v += 4;
1346                             }
1347                             mv.visitTableSwitchInsn(min,
1348                                     max,
1349                                     labels[label],
1350                                     table);
1351                             break;
1352                         case ClassWriter.LOOK_INSN:
1353                             // skips 0 to 3 padding bytes
1354                             v = v + 4 - (w & 3);
1355                             // reads instruction
1356                             label = w + readInt(v);
1357                             j = readInt(v + 4);
1358                             v += 8;
1359                             int[] keys = new int[j];
1360                             Label[] values = new Label[j];
1361                             for (j = 0; j < keys.length; ++j) {
1362                                 keys[j] = readInt(v);
1363                                 values[j] = labels[w + readInt(v + 4)];
1364                                 v += 8;
1365                             }
1366                             mv.visitLookupSwitchInsn(labels[label],
1367                                     keys,
1368                                     values);
1369                             break;
1370                         case ClassWriter.VAR_INSN:
1371                             mv.visitVarInsn(opcode, b[v + 1] & 0xFF);
1372                             v += 2;
1373                             break;
1374                         case ClassWriter.SBYTE_INSN:
1375                             mv.visitIntInsn(opcode, b[v + 1]);
1376                             v += 2;
1377                             break;
1378                         case ClassWriter.SHORT_INSN:
1379                             mv.visitIntInsn(opcode, readShort(v + 1));
1380                             v += 3;
1381                             break;
1382                         case ClassWriter.LDC_INSN:
1383                             mv.visitLdcInsn(readConst(b[v + 1] & 0xFF, c));
1384                             v += 2;
1385                             break;
1386                         case ClassWriter.LDCW_INSN:
1387                             mv.visitLdcInsn(readConst(readUnsignedShort(v + 1),
1388                                     c));
1389                             v += 3;
1390                             break;
1391                         case ClassWriter.FIELDORMETH_INSN:
1392                         case ClassWriter.ITFMETH_INSN:
1393                             int cpIndex = items[readUnsignedShort(v + 1)];
1394                             String iowner = readClass(cpIndex, c);
1395                             cpIndex = items[readUnsignedShort(cpIndex + 2)];
1396                             String iname = readUTF8(cpIndex, c);
1397                             String idesc = readUTF8(cpIndex + 2, c);
1398                             if (opcode < Opcodes.INVOKEVIRTUAL) {
1399                                 mv.visitFieldInsn(opcode, iowner, iname, idesc);
1400                             } else {
1401                                 mv.visitMethodInsn(opcode, iowner, iname, idesc);
1402                             }
1403                             if (opcode == Opcodes.INVOKEINTERFACE) {
1404                                 v += 5;
1405                             } else {
1406                                 v += 3;
1407                             }
1408                             break;
1409                         case ClassWriter.TYPE_INSN:
1410                             mv.visitTypeInsn(opcode, readClass(v + 1, c));
1411                             v += 3;
1412                             break;
1413                         case ClassWriter.IINC_INSN:
1414                             mv.visitIincInsn(b[v + 1] & 0xFF, b[v + 2]);
1415                             v += 3;
1416                             break;
1417                         // case MANA_INSN:
1418                         default:
1419                             mv.visitMultiANewArrayInsn(readClass(v + 1, c),
1420                                     b[v + 3] & 0xFF);
1421                             v += 4;
1422                             break;
1423                     }
1424                 }
1425                 l = labels[codeEnd - codeStart];
1426                 if (l != null) {
1427                     mv.visitLabel(l);
1428                 }
1429                 // visits the local variable tables
1430                 if (!skipDebug && varTable != 0) {
1431                     int[] typeTable = null;
1432                     if (varTypeTable != 0) {
1433                         k = readUnsignedShort(varTypeTable) * 3;
1434                         w = varTypeTable + 2;
1435                         typeTable = new int[k];
1436                         while (k > 0) {
1437                             typeTable[--k] = w + 6; // signature
1438                             typeTable[--k] = readUnsignedShort(w + 8); // index
1439                             typeTable[--k] = readUnsignedShort(w); // start
1440                             w += 10;
1441                         }
1442                     }
1443                     k = readUnsignedShort(varTable);
1444                     w = varTable + 2;
1445                     for (; k > 0; --k) {
1446                         int start = readUnsignedShort(w);
1447                         int length = readUnsignedShort(w + 2);
1448                         int index = readUnsignedShort(w + 8);
1449                         String vsignature = null;
1450                         if (typeTable != null) {
1451                             for (int a = 0; a < typeTable.length; a += 3) {
1452                                 if (typeTable[a] == start
1453                                         && typeTable[a + 1] == index)
1454                                 {
1455                                     vsignature = readUTF8(typeTable[a + 2], c);
1456                                     break;
1457                                 }
1458                             }
1459                         }
1460                         mv.visitLocalVariable(readUTF8(w + 4, c),
1461                                 readUTF8(w + 6, c),
1462                                 vsignature,
1463                                 labels[start],
1464                                 labels[start + length],
1465                                 index);
1466                         w += 10;
1467                     }
1468                 }
1469                 // visits the other attributes
1470                 while (cattrs != null) {
1471                     attr = cattrs.next;
1472                     cattrs.next = null;
1473                     mv.visitAttribute(cattrs);
1474                     cattrs = attr;
1475                 }
1476                 // visits the max stack and max locals values
1477                 mv.visitMaxs(maxStack, maxLocals);
1478             }
1479 
1480             if (mv != null) {
1481                 mv.visitEnd();
1482             }
1483         }
1484 
1485         // visits the end of the class
1486         classVisitor.visitEnd();
1487     }
1488 
1489     /**
1490      * Reads parameter annotations and makes the given visitor visit them.
1491      *
1492      * @param v start offset in {@link #b b} of the annotations to be read.
1493      * @param desc the method descriptor.
1494      * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
1495      *        {@link #readClass(int,char[]) readClass} or
1496      *        {@link #readConst readConst}.
1497      * @param visible <tt>true</tt> if the annotations to be read are visible
1498      *        at runtime.
1499      * @param mv the visitor that must visit the annotations.
1500      */
1501     private void readParameterAnnotations(
1502         int v,
1503         final String desc,
1504         final char[] buf,
1505         final boolean visible,
1506         final MethodVisitor mv)
1507     {
1508         int i;
1509         int n = b[v++] & 0xFF;
1510         // workaround for a bug in javac (javac compiler generates a parameter
1511         // annotation array whose size is equal to the number of parameters in
1512         // the Java source file, while it should generate an array whose size is
1513         // equal to the number of parameters in the method descriptor - which
1514         // includes the synthetic parameters added by the compiler). This work-
1515         // around supposes that the synthetic parameters are the first ones.
1516         int synthetics = Type.getArgumentTypes(desc).length - n;
1517         AnnotationVisitor av;
1518         for (i = 0; i < synthetics; ++i) {
1519             // virtual annotation to detect synthetic parameters in MethodWriter
1520             av = mv.visitParameterAnnotation(i, "Ljava/lang/Synthetic;", false);
1521             if (av != null) {
1522                 av.visitEnd();
1523             }
1524         }
1525         for (; i < n + synthetics; ++i) {
1526             int j = readUnsignedShort(v);
1527             v += 2;
1528             for (; j > 0; --j) {
1529                 av = mv.visitParameterAnnotation(i, readUTF8(v, buf), visible);
1530                 v = readAnnotationValues(v + 2, buf, true, av);
1531             }
1532         }
1533     }
1534 
1535     /**
1536      * Reads the values of an annotation and makes the given visitor visit them.
1537      *
1538      * @param v the start offset in {@link #b b} of the values to be read
1539      *        (including the unsigned short that gives the number of values).
1540      * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
1541      *        {@link #readClass(int,char[]) readClass} or
1542      *        {@link #readConst readConst}.
1543      * @param named if the annotation values are named or not.
1544      * @param av the visitor that must visit the values.
1545      * @return the end offset of the annotation values.
1546      */
1547     private int readAnnotationValues(
1548         int v,
1549         final char[] buf,
1550         final boolean named,
1551         final AnnotationVisitor av)
1552     {
1553         int i = readUnsignedShort(v);
1554         v += 2;
1555         if (named) {
1556             for (; i > 0; --i) {
1557                 v = readAnnotationValue(v + 2, buf, readUTF8(v, buf), av);
1558             }
1559         } else {
1560             for (; i > 0; --i) {
1561                 v = readAnnotationValue(v, buf, null, av);
1562             }
1563         }
1564         if (av != null) {
1565             av.visitEnd();
1566         }
1567         return v;
1568     }
1569 
1570     /**
1571      * Reads a value of an annotation and makes the given visitor visit it.
1572      *
1573      * @param v the start offset in {@link #b b} of the value to be read (<i>not
1574      *        including the value name constant pool index</i>).
1575      * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
1576      *        {@link #readClass(int,char[]) readClass} or
1577      *        {@link #readConst readConst}.
1578      * @param name the name of the value to be read.
1579      * @param av the visitor that must visit the value.
1580      * @return the end offset of the annotation value.
1581      */
1582     private int readAnnotationValue(
1583         int v,
1584         final char[] buf,
1585         final String name,
1586         final AnnotationVisitor av)
1587     {
1588         int i;
1589         if (av == null) {
1590             switch (b[v] & 0xFF) {
1591                 case 'e': // enum_const_value
1592                     return v + 5;
1593                 case '@': // annotation_value
1594                     return readAnnotationValues(v + 3, buf, true, null);
1595                 case '[': // array_value
1596                     return readAnnotationValues(v + 1, buf, false, null);
1597                 default:
1598                     return v + 3;
1599             }
1600         }
1601         switch (b[v++] & 0xFF) {
1602             case 'I': // pointer to CONSTANT_Integer
1603             case 'J': // pointer to CONSTANT_Long
1604             case 'F': // pointer to CONSTANT_Float
1605             case 'D': // pointer to CONSTANT_Double
1606                 av.visit(name, readConst(readUnsignedShort(v), buf));
1607                 v += 2;
1608                 break;
1609             case 'B': // pointer to CONSTANT_Byte
1610                 av.visit(name,
1611                         new Byte((byte) readInt(items[readUnsignedShort(v)])));
1612                 v += 2;
1613                 break;
1614             case 'Z': // pointer to CONSTANT_Boolean
1615                 av.visit(name, readInt(items[readUnsignedShort(v)]) == 0
1616                         ? Boolean.FALSE
1617                         : Boolean.TRUE);
1618                 v += 2;
1619                 break;
1620             case 'S': // pointer to CONSTANT_Short
1621                 av.visit(name,
1622                         new Short((short) readInt(items[readUnsignedShort(v)])));
1623                 v += 2;
1624                 break;
1625             case 'C': // pointer to CONSTANT_Char
1626                 av.visit(name,
1627                         new Character((char) readInt(items[readUnsignedShort(v)])));
1628                 v += 2;
1629                 break;
1630             case 's': // pointer to CONSTANT_Utf8
1631                 av.visit(name, readUTF8(v, buf));
1632                 v += 2;
1633                 break;
1634             case 'e': // enum_const_value
1635                 av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf));
1636                 v += 4;
1637                 break;
1638             case 'c': // class_info
1639                 av.visit(name, Type.getType(readUTF8(v, buf)));
1640                 v += 2;
1641                 break;
1642             case '@': // annotation_value
1643                 v = readAnnotationValues(v + 2,
1644                         buf,
1645                         true,
1646                         av.visitAnnotation(name, readUTF8(v, buf)));
1647                 break;
1648             case '[': // array_value
1649                 int size = readUnsignedShort(v);
1650                 v += 2;
1651                 if (size == 0) {
1652                     return readAnnotationValues(v - 2,
1653                             buf,
1654                             false,
1655                             av.visitArray(name));
1656                 }
1657                 switch (this.b[v++] & 0xFF) {
1658                     case 'B':
1659                         byte[] bv = new byte[size];
1660                         for (i = 0; i < size; i++) {
1661                             bv[i] = (byte) readInt(items[readUnsignedShort(v)]);
1662                             v += 3;
1663                         }
1664                         av.visit(name, bv);
1665                         --v;
1666                         break;
1667                     case 'Z':
1668                         boolean[] zv = new boolean[size];
1669                         for (i = 0; i < size; i++) {
1670                             zv[i] = readInt(items[readUnsignedShort(v)]) != 0;
1671                             v += 3;
1672                         }
1673                         av.visit(name, zv);
1674                         --v;
1675                         break;
1676                     case 'S':
1677                         short[] sv = new short[size];
1678                         for (i = 0; i < size; i++) {
1679                             sv[i] = (short) readInt(items[readUnsignedShort(v)]);
1680                             v += 3;
1681                         }
1682                         av.visit(name, sv);
1683                         --v;
1684                         break;
1685                     case 'C':
1686                         char[] cv = new char[size];
1687                         for (i = 0; i < size; i++) {
1688                             cv[i] = (char) readInt(items[readUnsignedShort(v)]);
1689                             v += 3;
1690                         }
1691                         av.visit(name, cv);
1692                         --v;
1693                         break;
1694                     case 'I':
1695                         int[] iv = new int[size];
1696                         for (i = 0; i < size; i++) {
1697                             iv[i] = readInt(items[readUnsignedShort(v)]);
1698                             v += 3;
1699                         }
1700                         av.visit(name, iv);
1701                         --v;
1702                         break;
1703                     case 'J':
1704                         long[] lv = new long[size];
1705                         for (i = 0; i < size; i++) {
1706                             lv[i] = readLong(items[readUnsignedShort(v)]);
1707                             v += 3;
1708                         }
1709                         av.visit(name, lv);
1710                         --v;
1711                         break;
1712                     case 'F':
1713                         float[] fv = new float[size];
1714                         for (i = 0; i < size; i++) {
1715                             fv[i] = Float.intBitsToFloat(readInt(items[readUnsignedShort(v)]));
1716                             v += 3;
1717                         }
1718                         av.visit(name, fv);
1719                         --v;
1720                         break;
1721                     case 'D':
1722                         double[] dv = new double[size];
1723                         for (i = 0; i < size; i++) {
1724                             dv[i] = Double.longBitsToDouble(readLong(items[readUnsignedShort(v)]));
1725                             v += 3;
1726                         }
1727                         av.visit(name, dv);
1728                         --v;
1729                         break;
1730                     default:
1731                         v = readAnnotationValues(v - 3,
1732                                 buf,
1733                                 false,
1734                                 av.visitArray(name));
1735                 }
1736         }
1737         return v;
1738     }
1739 
1740     private int readFrameType(
1741         final Object[] frame,
1742         final int index,
1743         int v,
1744         final char[] buf,
1745         final Label[] labels)
1746     {
1747         int type = b[v++] & 0xFF;
1748         switch (type) {
1749             case 0:
1750                 frame[index] = Opcodes.TOP;
1751                 break;
1752             case 1:
1753                 frame[index] = Opcodes.INTEGER;
1754                 break;
1755             case 2:
1756                 frame[index] = Opcodes.FLOAT;
1757                 break;
1758             case 3:
1759                 frame[index] = Opcodes.DOUBLE;
1760                 break;
1761             case 4:
1762                 frame[index] = Opcodes.LONG;
1763                 break;
1764             case 5:
1765                 frame[index] = Opcodes.NULL;
1766                 break;
1767             case 6:
1768                 frame[index] = Opcodes.UNINITIALIZED_THIS;
1769                 break;
1770             case 7: // Object
1771                 frame[index] = readClass(v, buf);
1772                 v += 2;
1773                 break;
1774             default: // Uninitialized
1775                 frame[index] = readLabel(readUnsignedShort(v), labels);
1776                 v += 2;
1777         }
1778         return v;
1779     }
1780 
1781     /**
1782      * Returns the label corresponding to the given offset. The default
1783      * implementation of this method creates a label for the given offset if it
1784      * has not been already created.
1785      *
1786      * @param offset a bytecode offset in a method.
1787      * @param labels the already created labels, indexed by their offset. If a
1788      *        label already exists for offset this method must not create a new
1789      *        one. Otherwise it must store the new label in this array.
1790      * @return a non null Label, which must be equal to labels[offset].
1791      */
1792     protected Label readLabel(int offset, Label[] labels) {
1793         if (labels[offset] == null) {
1794             labels[offset] = new Label();
1795         }
1796         return labels[offset];
1797     }
1798 
1799     /**
1800      * Reads an attribute in {@link #b b}.
1801      *
1802      * @param attrs prototypes of the attributes that must be parsed during the
1803      *        visit of the class. Any attribute whose type is not equal to the
1804      *        type of one the prototypes is ignored (i.e. an empty
1805      *        {@link Attribute} instance is returned).
1806      * @param type the type of the attribute.
1807      * @param off index of the first byte of the attribute's content in
1808      *        {@link #b b}. The 6 attribute header bytes, containing the type
1809      *        and the length of the attribute, are not taken into account here
1810      *        (they have already been read).
1811      * @param len the length of the attribute's content.
1812      * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
1813      *        {@link #readClass(int,char[]) readClass} or
1814      *        {@link #readConst readConst}.
1815      * @param codeOff index of the first byte of code's attribute content in
1816      *        {@link #b b}, or -1 if the attribute to be read is not a code
1817      *        attribute. The 6 attribute header bytes, containing the type and
1818      *        the length of the attribute, are not taken into account here.
1819      * @param labels the labels of the method's code, or <tt>null</tt> if the
1820      *        attribute to be read is not a code attribute.
1821      * @return the attribute that has been read, or <tt>null</tt> to skip this
1822      *         attribute.
1823      */
1824     private Attribute readAttribute(
1825         final Attribute[] attrs,
1826         final String type,
1827         final int off,
1828         final int len,
1829         final char[] buf,
1830         final int codeOff,
1831         final Label[] labels)
1832     {
1833         for (int i = 0; i < attrs.length; ++i) {
1834             if (attrs[i].type.equals(type)) {
1835                 return attrs[i].read(this, off, len, buf, codeOff, labels);
1836             }
1837         }
1838         return new Attribute(type).read(this, off, len, null, -1, null);
1839     }
1840 
1841     // ------------------------------------------------------------------------
1842     // Utility methods: low level parsing
1843     // ------------------------------------------------------------------------
1844 
1845     /**
1846      * Returns the start index of the constant pool item in {@link #b b}, plus
1847      * one. <i>This method is intended for {@link Attribute} sub classes, and is
1848      * normally not needed by class generators or adapters.</i>
1849      *
1850      * @param item the index a constant pool item.
1851      * @return the start index of the constant pool item in {@link #b b}, plus
1852      *         one.
1853      */
1854     public int getItem(final int item) {
1855         return items[item];
1856     }
1857 
1858     /**
1859      * Reads a byte value in {@link #b b}. <i>This method is intended for
1860      * {@link Attribute} sub classes, and is normally not needed by class
1861      * generators or adapters.</i>
1862      *
1863      * @param index the start index of the value to be read in {@link #b b}.
1864      * @return the read value.
1865      */
1866     public int readByte(final int index) {
1867         return b[index] & 0xFF;
1868     }
1869 
1870     /**
1871      * Reads an unsigned short value in {@link #b b}. <i>This method is
1872      * intended for {@link Attribute} sub classes, and is normally not needed by
1873      * class generators or adapters.</i>
1874      *
1875      * @param index the start index of the value to be read in {@link #b b}.
1876      * @return the read value.
1877      */
1878     public int readUnsignedShort(final int index) {
1879         byte[] b = this.b;
1880         return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF);
1881     }
1882 
1883     /**
1884      * Reads a signed short value in {@link #b b}. <i>This method is intended
1885      * for {@link Attribute} sub classes, and is normally not needed by class
1886      * generators or adapters.</i>
1887      *
1888      * @param index the start index of the value to be read in {@link #b b}.
1889      * @return the read value.
1890      */
1891     public short readShort(final int index) {
1892         byte[] b = this.b;
1893         return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF));
1894     }
1895 
1896     /**
1897      * Reads a signed int value in {@link #b b}. <i>This method is intended for
1898      * {@link Attribute} sub classes, and is normally not needed by class
1899      * generators or adapters.</i>
1900      *
1901      * @param index the start index of the value to be read in {@link #b b}.
1902      * @return the read value.
1903      */
1904     public int readInt(final int index) {
1905         byte[] b = this.b;
1906         return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16)
1907                 | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF);
1908     }
1909 
1910     /**
1911      * Reads a signed long value in {@link #b b}. <i>This method is intended
1912      * for {@link Attribute} sub classes, and is normally not needed by class
1913      * generators or adapters.</i>
1914      *
1915      * @param index the start index of the value to be read in {@link #b b}.
1916      * @return the read value.
1917      */
1918     public long readLong(final int index) {
1919         long l1 = readInt(index);
1920         long l0 = readInt(index + 4) & 0xFFFFFFFFL;
1921         return (l1 << 32) | l0;
1922     }
1923 
1924     /**
1925      * Reads an UTF8 string constant pool item in {@link #b b}. <i>This method
1926      * is intended for {@link Attribute} sub classes, and is normally not needed
1927      * by class generators or adapters.</i>
1928      *
1929      * @param index the start index of an unsigned short value in {@link #b b},
1930      *        whose value is the index of an UTF8 constant pool item.
1931      * @param buf buffer to be used to read the item. This buffer must be
1932      *        sufficiently large. It is not automatically resized.
1933      * @return the String corresponding to the specified UTF8 item.
1934      */
1935     public String readUTF8(int index, final char[] buf) {
1936         int item = readUnsignedShort(index);
1937         String s = strings[item];
1938         if (s != null) {
1939             return s;
1940         }
1941         index = items[item];
1942         return strings[item] = readUTF(index + 2, readUnsignedShort(index), buf);
1943     }
1944 
1945     /**
1946      * Reads UTF8 string in {@link #b b}.
1947      *
1948      * @param index start offset of the UTF8 string to be read.
1949      * @param utfLen length of the UTF8 string to be read.
1950      * @param buf buffer to be used to read the string. This buffer must be
1951      *        sufficiently large. It is not automatically resized.
1952      * @return the String corresponding to the specified UTF8 string.
1953      */
1954     private String readUTF(int index, final int utfLen, final char[] buf) {
1955         int endIndex = index + utfLen;
1956         byte[] b = this.b;
1957         int strLen = 0;
1958         int c, d, e;
1959         while (index < endIndex) {
1960             c = b[index++] & 0xFF;
1961             switch (c >> 4) {
1962                 case 0:
1963                 case 1:
1964                 case 2:
1965                 case 3:
1966                 case 4:
1967                 case 5:
1968                 case 6:
1969                 case 7:
1970                     // 0xxxxxxx
1971                     buf[strLen++] = (char) c;
1972                     break;
1973                 case 12:
1974                 case 13:
1975                     // 110x xxxx 10xx xxxx
1976                     d = b[index++];
1977                     buf[strLen++] = (char) (((c & 0x1F) << 6) | (d & 0x3F));
1978                     break;
1979                 default:
1980                     // 1110 xxxx 10xx xxxx 10xx xxxx
1981                     d = b[index++];
1982                     e = b[index++];
1983                     buf[strLen++] = (char) (((c & 0x0F) << 12)
1984                             | ((d & 0x3F) << 6) | (e & 0x3F));
1985                     break;
1986             }
1987         }
1988         return new String(buf, 0, strLen);
1989     }
1990 
1991     /**
1992      * Reads a class constant pool item in {@link #b b}. <i>This method is
1993      * intended for {@link Attribute} sub classes, and is normally not needed by
1994      * class generators or adapters.</i>
1995      *
1996      * @param index the start index of an unsigned short value in {@link #b b},
1997      *        whose value is the index of a class constant pool item.
1998      * @param buf buffer to be used to read the item. This buffer must be
1999      *        sufficiently large. It is not automatically resized.
2000      * @return the String corresponding to the specified class item.
2001      */
2002     public String readClass(final int index, final char[] buf) {
2003         // computes the start index of the CONSTANT_Class item in b
2004         // and reads the CONSTANT_Utf8 item designated by
2005         // the first two bytes of this CONSTANT_Class item
2006         return readUTF8(items[readUnsignedShort(index)], buf);
2007     }
2008 
2009     /**
2010      * Reads a numeric or string constant pool item in {@link #b b}. <i>This
2011      * method is intended for {@link Attribute} sub classes, and is normally not
2012      * needed by class generators or adapters.</i>
2013      *
2014      * @param item the index of a constant pool item.
2015      * @param buf buffer to be used to read the item. This buffer must be
2016      *        sufficiently large. It is not automatically resized.
2017      * @return the {@link Integer}, {@link Float}, {@link Long},
2018      *         {@link Double}, {@link String} or {@link Type} corresponding to
2019      *         the given constant pool item.
2020      */
2021     public Object readConst(final int item, final char[] buf) {
2022         int index = items[item];
2023         switch (b[index - 1]) {
2024             case ClassWriter.INT:
2025                 return new Integer(readInt(index));
2026             case ClassWriter.FLOAT:
2027                 return new Float(Float.intBitsToFloat(readInt(index)));
2028             case ClassWriter.LONG:
2029                 return new Long(readLong(index));
2030             case ClassWriter.DOUBLE:
2031                 return new Double(Double.longBitsToDouble(readLong(index)));
2032             case ClassWriter.CLASS:
2033                 return Type.getObjectType(readUTF8(index, buf));
2034                 // case ClassWriter.STR:
2035             default:
2036                 return readUTF8(index, buf);
2037         }
2038     }
2039 }