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