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  */
  59 package jdk.internal.org.objectweb.asm;
  60 
  61 import java.io.IOException;
  62 import 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  */
  73 public 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_8) {
 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 numeric or string constant pool item in {@link #b b}. <i>This
2495      * method is intended for {@link Attribute} sub classes, and is normally not
2496      * needed by class generators or adapters.</i>
2497      *
2498      * @param item
2499      *            the index of a constant pool item.
2500      * @param buf
2501      *            buffer to be used to read the item. This buffer must be
2502      *            sufficiently large. It is not automatically resized.
2503      * @return the {@link Integer}, {@link Float}, {@link Long}, {@link Double},
2504      *         {@link String}, {@link Type} or {@link Handle} corresponding to
2505      *         the given constant pool item.
2506      */
2507     public Object readConst(final int item, final char[] buf) {
2508         int index = items[item];
2509         switch (b[index - 1]) {
2510         case ClassWriter.INT:
2511             return readInt(index);
2512         case ClassWriter.FLOAT:
2513             return Float.intBitsToFloat(readInt(index));
2514         case ClassWriter.LONG:
2515             return readLong(index);
2516         case ClassWriter.DOUBLE:
2517             return Double.longBitsToDouble(readLong(index));
2518         case ClassWriter.CLASS:
2519             return Type.getObjectType(readUTF8(index, buf));
2520         case ClassWriter.STR:
2521             return readUTF8(index, buf);
2522         case ClassWriter.MTYPE:
2523             return Type.getMethodType(readUTF8(index, buf));
2524         default: // case ClassWriter.HANDLE_BASE + [1..9]:
2525             int tag = readByte(index);
2526             int[] items = this.items;
2527             int cpIndex = items[readUnsignedShort(index + 1)];
2528             boolean itf = b[cpIndex - 1] == ClassWriter.IMETH;
2529             String owner = readClass(cpIndex, buf);
2530             cpIndex = items[readUnsignedShort(cpIndex + 2)];
2531             String name = readUTF8(cpIndex, buf);
2532             String desc = readUTF8(cpIndex + 2, buf);
2533             return new Handle(tag, owner, name, desc, itf);
2534         }
2535     }
2536 }