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