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                         labels[label].line = readUnsignedShort(v + 12);
1203                         v += 4;
1204                     }
1205                 }
1206             } else if (ANNOTATIONS
1207                     && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
1208                 tanns = readTypeAnnotations(mv, context, u + 8, true);
1209                 ntoff = tanns.length == 0 || readByte(tanns[0]) < 0x43 ? -1
1210                         : readUnsignedShort(tanns[0] + 1);
1211             } else if (ANNOTATIONS
1212                     && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
1213                 itanns = readTypeAnnotations(mv, context, u + 8, false);
1214                 nitoff = itanns.length == 0 || readByte(itanns[0]) < 0x43 ? -1
1215                         : readUnsignedShort(itanns[0] + 1);
1216             } else if (FRAMES && "StackMapTable".equals(attrName)) {
1217                 if ((context.flags & SKIP_FRAMES) == 0) {
1218                     stackMap = u + 10;
1219                     stackMapSize = readInt(u + 4);
1220                     frameCount = readUnsignedShort(u + 8);
1221                 }
1222                 /*
1223                  * here we do not extract the labels corresponding to the
1224                  * attribute content. This would require a full parsing of the
1225                  * attribute, which would need to be repeated in the second
1226                  * phase (see below). Instead the content of the attribute is
1227                  * read one frame at a time (i.e. after a frame has been
1228                  * visited, the next frame is read), and the labels it contains
1229                  * are also extracted one frame at a time. Thanks to the
1230                  * ordering of frames, having only a "one frame lookahead" is
1231                  * not a problem, i.e. it is not possible to see an offset
1232                  * smaller than the offset of the current insn and for which no
1233                  * Label exist.
1234                  */
1235                 /*
1236                  * This is not true for UNINITIALIZED type offsets. We solve
1237                  * this by parsing the stack map table without a full decoding
1238                  * (see below).
1239                  */
1240             } else if (FRAMES && "StackMap".equals(attrName)) {
1241                 if ((context.flags & SKIP_FRAMES) == 0) {
1242                     zip = false;
1243                     stackMap = u + 10;
1244                     stackMapSize = readInt(u + 4);
1245                     frameCount = readUnsignedShort(u + 8);
1246                 }
1247                 /*
1248                  * IMPORTANT! here we assume that the frames are ordered, as in
1249                  * the StackMapTable attribute, although this is not guaranteed
1250                  * by the attribute format.
1251                  */
1252             } else {
1253                 for (int j = 0; j < context.attrs.length; ++j) {
1254                     if (context.attrs[j].type.equals(attrName)) {
1255                         Attribute attr = context.attrs[j].read(this, u + 8,
1256                                 readInt(u + 4), c, codeStart - 8, labels);
1257                         if (attr != null) {
1258                             attr.next = attributes;
1259                             attributes = attr;
1260                         }
1261                     }
1262                 }
1263             }
1264             u += 6 + readInt(u + 4);
1265         }
1266         u += 2;
1267 
1268         // generates the first (implicit) stack map frame
1269         if (FRAMES && stackMap != 0) {
1270             /*
1271              * for the first explicit frame the offset is not offset_delta + 1
1272              * but only offset_delta; setting the implicit frame offset to -1
1273              * allow the use of the "offset_delta + 1" rule in all cases
1274              */
1275             frame = context;
1276             frame.offset = -1;
1277             frame.mode = 0;
1278             frame.localCount = 0;
1279             frame.localDiff = 0;
1280             frame.stackCount = 0;
1281             frame.local = new Object[maxLocals];
1282             frame.stack = new Object[maxStack];
1283             if (unzip) {
1284                 getImplicitFrame(context);
1285             }
1286             /*
1287              * Finds labels for UNINITIALIZED frame types. Instead of decoding
1288              * each element of the stack map table, we look for 3 consecutive
1289              * bytes that "look like" an UNINITIALIZED type (tag 8, offset
1290              * within code bounds, NEW instruction at this offset). We may find
1291              * false positives (i.e. not real UNINITIALIZED types), but this
1292              * should be rare, and the only consequence will be the creation of
1293              * an unneeded label. This is better than creating a label for each
1294              * NEW instruction, and faster than fully decoding the whole stack
1295              * map table.
1296              */
1297             for (int i = stackMap; i < stackMap + stackMapSize - 2; ++i) {
1298                 if (b[i] == 8) { // UNINITIALIZED FRAME TYPE
1299                     int v = readUnsignedShort(i + 1);
1300                     if (v >= 0 && v < codeLength) {
1301                         if ((b[codeStart + v] & 0xFF) == Opcodes.NEW) {
1302                             readLabel(v, labels);
1303                         }
1304                     }
1305                 }
1306             }
1307         }
1308 
1309         // visits the instructions
1310         u = codeStart;
1311         while (u < codeEnd) {
1312             int offset = u - codeStart;
1313 
1314             // visits the label and line number for this offset, if any
1315             Label l = labels[offset];
1316             if (l != null) {
1317                 mv.visitLabel(l);
1318                 if ((context.flags & SKIP_DEBUG) == 0 && l.line > 0) {
1319                     mv.visitLineNumber(l.line, l);
1320                 }
1321             }
1322 
1323             // visits the frame for this offset, if any
1324             while (FRAMES && frame != null
1325                     && (frame.offset == offset || frame.offset == -1)) {
1326                 // if there is a frame for this offset, makes the visitor visit
1327                 // it, and reads the next frame if there is one.
1328                 if (frame.offset != -1) {
1329                     if (!zip || unzip) {
1330                         mv.visitFrame(Opcodes.F_NEW, frame.localCount,
1331                                 frame.local, frame.stackCount, frame.stack);
1332                     } else {
1333                         mv.visitFrame(frame.mode, frame.localDiff, frame.local,
1334                                 frame.stackCount, frame.stack);
1335                     }
1336                 }
1337                 if (frameCount > 0) {
1338                     stackMap = readFrame(stackMap, zip, unzip, frame);
1339                     --frameCount;
1340                 } else {
1341                     frame = null;
1342                 }
1343             }
1344 
1345             // visits the instruction at this offset
1346             int opcode = b[u] & 0xFF;
1347             switch (ClassWriter.TYPE[opcode]) {
1348             case ClassWriter.NOARG_INSN:
1349                 mv.visitInsn(opcode);
1350                 u += 1;
1351                 break;
1352             case ClassWriter.IMPLVAR_INSN:
1353                 if (opcode > Opcodes.ISTORE) {
1354                     opcode -= 59; // ISTORE_0
1355                     mv.visitVarInsn(Opcodes.ISTORE + (opcode >> 2),
1356                             opcode & 0x3);
1357                 } else {
1358                     opcode -= 26; // ILOAD_0
1359                     mv.visitVarInsn(Opcodes.ILOAD + (opcode >> 2), opcode & 0x3);
1360                 }
1361                 u += 1;
1362                 break;
1363             case ClassWriter.LABEL_INSN:
1364                 mv.visitJumpInsn(opcode, labels[offset + readShort(u + 1)]);
1365                 u += 3;
1366                 break;
1367             case ClassWriter.LABELW_INSN:
1368                 mv.visitJumpInsn(opcode - 33, labels[offset + readInt(u + 1)]);
1369                 u += 5;
1370                 break;
1371             case ClassWriter.WIDE_INSN:
1372                 opcode = b[u + 1] & 0xFF;
1373                 if (opcode == Opcodes.IINC) {
1374                     mv.visitIincInsn(readUnsignedShort(u + 2), readShort(u + 4));
1375                     u += 6;
1376                 } else {
1377                     mv.visitVarInsn(opcode, readUnsignedShort(u + 2));
1378                     u += 4;
1379                 }
1380                 break;
1381             case ClassWriter.TABL_INSN: {
1382                 // skips 0 to 3 padding bytes
1383                 u = u + 4 - (offset & 3);
1384                 // reads instruction
1385                 int label = offset + readInt(u);
1386                 int min = readInt(u + 4);
1387                 int max = readInt(u + 8);
1388                 Label[] table = new Label[max - min + 1];
1389                 u += 12;
1390                 for (int i = 0; i < table.length; ++i) {
1391                     table[i] = labels[offset + readInt(u)];
1392                     u += 4;
1393                 }
1394                 mv.visitTableSwitchInsn(min, max, labels[label], table);
1395                 break;
1396             }
1397             case ClassWriter.LOOK_INSN: {
1398                 // skips 0 to 3 padding bytes
1399                 u = u + 4 - (offset & 3);
1400                 // reads instruction
1401                 int label = offset + readInt(u);
1402                 int len = readInt(u + 4);
1403                 int[] keys = new int[len];
1404                 Label[] values = new Label[len];
1405                 u += 8;
1406                 for (int i = 0; i < len; ++i) {
1407                     keys[i] = readInt(u);
1408                     values[i] = labels[offset + readInt(u + 4)];
1409                     u += 8;
1410                 }
1411                 mv.visitLookupSwitchInsn(labels[label], keys, values);
1412                 break;
1413             }
1414             case ClassWriter.VAR_INSN:
1415                 mv.visitVarInsn(opcode, b[u + 1] & 0xFF);
1416                 u += 2;
1417                 break;
1418             case ClassWriter.SBYTE_INSN:
1419                 mv.visitIntInsn(opcode, b[u + 1]);
1420                 u += 2;
1421                 break;
1422             case ClassWriter.SHORT_INSN:
1423                 mv.visitIntInsn(opcode, readShort(u + 1));
1424                 u += 3;
1425                 break;
1426             case ClassWriter.LDC_INSN:
1427                 mv.visitLdcInsn(readConst(b[u + 1] & 0xFF, c));
1428                 u += 2;
1429                 break;
1430             case ClassWriter.LDCW_INSN:
1431                 mv.visitLdcInsn(readConst(readUnsignedShort(u + 1), c));
1432                 u += 3;
1433                 break;
1434             case ClassWriter.FIELDORMETH_INSN:
1435             case ClassWriter.ITFMETH_INSN: {
1436                 int cpIndex = items[readUnsignedShort(u + 1)];
1437                 boolean itf = b[cpIndex - 1] == ClassWriter.IMETH;
1438                 String iowner = readClass(cpIndex, c);
1439                 cpIndex = items[readUnsignedShort(cpIndex + 2)];
1440                 String iname = readUTF8(cpIndex, c);
1441                 String idesc = readUTF8(cpIndex + 2, c);
1442                 if (opcode < Opcodes.INVOKEVIRTUAL) {
1443                     mv.visitFieldInsn(opcode, iowner, iname, idesc);
1444                 } else {
1445                     mv.visitMethodInsn(opcode, iowner, iname, idesc, itf);
1446                 }
1447                 if (opcode == Opcodes.INVOKEINTERFACE) {
1448                     u += 5;
1449                 } else {
1450                     u += 3;
1451                 }
1452                 break;
1453             }
1454             case ClassWriter.INDYMETH_INSN: {
1455                 int cpIndex = items[readUnsignedShort(u + 1)];
1456                 int bsmIndex = context.bootstrapMethods[readUnsignedShort(cpIndex)];
1457                 Handle bsm = (Handle) readConst(readUnsignedShort(bsmIndex), c);
1458                 int bsmArgCount = readUnsignedShort(bsmIndex + 2);
1459                 Object[] bsmArgs = new Object[bsmArgCount];
1460                 bsmIndex += 4;
1461                 for (int i = 0; i < bsmArgCount; i++) {
1462                     bsmArgs[i] = readConst(readUnsignedShort(bsmIndex), c);
1463                     bsmIndex += 2;
1464                 }
1465                 cpIndex = items[readUnsignedShort(cpIndex + 2)];
1466                 String iname = readUTF8(cpIndex, c);
1467                 String idesc = readUTF8(cpIndex + 2, c);
1468                 mv.visitInvokeDynamicInsn(iname, idesc, bsm, bsmArgs);
1469                 u += 5;
1470                 break;
1471             }
1472             case ClassWriter.TYPE_INSN:
1473                 mv.visitTypeInsn(opcode, readClass(u + 1, c));
1474                 u += 3;
1475                 break;
1476             case ClassWriter.IINC_INSN:
1477                 mv.visitIincInsn(b[u + 1] & 0xFF, b[u + 2]);
1478                 u += 3;
1479                 break;
1480             // case MANA_INSN:
1481             default:
1482                 mv.visitMultiANewArrayInsn(readClass(u + 1, c), b[u + 3] & 0xFF);
1483                 u += 4;
1484                 break;
1485             }
1486 
1487             // visit the instruction annotations, if any
1488             while (tanns != null && tann < tanns.length && ntoff <= offset) {
1489                 if (ntoff == offset) {
1490                     int v = readAnnotationTarget(context, tanns[tann]);
1491                     readAnnotationValues(v + 2, c, true,
1492                             mv.visitInsnAnnotation(context.typeRef,
1493                                     context.typePath, readUTF8(v, c), true));
1494                 }
1495                 ntoff = ++tann >= tanns.length || readByte(tanns[tann]) < 0x43 ? -1
1496                         : readUnsignedShort(tanns[tann] + 1);
1497             }
1498             while (itanns != null && itann < itanns.length && nitoff <= offset) {
1499                 if (nitoff == offset) {
1500                     int v = readAnnotationTarget(context, itanns[itann]);
1501                     readAnnotationValues(v + 2, c, true,
1502                             mv.visitInsnAnnotation(context.typeRef,
1503                                     context.typePath, readUTF8(v, c), false));
1504                 }
1505                 nitoff = ++itann >= itanns.length
1506                         || readByte(itanns[itann]) < 0x43 ? -1
1507                         : readUnsignedShort(itanns[itann] + 1);
1508             }
1509         }
1510         if (labels[codeLength] != null) {
1511             mv.visitLabel(labels[codeLength]);
1512         }
1513 
1514         // visits the local variable tables
1515         if ((context.flags & SKIP_DEBUG) == 0 && varTable != 0) {
1516             int[] typeTable = null;
1517             if (varTypeTable != 0) {
1518                 u = varTypeTable + 2;
1519                 typeTable = new int[readUnsignedShort(varTypeTable) * 3];
1520                 for (int i = typeTable.length; i > 0;) {
1521                     typeTable[--i] = u + 6; // signature
1522                     typeTable[--i] = readUnsignedShort(u + 8); // index
1523                     typeTable[--i] = readUnsignedShort(u); // start
1524                     u += 10;
1525                 }
1526             }
1527             u = varTable + 2;
1528             for (int i = readUnsignedShort(varTable); i > 0; --i) {
1529                 int start = readUnsignedShort(u);
1530                 int length = readUnsignedShort(u + 2);
1531                 int index = readUnsignedShort(u + 8);
1532                 String vsignature = null;
1533                 if (typeTable != null) {
1534                     for (int j = 0; j < typeTable.length; j += 3) {
1535                         if (typeTable[j] == start && typeTable[j + 1] == index) {
1536                             vsignature = readUTF8(typeTable[j + 2], c);
1537                             break;
1538                         }
1539                     }
1540                 }
1541                 mv.visitLocalVariable(readUTF8(u + 4, c), readUTF8(u + 6, c),
1542                         vsignature, labels[start], labels[start + length],
1543                         index);
1544                 u += 10;
1545             }
1546         }
1547 
1548         // visits the local variables type annotations
1549         if (tanns != null) {
1550             for (int i = 0; i < tanns.length; ++i) {
1551                 if ((readByte(tanns[i]) >> 1) == (0x40 >> 1)) {
1552                     int v = readAnnotationTarget(context, tanns[i]);
1553                     v = readAnnotationValues(v + 2, c, true,
1554                             mv.visitLocalVariableAnnotation(context.typeRef,
1555                                     context.typePath, context.start,
1556                                     context.end, context.index, readUTF8(v, c),
1557                                     true));
1558                 }
1559             }
1560         }
1561         if (itanns != null) {
1562             for (int i = 0; i < itanns.length; ++i) {
1563                 if ((readByte(itanns[i]) >> 1) == (0x40 >> 1)) {
1564                     int v = readAnnotationTarget(context, itanns[i]);
1565                     v = readAnnotationValues(v + 2, c, true,
1566                             mv.visitLocalVariableAnnotation(context.typeRef,
1567                                     context.typePath, context.start,
1568                                     context.end, context.index, readUTF8(v, c),
1569                                     false));
1570                 }
1571             }
1572         }
1573 
1574         // visits the code attributes
1575         while (attributes != null) {
1576             Attribute attr = attributes.next;
1577             attributes.next = null;
1578             mv.visitAttribute(attributes);
1579             attributes = attr;
1580         }
1581 
1582         // visits the max stack and max locals values
1583         mv.visitMaxs(maxStack, maxLocals);
1584     }
1585 
1586     /**
1587      * Parses a type annotation table to find the labels, and to visit the try
1588      * catch block annotations.
1589      *
1590      * @param u
1591      *            the start offset of a type annotation table.
1592      * @param mv
1593      *            the method visitor to be used to visit the try catch block
1594      *            annotations.
1595      * @param context
1596      *            information about the class being parsed.
1597      * @param visible
1598      *            if the type annotation table to parse contains runtime visible
1599      *            annotations.
1600      * @return the start offset of each type annotation in the parsed table.
1601      */
1602     private int[] readTypeAnnotations(final MethodVisitor mv,
1603             final Context context, int u, boolean visible) {
1604         char[] c = context.buffer;
1605         int[] offsets = new int[readUnsignedShort(u)];
1606         u += 2;
1607         for (int i = 0; i < offsets.length; ++i) {
1608             offsets[i] = u;
1609             int target = readInt(u);
1610             switch (target >>> 24) {
1611             case 0x00: // CLASS_TYPE_PARAMETER
1612             case 0x01: // METHOD_TYPE_PARAMETER
1613             case 0x16: // METHOD_FORMAL_PARAMETER
1614                 u += 2;
1615                 break;
1616             case 0x13: // FIELD
1617             case 0x14: // METHOD_RETURN
1618             case 0x15: // METHOD_RECEIVER
1619                 u += 1;
1620                 break;
1621             case 0x40: // LOCAL_VARIABLE
1622             case 0x41: // RESOURCE_VARIABLE
1623                 for (int j = readUnsignedShort(u + 1); j > 0; --j) {
1624                     int start = readUnsignedShort(u + 3);
1625                     int length = readUnsignedShort(u + 5);
1626                     readLabel(start, context.labels);
1627                     readLabel(start + length, context.labels);
1628                     u += 6;
1629                 }
1630                 u += 3;
1631                 break;
1632             case 0x47: // CAST
1633             case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
1634             case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT
1635             case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
1636             case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT
1637                 u += 4;
1638                 break;
1639             // case 0x10: // CLASS_EXTENDS
1640             // case 0x11: // CLASS_TYPE_PARAMETER_BOUND
1641             // case 0x12: // METHOD_TYPE_PARAMETER_BOUND
1642             // case 0x17: // THROWS
1643             // case 0x42: // EXCEPTION_PARAMETER
1644             // case 0x43: // INSTANCEOF
1645             // case 0x44: // NEW
1646             // case 0x45: // CONSTRUCTOR_REFERENCE
1647             // case 0x46: // METHOD_REFERENCE
1648             default:
1649                 u += 3;
1650                 break;
1651             }
1652             int pathLength = readByte(u);
1653             if ((target >>> 24) == 0x42) {
1654                 TypePath path = pathLength == 0 ? null : new TypePath(b, u);
1655                 u += 1 + 2 * pathLength;
1656                 u = readAnnotationValues(u + 2, c, true,
1657                         mv.visitTryCatchAnnotation(target, path,
1658                                 readUTF8(u, c), visible));
1659             } else {
1660                 u = readAnnotationValues(u + 3 + 2 * pathLength, c, true, null);
1661             }
1662         }
1663         return offsets;
1664     }
1665 
1666     /**
1667      * Parses the header of a type annotation to extract its target_type and
1668      * target_path (the result is stored in the given context), and returns the
1669      * start offset of the rest of the type_annotation structure (i.e. the
1670      * offset to the type_index field, which is followed by
1671      * num_element_value_pairs and then the name,value pairs).
1672      *
1673      * @param context
1674      *            information about the class being parsed. This is where the
1675      *            extracted target_type and target_path must be stored.
1676      * @param u
1677      *            the start offset of a type_annotation structure.
1678      * @return the start offset of the rest of the type_annotation structure.
1679      */
1680     private int readAnnotationTarget(final Context context, int u) {
1681         int target = readInt(u);
1682         switch (target >>> 24) {
1683         case 0x00: // CLASS_TYPE_PARAMETER
1684         case 0x01: // METHOD_TYPE_PARAMETER
1685         case 0x16: // METHOD_FORMAL_PARAMETER
1686             target &= 0xFFFF0000;
1687             u += 2;
1688             break;
1689         case 0x13: // FIELD
1690         case 0x14: // METHOD_RETURN
1691         case 0x15: // METHOD_RECEIVER
1692             target &= 0xFF000000;
1693             u += 1;
1694             break;
1695         case 0x40: // LOCAL_VARIABLE
1696         case 0x41: { // RESOURCE_VARIABLE
1697             target &= 0xFF000000;
1698             int n = readUnsignedShort(u + 1);
1699             context.start = new Label[n];
1700             context.end = new Label[n];
1701             context.index = new int[n];
1702             u += 3;
1703             for (int i = 0; i < n; ++i) {
1704                 int start = readUnsignedShort(u);
1705                 int length = readUnsignedShort(u + 2);
1706                 context.start[i] = readLabel(start, context.labels);
1707                 context.end[i] = readLabel(start + length, context.labels);
1708                 context.index[i] = readUnsignedShort(u + 4);
1709                 u += 6;
1710             }
1711             break;
1712         }
1713         case 0x47: // CAST
1714         case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
1715         case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT
1716         case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
1717         case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT
1718             target &= 0xFF0000FF;
1719             u += 4;
1720             break;
1721         // case 0x10: // CLASS_EXTENDS
1722         // case 0x11: // CLASS_TYPE_PARAMETER_BOUND
1723         // case 0x12: // METHOD_TYPE_PARAMETER_BOUND
1724         // case 0x17: // THROWS
1725         // case 0x42: // EXCEPTION_PARAMETER
1726         // case 0x43: // INSTANCEOF
1727         // case 0x44: // NEW
1728         // case 0x45: // CONSTRUCTOR_REFERENCE
1729         // case 0x46: // METHOD_REFERENCE
1730         default:
1731             target &= (target >>> 24) < 0x43 ? 0xFFFFFF00 : 0xFF000000;
1732             u += 3;
1733             break;
1734         }
1735         int pathLength = readByte(u);
1736         context.typeRef = target;
1737         context.typePath = pathLength == 0 ? null : new TypePath(b, u);
1738         return u + 1 + 2 * pathLength;
1739     }
1740 
1741     /**
1742      * Reads parameter annotations and makes the given visitor visit them.
1743      *
1744      * @param mv
1745      *            the visitor that must visit the annotations.
1746      * @param context
1747      *            information about the class being parsed.
1748      * @param v
1749      *            start offset in {@link #b b} of the annotations to be read.
1750      * @param visible
1751      *            <tt>true</tt> if the annotations to be read are visible at
1752      *            runtime.
1753      */
1754     private void readParameterAnnotations(final MethodVisitor mv,
1755             final Context context, int v, final boolean visible) {
1756         int i;
1757         int n = b[v++] & 0xFF;
1758         // workaround for a bug in javac (javac compiler generates a parameter
1759         // annotation array whose size is equal to the number of parameters in
1760         // the Java source file, while it should generate an array whose size is
1761         // equal to the number of parameters in the method descriptor - which
1762         // includes the synthetic parameters added by the compiler). This work-
1763         // around supposes that the synthetic parameters are the first ones.
1764         int synthetics = Type.getArgumentTypes(context.desc).length - n;
1765         AnnotationVisitor av;
1766         for (i = 0; i < synthetics; ++i) {
1767             // virtual annotation to detect synthetic parameters in MethodWriter
1768             av = mv.visitParameterAnnotation(i, "Ljava/lang/Synthetic;", false);
1769             if (av != null) {
1770                 av.visitEnd();
1771             }
1772         }
1773         char[] c = context.buffer;
1774         for (; i < n + synthetics; ++i) {
1775             int j = readUnsignedShort(v);
1776             v += 2;
1777             for (; j > 0; --j) {
1778                 av = mv.visitParameterAnnotation(i, readUTF8(v, c), visible);
1779                 v = readAnnotationValues(v + 2, c, true, av);
1780             }
1781         }
1782     }
1783 
1784     /**
1785      * Reads the values of an annotation and makes the given visitor visit them.
1786      *
1787      * @param v
1788      *            the start offset in {@link #b b} of the values to be read
1789      *            (including the unsigned short that gives the number of
1790      *            values).
1791      * @param buf
1792      *            buffer to be used to call {@link #readUTF8 readUTF8},
1793      *            {@link #readClass(int,char[]) readClass} or {@link #readConst
1794      *            readConst}.
1795      * @param named
1796      *            if the annotation values are named or not.
1797      * @param av
1798      *            the visitor that must visit the values.
1799      * @return the end offset of the annotation values.
1800      */
1801     private int readAnnotationValues(int v, final char[] buf,
1802             final boolean named, final AnnotationVisitor av) {
1803         int i = readUnsignedShort(v);
1804         v += 2;
1805         if (named) {
1806             for (; i > 0; --i) {
1807                 v = readAnnotationValue(v + 2, buf, readUTF8(v, buf), av);
1808             }
1809         } else {
1810             for (; i > 0; --i) {
1811                 v = readAnnotationValue(v, buf, null, av);
1812             }
1813         }
1814         if (av != null) {
1815             av.visitEnd();
1816         }
1817         return v;
1818     }
1819 
1820     /**
1821      * Reads a value of an annotation and makes the given visitor visit it.
1822      *
1823      * @param v
1824      *            the start offset in {@link #b b} of the value to be read
1825      *            (<i>not including the value name constant pool index</i>).
1826      * @param buf
1827      *            buffer to be used to call {@link #readUTF8 readUTF8},
1828      *            {@link #readClass(int,char[]) readClass} or {@link #readConst
1829      *            readConst}.
1830      * @param name
1831      *            the name of the value to be read.
1832      * @param av
1833      *            the visitor that must visit the value.
1834      * @return the end offset of the annotation value.
1835      */
1836     private int readAnnotationValue(int v, final char[] buf, final String name,
1837             final AnnotationVisitor av) {
1838         int i;
1839         if (av == null) {
1840             switch (b[v] & 0xFF) {
1841             case 'e': // enum_const_value
1842                 return v + 5;
1843             case '@': // annotation_value
1844                 return readAnnotationValues(v + 3, buf, true, null);
1845             case '[': // array_value
1846                 return readAnnotationValues(v + 1, buf, false, null);
1847             default:
1848                 return v + 3;
1849             }
1850         }
1851         switch (b[v++] & 0xFF) {
1852         case 'I': // pointer to CONSTANT_Integer
1853         case 'J': // pointer to CONSTANT_Long
1854         case 'F': // pointer to CONSTANT_Float
1855         case 'D': // pointer to CONSTANT_Double
1856             av.visit(name, readConst(readUnsignedShort(v), buf));
1857             v += 2;
1858             break;
1859         case 'B': // pointer to CONSTANT_Byte
1860             av.visit(name,
1861                     new Byte((byte) readInt(items[readUnsignedShort(v)])));
1862             v += 2;
1863             break;
1864         case 'Z': // pointer to CONSTANT_Boolean
1865             av.visit(name,
1866                     readInt(items[readUnsignedShort(v)]) == 0 ? Boolean.FALSE
1867                             : Boolean.TRUE);
1868             v += 2;
1869             break;
1870         case 'S': // pointer to CONSTANT_Short
1871             av.visit(name, new Short(
1872                     (short) readInt(items[readUnsignedShort(v)])));
1873             v += 2;
1874             break;
1875         case 'C': // pointer to CONSTANT_Char
1876             av.visit(name, new Character(
1877                     (char) readInt(items[readUnsignedShort(v)])));
1878             v += 2;
1879             break;
1880         case 's': // pointer to CONSTANT_Utf8
1881             av.visit(name, readUTF8(v, buf));
1882             v += 2;
1883             break;
1884         case 'e': // enum_const_value
1885             av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf));
1886             v += 4;
1887             break;
1888         case 'c': // class_info
1889             av.visit(name, Type.getType(readUTF8(v, buf)));
1890             v += 2;
1891             break;
1892         case '@': // annotation_value
1893             v = readAnnotationValues(v + 2, buf, true,
1894                     av.visitAnnotation(name, readUTF8(v, buf)));
1895             break;
1896         case '[': // array_value
1897             int size = readUnsignedShort(v);
1898             v += 2;
1899             if (size == 0) {
1900                 return readAnnotationValues(v - 2, buf, false,
1901                         av.visitArray(name));
1902             }
1903             switch (this.b[v++] & 0xFF) {
1904             case 'B':
1905                 byte[] bv = new byte[size];
1906                 for (i = 0; i < size; i++) {
1907                     bv[i] = (byte) readInt(items[readUnsignedShort(v)]);
1908                     v += 3;
1909                 }
1910                 av.visit(name, bv);
1911                 --v;
1912                 break;
1913             case 'Z':
1914                 boolean[] zv = new boolean[size];
1915                 for (i = 0; i < size; i++) {
1916                     zv[i] = readInt(items[readUnsignedShort(v)]) != 0;
1917                     v += 3;
1918                 }
1919                 av.visit(name, zv);
1920                 --v;
1921                 break;
1922             case 'S':
1923                 short[] sv = new short[size];
1924                 for (i = 0; i < size; i++) {
1925                     sv[i] = (short) readInt(items[readUnsignedShort(v)]);
1926                     v += 3;
1927                 }
1928                 av.visit(name, sv);
1929                 --v;
1930                 break;
1931             case 'C':
1932                 char[] cv = new char[size];
1933                 for (i = 0; i < size; i++) {
1934                     cv[i] = (char) readInt(items[readUnsignedShort(v)]);
1935                     v += 3;
1936                 }
1937                 av.visit(name, cv);
1938                 --v;
1939                 break;
1940             case 'I':
1941                 int[] iv = new int[size];
1942                 for (i = 0; i < size; i++) {
1943                     iv[i] = readInt(items[readUnsignedShort(v)]);
1944                     v += 3;
1945                 }
1946                 av.visit(name, iv);
1947                 --v;
1948                 break;
1949             case 'J':
1950                 long[] lv = new long[size];
1951                 for (i = 0; i < size; i++) {
1952                     lv[i] = readLong(items[readUnsignedShort(v)]);
1953                     v += 3;
1954                 }
1955                 av.visit(name, lv);
1956                 --v;
1957                 break;
1958             case 'F':
1959                 float[] fv = new float[size];
1960                 for (i = 0; i < size; i++) {
1961                     fv[i] = Float
1962                             .intBitsToFloat(readInt(items[readUnsignedShort(v)]));
1963                     v += 3;
1964                 }
1965                 av.visit(name, fv);
1966                 --v;
1967                 break;
1968             case 'D':
1969                 double[] dv = new double[size];
1970                 for (i = 0; i < size; i++) {
1971                     dv[i] = Double
1972                             .longBitsToDouble(readLong(items[readUnsignedShort(v)]));
1973                     v += 3;
1974                 }
1975                 av.visit(name, dv);
1976                 --v;
1977                 break;
1978             default:
1979                 v = readAnnotationValues(v - 3, buf, false, av.visitArray(name));
1980             }
1981         }
1982         return v;
1983     }
1984 
1985     /**
1986      * Computes the implicit frame of the method currently being parsed (as
1987      * defined in the given {@link Context}) and stores it in the given context.
1988      *
1989      * @param frame
1990      *            information about the class being parsed.
1991      */
1992     private void getImplicitFrame(final Context frame) {
1993         String desc = frame.desc;
1994         Object[] locals = frame.local;
1995         int local = 0;
1996         if ((frame.access & Opcodes.ACC_STATIC) == 0) {
1997             if ("<init>".equals(frame.name)) {
1998                 locals[local++] = Opcodes.UNINITIALIZED_THIS;
1999             } else {
2000                 locals[local++] = readClass(header + 2, frame.buffer);
2001             }
2002         }
2003         int i = 1;
2004         loop: while (true) {
2005             int j = i;
2006             switch (desc.charAt(i++)) {
2007             case 'Z':
2008             case 'C':
2009             case 'B':
2010             case 'S':
2011             case 'I':
2012                 locals[local++] = Opcodes.INTEGER;
2013                 break;
2014             case 'F':
2015                 locals[local++] = Opcodes.FLOAT;
2016                 break;
2017             case 'J':
2018                 locals[local++] = Opcodes.LONG;
2019                 break;
2020             case 'D':
2021                 locals[local++] = Opcodes.DOUBLE;
2022                 break;
2023             case '[':
2024                 while (desc.charAt(i) == '[') {
2025                     ++i;
2026                 }
2027                 if (desc.charAt(i) == 'L') {
2028                     ++i;
2029                     while (desc.charAt(i) != ';') {
2030                         ++i;
2031                     }
2032                 }
2033                 locals[local++] = desc.substring(j, ++i);
2034                 break;
2035             case 'L':
2036                 while (desc.charAt(i) != ';') {
2037                     ++i;
2038                 }
2039                 locals[local++] = desc.substring(j + 1, i++);
2040                 break;
2041             default:
2042                 break loop;
2043             }
2044         }
2045         frame.localCount = local;
2046     }
2047 
2048     /**
2049      * Reads a stack map frame and stores the result in the given
2050      * {@link Context} object.
2051      *
2052      * @param stackMap
2053      *            the start offset of a stack map frame in the class file.
2054      * @param zip
2055      *            if the stack map frame at stackMap is compressed or not.
2056      * @param unzip
2057      *            if the stack map frame must be uncompressed.
2058      * @param frame
2059      *            where the parsed stack map frame must be stored.
2060      * @return the offset of the first byte following the parsed frame.
2061      */
2062     private int readFrame(int stackMap, boolean zip, boolean unzip,
2063             Context frame) {
2064         char[] c = frame.buffer;
2065         Label[] labels = frame.labels;
2066         int tag;
2067         int delta;
2068         if (zip) {
2069             tag = b[stackMap++] & 0xFF;
2070         } else {
2071             tag = MethodWriter.FULL_FRAME;
2072             frame.offset = -1;
2073         }
2074         frame.localDiff = 0;
2075         if (tag < MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME) {
2076             delta = tag;
2077             frame.mode = Opcodes.F_SAME;
2078             frame.stackCount = 0;
2079         } else if (tag < MethodWriter.RESERVED) {
2080             delta = tag - MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME;
2081             stackMap = readFrameType(frame.stack, 0, stackMap, c, labels);
2082             frame.mode = Opcodes.F_SAME1;
2083             frame.stackCount = 1;
2084         } else {
2085             delta = readUnsignedShort(stackMap);
2086             stackMap += 2;
2087             if (tag == MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) {
2088                 stackMap = readFrameType(frame.stack, 0, stackMap, c, labels);
2089                 frame.mode = Opcodes.F_SAME1;
2090                 frame.stackCount = 1;
2091             } else if (tag >= MethodWriter.CHOP_FRAME
2092                     && tag < MethodWriter.SAME_FRAME_EXTENDED) {
2093                 frame.mode = Opcodes.F_CHOP;
2094                 frame.localDiff = MethodWriter.SAME_FRAME_EXTENDED - tag;
2095                 frame.localCount -= frame.localDiff;
2096                 frame.stackCount = 0;
2097             } else if (tag == MethodWriter.SAME_FRAME_EXTENDED) {
2098                 frame.mode = Opcodes.F_SAME;
2099                 frame.stackCount = 0;
2100             } else if (tag < MethodWriter.FULL_FRAME) {
2101                 int local = unzip ? frame.localCount : 0;
2102                 for (int i = tag - MethodWriter.SAME_FRAME_EXTENDED; i > 0; i--) {
2103                     stackMap = readFrameType(frame.local, local++, stackMap, c,
2104                             labels);
2105                 }
2106                 frame.mode = Opcodes.F_APPEND;
2107                 frame.localDiff = tag - MethodWriter.SAME_FRAME_EXTENDED;
2108                 frame.localCount += frame.localDiff;
2109                 frame.stackCount = 0;
2110             } else { // if (tag == FULL_FRAME) {
2111                 frame.mode = Opcodes.F_FULL;
2112                 int n = readUnsignedShort(stackMap);
2113                 stackMap += 2;
2114                 frame.localDiff = n;
2115                 frame.localCount = n;
2116                 for (int local = 0; n > 0; n--) {
2117                     stackMap = readFrameType(frame.local, local++, stackMap, c,
2118                             labels);
2119                 }
2120                 n = readUnsignedShort(stackMap);
2121                 stackMap += 2;
2122                 frame.stackCount = n;
2123                 for (int stack = 0; n > 0; n--) {
2124                     stackMap = readFrameType(frame.stack, stack++, stackMap, c,
2125                             labels);
2126                 }
2127             }
2128         }
2129         frame.offset += delta + 1;
2130         readLabel(frame.offset, labels);
2131         return stackMap;
2132     }
2133 
2134     /**
2135      * Reads a stack map frame type and stores it at the given index in the
2136      * given array.
2137      *
2138      * @param frame
2139      *            the array where the parsed type must be stored.
2140      * @param index
2141      *            the index in 'frame' where the parsed type must be stored.
2142      * @param v
2143      *            the start offset of the stack map frame type to read.
2144      * @param buf
2145      *            a buffer to read strings.
2146      * @param labels
2147      *            the labels of the method currently being parsed, indexed by
2148      *            their offset. If the parsed type is an Uninitialized type, a
2149      *            new label for the corresponding NEW instruction is stored in
2150      *            this array if it does not already exist.
2151      * @return the offset of the first byte after the parsed type.
2152      */
2153     private int readFrameType(final Object[] frame, final int index, int v,
2154             final char[] buf, final Label[] labels) {
2155         int type = b[v++] & 0xFF;
2156         switch (type) {
2157         case 0:
2158             frame[index] = Opcodes.TOP;
2159             break;
2160         case 1:
2161             frame[index] = Opcodes.INTEGER;
2162             break;
2163         case 2:
2164             frame[index] = Opcodes.FLOAT;
2165             break;
2166         case 3:
2167             frame[index] = Opcodes.DOUBLE;
2168             break;
2169         case 4:
2170             frame[index] = Opcodes.LONG;
2171             break;
2172         case 5:
2173             frame[index] = Opcodes.NULL;
2174             break;
2175         case 6:
2176             frame[index] = Opcodes.UNINITIALIZED_THIS;
2177             break;
2178         case 7: // Object
2179             frame[index] = readClass(v, buf);
2180             v += 2;
2181             break;
2182         default: // Uninitialized
2183             frame[index] = readLabel(readUnsignedShort(v), labels);
2184             v += 2;
2185         }
2186         return v;
2187     }
2188 
2189     /**
2190      * Returns the label corresponding to the given offset. The default
2191      * implementation of this method creates a label for the given offset if it
2192      * has not been already created.
2193      *
2194      * @param offset
2195      *            a bytecode offset in a method.
2196      * @param labels
2197      *            the already created labels, indexed by their offset. If a
2198      *            label already exists for offset this method must not create a
2199      *            new one. Otherwise it must store the new label in this array.
2200      * @return a non null Label, which must be equal to labels[offset].
2201      */
2202     protected Label readLabel(int offset, Label[] labels) {
2203         if (labels[offset] == null) {
2204             labels[offset] = new Label();
2205         }
2206         return labels[offset];
2207     }
2208 
2209     /**
2210      * Returns the start index of the attribute_info structure of this class.
2211      *
2212      * @return the start index of the attribute_info structure of this class.
2213      */
2214     private int getAttributes() {
2215         // skips the header
2216         int u = header + 8 + readUnsignedShort(header + 6) * 2;
2217         // skips fields and methods
2218         for (int i = readUnsignedShort(u); i > 0; --i) {
2219             for (int j = readUnsignedShort(u + 8); j > 0; --j) {
2220                 u += 6 + readInt(u + 12);
2221             }
2222             u += 8;
2223         }
2224         u += 2;
2225         for (int i = readUnsignedShort(u); i > 0; --i) {
2226             for (int j = readUnsignedShort(u + 8); j > 0; --j) {
2227                 u += 6 + readInt(u + 12);
2228             }
2229             u += 8;
2230         }
2231         // the attribute_info structure starts just after the methods
2232         return u + 2;
2233     }
2234 
2235     /**
2236      * Reads an attribute in {@link #b b}.
2237      *
2238      * @param attrs
2239      *            prototypes of the attributes that must be parsed during the
2240      *            visit of the class. Any attribute whose type is not equal to
2241      *            the type of one the prototypes is ignored (i.e. an empty
2242      *            {@link Attribute} instance is returned).
2243      * @param type
2244      *            the type of the attribute.
2245      * @param off
2246      *            index of the first byte of the attribute's content in
2247      *            {@link #b b}. The 6 attribute header bytes, containing the
2248      *            type and the length of the attribute, are not taken into
2249      *            account here (they have already been read).
2250      * @param len
2251      *            the length of the attribute's content.
2252      * @param buf
2253      *            buffer to be used to call {@link #readUTF8 readUTF8},
2254      *            {@link #readClass(int,char[]) readClass} or {@link #readConst
2255      *            readConst}.
2256      * @param codeOff
2257      *            index of the first byte of code's attribute content in
2258      *            {@link #b b}, or -1 if the attribute to be read is not a code
2259      *            attribute. The 6 attribute header bytes, containing the type
2260      *            and the length of the attribute, are not taken into account
2261      *            here.
2262      * @param labels
2263      *            the labels of the method's code, or <tt>null</tt> if the
2264      *            attribute to be read is not a code attribute.
2265      * @return the attribute that has been read, or <tt>null</tt> to skip this
2266      *         attribute.
2267      */
2268     private Attribute readAttribute(final Attribute[] attrs, final String type,
2269             final int off, final int len, final char[] buf, final int codeOff,
2270             final Label[] labels) {
2271         for (int i = 0; i < attrs.length; ++i) {
2272             if (attrs[i].type.equals(type)) {
2273                 return attrs[i].read(this, off, len, buf, codeOff, labels);
2274             }
2275         }
2276         return new Attribute(type).read(this, off, len, null, -1, null);
2277     }
2278 
2279     // ------------------------------------------------------------------------
2280     // Utility methods: low level parsing
2281     // ------------------------------------------------------------------------
2282 
2283     /**
2284      * Returns the number of constant pool items in {@link #b b}.
2285      *
2286      * @return the number of constant pool items in {@link #b b}.
2287      */
2288     public int getItemCount() {
2289         return items.length;
2290     }
2291 
2292     /**
2293      * Returns the start index of the constant pool item in {@link #b b}, plus
2294      * one. <i>This method is intended for {@link Attribute} sub classes, and is
2295      * normally not needed by class generators or adapters.</i>
2296      *
2297      * @param item
2298      *            the index a constant pool item.
2299      * @return the start index of the constant pool item in {@link #b b}, plus
2300      *         one.
2301      */
2302     public int getItem(final int item) {
2303         return items[item];
2304     }
2305 
2306     /**
2307      * Returns the maximum length of the strings contained in the constant pool
2308      * of the class.
2309      *
2310      * @return the maximum length of the strings contained in the constant pool
2311      *         of the class.
2312      */
2313     public int getMaxStringLength() {
2314         return maxStringLength;
2315     }
2316 
2317     /**
2318      * Reads a byte value in {@link #b b}. <i>This method is intended for
2319      * {@link Attribute} sub classes, and is normally not needed by class
2320      * generators or adapters.</i>
2321      *
2322      * @param index
2323      *            the start index of the value to be read in {@link #b b}.
2324      * @return the read value.
2325      */
2326     public int readByte(final int index) {
2327         return b[index] & 0xFF;
2328     }
2329 
2330     /**
2331      * Reads an unsigned short value in {@link #b b}. <i>This method is intended
2332      * for {@link Attribute} sub classes, and is normally not needed by class
2333      * generators or adapters.</i>
2334      *
2335      * @param index
2336      *            the start index of the value to be read in {@link #b b}.
2337      * @return the read value.
2338      */
2339     public int readUnsignedShort(final int index) {
2340         byte[] b = this.b;
2341         return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF);
2342     }
2343 
2344     /**
2345      * Reads a signed short value in {@link #b b}. <i>This method is intended
2346      * for {@link Attribute} sub classes, and is normally not needed by class
2347      * generators or adapters.</i>
2348      *
2349      * @param index
2350      *            the start index of the value to be read in {@link #b b}.
2351      * @return the read value.
2352      */
2353     public short readShort(final int index) {
2354         byte[] b = this.b;
2355         return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF));
2356     }
2357 
2358     /**
2359      * Reads a signed int value in {@link #b b}. <i>This method is intended for
2360      * {@link Attribute} sub classes, and is normally not needed by class
2361      * generators or adapters.</i>
2362      *
2363      * @param index
2364      *            the start index of the value to be read in {@link #b b}.
2365      * @return the read value.
2366      */
2367     public int readInt(final int index) {
2368         byte[] b = this.b;
2369         return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16)
2370                 | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF);
2371     }
2372 
2373     /**
2374      * Reads a signed long value in {@link #b b}. <i>This method is intended for
2375      * {@link Attribute} sub classes, and is normally not needed by class
2376      * generators or adapters.</i>
2377      *
2378      * @param index
2379      *            the start index of the value to be read in {@link #b b}.
2380      * @return the read value.
2381      */
2382     public long readLong(final int index) {
2383         long l1 = readInt(index);
2384         long l0 = readInt(index + 4) & 0xFFFFFFFFL;
2385         return (l1 << 32) | l0;
2386     }
2387 
2388     /**
2389      * Reads an UTF8 string constant pool item in {@link #b b}. <i>This method
2390      * is intended for {@link Attribute} sub classes, and is normally not needed
2391      * by class generators or adapters.</i>
2392      *
2393      * @param index
2394      *            the start index of an unsigned short value in {@link #b b},
2395      *            whose value is the index of an UTF8 constant pool item.
2396      * @param buf
2397      *            buffer to be used to read the item. This buffer must be
2398      *            sufficiently large. It is not automatically resized.
2399      * @return the String corresponding to the specified UTF8 item.
2400      */
2401     public String readUTF8(int index, final char[] buf) {
2402         int item = readUnsignedShort(index);
2403         if (index == 0 || item == 0) {
2404             return null;
2405         }
2406         String s = strings[item];
2407         if (s != null) {
2408             return s;
2409         }
2410         index = items[item];
2411         return strings[item] = readUTF(index + 2, readUnsignedShort(index), buf);
2412     }
2413 
2414     /**
2415      * Reads UTF8 string in {@link #b b}.
2416      *
2417      * @param index
2418      *            start offset of the UTF8 string to be read.
2419      * @param utfLen
2420      *            length of the UTF8 string to be read.
2421      * @param buf
2422      *            buffer to be used to read the string. This buffer must be
2423      *            sufficiently large. It is not automatically resized.
2424      * @return the String corresponding to the specified UTF8 string.
2425      */
2426     private String readUTF(int index, final int utfLen, final char[] buf) {
2427         int endIndex = index + utfLen;
2428         byte[] b = this.b;
2429         int strLen = 0;
2430         int c;
2431         int st = 0;
2432         char cc = 0;
2433         while (index < endIndex) {
2434             c = b[index++];
2435             switch (st) {
2436             case 0:
2437                 c = c & 0xFF;
2438                 if (c < 0x80) { // 0xxxxxxx
2439                     buf[strLen++] = (char) c;
2440                 } else if (c < 0xE0 && c > 0xBF) { // 110x xxxx 10xx xxxx
2441                     cc = (char) (c & 0x1F);
2442                     st = 1;
2443                 } else { // 1110 xxxx 10xx xxxx 10xx xxxx
2444                     cc = (char) (c & 0x0F);
2445                     st = 2;
2446                 }
2447                 break;
2448 
2449             case 1: // byte 2 of 2-byte char or byte 3 of 3-byte char
2450                 buf[strLen++] = (char) ((cc << 6) | (c & 0x3F));
2451                 st = 0;
2452                 break;
2453 
2454             case 2: // byte 2 of 3-byte char
2455                 cc = (char) ((cc << 6) | (c & 0x3F));
2456                 st = 1;
2457                 break;
2458             }
2459         }
2460         return new String(buf, 0, strLen);
2461     }
2462 
2463     /**
2464      * Reads a class constant pool item in {@link #b b}. <i>This method is
2465      * intended for {@link Attribute} sub classes, and is normally not needed by
2466      * class generators or adapters.</i>
2467      *
2468      * @param index
2469      *            the start index of an unsigned short value in {@link #b b},
2470      *            whose value is the index of a class constant pool item.
2471      * @param buf
2472      *            buffer to be used to read the item. This buffer must be
2473      *            sufficiently large. It is not automatically resized.
2474      * @return the String corresponding to the specified class item.
2475      */
2476     public String readClass(final int index, final char[] buf) {
2477         // computes the start index of the CONSTANT_Class item in b
2478         // and reads the CONSTANT_Utf8 item designated by
2479         // the first two bytes of this CONSTANT_Class item
2480         return readUTF8(items[readUnsignedShort(index)], buf);
2481     }
2482 
2483     /**
2484      * Reads a numeric or string constant pool item in {@link #b b}. <i>This
2485      * method is intended for {@link Attribute} sub classes, and is normally not
2486      * needed by class generators or adapters.</i>
2487      *
2488      * @param item
2489      *            the index of a constant pool item.
2490      * @param buf
2491      *            buffer to be used to read the item. This buffer must be
2492      *            sufficiently large. It is not automatically resized.
2493      * @return the {@link Integer}, {@link Float}, {@link Long}, {@link Double},
2494      *         {@link String}, {@link Type} or {@link Handle} corresponding to
2495      *         the given constant pool item.
2496      */
2497     public Object readConst(final int item, final char[] buf) {
2498         int index = items[item];
2499         switch (b[index - 1]) {
2500         case ClassWriter.INT:
2501             return new Integer(readInt(index));
2502         case ClassWriter.FLOAT:
2503             return new Float(Float.intBitsToFloat(readInt(index)));
2504         case ClassWriter.LONG:
2505             return new Long(readLong(index));
2506         case ClassWriter.DOUBLE:
2507             return new Double(Double.longBitsToDouble(readLong(index)));
2508         case ClassWriter.CLASS:
2509             return Type.getObjectType(readUTF8(index, buf));
2510         case ClassWriter.STR:
2511             return readUTF8(index, buf);
2512         case ClassWriter.MTYPE:
2513             return Type.getMethodType(readUTF8(index, buf));
2514         default: // case ClassWriter.HANDLE_BASE + [1..9]:
2515             int tag = readByte(index);
2516             int[] items = this.items;
2517             int cpIndex = items[readUnsignedShort(index + 1)];
2518             String owner = readClass(cpIndex, buf);
2519             cpIndex = items[readUnsignedShort(cpIndex + 2)];
2520             String name = readUTF8(cpIndex, buf);
2521             String desc = readUTF8(cpIndex + 2, buf);
2522             return new Handle(tag, owner, name, desc);
2523         }
2524     }
2525 }