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