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