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 
  60 package jdk.internal.org.objectweb.asm;
  61 
  62 import java.io.ByteArrayOutputStream;
  63 import java.io.IOException;
  64 import java.io.InputStream;
  65 
  66 /**
  67  * A parser to make a {@link ClassVisitor} visit a ClassFile structure, as defined in the Java
  68  * Virtual Machine Specification (JVMS). This class parses the ClassFile content and calls the
  69  * appropriate visit methods of a given {@link ClassVisitor} for each field, method and bytecode
  70  * instruction encountered.
  71  *
  72  * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html">JVMS 4</a>
  73  * @author Eric Bruneton
  74  * @author Eugene Kuleshov
  75  */
  76 public class ClassReader {
  77 
  78     /**
  79       * A flag to skip the Code attributes. If this flag is set the Code attributes are neither parsed
  80       * nor visited.
  81       */
  82     public static final int SKIP_CODE = 1;
  83 
  84     /**
  85       * A flag to skip the SourceFile, SourceDebugExtension, LocalVariableTable,
  86       * LocalVariableTypeTable, LineNumberTable and MethodParameters attributes. If this flag is set
  87       * these attributes are neither parsed nor visited (i.e. {@link ClassVisitor#visitSource}, {@link
  88       * MethodVisitor#visitLocalVariable}, {@link MethodVisitor#visitLineNumber} and {@link
  89       * MethodVisitor#visitParameter} are not called).
  90       */
  91     public static final int SKIP_DEBUG = 2;
  92 
  93     /**
  94       * A flag to skip the StackMap and StackMapTable attributes. If this flag is set these attributes
  95       * are neither parsed nor visited (i.e. {@link MethodVisitor#visitFrame} is not called). This flag
  96       * is useful when the {@link ClassWriter#COMPUTE_FRAMES} option is used: it avoids visiting frames
  97       * that will be ignored and recomputed from scratch.
  98       */
  99     public static final int SKIP_FRAMES = 4;
 100 
 101     /**
 102       * A flag to expand the stack map frames. By default stack map frames are visited in their
 103       * original format (i.e. "expanded" for classes whose version is less than V1_6, and "compressed"
 104       * for the other classes). If this flag is set, stack map frames are always visited in expanded
 105       * format (this option adds a decompression/compression step in ClassReader and ClassWriter which
 106       * degrades performance quite a lot).
 107       */
 108     public static final int EXPAND_FRAMES = 8;
 109 
 110     /**
 111       * A flag to expand the ASM specific instructions into an equivalent sequence of standard bytecode
 112       * instructions. When resolving a forward jump it may happen that the signed 2 bytes offset
 113       * reserved for it is not sufficient to store the bytecode offset. In this case the jump
 114       * instruction is replaced with a temporary ASM specific instruction using an unsigned 2 bytes
 115       * offset (see {@link Label#resolve}). This internal flag is used to re-read classes containing
 116       * such instructions, in order to replace them with standard instructions. In addition, when this
 117       * flag is used, goto_w and jsr_w are <i>not</i> converted into goto and jsr, to make sure that
 118       * infinite loops where a goto_w is replaced with a goto in ClassReader and converted back to a
 119       * goto_w in ClassWriter cannot occur.
 120       */
 121     static final int EXPAND_ASM_INSNS = 256;
 122 
 123     /** The maximum size of array to allocate. */
 124     private static final int MAX_BUFFER_SIZE = 1024 * 1024;
 125 
 126     /** The size of the temporary byte array used to read class input streams chunk by chunk. */
 127     private static final int INPUT_STREAM_DATA_CHUNK_SIZE = 4096;
 128 
 129     /**
 130       * A byte array containing the JVMS ClassFile structure to be parsed.
 131       *
 132       * @deprecated Use {@link #readByte(int)} and the other read methods instead. This field will
 133       *     eventually be deleted.
 134       */
 135     @Deprecated
 136     // DontCheck(MemberName): can't be renamed (for backward binary compatibility).
 137     public final byte[] b;
 138 
 139     /** The offset in bytes of the ClassFile's access_flags field. */
 140     public final int header;
 141 
 142     /**
 143       * A byte array containing the JVMS ClassFile structure to be parsed. <i>The content of this array
 144       * must not be modified. This field is intended for {@link Attribute} sub classes, and is normally
 145       * not needed by class visitors.</i>
 146       *
 147       * <p>NOTE: the ClassFile structure can start at any offset within this array, i.e. it does not
 148       * necessarily start at offset 0. Use {@link #getItem} and {@link #header} to get correct
 149       * ClassFile element offsets within this byte array.
 150       */
 151     final byte[] classFileBuffer;
 152 
 153     /**
 154       * The offset in bytes, in {@link #classFileBuffer}, of each cp_info entry of the ClassFile's
 155       * constant_pool array, <i>plus one</i>. In other words, the offset of constant pool entry i is
 156       * given by cpInfoOffsets[i] - 1, i.e. its cp_info's tag field is given by b[cpInfoOffsets[i] -
 157       * 1].
 158       */
 159     private final int[] cpInfoOffsets;
 160 
 161     /**
 162       * The String objects corresponding to the CONSTANT_Utf8 constant pool items. This cache avoids
 163       * multiple parsing of a given CONSTANT_Utf8 constant pool item.
 164       */
 165     private final String[] constantUtf8Values;
 166 
 167     /**
 168       * The ConstantDynamic objects corresponding to the CONSTANT_Dynamic constant pool items. This
 169       * cache avoids multiple parsing of a given CONSTANT_Dynamic constant pool item.
 170       */
 171     private final ConstantDynamic[] constantDynamicValues;
 172 
 173     /**
 174       * The start offsets in {@link #classFileBuffer} of each element of the bootstrap_methods array
 175       * (in the BootstrapMethods attribute).
 176       *
 177       * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.23">JVMS
 178       *     4.7.23</a>
 179       */
 180     private final int[] bootstrapMethodOffsets;
 181 
 182     /**
 183       * A conservative estimate of the maximum length of the strings contained in the constant pool of
 184       * the class.
 185       */
 186     private final int maxStringLength;
 187 
 188     // -----------------------------------------------------------------------------------------------
 189     // Constructors
 190     // -----------------------------------------------------------------------------------------------
 191 
 192     /**
 193       * Constructs a new {@link ClassReader} object.
 194       *
 195       * @param classFile the JVMS ClassFile structure to be read.
 196       */
 197     public ClassReader(final byte[] classFile) {
 198         this(classFile, 0, classFile.length);
 199     }
 200 
 201     /**
 202       * Constructs a new {@link ClassReader} object.
 203       *
 204       * @param classFileBuffer a byte array containing the JVMS ClassFile structure to be read.
 205       * @param classFileOffset the offset in byteBuffer of the first byte of the ClassFile to be read.
 206       * @param classFileLength the length in bytes of the ClassFile to be read.
 207       */
 208     public ClassReader(
 209             final byte[] classFileBuffer,
 210             final int classFileOffset,
 211             final int classFileLength) { // NOPMD(UnusedFormalParameter) used for backward compatibility.
 212         this(classFileBuffer, classFileOffset, /* checkClassVersion = */ true);
 213     }
 214 
 215     /**
 216       * Constructs a new {@link ClassReader} object. <i>This internal constructor must not be exposed
 217       * as a public API</i>.
 218       *
 219       * @param classFileBuffer a byte array containing the JVMS ClassFile structure to be read.
 220       * @param classFileOffset the offset in byteBuffer of the first byte of the ClassFile to be read.
 221       * @param checkClassVersion whether to check the class version or not.
 222       */
 223     ClassReader(
 224             final byte[] classFileBuffer, final int classFileOffset, final boolean checkClassVersion) {
 225         this.classFileBuffer = classFileBuffer;
 226         this.b = classFileBuffer;
 227         // Check the class' major_version. This field is after the magic and minor_version fields, which
 228         // use 4 and 2 bytes respectively.
 229         if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V21) {
 230             throw new IllegalArgumentException(
 231                     "Unsupported class file major version " + readShort(classFileOffset + 6));
 232         }
 233         // Create the constant pool arrays. The constant_pool_count field is after the magic,
 234         // minor_version and major_version fields, which use 4, 2 and 2 bytes respectively.
 235         int constantPoolCount = readUnsignedShort(classFileOffset + 8);
 236         cpInfoOffsets = new int[constantPoolCount];
 237         constantUtf8Values = new String[constantPoolCount];
 238         // Compute the offset of each constant pool entry, as well as a conservative estimate of the
 239         // maximum length of the constant pool strings. The first constant pool entry is after the
 240         // magic, minor_version, major_version and constant_pool_count fields, which use 4, 2, 2 and 2
 241         // bytes respectively.
 242         int currentCpInfoIndex = 1;
 243         int currentCpInfoOffset = classFileOffset + 10;
 244         int currentMaxStringLength = 0;
 245         boolean hasBootstrapMethods = false;
 246         boolean hasConstantDynamic = false;
 247         // The offset of the other entries depend on the total size of all the previous entries.
 248         while (currentCpInfoIndex < constantPoolCount) {
 249             cpInfoOffsets[currentCpInfoIndex++] = currentCpInfoOffset + 1;
 250             int cpInfoSize;
 251             switch (classFileBuffer[currentCpInfoOffset]) {
 252                 case Symbol.CONSTANT_FIELDREF_TAG:
 253                 case Symbol.CONSTANT_METHODREF_TAG:
 254                 case Symbol.CONSTANT_INTERFACE_METHODREF_TAG:
 255                 case Symbol.CONSTANT_INTEGER_TAG:
 256                 case Symbol.CONSTANT_FLOAT_TAG:
 257                 case Symbol.CONSTANT_NAME_AND_TYPE_TAG:
 258                     cpInfoSize = 5;
 259                     break;
 260                 case Symbol.CONSTANT_DYNAMIC_TAG:
 261                     cpInfoSize = 5;
 262                     hasBootstrapMethods = true;
 263                     hasConstantDynamic = true;
 264                     break;
 265                 case Symbol.CONSTANT_INVOKE_DYNAMIC_TAG:
 266                     cpInfoSize = 5;
 267                     hasBootstrapMethods = true;
 268                     break;
 269                 case Symbol.CONSTANT_LONG_TAG:
 270                 case Symbol.CONSTANT_DOUBLE_TAG:
 271                     cpInfoSize = 9;
 272                     currentCpInfoIndex++;
 273                     break;
 274                 case Symbol.CONSTANT_UTF8_TAG:
 275                     cpInfoSize = 3 + readUnsignedShort(currentCpInfoOffset + 1);
 276                     if (cpInfoSize > currentMaxStringLength) {
 277                         // The size in bytes of this CONSTANT_Utf8 structure provides a conservative estimate
 278                         // of the length in characters of the corresponding string, and is much cheaper to
 279                         // compute than this exact length.
 280                         currentMaxStringLength = cpInfoSize;
 281                     }
 282                     break;
 283                 case Symbol.CONSTANT_METHOD_HANDLE_TAG:
 284                     cpInfoSize = 4;
 285                     break;
 286                 case Symbol.CONSTANT_CLASS_TAG:
 287                 case Symbol.CONSTANT_STRING_TAG:
 288                 case Symbol.CONSTANT_METHOD_TYPE_TAG:
 289                 case Symbol.CONSTANT_PACKAGE_TAG:
 290                 case Symbol.CONSTANT_MODULE_TAG:
 291                     cpInfoSize = 3;
 292                     break;
 293                 default:
 294                     throw new IllegalArgumentException();
 295             }
 296             currentCpInfoOffset += cpInfoSize;
 297         }
 298         maxStringLength = currentMaxStringLength;
 299         // The Classfile's access_flags field is just after the last constant pool entry.
 300         header = currentCpInfoOffset;
 301 
 302         // Allocate the cache of ConstantDynamic values, if there is at least one.
 303         constantDynamicValues = hasConstantDynamic ? new ConstantDynamic[constantPoolCount] : null;
 304 
 305         // Read the BootstrapMethods attribute, if any (only get the offset of each method).
 306         bootstrapMethodOffsets =
 307                 hasBootstrapMethods ? readBootstrapMethodsAttribute(currentMaxStringLength) : null;
 308     }
 309 
 310     /**
 311       * Constructs a new {@link ClassReader} object.
 312       *
 313       * @param inputStream an input stream of the JVMS ClassFile structure to be read. This input
 314       *     stream must contain nothing more than the ClassFile structure itself. It is read from its
 315       *     current position to its end.
 316       * @throws IOException if a problem occurs during reading.
 317       */
 318     public ClassReader(final InputStream inputStream) throws IOException {
 319         this(readStream(inputStream, false));
 320     }
 321 
 322     /**
 323       * Constructs a new {@link ClassReader} object.
 324       *
 325       * @param className the fully qualified name of the class to be read. The ClassFile structure is
 326       *     retrieved with the current class loader's {@link ClassLoader#getSystemResourceAsStream}.
 327       * @throws IOException if an exception occurs during reading.
 328       */
 329     public ClassReader(final String className) throws IOException {
 330         this(
 331                 readStream(
 332                         ClassLoader.getSystemResourceAsStream(className.replace('.', '/') + ".class"), true));
 333     }
 334 
 335     /**
 336       * Reads the given input stream and returns its content as a byte array.
 337       *
 338       * @param inputStream an input stream.
 339       * @param close true to close the input stream after reading.
 340       * @return the content of the given input stream.
 341       * @throws IOException if a problem occurs during reading.
 342       */
 343     @SuppressWarnings("PMD.UseTryWithResources")
 344     private static byte[] readStream(final InputStream inputStream, final boolean close)
 345             throws IOException {
 346         if (inputStream == null) {
 347             throw new IOException("Class not found");
 348         }
 349         int bufferSize = computeBufferSize(inputStream);
 350         try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
 351             byte[] data = new byte[bufferSize];
 352             int bytesRead;
 353             int readCount = 0;
 354             while ((bytesRead = inputStream.read(data, 0, bufferSize)) != -1) {
 355                 outputStream.write(data, 0, bytesRead);
 356                 readCount++;
 357             }
 358             outputStream.flush();
 359             if (readCount == 1) {
 360                 return data;
 361             }
 362             return outputStream.toByteArray();
 363         } finally {
 364             if (close) {
 365                 inputStream.close();
 366             }
 367         }
 368     }
 369 
 370     private static int computeBufferSize(final InputStream inputStream) throws IOException {
 371         int expectedLength = inputStream.available();
 372         /*
 373           * Some implementations can return 0 while holding available data (e.g. new
 374           * FileInputStream("/proc/a_file")). Also in some pathological cases a very small number might
 375           * be returned, and in this case we use a default size.
 376           */
 377         if (expectedLength < 256) {
 378             return INPUT_STREAM_DATA_CHUNK_SIZE;
 379         }
 380         return Math.min(expectedLength, MAX_BUFFER_SIZE);
 381     }
 382 
 383     // -----------------------------------------------------------------------------------------------
 384     // Accessors
 385     // -----------------------------------------------------------------------------------------------
 386 
 387     /**
 388       * Returns the class's access flags (see {@link Opcodes}). This value may not reflect Deprecated
 389       * and Synthetic flags when bytecode is before 1.5 and those flags are represented by attributes.
 390       *
 391       * @return the class access flags.
 392       * @see ClassVisitor#visit(int, int, String, String, String, String[])
 393       */
 394     public int getAccess() {
 395         return readUnsignedShort(header);
 396     }
 397 
 398     /**
 399       * Returns the internal name of the class (see {@link Type#getInternalName()}).
 400       *
 401       * @return the internal class name.
 402       * @see ClassVisitor#visit(int, int, String, String, String, String[])
 403       */
 404     public String getClassName() {
 405         // this_class is just after the access_flags field (using 2 bytes).
 406         return readClass(header + 2, new char[maxStringLength]);
 407     }
 408 
 409     /**
 410       * Returns the internal of name of the super class (see {@link Type#getInternalName()}). For
 411       * interfaces, the super class is {@link Object}.
 412       *
 413       * @return the internal name of the super class, or {@literal null} for {@link Object} class.
 414       * @see ClassVisitor#visit(int, int, String, String, String, String[])
 415       */
 416     public String getSuperName() {
 417         // super_class is after the access_flags and this_class fields (2 bytes each).
 418         return readClass(header + 4, new char[maxStringLength]);
 419     }
 420 
 421     /**
 422       * Returns the internal names of the implemented interfaces (see {@link Type#getInternalName()}).
 423       *
 424       * @return the internal names of the directly implemented interfaces. Inherited implemented
 425       *     interfaces are not returned.
 426       * @see ClassVisitor#visit(int, int, String, String, String, String[])
 427       */
 428     public String[] getInterfaces() {
 429         // interfaces_count is after the access_flags, this_class and super_class fields (2 bytes each).
 430         int currentOffset = header + 6;
 431         int interfacesCount = readUnsignedShort(currentOffset);
 432         String[] interfaces = new String[interfacesCount];
 433         if (interfacesCount > 0) {
 434             char[] charBuffer = new char[maxStringLength];
 435             for (int i = 0; i < interfacesCount; ++i) {
 436                 currentOffset += 2;
 437                 interfaces[i] = readClass(currentOffset, charBuffer);
 438             }
 439         }
 440         return interfaces;
 441     }
 442 
 443     // -----------------------------------------------------------------------------------------------
 444     // Public methods
 445     // -----------------------------------------------------------------------------------------------
 446 
 447     /**
 448       * Makes the given visitor visit the JVMS ClassFile structure passed to the constructor of this
 449       * {@link ClassReader}.
 450       *
 451       * @param classVisitor the visitor that must visit this class.
 452       * @param parsingOptions the options to use to parse this class. One or more of {@link
 453       *     #SKIP_CODE}, {@link #SKIP_DEBUG}, {@link #SKIP_FRAMES} or {@link #EXPAND_FRAMES}.
 454       */
 455     public void accept(final ClassVisitor classVisitor, final int parsingOptions) {
 456         accept(classVisitor, new Attribute[0], parsingOptions);
 457     }
 458 
 459     /**
 460       * Makes the given visitor visit the JVMS ClassFile structure passed to the constructor of this
 461       * {@link ClassReader}.
 462       *
 463       * @param classVisitor the visitor that must visit this class.
 464       * @param attributePrototypes prototypes of the attributes that must be parsed during the visit of
 465       *     the class. Any attribute whose type is not equal to the type of one the prototypes will not
 466       *     be parsed: its byte array value will be passed unchanged to the ClassWriter. <i>This may
 467       *     corrupt it if this value contains references to the constant pool, or has syntactic or
 468       *     semantic links with a class element that has been transformed by a class adapter between
 469       *     the reader and the writer</i>.
 470       * @param parsingOptions the options to use to parse this class. One or more of {@link
 471       *     #SKIP_CODE}, {@link #SKIP_DEBUG}, {@link #SKIP_FRAMES} or {@link #EXPAND_FRAMES}.
 472       */
 473     public void accept(
 474             final ClassVisitor classVisitor,
 475             final Attribute[] attributePrototypes,
 476             final int parsingOptions) {
 477         Context context = new Context();
 478         context.attributePrototypes = attributePrototypes;
 479         context.parsingOptions = parsingOptions;
 480         context.charBuffer = new char[maxStringLength];
 481 
 482         // Read the access_flags, this_class, super_class, interface_count and interfaces fields.
 483         char[] charBuffer = context.charBuffer;
 484         int currentOffset = header;
 485         int accessFlags = readUnsignedShort(currentOffset);
 486         String thisClass = readClass(currentOffset + 2, charBuffer);
 487         String superClass = readClass(currentOffset + 4, charBuffer);
 488         String[] interfaces = new String[readUnsignedShort(currentOffset + 6)];
 489         currentOffset += 8;
 490         for (int i = 0; i < interfaces.length; ++i) {
 491             interfaces[i] = readClass(currentOffset, charBuffer);
 492             currentOffset += 2;
 493         }
 494 
 495         // Read the class attributes (the variables are ordered as in Section 4.7 of the JVMS).
 496         // Attribute offsets exclude the attribute_name_index and attribute_length fields.
 497         // - The offset of the InnerClasses attribute, or 0.
 498         int innerClassesOffset = 0;
 499         // - The offset of the EnclosingMethod attribute, or 0.
 500         int enclosingMethodOffset = 0;
 501         // - The string corresponding to the Signature attribute, or null.
 502         String signature = null;
 503         // - The string corresponding to the SourceFile attribute, or null.
 504         String sourceFile = null;
 505         // - The string corresponding to the SourceDebugExtension attribute, or null.
 506         String sourceDebugExtension = null;
 507         // - The offset of the RuntimeVisibleAnnotations attribute, or 0.
 508         int runtimeVisibleAnnotationsOffset = 0;
 509         // - The offset of the RuntimeInvisibleAnnotations attribute, or 0.
 510         int runtimeInvisibleAnnotationsOffset = 0;
 511         // - The offset of the RuntimeVisibleTypeAnnotations attribute, or 0.
 512         int runtimeVisibleTypeAnnotationsOffset = 0;
 513         // - The offset of the RuntimeInvisibleTypeAnnotations attribute, or 0.
 514         int runtimeInvisibleTypeAnnotationsOffset = 0;
 515         // - The offset of the Module attribute, or 0.
 516         int moduleOffset = 0;
 517         // - The offset of the ModulePackages attribute, or 0.
 518         int modulePackagesOffset = 0;
 519         // - The string corresponding to the ModuleMainClass attribute, or null.
 520         String moduleMainClass = null;
 521         // - The string corresponding to the NestHost attribute, or null.
 522         String nestHostClass = null;
 523         // - The offset of the NestMembers attribute, or 0.
 524         int nestMembersOffset = 0;
 525         // - The offset of the PermittedSubclasses attribute, or 0
 526         int permittedSubclassesOffset = 0;
 527         // - The offset of the Record attribute, or 0.
 528         int recordOffset = 0;
 529         // - The non standard attributes (linked with their {@link Attribute#nextAttribute} field).
 530         //   This list in the <i>reverse order</i> or their order in the ClassFile structure.
 531         Attribute attributes = null;
 532 
 533         int currentAttributeOffset = getFirstAttributeOffset();
 534         for (int i = readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) {
 535             // Read the attribute_info's attribute_name and attribute_length fields.
 536             String attributeName = readUTF8(currentAttributeOffset, charBuffer);
 537             int attributeLength = readInt(currentAttributeOffset + 2);
 538             currentAttributeOffset += 6;
 539             // The tests are sorted in decreasing frequency order (based on frequencies observed on
 540             // typical classes).
 541             if (Constants.SOURCE_FILE.equals(attributeName)) {
 542                 sourceFile = readUTF8(currentAttributeOffset, charBuffer);
 543             } else if (Constants.INNER_CLASSES.equals(attributeName)) {
 544                 innerClassesOffset = currentAttributeOffset;
 545             } else if (Constants.ENCLOSING_METHOD.equals(attributeName)) {
 546                 enclosingMethodOffset = currentAttributeOffset;
 547             } else if (Constants.NEST_HOST.equals(attributeName)) {
 548                 nestHostClass = readClass(currentAttributeOffset, charBuffer);
 549             } else if (Constants.NEST_MEMBERS.equals(attributeName)) {
 550                 nestMembersOffset = currentAttributeOffset;
 551             } else if (Constants.PERMITTED_SUBCLASSES.equals(attributeName)) {
 552                 permittedSubclassesOffset = currentAttributeOffset;
 553             } else if (Constants.SIGNATURE.equals(attributeName)) {
 554                 signature = readUTF8(currentAttributeOffset, charBuffer);
 555             } else if (Constants.RUNTIME_VISIBLE_ANNOTATIONS.equals(attributeName)) {
 556                 runtimeVisibleAnnotationsOffset = currentAttributeOffset;
 557             } else if (Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
 558                 runtimeVisibleTypeAnnotationsOffset = currentAttributeOffset;
 559             } else if (Constants.DEPRECATED.equals(attributeName)) {
 560                 accessFlags |= Opcodes.ACC_DEPRECATED;
 561             } else if (Constants.SYNTHETIC.equals(attributeName)) {
 562                 accessFlags |= Opcodes.ACC_SYNTHETIC;
 563             } else if (Constants.SOURCE_DEBUG_EXTENSION.equals(attributeName)) {
 564                 if (attributeLength > classFileBuffer.length - currentAttributeOffset) {
 565                     throw new IllegalArgumentException();
 566                 }
 567                 sourceDebugExtension =
 568                         readUtf(currentAttributeOffset, attributeLength, new char[attributeLength]);
 569             } else if (Constants.RUNTIME_INVISIBLE_ANNOTATIONS.equals(attributeName)) {
 570                 runtimeInvisibleAnnotationsOffset = currentAttributeOffset;
 571             } else if (Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
 572                 runtimeInvisibleTypeAnnotationsOffset = currentAttributeOffset;
 573             } else if (Constants.RECORD.equals(attributeName)) {
 574                 recordOffset = currentAttributeOffset;
 575                 accessFlags |= Opcodes.ACC_RECORD;
 576             } else if (Constants.MODULE.equals(attributeName)) {
 577                 moduleOffset = currentAttributeOffset;
 578             } else if (Constants.MODULE_MAIN_CLASS.equals(attributeName)) {
 579                 moduleMainClass = readClass(currentAttributeOffset, charBuffer);
 580             } else if (Constants.MODULE_PACKAGES.equals(attributeName)) {
 581                 modulePackagesOffset = currentAttributeOffset;
 582             } else if (!Constants.BOOTSTRAP_METHODS.equals(attributeName)) {
 583                 // The BootstrapMethods attribute is read in the constructor.
 584                 Attribute attribute =
 585                         readAttribute(
 586                                 attributePrototypes,
 587                                 attributeName,
 588                                 currentAttributeOffset,
 589                                 attributeLength,
 590                                 charBuffer,
 591                                 -1,
 592                                 null);
 593                 attribute.nextAttribute = attributes;
 594                 attributes = attribute;
 595             }
 596             currentAttributeOffset += attributeLength;
 597         }
 598 
 599         // Visit the class declaration. The minor_version and major_version fields start 6 bytes before
 600         // the first constant pool entry, which itself starts at cpInfoOffsets[1] - 1 (by definition).
 601         classVisitor.visit(
 602                 readInt(cpInfoOffsets[1] - 7), accessFlags, thisClass, signature, superClass, interfaces);
 603 
 604         // Visit the SourceFile and SourceDebugExtenstion attributes.
 605         if ((parsingOptions & SKIP_DEBUG) == 0
 606                 && (sourceFile != null || sourceDebugExtension != null)) {
 607             classVisitor.visitSource(sourceFile, sourceDebugExtension);
 608         }
 609 
 610         // Visit the Module, ModulePackages and ModuleMainClass attributes.
 611         if (moduleOffset != 0) {
 612             readModuleAttributes(
 613                     classVisitor, context, moduleOffset, modulePackagesOffset, moduleMainClass);
 614         }
 615 
 616         // Visit the NestHost attribute.
 617         if (nestHostClass != null) {
 618             classVisitor.visitNestHost(nestHostClass);
 619         }
 620 
 621         // Visit the EnclosingMethod attribute.
 622         if (enclosingMethodOffset != 0) {
 623             String className = readClass(enclosingMethodOffset, charBuffer);
 624             int methodIndex = readUnsignedShort(enclosingMethodOffset + 2);
 625             String name = methodIndex == 0 ? null : readUTF8(cpInfoOffsets[methodIndex], charBuffer);
 626             String type = methodIndex == 0 ? null : readUTF8(cpInfoOffsets[methodIndex] + 2, charBuffer);
 627             classVisitor.visitOuterClass(className, name, type);
 628         }
 629 
 630         // Visit the RuntimeVisibleAnnotations attribute.
 631         if (runtimeVisibleAnnotationsOffset != 0) {
 632             int numAnnotations = readUnsignedShort(runtimeVisibleAnnotationsOffset);
 633             int currentAnnotationOffset = runtimeVisibleAnnotationsOffset + 2;
 634             while (numAnnotations-- > 0) {
 635                 // Parse the type_index field.
 636                 String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
 637                 currentAnnotationOffset += 2;
 638                 // Parse num_element_value_pairs and element_value_pairs and visit these values.
 639                 currentAnnotationOffset =
 640                         readElementValues(
 641                                 classVisitor.visitAnnotation(annotationDescriptor, /* visible = */ true),
 642                                 currentAnnotationOffset,
 643                                 /* named = */ true,
 644                                 charBuffer);
 645             }
 646         }
 647 
 648         // Visit the RuntimeInvisibleAnnotations attribute.
 649         if (runtimeInvisibleAnnotationsOffset != 0) {
 650             int numAnnotations = readUnsignedShort(runtimeInvisibleAnnotationsOffset);
 651             int currentAnnotationOffset = runtimeInvisibleAnnotationsOffset + 2;
 652             while (numAnnotations-- > 0) {
 653                 // Parse the type_index field.
 654                 String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
 655                 currentAnnotationOffset += 2;
 656                 // Parse num_element_value_pairs and element_value_pairs and visit these values.
 657                 currentAnnotationOffset =
 658                         readElementValues(
 659                                 classVisitor.visitAnnotation(annotationDescriptor, /* visible = */ false),
 660                                 currentAnnotationOffset,
 661                                 /* named = */ true,
 662                                 charBuffer);
 663             }
 664         }
 665 
 666         // Visit the RuntimeVisibleTypeAnnotations attribute.
 667         if (runtimeVisibleTypeAnnotationsOffset != 0) {
 668             int numAnnotations = readUnsignedShort(runtimeVisibleTypeAnnotationsOffset);
 669             int currentAnnotationOffset = runtimeVisibleTypeAnnotationsOffset + 2;
 670             while (numAnnotations-- > 0) {
 671                 // Parse the target_type, target_info and target_path fields.
 672                 currentAnnotationOffset = readTypeAnnotationTarget(context, currentAnnotationOffset);
 673                 // Parse the type_index field.
 674                 String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
 675                 currentAnnotationOffset += 2;
 676                 // Parse num_element_value_pairs and element_value_pairs and visit these values.
 677                 currentAnnotationOffset =
 678                         readElementValues(
 679                                 classVisitor.visitTypeAnnotation(
 680                                         context.currentTypeAnnotationTarget,
 681                                         context.currentTypeAnnotationTargetPath,
 682                                         annotationDescriptor,
 683                                         /* visible = */ true),
 684                                 currentAnnotationOffset,
 685                                 /* named = */ true,
 686                                 charBuffer);
 687             }
 688         }
 689 
 690         // Visit the RuntimeInvisibleTypeAnnotations attribute.
 691         if (runtimeInvisibleTypeAnnotationsOffset != 0) {
 692             int numAnnotations = readUnsignedShort(runtimeInvisibleTypeAnnotationsOffset);
 693             int currentAnnotationOffset = runtimeInvisibleTypeAnnotationsOffset + 2;
 694             while (numAnnotations-- > 0) {
 695                 // Parse the target_type, target_info and target_path fields.
 696                 currentAnnotationOffset = readTypeAnnotationTarget(context, currentAnnotationOffset);
 697                 // Parse the type_index field.
 698                 String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
 699                 currentAnnotationOffset += 2;
 700                 // Parse num_element_value_pairs and element_value_pairs and visit these values.
 701                 currentAnnotationOffset =
 702                         readElementValues(
 703                                 classVisitor.visitTypeAnnotation(
 704                                         context.currentTypeAnnotationTarget,
 705                                         context.currentTypeAnnotationTargetPath,
 706                                         annotationDescriptor,
 707                                         /* visible = */ false),
 708                                 currentAnnotationOffset,
 709                                 /* named = */ true,
 710                                 charBuffer);
 711             }
 712         }
 713 
 714         // Visit the non standard attributes.
 715         while (attributes != null) {
 716             // Copy and reset the nextAttribute field so that it can also be used in ClassWriter.
 717             Attribute nextAttribute = attributes.nextAttribute;
 718             attributes.nextAttribute = null;
 719             classVisitor.visitAttribute(attributes);
 720             attributes = nextAttribute;
 721         }
 722 
 723         // Visit the NestedMembers attribute.
 724         if (nestMembersOffset != 0) {
 725             int numberOfNestMembers = readUnsignedShort(nestMembersOffset);
 726             int currentNestMemberOffset = nestMembersOffset + 2;
 727             while (numberOfNestMembers-- > 0) {
 728                 classVisitor.visitNestMember(readClass(currentNestMemberOffset, charBuffer));
 729                 currentNestMemberOffset += 2;
 730             }
 731         }
 732 
 733         // Visit the PermittedSubclasses attribute.
 734         if (permittedSubclassesOffset != 0) {
 735             int numberOfPermittedSubclasses = readUnsignedShort(permittedSubclassesOffset);
 736             int currentPermittedSubclassesOffset = permittedSubclassesOffset + 2;
 737             while (numberOfPermittedSubclasses-- > 0) {
 738                 classVisitor.visitPermittedSubclass(
 739                         readClass(currentPermittedSubclassesOffset, charBuffer));
 740                 currentPermittedSubclassesOffset += 2;
 741             }
 742         }
 743 
 744         // Visit the InnerClasses attribute.
 745         if (innerClassesOffset != 0) {
 746             int numberOfClasses = readUnsignedShort(innerClassesOffset);
 747             int currentClassesOffset = innerClassesOffset + 2;
 748             while (numberOfClasses-- > 0) {
 749                 classVisitor.visitInnerClass(
 750                         readClass(currentClassesOffset, charBuffer),
 751                         readClass(currentClassesOffset + 2, charBuffer),
 752                         readUTF8(currentClassesOffset + 4, charBuffer),
 753                         readUnsignedShort(currentClassesOffset + 6));
 754                 currentClassesOffset += 8;
 755             }
 756         }
 757 
 758         // Visit Record components.
 759         if (recordOffset != 0) {
 760             int recordComponentsCount = readUnsignedShort(recordOffset);
 761             recordOffset += 2;
 762             while (recordComponentsCount-- > 0) {
 763                 recordOffset = readRecordComponent(classVisitor, context, recordOffset);
 764             }
 765         }
 766 
 767         // Visit the fields and methods.
 768         int fieldsCount = readUnsignedShort(currentOffset);
 769         currentOffset += 2;
 770         while (fieldsCount-- > 0) {
 771             currentOffset = readField(classVisitor, context, currentOffset);
 772         }
 773         int methodsCount = readUnsignedShort(currentOffset);
 774         currentOffset += 2;
 775         while (methodsCount-- > 0) {
 776             currentOffset = readMethod(classVisitor, context, currentOffset);
 777         }
 778 
 779         // Visit the end of the class.
 780         classVisitor.visitEnd();
 781     }
 782 
 783     // ----------------------------------------------------------------------------------------------
 784     // Methods to parse modules, fields and methods
 785     // ----------------------------------------------------------------------------------------------
 786 
 787     /**
 788       * Reads the Module, ModulePackages and ModuleMainClass attributes and visit them.
 789       *
 790       * @param classVisitor the current class visitor
 791       * @param context information about the class being parsed.
 792       * @param moduleOffset the offset of the Module attribute (excluding the attribute_info's
 793       *     attribute_name_index and attribute_length fields).
 794       * @param modulePackagesOffset the offset of the ModulePackages attribute (excluding the
 795       *     attribute_info's attribute_name_index and attribute_length fields), or 0.
 796       * @param moduleMainClass the string corresponding to the ModuleMainClass attribute, or {@literal
 797       *     null}.
 798       */
 799     private void readModuleAttributes(
 800             final ClassVisitor classVisitor,
 801             final Context context,
 802             final int moduleOffset,
 803             final int modulePackagesOffset,
 804             final String moduleMainClass) {
 805         char[] buffer = context.charBuffer;
 806 
 807         // Read the module_name_index, module_flags and module_version_index fields and visit them.
 808         int currentOffset = moduleOffset;
 809         String moduleName = readModule(currentOffset, buffer);
 810         int moduleFlags = readUnsignedShort(currentOffset + 2);
 811         String moduleVersion = readUTF8(currentOffset + 4, buffer);
 812         currentOffset += 6;
 813         ModuleVisitor moduleVisitor = classVisitor.visitModule(moduleName, moduleFlags, moduleVersion);
 814         if (moduleVisitor == null) {
 815             return;
 816         }
 817 
 818         // Visit the ModuleMainClass attribute.
 819         if (moduleMainClass != null) {
 820             moduleVisitor.visitMainClass(moduleMainClass);
 821         }
 822 
 823         // Visit the ModulePackages attribute.
 824         if (modulePackagesOffset != 0) {
 825             int packageCount = readUnsignedShort(modulePackagesOffset);
 826             int currentPackageOffset = modulePackagesOffset + 2;
 827             while (packageCount-- > 0) {
 828                 moduleVisitor.visitPackage(readPackage(currentPackageOffset, buffer));
 829                 currentPackageOffset += 2;
 830             }
 831         }
 832 
 833         // Read the 'requires_count' and 'requires' fields.
 834         int requiresCount = readUnsignedShort(currentOffset);
 835         currentOffset += 2;
 836         while (requiresCount-- > 0) {
 837             // Read the requires_index, requires_flags and requires_version fields and visit them.
 838             String requires = readModule(currentOffset, buffer);
 839             int requiresFlags = readUnsignedShort(currentOffset + 2);
 840             String requiresVersion = readUTF8(currentOffset + 4, buffer);
 841             currentOffset += 6;
 842             moduleVisitor.visitRequire(requires, requiresFlags, requiresVersion);
 843         }
 844 
 845         // Read the 'exports_count' and 'exports' fields.
 846         int exportsCount = readUnsignedShort(currentOffset);
 847         currentOffset += 2;
 848         while (exportsCount-- > 0) {
 849             // Read the exports_index, exports_flags, exports_to_count and exports_to_index fields
 850             // and visit them.
 851             String exports = readPackage(currentOffset, buffer);
 852             int exportsFlags = readUnsignedShort(currentOffset + 2);
 853             int exportsToCount = readUnsignedShort(currentOffset + 4);
 854             currentOffset += 6;
 855             String[] exportsTo = null;
 856             if (exportsToCount != 0) {
 857                 exportsTo = new String[exportsToCount];
 858                 for (int i = 0; i < exportsToCount; ++i) {
 859                     exportsTo[i] = readModule(currentOffset, buffer);
 860                     currentOffset += 2;
 861                 }
 862             }
 863             moduleVisitor.visitExport(exports, exportsFlags, exportsTo);
 864         }
 865 
 866         // Reads the 'opens_count' and 'opens' fields.
 867         int opensCount = readUnsignedShort(currentOffset);
 868         currentOffset += 2;
 869         while (opensCount-- > 0) {
 870             // Read the opens_index, opens_flags, opens_to_count and opens_to_index fields and visit them.
 871             String opens = readPackage(currentOffset, buffer);
 872             int opensFlags = readUnsignedShort(currentOffset + 2);
 873             int opensToCount = readUnsignedShort(currentOffset + 4);
 874             currentOffset += 6;
 875             String[] opensTo = null;
 876             if (opensToCount != 0) {
 877                 opensTo = new String[opensToCount];
 878                 for (int i = 0; i < opensToCount; ++i) {
 879                     opensTo[i] = readModule(currentOffset, buffer);
 880                     currentOffset += 2;
 881                 }
 882             }
 883             moduleVisitor.visitOpen(opens, opensFlags, opensTo);
 884         }
 885 
 886         // Read the 'uses_count' and 'uses' fields.
 887         int usesCount = readUnsignedShort(currentOffset);
 888         currentOffset += 2;
 889         while (usesCount-- > 0) {
 890             moduleVisitor.visitUse(readClass(currentOffset, buffer));
 891             currentOffset += 2;
 892         }
 893 
 894         // Read the 'provides_count' and 'provides' fields.
 895         int providesCount = readUnsignedShort(currentOffset);
 896         currentOffset += 2;
 897         while (providesCount-- > 0) {
 898             // Read the provides_index, provides_with_count and provides_with_index fields and visit them.
 899             String provides = readClass(currentOffset, buffer);
 900             int providesWithCount = readUnsignedShort(currentOffset + 2);
 901             currentOffset += 4;
 902             String[] providesWith = new String[providesWithCount];
 903             for (int i = 0; i < providesWithCount; ++i) {
 904                 providesWith[i] = readClass(currentOffset, buffer);
 905                 currentOffset += 2;
 906             }
 907             moduleVisitor.visitProvide(provides, providesWith);
 908         }
 909 
 910         // Visit the end of the module attributes.
 911         moduleVisitor.visitEnd();
 912     }
 913 
 914     /**
 915       * Reads a record component and visit it.
 916       *
 917       * @param classVisitor the current class visitor
 918       * @param context information about the class being parsed.
 919       * @param recordComponentOffset the offset of the current record component.
 920       * @return the offset of the first byte following the record component.
 921       */
 922     private int readRecordComponent(
 923             final ClassVisitor classVisitor, final Context context, final int recordComponentOffset) {
 924         char[] charBuffer = context.charBuffer;
 925 
 926         int currentOffset = recordComponentOffset;
 927         String name = readUTF8(currentOffset, charBuffer);
 928         String descriptor = readUTF8(currentOffset + 2, charBuffer);
 929         currentOffset += 4;
 930 
 931         // Read the record component attributes (the variables are ordered as in Section 4.7 of the
 932         // JVMS).
 933 
 934         // Attribute offsets exclude the attribute_name_index and attribute_length fields.
 935         // - The string corresponding to the Signature attribute, or null.
 936         String signature = null;
 937         // - The offset of the RuntimeVisibleAnnotations attribute, or 0.
 938         int runtimeVisibleAnnotationsOffset = 0;
 939         // - The offset of the RuntimeInvisibleAnnotations attribute, or 0.
 940         int runtimeInvisibleAnnotationsOffset = 0;
 941         // - The offset of the RuntimeVisibleTypeAnnotations attribute, or 0.
 942         int runtimeVisibleTypeAnnotationsOffset = 0;
 943         // - The offset of the RuntimeInvisibleTypeAnnotations attribute, or 0.
 944         int runtimeInvisibleTypeAnnotationsOffset = 0;
 945         // - The non standard attributes (linked with their {@link Attribute#nextAttribute} field).
 946         //   This list in the <i>reverse order</i> or their order in the ClassFile structure.
 947         Attribute attributes = null;
 948 
 949         int attributesCount = readUnsignedShort(currentOffset);
 950         currentOffset += 2;
 951         while (attributesCount-- > 0) {
 952             // Read the attribute_info's attribute_name and attribute_length fields.
 953             String attributeName = readUTF8(currentOffset, charBuffer);
 954             int attributeLength = readInt(currentOffset + 2);
 955             currentOffset += 6;
 956             // The tests are sorted in decreasing frequency order (based on frequencies observed on
 957             // typical classes).
 958             if (Constants.SIGNATURE.equals(attributeName)) {
 959                 signature = readUTF8(currentOffset, charBuffer);
 960             } else if (Constants.RUNTIME_VISIBLE_ANNOTATIONS.equals(attributeName)) {
 961                 runtimeVisibleAnnotationsOffset = currentOffset;
 962             } else if (Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
 963                 runtimeVisibleTypeAnnotationsOffset = currentOffset;
 964             } else if (Constants.RUNTIME_INVISIBLE_ANNOTATIONS.equals(attributeName)) {
 965                 runtimeInvisibleAnnotationsOffset = currentOffset;
 966             } else if (Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
 967                 runtimeInvisibleTypeAnnotationsOffset = currentOffset;
 968             } else {
 969                 Attribute attribute =
 970                         readAttribute(
 971                                 context.attributePrototypes,
 972                                 attributeName,
 973                                 currentOffset,
 974                                 attributeLength,
 975                                 charBuffer,
 976                                 -1,
 977                                 null);
 978                 attribute.nextAttribute = attributes;
 979                 attributes = attribute;
 980             }
 981             currentOffset += attributeLength;
 982         }
 983 
 984         RecordComponentVisitor recordComponentVisitor =
 985                 classVisitor.visitRecordComponent(name, descriptor, signature);
 986         if (recordComponentVisitor == null) {
 987             return currentOffset;
 988         }
 989 
 990         // Visit the RuntimeVisibleAnnotations attribute.
 991         if (runtimeVisibleAnnotationsOffset != 0) {
 992             int numAnnotations = readUnsignedShort(runtimeVisibleAnnotationsOffset);
 993             int currentAnnotationOffset = runtimeVisibleAnnotationsOffset + 2;
 994             while (numAnnotations-- > 0) {
 995                 // Parse the type_index field.
 996                 String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
 997                 currentAnnotationOffset += 2;
 998                 // Parse num_element_value_pairs and element_value_pairs and visit these values.
 999                 currentAnnotationOffset =
1000                         readElementValues(
1001                                 recordComponentVisitor.visitAnnotation(annotationDescriptor, /* visible = */ true),
1002                                 currentAnnotationOffset,
1003                                 /* named = */ true,
1004                                 charBuffer);
1005             }
1006         }
1007 
1008         // Visit the RuntimeInvisibleAnnotations attribute.
1009         if (runtimeInvisibleAnnotationsOffset != 0) {
1010             int numAnnotations = readUnsignedShort(runtimeInvisibleAnnotationsOffset);
1011             int currentAnnotationOffset = runtimeInvisibleAnnotationsOffset + 2;
1012             while (numAnnotations-- > 0) {
1013                 // Parse the type_index field.
1014                 String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
1015                 currentAnnotationOffset += 2;
1016                 // Parse num_element_value_pairs and element_value_pairs and visit these values.
1017                 currentAnnotationOffset =
1018                         readElementValues(
1019                                 recordComponentVisitor.visitAnnotation(annotationDescriptor, /* visible = */ false),
1020                                 currentAnnotationOffset,
1021                                 /* named = */ true,
1022                                 charBuffer);
1023             }
1024         }
1025 
1026         // Visit the RuntimeVisibleTypeAnnotations attribute.
1027         if (runtimeVisibleTypeAnnotationsOffset != 0) {
1028             int numAnnotations = readUnsignedShort(runtimeVisibleTypeAnnotationsOffset);
1029             int currentAnnotationOffset = runtimeVisibleTypeAnnotationsOffset + 2;
1030             while (numAnnotations-- > 0) {
1031                 // Parse the target_type, target_info and target_path fields.
1032                 currentAnnotationOffset = readTypeAnnotationTarget(context, currentAnnotationOffset);
1033                 // Parse the type_index field.
1034                 String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
1035                 currentAnnotationOffset += 2;
1036                 // Parse num_element_value_pairs and element_value_pairs and visit these values.
1037                 currentAnnotationOffset =
1038                         readElementValues(
1039                                 recordComponentVisitor.visitTypeAnnotation(
1040                                         context.currentTypeAnnotationTarget,
1041                                         context.currentTypeAnnotationTargetPath,
1042                                         annotationDescriptor,
1043                                         /* visible = */ true),
1044                                 currentAnnotationOffset,
1045                                 /* named = */ true,
1046                                 charBuffer);
1047             }
1048         }
1049 
1050         // Visit the RuntimeInvisibleTypeAnnotations attribute.
1051         if (runtimeInvisibleTypeAnnotationsOffset != 0) {
1052             int numAnnotations = readUnsignedShort(runtimeInvisibleTypeAnnotationsOffset);
1053             int currentAnnotationOffset = runtimeInvisibleTypeAnnotationsOffset + 2;
1054             while (numAnnotations-- > 0) {
1055                 // Parse the target_type, target_info and target_path fields.
1056                 currentAnnotationOffset = readTypeAnnotationTarget(context, currentAnnotationOffset);
1057                 // Parse the type_index field.
1058                 String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
1059                 currentAnnotationOffset += 2;
1060                 // Parse num_element_value_pairs and element_value_pairs and visit these values.
1061                 currentAnnotationOffset =
1062                         readElementValues(
1063                                 recordComponentVisitor.visitTypeAnnotation(
1064                                         context.currentTypeAnnotationTarget,
1065                                         context.currentTypeAnnotationTargetPath,
1066                                         annotationDescriptor,
1067                                         /* visible = */ false),
1068                                 currentAnnotationOffset,
1069                                 /* named = */ true,
1070                                 charBuffer);
1071             }
1072         }
1073 
1074         // Visit the non standard attributes.
1075         while (attributes != null) {
1076             // Copy and reset the nextAttribute field so that it can also be used in FieldWriter.
1077             Attribute nextAttribute = attributes.nextAttribute;
1078             attributes.nextAttribute = null;
1079             recordComponentVisitor.visitAttribute(attributes);
1080             attributes = nextAttribute;
1081         }
1082 
1083         // Visit the end of the field.
1084         recordComponentVisitor.visitEnd();
1085         return currentOffset;
1086     }
1087 
1088     /**
1089       * Reads a JVMS field_info structure and makes the given visitor visit it.
1090       *
1091       * @param classVisitor the visitor that must visit the field.
1092       * @param context information about the class being parsed.
1093       * @param fieldInfoOffset the start offset of the field_info structure.
1094       * @return the offset of the first byte following the field_info structure.
1095       */
1096     private int readField(
1097             final ClassVisitor classVisitor, final Context context, final int fieldInfoOffset) {
1098         char[] charBuffer = context.charBuffer;
1099 
1100         // Read the access_flags, name_index and descriptor_index fields.
1101         int currentOffset = fieldInfoOffset;
1102         int accessFlags = readUnsignedShort(currentOffset);
1103         String name = readUTF8(currentOffset + 2, charBuffer);
1104         String descriptor = readUTF8(currentOffset + 4, charBuffer);
1105         currentOffset += 6;
1106 
1107         // Read the field attributes (the variables are ordered as in Section 4.7 of the JVMS).
1108         // Attribute offsets exclude the attribute_name_index and attribute_length fields.
1109         // - The value corresponding to the ConstantValue attribute, or null.
1110         Object constantValue = null;
1111         // - The string corresponding to the Signature attribute, or null.
1112         String signature = null;
1113         // - The offset of the RuntimeVisibleAnnotations attribute, or 0.
1114         int runtimeVisibleAnnotationsOffset = 0;
1115         // - The offset of the RuntimeInvisibleAnnotations attribute, or 0.
1116         int runtimeInvisibleAnnotationsOffset = 0;
1117         // - The offset of the RuntimeVisibleTypeAnnotations attribute, or 0.
1118         int runtimeVisibleTypeAnnotationsOffset = 0;
1119         // - The offset of the RuntimeInvisibleTypeAnnotations attribute, or 0.
1120         int runtimeInvisibleTypeAnnotationsOffset = 0;
1121         // - The non standard attributes (linked with their {@link Attribute#nextAttribute} field).
1122         //   This list in the <i>reverse order</i> or their order in the ClassFile structure.
1123         Attribute attributes = null;
1124 
1125         int attributesCount = readUnsignedShort(currentOffset);
1126         currentOffset += 2;
1127         while (attributesCount-- > 0) {
1128             // Read the attribute_info's attribute_name and attribute_length fields.
1129             String attributeName = readUTF8(currentOffset, charBuffer);
1130             int attributeLength = readInt(currentOffset + 2);
1131             currentOffset += 6;
1132             // The tests are sorted in decreasing frequency order (based on frequencies observed on
1133             // typical classes).
1134             if (Constants.CONSTANT_VALUE.equals(attributeName)) {
1135                 int constantvalueIndex = readUnsignedShort(currentOffset);
1136                 constantValue = constantvalueIndex == 0 ? null : readConst(constantvalueIndex, charBuffer);
1137             } else if (Constants.SIGNATURE.equals(attributeName)) {
1138                 signature = readUTF8(currentOffset, charBuffer);
1139             } else if (Constants.DEPRECATED.equals(attributeName)) {
1140                 accessFlags |= Opcodes.ACC_DEPRECATED;
1141             } else if (Constants.SYNTHETIC.equals(attributeName)) {
1142                 accessFlags |= Opcodes.ACC_SYNTHETIC;
1143             } else if (Constants.RUNTIME_VISIBLE_ANNOTATIONS.equals(attributeName)) {
1144                 runtimeVisibleAnnotationsOffset = currentOffset;
1145             } else if (Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
1146                 runtimeVisibleTypeAnnotationsOffset = currentOffset;
1147             } else if (Constants.RUNTIME_INVISIBLE_ANNOTATIONS.equals(attributeName)) {
1148                 runtimeInvisibleAnnotationsOffset = currentOffset;
1149             } else if (Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
1150                 runtimeInvisibleTypeAnnotationsOffset = currentOffset;
1151             } else {
1152                 Attribute attribute =
1153                         readAttribute(
1154                                 context.attributePrototypes,
1155                                 attributeName,
1156                                 currentOffset,
1157                                 attributeLength,
1158                                 charBuffer,
1159                                 -1,
1160                                 null);
1161                 attribute.nextAttribute = attributes;
1162                 attributes = attribute;
1163             }
1164             currentOffset += attributeLength;
1165         }
1166 
1167         // Visit the field declaration.
1168         FieldVisitor fieldVisitor =
1169                 classVisitor.visitField(accessFlags, name, descriptor, signature, constantValue);
1170         if (fieldVisitor == null) {
1171             return currentOffset;
1172         }
1173 
1174         // Visit the RuntimeVisibleAnnotations attribute.
1175         if (runtimeVisibleAnnotationsOffset != 0) {
1176             int numAnnotations = readUnsignedShort(runtimeVisibleAnnotationsOffset);
1177             int currentAnnotationOffset = runtimeVisibleAnnotationsOffset + 2;
1178             while (numAnnotations-- > 0) {
1179                 // Parse the type_index field.
1180                 String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
1181                 currentAnnotationOffset += 2;
1182                 // Parse num_element_value_pairs and element_value_pairs and visit these values.
1183                 currentAnnotationOffset =
1184                         readElementValues(
1185                                 fieldVisitor.visitAnnotation(annotationDescriptor, /* visible = */ true),
1186                                 currentAnnotationOffset,
1187                                 /* named = */ true,
1188                                 charBuffer);
1189             }
1190         }
1191 
1192         // Visit the RuntimeInvisibleAnnotations attribute.
1193         if (runtimeInvisibleAnnotationsOffset != 0) {
1194             int numAnnotations = readUnsignedShort(runtimeInvisibleAnnotationsOffset);
1195             int currentAnnotationOffset = runtimeInvisibleAnnotationsOffset + 2;
1196             while (numAnnotations-- > 0) {
1197                 // Parse the type_index field.
1198                 String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
1199                 currentAnnotationOffset += 2;
1200                 // Parse num_element_value_pairs and element_value_pairs and visit these values.
1201                 currentAnnotationOffset =
1202                         readElementValues(
1203                                 fieldVisitor.visitAnnotation(annotationDescriptor, /* visible = */ false),
1204                                 currentAnnotationOffset,
1205                                 /* named = */ true,
1206                                 charBuffer);
1207             }
1208         }
1209 
1210         // Visit the RuntimeVisibleTypeAnnotations attribute.
1211         if (runtimeVisibleTypeAnnotationsOffset != 0) {
1212             int numAnnotations = readUnsignedShort(runtimeVisibleTypeAnnotationsOffset);
1213             int currentAnnotationOffset = runtimeVisibleTypeAnnotationsOffset + 2;
1214             while (numAnnotations-- > 0) {
1215                 // Parse the target_type, target_info and target_path fields.
1216                 currentAnnotationOffset = readTypeAnnotationTarget(context, currentAnnotationOffset);
1217                 // Parse the type_index field.
1218                 String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
1219                 currentAnnotationOffset += 2;
1220                 // Parse num_element_value_pairs and element_value_pairs and visit these values.
1221                 currentAnnotationOffset =
1222                         readElementValues(
1223                                 fieldVisitor.visitTypeAnnotation(
1224                                         context.currentTypeAnnotationTarget,
1225                                         context.currentTypeAnnotationTargetPath,
1226                                         annotationDescriptor,
1227                                         /* visible = */ true),
1228                                 currentAnnotationOffset,
1229                                 /* named = */ true,
1230                                 charBuffer);
1231             }
1232         }
1233 
1234         // Visit the RuntimeInvisibleTypeAnnotations attribute.
1235         if (runtimeInvisibleTypeAnnotationsOffset != 0) {
1236             int numAnnotations = readUnsignedShort(runtimeInvisibleTypeAnnotationsOffset);
1237             int currentAnnotationOffset = runtimeInvisibleTypeAnnotationsOffset + 2;
1238             while (numAnnotations-- > 0) {
1239                 // Parse the target_type, target_info and target_path fields.
1240                 currentAnnotationOffset = readTypeAnnotationTarget(context, currentAnnotationOffset);
1241                 // Parse the type_index field.
1242                 String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
1243                 currentAnnotationOffset += 2;
1244                 // Parse num_element_value_pairs and element_value_pairs and visit these values.
1245                 currentAnnotationOffset =
1246                         readElementValues(
1247                                 fieldVisitor.visitTypeAnnotation(
1248                                         context.currentTypeAnnotationTarget,
1249                                         context.currentTypeAnnotationTargetPath,
1250                                         annotationDescriptor,
1251                                         /* visible = */ false),
1252                                 currentAnnotationOffset,
1253                                 /* named = */ true,
1254                                 charBuffer);
1255             }
1256         }
1257 
1258         // Visit the non standard attributes.
1259         while (attributes != null) {
1260             // Copy and reset the nextAttribute field so that it can also be used in FieldWriter.
1261             Attribute nextAttribute = attributes.nextAttribute;
1262             attributes.nextAttribute = null;
1263             fieldVisitor.visitAttribute(attributes);
1264             attributes = nextAttribute;
1265         }
1266 
1267         // Visit the end of the field.
1268         fieldVisitor.visitEnd();
1269         return currentOffset;
1270     }
1271 
1272     /**
1273       * Reads a JVMS method_info structure and makes the given visitor visit it.
1274       *
1275       * @param classVisitor the visitor that must visit the method.
1276       * @param context information about the class being parsed.
1277       * @param methodInfoOffset the start offset of the method_info structure.
1278       * @return the offset of the first byte following the method_info structure.
1279       */
1280     private int readMethod(
1281             final ClassVisitor classVisitor, final Context context, final int methodInfoOffset) {
1282         char[] charBuffer = context.charBuffer;
1283 
1284         // Read the access_flags, name_index and descriptor_index fields.
1285         int currentOffset = methodInfoOffset;
1286         context.currentMethodAccessFlags = readUnsignedShort(currentOffset);
1287         context.currentMethodName = readUTF8(currentOffset + 2, charBuffer);
1288         context.currentMethodDescriptor = readUTF8(currentOffset + 4, charBuffer);
1289         currentOffset += 6;
1290 
1291         // Read the method attributes (the variables are ordered as in Section 4.7 of the JVMS).
1292         // Attribute offsets exclude the attribute_name_index and attribute_length fields.
1293         // - The offset of the Code attribute, or 0.
1294         int codeOffset = 0;
1295         // - The offset of the Exceptions attribute, or 0.
1296         int exceptionsOffset = 0;
1297         // - The strings corresponding to the Exceptions attribute, or null.
1298         String[] exceptions = null;
1299         // - Whether the method has a Synthetic attribute.
1300         boolean synthetic = false;
1301         // - The constant pool index contained in the Signature attribute, or 0.
1302         int signatureIndex = 0;
1303         // - The offset of the RuntimeVisibleAnnotations attribute, or 0.
1304         int runtimeVisibleAnnotationsOffset = 0;
1305         // - The offset of the RuntimeInvisibleAnnotations attribute, or 0.
1306         int runtimeInvisibleAnnotationsOffset = 0;
1307         // - The offset of the RuntimeVisibleParameterAnnotations attribute, or 0.
1308         int runtimeVisibleParameterAnnotationsOffset = 0;
1309         // - The offset of the RuntimeInvisibleParameterAnnotations attribute, or 0.
1310         int runtimeInvisibleParameterAnnotationsOffset = 0;
1311         // - The offset of the RuntimeVisibleTypeAnnotations attribute, or 0.
1312         int runtimeVisibleTypeAnnotationsOffset = 0;
1313         // - The offset of the RuntimeInvisibleTypeAnnotations attribute, or 0.
1314         int runtimeInvisibleTypeAnnotationsOffset = 0;
1315         // - The offset of the AnnotationDefault attribute, or 0.
1316         int annotationDefaultOffset = 0;
1317         // - The offset of the MethodParameters attribute, or 0.
1318         int methodParametersOffset = 0;
1319         // - The non standard attributes (linked with their {@link Attribute#nextAttribute} field).
1320         //   This list in the <i>reverse order</i> or their order in the ClassFile structure.
1321         Attribute attributes = null;
1322 
1323         int attributesCount = readUnsignedShort(currentOffset);
1324         currentOffset += 2;
1325         while (attributesCount-- > 0) {
1326             // Read the attribute_info's attribute_name and attribute_length fields.
1327             String attributeName = readUTF8(currentOffset, charBuffer);
1328             int attributeLength = readInt(currentOffset + 2);
1329             currentOffset += 6;
1330             // The tests are sorted in decreasing frequency order (based on frequencies observed on
1331             // typical classes).
1332             if (Constants.CODE.equals(attributeName)) {
1333                 if ((context.parsingOptions & SKIP_CODE) == 0) {
1334                     codeOffset = currentOffset;
1335                 }
1336             } else if (Constants.EXCEPTIONS.equals(attributeName)) {
1337                 exceptionsOffset = currentOffset;
1338                 exceptions = new String[readUnsignedShort(exceptionsOffset)];
1339                 int currentExceptionOffset = exceptionsOffset + 2;
1340                 for (int i = 0; i < exceptions.length; ++i) {
1341                     exceptions[i] = readClass(currentExceptionOffset, charBuffer);
1342                     currentExceptionOffset += 2;
1343                 }
1344             } else if (Constants.SIGNATURE.equals(attributeName)) {
1345                 signatureIndex = readUnsignedShort(currentOffset);
1346             } else if (Constants.DEPRECATED.equals(attributeName)) {
1347                 context.currentMethodAccessFlags |= Opcodes.ACC_DEPRECATED;
1348             } else if (Constants.RUNTIME_VISIBLE_ANNOTATIONS.equals(attributeName)) {
1349                 runtimeVisibleAnnotationsOffset = currentOffset;
1350             } else if (Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
1351                 runtimeVisibleTypeAnnotationsOffset = currentOffset;
1352             } else if (Constants.ANNOTATION_DEFAULT.equals(attributeName)) {
1353                 annotationDefaultOffset = currentOffset;
1354             } else if (Constants.SYNTHETIC.equals(attributeName)) {
1355                 synthetic = true;
1356                 context.currentMethodAccessFlags |= Opcodes.ACC_SYNTHETIC;
1357             } else if (Constants.RUNTIME_INVISIBLE_ANNOTATIONS.equals(attributeName)) {
1358                 runtimeInvisibleAnnotationsOffset = currentOffset;
1359             } else if (Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
1360                 runtimeInvisibleTypeAnnotationsOffset = currentOffset;
1361             } else if (Constants.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS.equals(attributeName)) {
1362                 runtimeVisibleParameterAnnotationsOffset = currentOffset;
1363             } else if (Constants.RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS.equals(attributeName)) {
1364                 runtimeInvisibleParameterAnnotationsOffset = currentOffset;
1365             } else if (Constants.METHOD_PARAMETERS.equals(attributeName)) {
1366                 methodParametersOffset = currentOffset;
1367             } else {
1368                 Attribute attribute =
1369                         readAttribute(
1370                                 context.attributePrototypes,
1371                                 attributeName,
1372                                 currentOffset,
1373                                 attributeLength,
1374                                 charBuffer,
1375                                 -1,
1376                                 null);
1377                 attribute.nextAttribute = attributes;
1378                 attributes = attribute;
1379             }
1380             currentOffset += attributeLength;
1381         }
1382 
1383         // Visit the method declaration.
1384         MethodVisitor methodVisitor =
1385                 classVisitor.visitMethod(
1386                         context.currentMethodAccessFlags,
1387                         context.currentMethodName,
1388                         context.currentMethodDescriptor,
1389                         signatureIndex == 0 ? null : readUtf(signatureIndex, charBuffer),
1390                         exceptions);
1391         if (methodVisitor == null) {
1392             return currentOffset;
1393         }
1394 
1395         // If the returned MethodVisitor is in fact a MethodWriter, it means there is no method
1396         // adapter between the reader and the writer. In this case, it might be possible to copy
1397         // the method attributes directly into the writer. If so, return early without visiting
1398         // the content of these attributes.
1399         if (methodVisitor instanceof MethodWriter) {
1400             MethodWriter methodWriter = (MethodWriter) methodVisitor;
1401             if (methodWriter.canCopyMethodAttributes(
1402                     this,
1403                     synthetic,
1404                     (context.currentMethodAccessFlags & Opcodes.ACC_DEPRECATED) != 0,
1405                     readUnsignedShort(methodInfoOffset + 4),
1406                     signatureIndex,
1407                     exceptionsOffset)) {
1408                 methodWriter.setMethodAttributesSource(methodInfoOffset, currentOffset - methodInfoOffset);
1409                 return currentOffset;
1410             }
1411         }
1412 
1413         // Visit the MethodParameters attribute.
1414         if (methodParametersOffset != 0 && (context.parsingOptions & SKIP_DEBUG) == 0) {
1415             int parametersCount = readByte(methodParametersOffset);
1416             int currentParameterOffset = methodParametersOffset + 1;
1417             while (parametersCount-- > 0) {
1418                 // Read the name_index and access_flags fields and visit them.
1419                 methodVisitor.visitParameter(
1420                         readUTF8(currentParameterOffset, charBuffer),
1421                         readUnsignedShort(currentParameterOffset + 2));
1422                 currentParameterOffset += 4;
1423             }
1424         }
1425 
1426         // Visit the AnnotationDefault attribute.
1427         if (annotationDefaultOffset != 0) {
1428             AnnotationVisitor annotationVisitor = methodVisitor.visitAnnotationDefault();
1429             readElementValue(annotationVisitor, annotationDefaultOffset, null, charBuffer);
1430             if (annotationVisitor != null) {
1431                 annotationVisitor.visitEnd();
1432             }
1433         }
1434 
1435         // Visit the RuntimeVisibleAnnotations attribute.
1436         if (runtimeVisibleAnnotationsOffset != 0) {
1437             int numAnnotations = readUnsignedShort(runtimeVisibleAnnotationsOffset);
1438             int currentAnnotationOffset = runtimeVisibleAnnotationsOffset + 2;
1439             while (numAnnotations-- > 0) {
1440                 // Parse the type_index field.
1441                 String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
1442                 currentAnnotationOffset += 2;
1443                 // Parse num_element_value_pairs and element_value_pairs and visit these values.
1444                 currentAnnotationOffset =
1445                         readElementValues(
1446                                 methodVisitor.visitAnnotation(annotationDescriptor, /* visible = */ true),
1447                                 currentAnnotationOffset,
1448                                 /* named = */ true,
1449                                 charBuffer);
1450             }
1451         }
1452 
1453         // Visit the RuntimeInvisibleAnnotations attribute.
1454         if (runtimeInvisibleAnnotationsOffset != 0) {
1455             int numAnnotations = readUnsignedShort(runtimeInvisibleAnnotationsOffset);
1456             int currentAnnotationOffset = runtimeInvisibleAnnotationsOffset + 2;
1457             while (numAnnotations-- > 0) {
1458                 // Parse the type_index field.
1459                 String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
1460                 currentAnnotationOffset += 2;
1461                 // Parse num_element_value_pairs and element_value_pairs and visit these values.
1462                 currentAnnotationOffset =
1463                         readElementValues(
1464                                 methodVisitor.visitAnnotation(annotationDescriptor, /* visible = */ false),
1465                                 currentAnnotationOffset,
1466                                 /* named = */ true,
1467                                 charBuffer);
1468             }
1469         }
1470 
1471         // Visit the RuntimeVisibleTypeAnnotations attribute.
1472         if (runtimeVisibleTypeAnnotationsOffset != 0) {
1473             int numAnnotations = readUnsignedShort(runtimeVisibleTypeAnnotationsOffset);
1474             int currentAnnotationOffset = runtimeVisibleTypeAnnotationsOffset + 2;
1475             while (numAnnotations-- > 0) {
1476                 // Parse the target_type, target_info and target_path fields.
1477                 currentAnnotationOffset = readTypeAnnotationTarget(context, currentAnnotationOffset);
1478                 // Parse the type_index field.
1479                 String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
1480                 currentAnnotationOffset += 2;
1481                 // Parse num_element_value_pairs and element_value_pairs and visit these values.
1482                 currentAnnotationOffset =
1483                         readElementValues(
1484                                 methodVisitor.visitTypeAnnotation(
1485                                         context.currentTypeAnnotationTarget,
1486                                         context.currentTypeAnnotationTargetPath,
1487                                         annotationDescriptor,
1488                                         /* visible = */ true),
1489                                 currentAnnotationOffset,
1490                                 /* named = */ true,
1491                                 charBuffer);
1492             }
1493         }
1494 
1495         // Visit the RuntimeInvisibleTypeAnnotations attribute.
1496         if (runtimeInvisibleTypeAnnotationsOffset != 0) {
1497             int numAnnotations = readUnsignedShort(runtimeInvisibleTypeAnnotationsOffset);
1498             int currentAnnotationOffset = runtimeInvisibleTypeAnnotationsOffset + 2;
1499             while (numAnnotations-- > 0) {
1500                 // Parse the target_type, target_info and target_path fields.
1501                 currentAnnotationOffset = readTypeAnnotationTarget(context, currentAnnotationOffset);
1502                 // Parse the type_index field.
1503                 String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
1504                 currentAnnotationOffset += 2;
1505                 // Parse num_element_value_pairs and element_value_pairs and visit these values.
1506                 currentAnnotationOffset =
1507                         readElementValues(
1508                                 methodVisitor.visitTypeAnnotation(
1509                                         context.currentTypeAnnotationTarget,
1510                                         context.currentTypeAnnotationTargetPath,
1511                                         annotationDescriptor,
1512                                         /* visible = */ false),
1513                                 currentAnnotationOffset,
1514                                 /* named = */ true,
1515                                 charBuffer);
1516             }
1517         }
1518 
1519         // Visit the RuntimeVisibleParameterAnnotations attribute.
1520         if (runtimeVisibleParameterAnnotationsOffset != 0) {
1521             readParameterAnnotations(
1522                     methodVisitor, context, runtimeVisibleParameterAnnotationsOffset, /* visible = */ true);
1523         }
1524 
1525         // Visit the RuntimeInvisibleParameterAnnotations attribute.
1526         if (runtimeInvisibleParameterAnnotationsOffset != 0) {
1527             readParameterAnnotations(
1528                     methodVisitor,
1529                     context,
1530                     runtimeInvisibleParameterAnnotationsOffset,
1531                     /* visible = */ false);
1532         }
1533 
1534         // Visit the non standard attributes.
1535         while (attributes != null) {
1536             // Copy and reset the nextAttribute field so that it can also be used in MethodWriter.
1537             Attribute nextAttribute = attributes.nextAttribute;
1538             attributes.nextAttribute = null;
1539             methodVisitor.visitAttribute(attributes);
1540             attributes = nextAttribute;
1541         }
1542 
1543         // Visit the Code attribute.
1544         if (codeOffset != 0) {
1545             methodVisitor.visitCode();
1546             readCode(methodVisitor, context, codeOffset);
1547         }
1548 
1549         // Visit the end of the method.
1550         methodVisitor.visitEnd();
1551         return currentOffset;
1552     }
1553 
1554     // ----------------------------------------------------------------------------------------------
1555     // Methods to parse a Code attribute
1556     // ----------------------------------------------------------------------------------------------
1557 
1558     /**
1559       * Reads a JVMS 'Code' attribute and makes the given visitor visit it.
1560       *
1561       * @param methodVisitor the visitor that must visit the Code attribute.
1562       * @param context information about the class being parsed.
1563       * @param codeOffset the start offset in {@link #classFileBuffer} of the Code attribute, excluding
1564       *     its attribute_name_index and attribute_length fields.
1565       */
1566     private void readCode(
1567             final MethodVisitor methodVisitor, final Context context, final int codeOffset) {
1568         int currentOffset = codeOffset;
1569 
1570         // Read the max_stack, max_locals and code_length fields.
1571         final byte[] classBuffer = classFileBuffer;
1572         final char[] charBuffer = context.charBuffer;
1573         final int maxStack = readUnsignedShort(currentOffset);
1574         final int maxLocals = readUnsignedShort(currentOffset + 2);
1575         final int codeLength = readInt(currentOffset + 4);
1576         currentOffset += 8;
1577         if (codeLength > classFileBuffer.length - currentOffset) {
1578             throw new IllegalArgumentException();
1579         }
1580 
1581         // Read the bytecode 'code' array to create a label for each referenced instruction.
1582         final int bytecodeStartOffset = currentOffset;
1583         final int bytecodeEndOffset = currentOffset + codeLength;
1584         final Label[] labels = context.currentMethodLabels = new Label[codeLength + 1];
1585         while (currentOffset < bytecodeEndOffset) {
1586             final int bytecodeOffset = currentOffset - bytecodeStartOffset;
1587             final int opcode = classBuffer[currentOffset] & 0xFF;
1588             switch (opcode) {
1589                 case Opcodes.NOP:
1590                 case Opcodes.ACONST_NULL:
1591                 case Opcodes.ICONST_M1:
1592                 case Opcodes.ICONST_0:
1593                 case Opcodes.ICONST_1:
1594                 case Opcodes.ICONST_2:
1595                 case Opcodes.ICONST_3:
1596                 case Opcodes.ICONST_4:
1597                 case Opcodes.ICONST_5:
1598                 case Opcodes.LCONST_0:
1599                 case Opcodes.LCONST_1:
1600                 case Opcodes.FCONST_0:
1601                 case Opcodes.FCONST_1:
1602                 case Opcodes.FCONST_2:
1603                 case Opcodes.DCONST_0:
1604                 case Opcodes.DCONST_1:
1605                 case Opcodes.IALOAD:
1606                 case Opcodes.LALOAD:
1607                 case Opcodes.FALOAD:
1608                 case Opcodes.DALOAD:
1609                 case Opcodes.AALOAD:
1610                 case Opcodes.BALOAD:
1611                 case Opcodes.CALOAD:
1612                 case Opcodes.SALOAD:
1613                 case Opcodes.IASTORE:
1614                 case Opcodes.LASTORE:
1615                 case Opcodes.FASTORE:
1616                 case Opcodes.DASTORE:
1617                 case Opcodes.AASTORE:
1618                 case Opcodes.BASTORE:
1619                 case Opcodes.CASTORE:
1620                 case Opcodes.SASTORE:
1621                 case Opcodes.POP:
1622                 case Opcodes.POP2:
1623                 case Opcodes.DUP:
1624                 case Opcodes.DUP_X1:
1625                 case Opcodes.DUP_X2:
1626                 case Opcodes.DUP2:
1627                 case Opcodes.DUP2_X1:
1628                 case Opcodes.DUP2_X2:
1629                 case Opcodes.SWAP:
1630                 case Opcodes.IADD:
1631                 case Opcodes.LADD:
1632                 case Opcodes.FADD:
1633                 case Opcodes.DADD:
1634                 case Opcodes.ISUB:
1635                 case Opcodes.LSUB:
1636                 case Opcodes.FSUB:
1637                 case Opcodes.DSUB:
1638                 case Opcodes.IMUL:
1639                 case Opcodes.LMUL:
1640                 case Opcodes.FMUL:
1641                 case Opcodes.DMUL:
1642                 case Opcodes.IDIV:
1643                 case Opcodes.LDIV:
1644                 case Opcodes.FDIV:
1645                 case Opcodes.DDIV:
1646                 case Opcodes.IREM:
1647                 case Opcodes.LREM:
1648                 case Opcodes.FREM:
1649                 case Opcodes.DREM:
1650                 case Opcodes.INEG:
1651                 case Opcodes.LNEG:
1652                 case Opcodes.FNEG:
1653                 case Opcodes.DNEG:
1654                 case Opcodes.ISHL:
1655                 case Opcodes.LSHL:
1656                 case Opcodes.ISHR:
1657                 case Opcodes.LSHR:
1658                 case Opcodes.IUSHR:
1659                 case Opcodes.LUSHR:
1660                 case Opcodes.IAND:
1661                 case Opcodes.LAND:
1662                 case Opcodes.IOR:
1663                 case Opcodes.LOR:
1664                 case Opcodes.IXOR:
1665                 case Opcodes.LXOR:
1666                 case Opcodes.I2L:
1667                 case Opcodes.I2F:
1668                 case Opcodes.I2D:
1669                 case Opcodes.L2I:
1670                 case Opcodes.L2F:
1671                 case Opcodes.L2D:
1672                 case Opcodes.F2I:
1673                 case Opcodes.F2L:
1674                 case Opcodes.F2D:
1675                 case Opcodes.D2I:
1676                 case Opcodes.D2L:
1677                 case Opcodes.D2F:
1678                 case Opcodes.I2B:
1679                 case Opcodes.I2C:
1680                 case Opcodes.I2S:
1681                 case Opcodes.LCMP:
1682                 case Opcodes.FCMPL:
1683                 case Opcodes.FCMPG:
1684                 case Opcodes.DCMPL:
1685                 case Opcodes.DCMPG:
1686                 case Opcodes.IRETURN:
1687                 case Opcodes.LRETURN:
1688                 case Opcodes.FRETURN:
1689                 case Opcodes.DRETURN:
1690                 case Opcodes.ARETURN:
1691                 case Opcodes.RETURN:
1692                 case Opcodes.ARRAYLENGTH:
1693                 case Opcodes.ATHROW:
1694                 case Opcodes.MONITORENTER:
1695                 case Opcodes.MONITOREXIT:
1696                 case Constants.ILOAD_0:
1697                 case Constants.ILOAD_1:
1698                 case Constants.ILOAD_2:
1699                 case Constants.ILOAD_3:
1700                 case Constants.LLOAD_0:
1701                 case Constants.LLOAD_1:
1702                 case Constants.LLOAD_2:
1703                 case Constants.LLOAD_3:
1704                 case Constants.FLOAD_0:
1705                 case Constants.FLOAD_1:
1706                 case Constants.FLOAD_2:
1707                 case Constants.FLOAD_3:
1708                 case Constants.DLOAD_0:
1709                 case Constants.DLOAD_1:
1710                 case Constants.DLOAD_2:
1711                 case Constants.DLOAD_3:
1712                 case Constants.ALOAD_0:
1713                 case Constants.ALOAD_1:
1714                 case Constants.ALOAD_2:
1715                 case Constants.ALOAD_3:
1716                 case Constants.ISTORE_0:
1717                 case Constants.ISTORE_1:
1718                 case Constants.ISTORE_2:
1719                 case Constants.ISTORE_3:
1720                 case Constants.LSTORE_0:
1721                 case Constants.LSTORE_1:
1722                 case Constants.LSTORE_2:
1723                 case Constants.LSTORE_3:
1724                 case Constants.FSTORE_0:
1725                 case Constants.FSTORE_1:
1726                 case Constants.FSTORE_2:
1727                 case Constants.FSTORE_3:
1728                 case Constants.DSTORE_0:
1729                 case Constants.DSTORE_1:
1730                 case Constants.DSTORE_2:
1731                 case Constants.DSTORE_3:
1732                 case Constants.ASTORE_0:
1733                 case Constants.ASTORE_1:
1734                 case Constants.ASTORE_2:
1735                 case Constants.ASTORE_3:
1736                     currentOffset += 1;
1737                     break;
1738                 case Opcodes.IFEQ:
1739                 case Opcodes.IFNE:
1740                 case Opcodes.IFLT:
1741                 case Opcodes.IFGE:
1742                 case Opcodes.IFGT:
1743                 case Opcodes.IFLE:
1744                 case Opcodes.IF_ICMPEQ:
1745                 case Opcodes.IF_ICMPNE:
1746                 case Opcodes.IF_ICMPLT:
1747                 case Opcodes.IF_ICMPGE:
1748                 case Opcodes.IF_ICMPGT:
1749                 case Opcodes.IF_ICMPLE:
1750                 case Opcodes.IF_ACMPEQ:
1751                 case Opcodes.IF_ACMPNE:
1752                 case Opcodes.GOTO:
1753                 case Opcodes.JSR:
1754                 case Opcodes.IFNULL:
1755                 case Opcodes.IFNONNULL:
1756                     createLabel(bytecodeOffset + readShort(currentOffset + 1), labels);
1757                     currentOffset += 3;
1758                     break;
1759                 case Constants.ASM_IFEQ:
1760                 case Constants.ASM_IFNE:
1761                 case Constants.ASM_IFLT:
1762                 case Constants.ASM_IFGE:
1763                 case Constants.ASM_IFGT:
1764                 case Constants.ASM_IFLE:
1765                 case Constants.ASM_IF_ICMPEQ:
1766                 case Constants.ASM_IF_ICMPNE:
1767                 case Constants.ASM_IF_ICMPLT:
1768                 case Constants.ASM_IF_ICMPGE:
1769                 case Constants.ASM_IF_ICMPGT:
1770                 case Constants.ASM_IF_ICMPLE:
1771                 case Constants.ASM_IF_ACMPEQ:
1772                 case Constants.ASM_IF_ACMPNE:
1773                 case Constants.ASM_GOTO:
1774                 case Constants.ASM_JSR:
1775                 case Constants.ASM_IFNULL:
1776                 case Constants.ASM_IFNONNULL:
1777                     createLabel(bytecodeOffset + readUnsignedShort(currentOffset + 1), labels);
1778                     currentOffset += 3;
1779                     break;
1780                 case Constants.GOTO_W:
1781                 case Constants.JSR_W:
1782                 case Constants.ASM_GOTO_W:
1783                     createLabel(bytecodeOffset + readInt(currentOffset + 1), labels);
1784                     currentOffset += 5;
1785                     break;
1786                 case Constants.WIDE:
1787                     switch (classBuffer[currentOffset + 1] & 0xFF) {
1788                         case Opcodes.ILOAD:
1789                         case Opcodes.FLOAD:
1790                         case Opcodes.ALOAD:
1791                         case Opcodes.LLOAD:
1792                         case Opcodes.DLOAD:
1793                         case Opcodes.ISTORE:
1794                         case Opcodes.FSTORE:
1795                         case Opcodes.ASTORE:
1796                         case Opcodes.LSTORE:
1797                         case Opcodes.DSTORE:
1798                         case Opcodes.RET:
1799                             currentOffset += 4;
1800                             break;
1801                         case Opcodes.IINC:
1802                             currentOffset += 6;
1803                             break;
1804                         default:
1805                             throw new IllegalArgumentException();
1806                     }
1807                     break;
1808                 case Opcodes.TABLESWITCH:
1809                     // Skip 0 to 3 padding bytes.
1810                     currentOffset += 4 - (bytecodeOffset & 3);
1811                     // Read the default label and the number of table entries.
1812                     createLabel(bytecodeOffset + readInt(currentOffset), labels);
1813                     int numTableEntries = readInt(currentOffset + 8) - readInt(currentOffset + 4) + 1;
1814                     currentOffset += 12;
1815                     // Read the table labels.
1816                     while (numTableEntries-- > 0) {
1817                         createLabel(bytecodeOffset + readInt(currentOffset), labels);
1818                         currentOffset += 4;
1819                     }
1820                     break;
1821                 case Opcodes.LOOKUPSWITCH:
1822                     // Skip 0 to 3 padding bytes.
1823                     currentOffset += 4 - (bytecodeOffset & 3);
1824                     // Read the default label and the number of switch cases.
1825                     createLabel(bytecodeOffset + readInt(currentOffset), labels);
1826                     int numSwitchCases = readInt(currentOffset + 4);
1827                     currentOffset += 8;
1828                     // Read the switch labels.
1829                     while (numSwitchCases-- > 0) {
1830                         createLabel(bytecodeOffset + readInt(currentOffset + 4), labels);
1831                         currentOffset += 8;
1832                     }
1833                     break;
1834                 case Opcodes.ILOAD:
1835                 case Opcodes.LLOAD:
1836                 case Opcodes.FLOAD:
1837                 case Opcodes.DLOAD:
1838                 case Opcodes.ALOAD:
1839                 case Opcodes.ISTORE:
1840                 case Opcodes.LSTORE:
1841                 case Opcodes.FSTORE:
1842                 case Opcodes.DSTORE:
1843                 case Opcodes.ASTORE:
1844                 case Opcodes.RET:
1845                 case Opcodes.BIPUSH:
1846                 case Opcodes.NEWARRAY:
1847                 case Opcodes.LDC:
1848                     currentOffset += 2;
1849                     break;
1850                 case Opcodes.SIPUSH:
1851                 case Constants.LDC_W:
1852                 case Constants.LDC2_W:
1853                 case Opcodes.GETSTATIC:
1854                 case Opcodes.PUTSTATIC:
1855                 case Opcodes.GETFIELD:
1856                 case Opcodes.PUTFIELD:
1857                 case Opcodes.INVOKEVIRTUAL:
1858                 case Opcodes.INVOKESPECIAL:
1859                 case Opcodes.INVOKESTATIC:
1860                 case Opcodes.NEW:
1861                 case Opcodes.ANEWARRAY:
1862                 case Opcodes.CHECKCAST:
1863                 case Opcodes.INSTANCEOF:
1864                 case Opcodes.IINC:
1865                     currentOffset += 3;
1866                     break;
1867                 case Opcodes.INVOKEINTERFACE:
1868                 case Opcodes.INVOKEDYNAMIC:
1869                     currentOffset += 5;
1870                     break;
1871                 case Opcodes.MULTIANEWARRAY:
1872                     currentOffset += 4;
1873                     break;
1874                 default:
1875                     throw new IllegalArgumentException();
1876             }
1877         }
1878 
1879         // Read the 'exception_table_length' and 'exception_table' field to create a label for each
1880         // referenced instruction, and to make methodVisitor visit the corresponding try catch blocks.
1881         int exceptionTableLength = readUnsignedShort(currentOffset);
1882         currentOffset += 2;
1883         while (exceptionTableLength-- > 0) {
1884             Label start = createLabel(readUnsignedShort(currentOffset), labels);
1885             Label end = createLabel(readUnsignedShort(currentOffset + 2), labels);
1886             Label handler = createLabel(readUnsignedShort(currentOffset + 4), labels);
1887             String catchType = readUTF8(cpInfoOffsets[readUnsignedShort(currentOffset + 6)], charBuffer);
1888             currentOffset += 8;
1889             methodVisitor.visitTryCatchBlock(start, end, handler, catchType);
1890         }
1891 
1892         // Read the Code attributes to create a label for each referenced instruction (the variables
1893         // are ordered as in Section 4.7 of the JVMS). Attribute offsets exclude the
1894         // attribute_name_index and attribute_length fields.
1895         // - The offset of the current 'stack_map_frame' in the StackMap[Table] attribute, or 0.
1896         // Initially, this is the offset of the first 'stack_map_frame' entry. Then this offset is
1897         // updated after each stack_map_frame is read.
1898         int stackMapFrameOffset = 0;
1899         // - The end offset of the StackMap[Table] attribute, or 0.
1900         int stackMapTableEndOffset = 0;
1901         // - Whether the stack map frames are compressed (i.e. in a StackMapTable) or not.
1902         boolean compressedFrames = true;
1903         // - The offset of the LocalVariableTable attribute, or 0.
1904         int localVariableTableOffset = 0;
1905         // - The offset of the LocalVariableTypeTable attribute, or 0.
1906         int localVariableTypeTableOffset = 0;
1907         // - The offset of each 'type_annotation' entry in the RuntimeVisibleTypeAnnotations
1908         // attribute, or null.
1909         int[] visibleTypeAnnotationOffsets = null;
1910         // - The offset of each 'type_annotation' entry in the RuntimeInvisibleTypeAnnotations
1911         // attribute, or null.
1912         int[] invisibleTypeAnnotationOffsets = null;
1913         // - The non standard attributes (linked with their {@link Attribute#nextAttribute} field).
1914         //   This list in the <i>reverse order</i> or their order in the ClassFile structure.
1915         Attribute attributes = null;
1916 
1917         int attributesCount = readUnsignedShort(currentOffset);
1918         currentOffset += 2;
1919         while (attributesCount-- > 0) {
1920             // Read the attribute_info's attribute_name and attribute_length fields.
1921             String attributeName = readUTF8(currentOffset, charBuffer);
1922             int attributeLength = readInt(currentOffset + 2);
1923             currentOffset += 6;
1924             if (Constants.LOCAL_VARIABLE_TABLE.equals(attributeName)) {
1925                 if ((context.parsingOptions & SKIP_DEBUG) == 0) {
1926                     localVariableTableOffset = currentOffset;
1927                     // Parse the attribute to find the corresponding (debug only) labels.
1928                     int currentLocalVariableTableOffset = currentOffset;
1929                     int localVariableTableLength = readUnsignedShort(currentLocalVariableTableOffset);
1930                     currentLocalVariableTableOffset += 2;
1931                     while (localVariableTableLength-- > 0) {
1932                         int startPc = readUnsignedShort(currentLocalVariableTableOffset);
1933                         createDebugLabel(startPc, labels);
1934                         int length = readUnsignedShort(currentLocalVariableTableOffset + 2);
1935                         createDebugLabel(startPc + length, labels);
1936                         // Skip the name_index, descriptor_index and index fields (2 bytes each).
1937                         currentLocalVariableTableOffset += 10;
1938                     }
1939                 }
1940             } else if (Constants.LOCAL_VARIABLE_TYPE_TABLE.equals(attributeName)) {
1941                 localVariableTypeTableOffset = currentOffset;
1942                 // Here we do not extract the labels corresponding to the attribute content. We assume they
1943                 // are the same or a subset of those of the LocalVariableTable attribute.
1944             } else if (Constants.LINE_NUMBER_TABLE.equals(attributeName)) {
1945                 if ((context.parsingOptions & SKIP_DEBUG) == 0) {
1946                     // Parse the attribute to find the corresponding (debug only) labels.
1947                     int currentLineNumberTableOffset = currentOffset;
1948                     int lineNumberTableLength = readUnsignedShort(currentLineNumberTableOffset);
1949                     currentLineNumberTableOffset += 2;
1950                     while (lineNumberTableLength-- > 0) {
1951                         int startPc = readUnsignedShort(currentLineNumberTableOffset);
1952                         int lineNumber = readUnsignedShort(currentLineNumberTableOffset + 2);
1953                         currentLineNumberTableOffset += 4;
1954                         createDebugLabel(startPc, labels);
1955                         labels[startPc].addLineNumber(lineNumber);
1956                     }
1957                 }
1958             } else if (Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
1959                 visibleTypeAnnotationOffsets =
1960                         readTypeAnnotations(methodVisitor, context, currentOffset, /* visible = */ true);
1961                 // Here we do not extract the labels corresponding to the attribute content. This would
1962                 // require a full parsing of the attribute, which would need to be repeated when parsing
1963                 // the bytecode instructions (see below). Instead, the content of the attribute is read one
1964                 // type annotation at a time (i.e. after a type annotation has been visited, the next type
1965                 // annotation is read), and the labels it contains are also extracted one annotation at a
1966                 // time. This assumes that type annotations are ordered by increasing bytecode offset.
1967             } else if (Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
1968                 invisibleTypeAnnotationOffsets =
1969                         readTypeAnnotations(methodVisitor, context, currentOffset, /* visible = */ false);
1970                 // Same comment as above for the RuntimeVisibleTypeAnnotations attribute.
1971             } else if (Constants.STACK_MAP_TABLE.equals(attributeName)) {
1972                 if ((context.parsingOptions & SKIP_FRAMES) == 0) {
1973                     stackMapFrameOffset = currentOffset + 2;
1974                     stackMapTableEndOffset = currentOffset + attributeLength;
1975                 }
1976                 // Here we do not extract the labels corresponding to the attribute content. This would
1977                 // require a full parsing of the attribute, which would need to be repeated when parsing
1978                 // the bytecode instructions (see below). Instead, the content of the attribute is read one
1979                 // frame at a time (i.e. after a frame has been visited, the next frame is read), and the
1980                 // labels it contains are also extracted one frame at a time. Thanks to the ordering of
1981                 // frames, having only a "one frame lookahead" is not a problem, i.e. it is not possible to
1982                 // see an offset smaller than the offset of the current instruction and for which no Label
1983                 // exist. Except for UNINITIALIZED type offsets. We solve this by parsing the stack map
1984                 // table without a full decoding (see below).
1985             } else if ("StackMap".equals(attributeName)) {
1986                 if ((context.parsingOptions & SKIP_FRAMES) == 0) {
1987                     stackMapFrameOffset = currentOffset + 2;
1988                     stackMapTableEndOffset = currentOffset + attributeLength;
1989                     compressedFrames = false;
1990                 }
1991                 // IMPORTANT! Here we assume that the frames are ordered, as in the StackMapTable attribute,
1992                 // although this is not guaranteed by the attribute format. This allows an incremental
1993                 // extraction of the labels corresponding to this attribute (see the comment above for the
1994                 // StackMapTable attribute).
1995             } else {
1996                 Attribute attribute =
1997                         readAttribute(
1998                                 context.attributePrototypes,
1999                                 attributeName,
2000                                 currentOffset,
2001                                 attributeLength,
2002                                 charBuffer,
2003                                 codeOffset,
2004                                 labels);
2005                 attribute.nextAttribute = attributes;
2006                 attributes = attribute;
2007             }
2008             currentOffset += attributeLength;
2009         }
2010 
2011         // Initialize the context fields related to stack map frames, and generate the first
2012         // (implicit) stack map frame, if needed.
2013         final boolean expandFrames = (context.parsingOptions & EXPAND_FRAMES) != 0;
2014         if (stackMapFrameOffset != 0) {
2015             // The bytecode offset of the first explicit frame is not offset_delta + 1 but only
2016             // offset_delta. Setting the implicit frame offset to -1 allows us to use of the
2017             // "offset_delta + 1" rule in all cases.
2018             context.currentFrameOffset = -1;
2019             context.currentFrameType = 0;
2020             context.currentFrameLocalCount = 0;
2021             context.currentFrameLocalCountDelta = 0;
2022             context.currentFrameLocalTypes = new Object[maxLocals];
2023             context.currentFrameStackCount = 0;
2024             context.currentFrameStackTypes = new Object[maxStack];
2025             if (expandFrames) {
2026                 computeImplicitFrame(context);
2027             }
2028             // Find the labels for UNINITIALIZED frame types. Instead of decoding each element of the
2029             // stack map table, we look for 3 consecutive bytes that "look like" an UNINITIALIZED type
2030             // (tag ITEM_Uninitialized, offset within bytecode bounds, NEW instruction at this offset).
2031             // We may find false positives (i.e. not real UNINITIALIZED types), but this should be rare,
2032             // and the only consequence will be the creation of an unneeded label. This is better than
2033             // creating a label for each NEW instruction, and faster than fully decoding the whole stack
2034             // map table.
2035             for (int offset = stackMapFrameOffset; offset < stackMapTableEndOffset - 2; ++offset) {
2036                 if (classBuffer[offset] == Frame.ITEM_UNINITIALIZED) {
2037                     int potentialBytecodeOffset = readUnsignedShort(offset + 1);
2038                     if (potentialBytecodeOffset >= 0
2039                             && potentialBytecodeOffset < codeLength
2040                             && (classBuffer[bytecodeStartOffset + potentialBytecodeOffset] & 0xFF)
2041                                     == Opcodes.NEW) {
2042                         createLabel(potentialBytecodeOffset, labels);
2043                     }
2044                 }
2045             }
2046         }
2047         if (expandFrames && (context.parsingOptions & EXPAND_ASM_INSNS) != 0) {
2048             // Expanding the ASM specific instructions can introduce F_INSERT frames, even if the method
2049             // does not currently have any frame. These inserted frames must be computed by simulating the
2050             // effect of the bytecode instructions, one by one, starting from the implicit first frame.
2051             // For this, MethodWriter needs to know maxLocals before the first instruction is visited. To
2052             // ensure this, we visit the implicit first frame here (passing only maxLocals - the rest is
2053             // computed in MethodWriter).
2054             methodVisitor.visitFrame(Opcodes.F_NEW, maxLocals, null, 0, null);
2055         }
2056 
2057         // Visit the bytecode instructions. First, introduce state variables for the incremental parsing
2058         // of the type annotations.
2059 
2060         // Index of the next runtime visible type annotation to read (in the
2061         // visibleTypeAnnotationOffsets array).
2062         int currentVisibleTypeAnnotationIndex = 0;
2063         // The bytecode offset of the next runtime visible type annotation to read, or -1.
2064         int currentVisibleTypeAnnotationBytecodeOffset =
2065                 getTypeAnnotationBytecodeOffset(visibleTypeAnnotationOffsets, 0);
2066         // Index of the next runtime invisible type annotation to read (in the
2067         // invisibleTypeAnnotationOffsets array).
2068         int currentInvisibleTypeAnnotationIndex = 0;
2069         // The bytecode offset of the next runtime invisible type annotation to read, or -1.
2070         int currentInvisibleTypeAnnotationBytecodeOffset =
2071                 getTypeAnnotationBytecodeOffset(invisibleTypeAnnotationOffsets, 0);
2072 
2073         // Whether a F_INSERT stack map frame must be inserted before the current instruction.
2074         boolean insertFrame = false;
2075 
2076         // The delta to subtract from a goto_w or jsr_w opcode to get the corresponding goto or jsr
2077         // opcode, or 0 if goto_w and jsr_w must be left unchanged (i.e. when expanding ASM specific
2078         // instructions).
2079         final int wideJumpOpcodeDelta =
2080                 (context.parsingOptions & EXPAND_ASM_INSNS) == 0 ? Constants.WIDE_JUMP_OPCODE_DELTA : 0;
2081 
2082         currentOffset = bytecodeStartOffset;
2083         while (currentOffset < bytecodeEndOffset) {
2084             final int currentBytecodeOffset = currentOffset - bytecodeStartOffset;
2085 
2086             // Visit the label and the line number(s) for this bytecode offset, if any.
2087             Label currentLabel = labels[currentBytecodeOffset];
2088             if (currentLabel != null) {
2089                 currentLabel.accept(methodVisitor, (context.parsingOptions & SKIP_DEBUG) == 0);
2090             }
2091 
2092             // Visit the stack map frame for this bytecode offset, if any.
2093             while (stackMapFrameOffset != 0
2094                     && (context.currentFrameOffset == currentBytecodeOffset
2095                             || context.currentFrameOffset == -1)) {
2096                 // If there is a stack map frame for this offset, make methodVisitor visit it, and read the
2097                 // next stack map frame if there is one.
2098                 if (context.currentFrameOffset != -1) {
2099                     if (!compressedFrames || expandFrames) {
2100                         methodVisitor.visitFrame(
2101                                 Opcodes.F_NEW,
2102                                 context.currentFrameLocalCount,
2103                                 context.currentFrameLocalTypes,
2104                                 context.currentFrameStackCount,
2105                                 context.currentFrameStackTypes);
2106                     } else {
2107                         methodVisitor.visitFrame(
2108                                 context.currentFrameType,
2109                                 context.currentFrameLocalCountDelta,
2110                                 context.currentFrameLocalTypes,
2111                                 context.currentFrameStackCount,
2112                                 context.currentFrameStackTypes);
2113                     }
2114                     // Since there is already a stack map frame for this bytecode offset, there is no need to
2115                     // insert a new one.
2116                     insertFrame = false;
2117                 }
2118                 if (stackMapFrameOffset < stackMapTableEndOffset) {
2119                     stackMapFrameOffset =
2120                             readStackMapFrame(stackMapFrameOffset, compressedFrames, expandFrames, context);
2121                 } else {
2122                     stackMapFrameOffset = 0;
2123                 }
2124             }
2125 
2126             // Insert a stack map frame for this bytecode offset, if requested by setting insertFrame to
2127             // true during the previous iteration. The actual frame content is computed in MethodWriter.
2128             if (insertFrame) {
2129                 if ((context.parsingOptions & EXPAND_FRAMES) != 0) {
2130                     methodVisitor.visitFrame(Constants.F_INSERT, 0, null, 0, null);
2131                 }
2132                 insertFrame = false;
2133             }
2134 
2135             // Visit the instruction at this bytecode offset.
2136             int opcode = classBuffer[currentOffset] & 0xFF;
2137             switch (opcode) {
2138                 case Opcodes.NOP:
2139                 case Opcodes.ACONST_NULL:
2140                 case Opcodes.ICONST_M1:
2141                 case Opcodes.ICONST_0:
2142                 case Opcodes.ICONST_1:
2143                 case Opcodes.ICONST_2:
2144                 case Opcodes.ICONST_3:
2145                 case Opcodes.ICONST_4:
2146                 case Opcodes.ICONST_5:
2147                 case Opcodes.LCONST_0:
2148                 case Opcodes.LCONST_1:
2149                 case Opcodes.FCONST_0:
2150                 case Opcodes.FCONST_1:
2151                 case Opcodes.FCONST_2:
2152                 case Opcodes.DCONST_0:
2153                 case Opcodes.DCONST_1:
2154                 case Opcodes.IALOAD:
2155                 case Opcodes.LALOAD:
2156                 case Opcodes.FALOAD:
2157                 case Opcodes.DALOAD:
2158                 case Opcodes.AALOAD:
2159                 case Opcodes.BALOAD:
2160                 case Opcodes.CALOAD:
2161                 case Opcodes.SALOAD:
2162                 case Opcodes.IASTORE:
2163                 case Opcodes.LASTORE:
2164                 case Opcodes.FASTORE:
2165                 case Opcodes.DASTORE:
2166                 case Opcodes.AASTORE:
2167                 case Opcodes.BASTORE:
2168                 case Opcodes.CASTORE:
2169                 case Opcodes.SASTORE:
2170                 case Opcodes.POP:
2171                 case Opcodes.POP2:
2172                 case Opcodes.DUP:
2173                 case Opcodes.DUP_X1:
2174                 case Opcodes.DUP_X2:
2175                 case Opcodes.DUP2:
2176                 case Opcodes.DUP2_X1:
2177                 case Opcodes.DUP2_X2:
2178                 case Opcodes.SWAP:
2179                 case Opcodes.IADD:
2180                 case Opcodes.LADD:
2181                 case Opcodes.FADD:
2182                 case Opcodes.DADD:
2183                 case Opcodes.ISUB:
2184                 case Opcodes.LSUB:
2185                 case Opcodes.FSUB:
2186                 case Opcodes.DSUB:
2187                 case Opcodes.IMUL:
2188                 case Opcodes.LMUL:
2189                 case Opcodes.FMUL:
2190                 case Opcodes.DMUL:
2191                 case Opcodes.IDIV:
2192                 case Opcodes.LDIV:
2193                 case Opcodes.FDIV:
2194                 case Opcodes.DDIV:
2195                 case Opcodes.IREM:
2196                 case Opcodes.LREM:
2197                 case Opcodes.FREM:
2198                 case Opcodes.DREM:
2199                 case Opcodes.INEG:
2200                 case Opcodes.LNEG:
2201                 case Opcodes.FNEG:
2202                 case Opcodes.DNEG:
2203                 case Opcodes.ISHL:
2204                 case Opcodes.LSHL:
2205                 case Opcodes.ISHR:
2206                 case Opcodes.LSHR:
2207                 case Opcodes.IUSHR:
2208                 case Opcodes.LUSHR:
2209                 case Opcodes.IAND:
2210                 case Opcodes.LAND:
2211                 case Opcodes.IOR:
2212                 case Opcodes.LOR:
2213                 case Opcodes.IXOR:
2214                 case Opcodes.LXOR:
2215                 case Opcodes.I2L:
2216                 case Opcodes.I2F:
2217                 case Opcodes.I2D:
2218                 case Opcodes.L2I:
2219                 case Opcodes.L2F:
2220                 case Opcodes.L2D:
2221                 case Opcodes.F2I:
2222                 case Opcodes.F2L:
2223                 case Opcodes.F2D:
2224                 case Opcodes.D2I:
2225                 case Opcodes.D2L:
2226                 case Opcodes.D2F:
2227                 case Opcodes.I2B:
2228                 case Opcodes.I2C:
2229                 case Opcodes.I2S:
2230                 case Opcodes.LCMP:
2231                 case Opcodes.FCMPL:
2232                 case Opcodes.FCMPG:
2233                 case Opcodes.DCMPL:
2234                 case Opcodes.DCMPG:
2235                 case Opcodes.IRETURN:
2236                 case Opcodes.LRETURN:
2237                 case Opcodes.FRETURN:
2238                 case Opcodes.DRETURN:
2239                 case Opcodes.ARETURN:
2240                 case Opcodes.RETURN:
2241                 case Opcodes.ARRAYLENGTH:
2242                 case Opcodes.ATHROW:
2243                 case Opcodes.MONITORENTER:
2244                 case Opcodes.MONITOREXIT:
2245                     methodVisitor.visitInsn(opcode);
2246                     currentOffset += 1;
2247                     break;
2248                 case Constants.ILOAD_0:
2249                 case Constants.ILOAD_1:
2250                 case Constants.ILOAD_2:
2251                 case Constants.ILOAD_3:
2252                 case Constants.LLOAD_0:
2253                 case Constants.LLOAD_1:
2254                 case Constants.LLOAD_2:
2255                 case Constants.LLOAD_3:
2256                 case Constants.FLOAD_0:
2257                 case Constants.FLOAD_1:
2258                 case Constants.FLOAD_2:
2259                 case Constants.FLOAD_3:
2260                 case Constants.DLOAD_0:
2261                 case Constants.DLOAD_1:
2262                 case Constants.DLOAD_2:
2263                 case Constants.DLOAD_3:
2264                 case Constants.ALOAD_0:
2265                 case Constants.ALOAD_1:
2266                 case Constants.ALOAD_2:
2267                 case Constants.ALOAD_3:
2268                     opcode -= Constants.ILOAD_0;
2269                     methodVisitor.visitVarInsn(Opcodes.ILOAD + (opcode >> 2), opcode & 0x3);
2270                     currentOffset += 1;
2271                     break;
2272                 case Constants.ISTORE_0:
2273                 case Constants.ISTORE_1:
2274                 case Constants.ISTORE_2:
2275                 case Constants.ISTORE_3:
2276                 case Constants.LSTORE_0:
2277                 case Constants.LSTORE_1:
2278                 case Constants.LSTORE_2:
2279                 case Constants.LSTORE_3:
2280                 case Constants.FSTORE_0:
2281                 case Constants.FSTORE_1:
2282                 case Constants.FSTORE_2:
2283                 case Constants.FSTORE_3:
2284                 case Constants.DSTORE_0:
2285                 case Constants.DSTORE_1:
2286                 case Constants.DSTORE_2:
2287                 case Constants.DSTORE_3:
2288                 case Constants.ASTORE_0:
2289                 case Constants.ASTORE_1:
2290                 case Constants.ASTORE_2:
2291                 case Constants.ASTORE_3:
2292                     opcode -= Constants.ISTORE_0;
2293                     methodVisitor.visitVarInsn(Opcodes.ISTORE + (opcode >> 2), opcode & 0x3);
2294                     currentOffset += 1;
2295                     break;
2296                 case Opcodes.IFEQ:
2297                 case Opcodes.IFNE:
2298                 case Opcodes.IFLT:
2299                 case Opcodes.IFGE:
2300                 case Opcodes.IFGT:
2301                 case Opcodes.IFLE:
2302                 case Opcodes.IF_ICMPEQ:
2303                 case Opcodes.IF_ICMPNE:
2304                 case Opcodes.IF_ICMPLT:
2305                 case Opcodes.IF_ICMPGE:
2306                 case Opcodes.IF_ICMPGT:
2307                 case Opcodes.IF_ICMPLE:
2308                 case Opcodes.IF_ACMPEQ:
2309                 case Opcodes.IF_ACMPNE:
2310                 case Opcodes.GOTO:
2311                 case Opcodes.JSR:
2312                 case Opcodes.IFNULL:
2313                 case Opcodes.IFNONNULL:
2314                     methodVisitor.visitJumpInsn(
2315                             opcode, labels[currentBytecodeOffset + readShort(currentOffset + 1)]);
2316                     currentOffset += 3;
2317                     break;
2318                 case Constants.GOTO_W:
2319                 case Constants.JSR_W:
2320                     methodVisitor.visitJumpInsn(
2321                             opcode - wideJumpOpcodeDelta,
2322                             labels[currentBytecodeOffset + readInt(currentOffset + 1)]);
2323                     currentOffset += 5;
2324                     break;
2325                 case Constants.ASM_IFEQ:
2326                 case Constants.ASM_IFNE:
2327                 case Constants.ASM_IFLT:
2328                 case Constants.ASM_IFGE:
2329                 case Constants.ASM_IFGT:
2330                 case Constants.ASM_IFLE:
2331                 case Constants.ASM_IF_ICMPEQ:
2332                 case Constants.ASM_IF_ICMPNE:
2333                 case Constants.ASM_IF_ICMPLT:
2334                 case Constants.ASM_IF_ICMPGE:
2335                 case Constants.ASM_IF_ICMPGT:
2336                 case Constants.ASM_IF_ICMPLE:
2337                 case Constants.ASM_IF_ACMPEQ:
2338                 case Constants.ASM_IF_ACMPNE:
2339                 case Constants.ASM_GOTO:
2340                 case Constants.ASM_JSR:
2341                 case Constants.ASM_IFNULL:
2342                 case Constants.ASM_IFNONNULL:
2343                     {
2344                         // A forward jump with an offset > 32767. In this case we automatically replace ASM_GOTO
2345                         // with GOTO_W, ASM_JSR with JSR_W and ASM_IFxxx <l> with IFNOTxxx <L> GOTO_W <l> L:...,
2346                         // where IFNOTxxx is the "opposite" opcode of ASMS_IFxxx (e.g. IFNE for ASM_IFEQ) and
2347                         // where <L> designates the instruction just after the GOTO_W.
2348                         // First, change the ASM specific opcodes ASM_IFEQ ... ASM_JSR, ASM_IFNULL and
2349                         // ASM_IFNONNULL to IFEQ ... JSR, IFNULL and IFNONNULL.
2350                         opcode =
2351                                 opcode < Constants.ASM_IFNULL
2352                                         ? opcode - Constants.ASM_OPCODE_DELTA
2353                                         : opcode - Constants.ASM_IFNULL_OPCODE_DELTA;
2354                         Label target = labels[currentBytecodeOffset + readUnsignedShort(currentOffset + 1)];
2355                         if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
2356                             // Replace GOTO with GOTO_W and JSR with JSR_W.
2357                             methodVisitor.visitJumpInsn(opcode + Constants.WIDE_JUMP_OPCODE_DELTA, target);
2358                         } else {
2359                             // Compute the "opposite" of opcode. This can be done by flipping the least
2360                             // significant bit for IFNULL and IFNONNULL, and similarly for IFEQ ... IF_ACMPEQ
2361                             // (with a pre and post offset by 1).
2362                             opcode = opcode < Opcodes.GOTO ? ((opcode + 1) ^ 1) - 1 : opcode ^ 1;
2363                             Label endif = createLabel(currentBytecodeOffset + 3, labels);
2364                             methodVisitor.visitJumpInsn(opcode, endif);
2365                             methodVisitor.visitJumpInsn(Constants.GOTO_W, target);
2366                             // endif designates the instruction just after GOTO_W, and is visited as part of the
2367                             // next instruction. Since it is a jump target, we need to insert a frame here.
2368                             insertFrame = true;
2369                         }
2370                         currentOffset += 3;
2371                         break;
2372                     }
2373                 case Constants.ASM_GOTO_W:
2374                     // Replace ASM_GOTO_W with GOTO_W.
2375                     methodVisitor.visitJumpInsn(
2376                             Constants.GOTO_W, labels[currentBytecodeOffset + readInt(currentOffset + 1)]);
2377                     // The instruction just after is a jump target (because ASM_GOTO_W is used in patterns
2378                     // IFNOTxxx <L> ASM_GOTO_W <l> L:..., see MethodWriter), so we need to insert a frame
2379                     // here.
2380                     insertFrame = true;
2381                     currentOffset += 5;
2382                     break;
2383                 case Constants.WIDE:
2384                     opcode = classBuffer[currentOffset + 1] & 0xFF;
2385                     if (opcode == Opcodes.IINC) {
2386                         methodVisitor.visitIincInsn(
2387                                 readUnsignedShort(currentOffset + 2), readShort(currentOffset + 4));
2388                         currentOffset += 6;
2389                     } else {
2390                         methodVisitor.visitVarInsn(opcode, readUnsignedShort(currentOffset + 2));
2391                         currentOffset += 4;
2392                     }
2393                     break;
2394                 case Opcodes.TABLESWITCH:
2395                     {
2396                         // Skip 0 to 3 padding bytes.
2397                         currentOffset += 4 - (currentBytecodeOffset & 3);
2398                         // Read the instruction.
2399                         Label defaultLabel = labels[currentBytecodeOffset + readInt(currentOffset)];
2400                         int low = readInt(currentOffset + 4);
2401                         int high = readInt(currentOffset + 8);
2402                         currentOffset += 12;
2403                         Label[] table = new Label[high - low + 1];
2404                         for (int i = 0; i < table.length; ++i) {
2405                             table[i] = labels[currentBytecodeOffset + readInt(currentOffset)];
2406                             currentOffset += 4;
2407                         }
2408                         methodVisitor.visitTableSwitchInsn(low, high, defaultLabel, table);
2409                         break;
2410                     }
2411                 case Opcodes.LOOKUPSWITCH:
2412                     {
2413                         // Skip 0 to 3 padding bytes.
2414                         currentOffset += 4 - (currentBytecodeOffset & 3);
2415                         // Read the instruction.
2416                         Label defaultLabel = labels[currentBytecodeOffset + readInt(currentOffset)];
2417                         int numPairs = readInt(currentOffset + 4);
2418                         currentOffset += 8;
2419                         int[] keys = new int[numPairs];
2420                         Label[] values = new Label[numPairs];
2421                         for (int i = 0; i < numPairs; ++i) {
2422                             keys[i] = readInt(currentOffset);
2423                             values[i] = labels[currentBytecodeOffset + readInt(currentOffset + 4)];
2424                             currentOffset += 8;
2425                         }
2426                         methodVisitor.visitLookupSwitchInsn(defaultLabel, keys, values);
2427                         break;
2428                     }
2429                 case Opcodes.ILOAD:
2430                 case Opcodes.LLOAD:
2431                 case Opcodes.FLOAD:
2432                 case Opcodes.DLOAD:
2433                 case Opcodes.ALOAD:
2434                 case Opcodes.ISTORE:
2435                 case Opcodes.LSTORE:
2436                 case Opcodes.FSTORE:
2437                 case Opcodes.DSTORE:
2438                 case Opcodes.ASTORE:
2439                 case Opcodes.RET:
2440                     methodVisitor.visitVarInsn(opcode, classBuffer[currentOffset + 1] & 0xFF);
2441                     currentOffset += 2;
2442                     break;
2443                 case Opcodes.BIPUSH:
2444                 case Opcodes.NEWARRAY:
2445                     methodVisitor.visitIntInsn(opcode, classBuffer[currentOffset + 1]);
2446                     currentOffset += 2;
2447                     break;
2448                 case Opcodes.SIPUSH:
2449                     methodVisitor.visitIntInsn(opcode, readShort(currentOffset + 1));
2450                     currentOffset += 3;
2451                     break;
2452                 case Opcodes.LDC:
2453                     methodVisitor.visitLdcInsn(readConst(classBuffer[currentOffset + 1] & 0xFF, charBuffer));
2454                     currentOffset += 2;
2455                     break;
2456                 case Constants.LDC_W:
2457                 case Constants.LDC2_W:
2458                     methodVisitor.visitLdcInsn(readConst(readUnsignedShort(currentOffset + 1), charBuffer));
2459                     currentOffset += 3;
2460                     break;
2461                 case Opcodes.GETSTATIC:
2462                 case Opcodes.PUTSTATIC:
2463                 case Opcodes.GETFIELD:
2464                 case Opcodes.PUTFIELD:
2465                 case Opcodes.INVOKEVIRTUAL:
2466                 case Opcodes.INVOKESPECIAL:
2467                 case Opcodes.INVOKESTATIC:
2468                 case Opcodes.INVOKEINTERFACE:
2469                     {
2470                         int cpInfoOffset = cpInfoOffsets[readUnsignedShort(currentOffset + 1)];
2471                         int nameAndTypeCpInfoOffset = cpInfoOffsets[readUnsignedShort(cpInfoOffset + 2)];
2472                         String owner = readClass(cpInfoOffset, charBuffer);
2473                         String name = readUTF8(nameAndTypeCpInfoOffset, charBuffer);
2474                         String descriptor = readUTF8(nameAndTypeCpInfoOffset + 2, charBuffer);
2475                         if (opcode < Opcodes.INVOKEVIRTUAL) {
2476                             methodVisitor.visitFieldInsn(opcode, owner, name, descriptor);
2477                         } else {
2478                             boolean isInterface =
2479                                     classBuffer[cpInfoOffset - 1] == Symbol.CONSTANT_INTERFACE_METHODREF_TAG;
2480                             methodVisitor.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
2481                         }
2482                         if (opcode == Opcodes.INVOKEINTERFACE) {
2483                             currentOffset += 5;
2484                         } else {
2485                             currentOffset += 3;
2486                         }
2487                         break;
2488                     }
2489                 case Opcodes.INVOKEDYNAMIC:
2490                     {
2491                         int cpInfoOffset = cpInfoOffsets[readUnsignedShort(currentOffset + 1)];
2492                         int nameAndTypeCpInfoOffset = cpInfoOffsets[readUnsignedShort(cpInfoOffset + 2)];
2493                         String name = readUTF8(nameAndTypeCpInfoOffset, charBuffer);
2494                         String descriptor = readUTF8(nameAndTypeCpInfoOffset + 2, charBuffer);
2495                         int bootstrapMethodOffset = bootstrapMethodOffsets[readUnsignedShort(cpInfoOffset)];
2496                         Handle handle =
2497                                 (Handle) readConst(readUnsignedShort(bootstrapMethodOffset), charBuffer);
2498                         Object[] bootstrapMethodArguments =
2499                                 new Object[readUnsignedShort(bootstrapMethodOffset + 2)];
2500                         bootstrapMethodOffset += 4;
2501                         for (int i = 0; i < bootstrapMethodArguments.length; i++) {
2502                             bootstrapMethodArguments[i] =
2503                                     readConst(readUnsignedShort(bootstrapMethodOffset), charBuffer);
2504                             bootstrapMethodOffset += 2;
2505                         }
2506                         methodVisitor.visitInvokeDynamicInsn(
2507                                 name, descriptor, handle, bootstrapMethodArguments);
2508                         currentOffset += 5;
2509                         break;
2510                     }
2511                 case Opcodes.NEW:
2512                 case Opcodes.ANEWARRAY:
2513                 case Opcodes.CHECKCAST:
2514                 case Opcodes.INSTANCEOF:
2515                     methodVisitor.visitTypeInsn(opcode, readClass(currentOffset + 1, charBuffer));
2516                     currentOffset += 3;
2517                     break;
2518                 case Opcodes.IINC:
2519                     methodVisitor.visitIincInsn(
2520                             classBuffer[currentOffset + 1] & 0xFF, classBuffer[currentOffset + 2]);
2521                     currentOffset += 3;
2522                     break;
2523                 case Opcodes.MULTIANEWARRAY:
2524                     methodVisitor.visitMultiANewArrayInsn(
2525                             readClass(currentOffset + 1, charBuffer), classBuffer[currentOffset + 3] & 0xFF);
2526                     currentOffset += 4;
2527                     break;
2528                 default:
2529                     throw new AssertionError();
2530             }
2531 
2532             // Visit the runtime visible instruction annotations, if any.
2533             while (visibleTypeAnnotationOffsets != null
2534                     && currentVisibleTypeAnnotationIndex < visibleTypeAnnotationOffsets.length
2535                     && currentVisibleTypeAnnotationBytecodeOffset <= currentBytecodeOffset) {
2536                 if (currentVisibleTypeAnnotationBytecodeOffset == currentBytecodeOffset) {
2537                     // Parse the target_type, target_info and target_path fields.
2538                     int currentAnnotationOffset =
2539                             readTypeAnnotationTarget(
2540                                     context, visibleTypeAnnotationOffsets[currentVisibleTypeAnnotationIndex]);
2541                     // Parse the type_index field.
2542                     String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
2543                     currentAnnotationOffset += 2;
2544                     // Parse num_element_value_pairs and element_value_pairs and visit these values.
2545                     readElementValues(
2546                             methodVisitor.visitInsnAnnotation(
2547                                     context.currentTypeAnnotationTarget,
2548                                     context.currentTypeAnnotationTargetPath,
2549                                     annotationDescriptor,
2550                                     /* visible = */ true),
2551                             currentAnnotationOffset,
2552                             /* named = */ true,
2553                             charBuffer);
2554                 }
2555                 currentVisibleTypeAnnotationBytecodeOffset =
2556                         getTypeAnnotationBytecodeOffset(
2557                                 visibleTypeAnnotationOffsets, ++currentVisibleTypeAnnotationIndex);
2558             }
2559 
2560             // Visit the runtime invisible instruction annotations, if any.
2561             while (invisibleTypeAnnotationOffsets != null
2562                     && currentInvisibleTypeAnnotationIndex < invisibleTypeAnnotationOffsets.length
2563                     && currentInvisibleTypeAnnotationBytecodeOffset <= currentBytecodeOffset) {
2564                 if (currentInvisibleTypeAnnotationBytecodeOffset == currentBytecodeOffset) {
2565                     // Parse the target_type, target_info and target_path fields.
2566                     int currentAnnotationOffset =
2567                             readTypeAnnotationTarget(
2568                                     context, invisibleTypeAnnotationOffsets[currentInvisibleTypeAnnotationIndex]);
2569                     // Parse the type_index field.
2570                     String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
2571                     currentAnnotationOffset += 2;
2572                     // Parse num_element_value_pairs and element_value_pairs and visit these values.
2573                     readElementValues(
2574                             methodVisitor.visitInsnAnnotation(
2575                                     context.currentTypeAnnotationTarget,
2576                                     context.currentTypeAnnotationTargetPath,
2577                                     annotationDescriptor,
2578                                     /* visible = */ false),
2579                             currentAnnotationOffset,
2580                             /* named = */ true,
2581                             charBuffer);
2582                 }
2583                 currentInvisibleTypeAnnotationBytecodeOffset =
2584                         getTypeAnnotationBytecodeOffset(
2585                                 invisibleTypeAnnotationOffsets, ++currentInvisibleTypeAnnotationIndex);
2586             }
2587         }
2588         if (labels[codeLength] != null) {
2589             methodVisitor.visitLabel(labels[codeLength]);
2590         }
2591 
2592         // Visit LocalVariableTable and LocalVariableTypeTable attributes.
2593         if (localVariableTableOffset != 0 && (context.parsingOptions & SKIP_DEBUG) == 0) {
2594             // The (start_pc, index, signature_index) fields of each entry of the LocalVariableTypeTable.
2595             int[] typeTable = null;
2596             if (localVariableTypeTableOffset != 0) {
2597                 typeTable = new int[readUnsignedShort(localVariableTypeTableOffset) * 3];
2598                 currentOffset = localVariableTypeTableOffset + 2;
2599                 int typeTableIndex = typeTable.length;
2600                 while (typeTableIndex > 0) {
2601                     // Store the offset of 'signature_index', and the value of 'index' and 'start_pc'.
2602                     typeTable[--typeTableIndex] = currentOffset + 6;
2603                     typeTable[--typeTableIndex] = readUnsignedShort(currentOffset + 8);
2604                     typeTable[--typeTableIndex] = readUnsignedShort(currentOffset);
2605                     currentOffset += 10;
2606                 }
2607             }
2608             int localVariableTableLength = readUnsignedShort(localVariableTableOffset);
2609             currentOffset = localVariableTableOffset + 2;
2610             while (localVariableTableLength-- > 0) {
2611                 int startPc = readUnsignedShort(currentOffset);
2612                 int length = readUnsignedShort(currentOffset + 2);
2613                 String name = readUTF8(currentOffset + 4, charBuffer);
2614                 String descriptor = readUTF8(currentOffset + 6, charBuffer);
2615                 int index = readUnsignedShort(currentOffset + 8);
2616                 currentOffset += 10;
2617                 String signature = null;
2618                 if (typeTable != null) {
2619                     for (int i = 0; i < typeTable.length; i += 3) {
2620                         if (typeTable[i] == startPc && typeTable[i + 1] == index) {
2621                             signature = readUTF8(typeTable[i + 2], charBuffer);
2622                             break;
2623                         }
2624                     }
2625                 }
2626                 methodVisitor.visitLocalVariable(
2627                         name, descriptor, signature, labels[startPc], labels[startPc + length], index);
2628             }
2629         }
2630 
2631         // Visit the local variable type annotations of the RuntimeVisibleTypeAnnotations attribute.
2632         if (visibleTypeAnnotationOffsets != null) {
2633             for (int typeAnnotationOffset : visibleTypeAnnotationOffsets) {
2634                 int targetType = readByte(typeAnnotationOffset);
2635                 if (targetType == TypeReference.LOCAL_VARIABLE
2636                         || targetType == TypeReference.RESOURCE_VARIABLE) {
2637                     // Parse the target_type, target_info and target_path fields.
2638                     currentOffset = readTypeAnnotationTarget(context, typeAnnotationOffset);
2639                     // Parse the type_index field.
2640                     String annotationDescriptor = readUTF8(currentOffset, charBuffer);
2641                     currentOffset += 2;
2642                     // Parse num_element_value_pairs and element_value_pairs and visit these values.
2643                     readElementValues(
2644                             methodVisitor.visitLocalVariableAnnotation(
2645                                     context.currentTypeAnnotationTarget,
2646                                     context.currentTypeAnnotationTargetPath,
2647                                     context.currentLocalVariableAnnotationRangeStarts,
2648                                     context.currentLocalVariableAnnotationRangeEnds,
2649                                     context.currentLocalVariableAnnotationRangeIndices,
2650                                     annotationDescriptor,
2651                                     /* visible = */ true),
2652                             currentOffset,
2653                             /* named = */ true,
2654                             charBuffer);
2655                 }
2656             }
2657         }
2658 
2659         // Visit the local variable type annotations of the RuntimeInvisibleTypeAnnotations attribute.
2660         if (invisibleTypeAnnotationOffsets != null) {
2661             for (int typeAnnotationOffset : invisibleTypeAnnotationOffsets) {
2662                 int targetType = readByte(typeAnnotationOffset);
2663                 if (targetType == TypeReference.LOCAL_VARIABLE
2664                         || targetType == TypeReference.RESOURCE_VARIABLE) {
2665                     // Parse the target_type, target_info and target_path fields.
2666                     currentOffset = readTypeAnnotationTarget(context, typeAnnotationOffset);
2667                     // Parse the type_index field.
2668                     String annotationDescriptor = readUTF8(currentOffset, charBuffer);
2669                     currentOffset += 2;
2670                     // Parse num_element_value_pairs and element_value_pairs and visit these values.
2671                     readElementValues(
2672                             methodVisitor.visitLocalVariableAnnotation(
2673                                     context.currentTypeAnnotationTarget,
2674                                     context.currentTypeAnnotationTargetPath,
2675                                     context.currentLocalVariableAnnotationRangeStarts,
2676                                     context.currentLocalVariableAnnotationRangeEnds,
2677                                     context.currentLocalVariableAnnotationRangeIndices,
2678                                     annotationDescriptor,
2679                                     /* visible = */ false),
2680                             currentOffset,
2681                             /* named = */ true,
2682                             charBuffer);
2683                 }
2684             }
2685         }
2686 
2687         // Visit the non standard attributes.
2688         while (attributes != null) {
2689             // Copy and reset the nextAttribute field so that it can also be used in MethodWriter.
2690             Attribute nextAttribute = attributes.nextAttribute;
2691             attributes.nextAttribute = null;
2692             methodVisitor.visitAttribute(attributes);
2693             attributes = nextAttribute;
2694         }
2695 
2696         // Visit the max stack and max locals values.
2697         methodVisitor.visitMaxs(maxStack, maxLocals);
2698     }
2699 
2700     /**
2701       * Returns the label corresponding to the given bytecode offset. The default implementation of
2702       * this method creates a label for the given offset if it has not been already created.
2703       *
2704       * @param bytecodeOffset a bytecode offset in a method.
2705       * @param labels the already created labels, indexed by their offset. If a label already exists
2706       *     for bytecodeOffset this method must not create a new one. Otherwise it must store the new
2707       *     label in this array.
2708       * @return a non null Label, which must be equal to labels[bytecodeOffset].
2709       */
2710     protected Label readLabel(final int bytecodeOffset, final Label[] labels) {
2711         if (labels[bytecodeOffset] == null) {
2712             labels[bytecodeOffset] = new Label();
2713         }
2714         return labels[bytecodeOffset];
2715     }
2716 
2717     /**
2718       * Creates a label without the {@link Label#FLAG_DEBUG_ONLY} flag set, for the given bytecode
2719       * offset. The label is created with a call to {@link #readLabel} and its {@link
2720       * Label#FLAG_DEBUG_ONLY} flag is cleared.
2721       *
2722       * @param bytecodeOffset a bytecode offset in a method.
2723       * @param labels the already created labels, indexed by their offset.
2724       * @return a Label without the {@link Label#FLAG_DEBUG_ONLY} flag set.
2725       */
2726     private Label createLabel(final int bytecodeOffset, final Label[] labels) {
2727         Label label = readLabel(bytecodeOffset, labels);
2728         label.flags &= ~Label.FLAG_DEBUG_ONLY;
2729         return label;
2730     }
2731 
2732     /**
2733       * Creates a label with the {@link Label#FLAG_DEBUG_ONLY} flag set, if there is no already
2734       * existing label for the given bytecode offset (otherwise does nothing). The label is created
2735       * with a call to {@link #readLabel}.
2736       *
2737       * @param bytecodeOffset a bytecode offset in a method.
2738       * @param labels the already created labels, indexed by their offset.
2739       */
2740     private void createDebugLabel(final int bytecodeOffset, final Label[] labels) {
2741         if (labels[bytecodeOffset] == null) {
2742             readLabel(bytecodeOffset, labels).flags |= Label.FLAG_DEBUG_ONLY;
2743         }
2744     }
2745 
2746     // ----------------------------------------------------------------------------------------------
2747     // Methods to parse annotations, type annotations and parameter annotations
2748     // ----------------------------------------------------------------------------------------------
2749 
2750     /**
2751       * Parses a Runtime[In]VisibleTypeAnnotations attribute to find the offset of each type_annotation
2752       * entry it contains, to find the corresponding labels, and to visit the try catch block
2753       * annotations.
2754       *
2755       * @param methodVisitor the method visitor to be used to visit the try catch block annotations.
2756       * @param context information about the class being parsed.
2757       * @param runtimeTypeAnnotationsOffset the start offset of a Runtime[In]VisibleTypeAnnotations
2758       *     attribute, excluding the attribute_info's attribute_name_index and attribute_length fields.
2759       * @param visible true if the attribute to parse is a RuntimeVisibleTypeAnnotations attribute,
2760       *     false it is a RuntimeInvisibleTypeAnnotations attribute.
2761       * @return the start offset of each entry of the Runtime[In]VisibleTypeAnnotations_attribute's
2762       *     'annotations' array field.
2763       */
2764     private int[] readTypeAnnotations(
2765             final MethodVisitor methodVisitor,
2766             final Context context,
2767             final int runtimeTypeAnnotationsOffset,
2768             final boolean visible) {
2769         char[] charBuffer = context.charBuffer;
2770         int currentOffset = runtimeTypeAnnotationsOffset;
2771         // Read the num_annotations field and create an array to store the type_annotation offsets.
2772         int[] typeAnnotationsOffsets = new int[readUnsignedShort(currentOffset)];
2773         currentOffset += 2;
2774         // Parse the 'annotations' array field.
2775         for (int i = 0; i < typeAnnotationsOffsets.length; ++i) {
2776             typeAnnotationsOffsets[i] = currentOffset;
2777             // Parse the type_annotation's target_type and the target_info fields. The size of the
2778             // target_info field depends on the value of target_type.
2779             int targetType = readInt(currentOffset);
2780             switch (targetType >>> 24) {
2781                 case TypeReference.LOCAL_VARIABLE:
2782                 case TypeReference.RESOURCE_VARIABLE:
2783                     // A localvar_target has a variable size, which depends on the value of their table_length
2784                     // field. It also references bytecode offsets, for which we need labels.
2785                     int tableLength = readUnsignedShort(currentOffset + 1);
2786                     currentOffset += 3;
2787                     while (tableLength-- > 0) {
2788                         int startPc = readUnsignedShort(currentOffset);
2789                         int length = readUnsignedShort(currentOffset + 2);
2790                         // Skip the index field (2 bytes).
2791                         currentOffset += 6;
2792                         createLabel(startPc, context.currentMethodLabels);
2793                         createLabel(startPc + length, context.currentMethodLabels);
2794                     }
2795                     break;
2796                 case TypeReference.CAST:
2797                 case TypeReference.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
2798                 case TypeReference.METHOD_INVOCATION_TYPE_ARGUMENT:
2799                 case TypeReference.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
2800                 case TypeReference.METHOD_REFERENCE_TYPE_ARGUMENT:
2801                     currentOffset += 4;
2802                     break;
2803                 case TypeReference.CLASS_EXTENDS:
2804                 case TypeReference.CLASS_TYPE_PARAMETER_BOUND:
2805                 case TypeReference.METHOD_TYPE_PARAMETER_BOUND:
2806                 case TypeReference.THROWS:
2807                 case TypeReference.EXCEPTION_PARAMETER:
2808                 case TypeReference.INSTANCEOF:
2809                 case TypeReference.NEW:
2810                 case TypeReference.CONSTRUCTOR_REFERENCE:
2811                 case TypeReference.METHOD_REFERENCE:
2812                     currentOffset += 3;
2813                     break;
2814                 case TypeReference.CLASS_TYPE_PARAMETER:
2815                 case TypeReference.METHOD_TYPE_PARAMETER:
2816                 case TypeReference.METHOD_FORMAL_PARAMETER:
2817                 case TypeReference.FIELD:
2818                 case TypeReference.METHOD_RETURN:
2819                 case TypeReference.METHOD_RECEIVER:
2820                 default:
2821                     // TypeReference type which can't be used in Code attribute, or which is unknown.
2822                     throw new IllegalArgumentException();
2823             }
2824             // Parse the rest of the type_annotation structure, starting with the target_path structure
2825             // (whose size depends on its path_length field).
2826             int pathLength = readByte(currentOffset);
2827             if ((targetType >>> 24) == TypeReference.EXCEPTION_PARAMETER) {
2828                 // Parse the target_path structure and create a corresponding TypePath.
2829                 TypePath path = pathLength == 0 ? null : new TypePath(classFileBuffer, currentOffset);
2830                 currentOffset += 1 + 2 * pathLength;
2831                 // Parse the type_index field.
2832                 String annotationDescriptor = readUTF8(currentOffset, charBuffer);
2833                 currentOffset += 2;
2834                 // Parse num_element_value_pairs and element_value_pairs and visit these values.
2835                 currentOffset =
2836                         readElementValues(
2837                                 methodVisitor.visitTryCatchAnnotation(
2838                                         targetType & 0xFFFFFF00, path, annotationDescriptor, visible),
2839                                 currentOffset,
2840                                 /* named = */ true,
2841                                 charBuffer);
2842             } else {
2843                 // We don't want to visit the other target_type annotations, so we just skip them (which
2844                 // requires some parsing because the element_value_pairs array has a variable size). First,
2845                 // skip the target_path structure:
2846                 currentOffset += 3 + 2 * pathLength;
2847                 // Then skip the num_element_value_pairs and element_value_pairs fields (by reading them
2848                 // with a null AnnotationVisitor).
2849                 currentOffset =
2850                         readElementValues(
2851                                 /* annotationVisitor = */ null, currentOffset, /* named = */ true, charBuffer);
2852             }
2853         }
2854         return typeAnnotationsOffsets;
2855     }
2856 
2857     /**
2858       * Returns the bytecode offset corresponding to the specified JVMS 'type_annotation' structure, or
2859       * -1 if there is no such type_annotation of if it does not have a bytecode offset.
2860       *
2861       * @param typeAnnotationOffsets the offset of each 'type_annotation' entry in a
2862       *     Runtime[In]VisibleTypeAnnotations attribute, or {@literal null}.
2863       * @param typeAnnotationIndex the index a 'type_annotation' entry in typeAnnotationOffsets.
2864       * @return bytecode offset corresponding to the specified JVMS 'type_annotation' structure, or -1
2865       *     if there is no such type_annotation of if it does not have a bytecode offset.
2866       */
2867     private int getTypeAnnotationBytecodeOffset(
2868             final int[] typeAnnotationOffsets, final int typeAnnotationIndex) {
2869         if (typeAnnotationOffsets == null
2870                 || typeAnnotationIndex >= typeAnnotationOffsets.length
2871                 || readByte(typeAnnotationOffsets[typeAnnotationIndex]) < TypeReference.INSTANCEOF) {
2872             return -1;
2873         }
2874         return readUnsignedShort(typeAnnotationOffsets[typeAnnotationIndex] + 1);
2875     }
2876 
2877     /**
2878       * Parses the header of a JVMS type_annotation structure to extract its target_type, target_info
2879       * and target_path (the result is stored in the given context), and returns the start offset of
2880       * the rest of the type_annotation structure.
2881       *
2882       * @param context information about the class being parsed. This is where the extracted
2883       *     target_type and target_path must be stored.
2884       * @param typeAnnotationOffset the start offset of a type_annotation structure.
2885       * @return the start offset of the rest of the type_annotation structure.
2886       */
2887     private int readTypeAnnotationTarget(final Context context, final int typeAnnotationOffset) {
2888         int currentOffset = typeAnnotationOffset;
2889         // Parse and store the target_type structure.
2890         int targetType = readInt(typeAnnotationOffset);
2891         switch (targetType >>> 24) {
2892             case TypeReference.CLASS_TYPE_PARAMETER:
2893             case TypeReference.METHOD_TYPE_PARAMETER:
2894             case TypeReference.METHOD_FORMAL_PARAMETER:
2895                 targetType &= 0xFFFF0000;
2896                 currentOffset += 2;
2897                 break;
2898             case TypeReference.FIELD:
2899             case TypeReference.METHOD_RETURN:
2900             case TypeReference.METHOD_RECEIVER:
2901                 targetType &= 0xFF000000;
2902                 currentOffset += 1;
2903                 break;
2904             case TypeReference.LOCAL_VARIABLE:
2905             case TypeReference.RESOURCE_VARIABLE:
2906                 targetType &= 0xFF000000;
2907                 int tableLength = readUnsignedShort(currentOffset + 1);
2908                 currentOffset += 3;
2909                 context.currentLocalVariableAnnotationRangeStarts = new Label[tableLength];
2910                 context.currentLocalVariableAnnotationRangeEnds = new Label[tableLength];
2911                 context.currentLocalVariableAnnotationRangeIndices = new int[tableLength];
2912                 for (int i = 0; i < tableLength; ++i) {
2913                     int startPc = readUnsignedShort(currentOffset);
2914                     int length = readUnsignedShort(currentOffset + 2);
2915                     int index = readUnsignedShort(currentOffset + 4);
2916                     currentOffset += 6;
2917                     context.currentLocalVariableAnnotationRangeStarts[i] =
2918                             createLabel(startPc, context.currentMethodLabels);
2919                     context.currentLocalVariableAnnotationRangeEnds[i] =
2920                             createLabel(startPc + length, context.currentMethodLabels);
2921                     context.currentLocalVariableAnnotationRangeIndices[i] = index;
2922                 }
2923                 break;
2924             case TypeReference.CAST:
2925             case TypeReference.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
2926             case TypeReference.METHOD_INVOCATION_TYPE_ARGUMENT:
2927             case TypeReference.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
2928             case TypeReference.METHOD_REFERENCE_TYPE_ARGUMENT:
2929                 targetType &= 0xFF0000FF;
2930                 currentOffset += 4;
2931                 break;
2932             case TypeReference.CLASS_EXTENDS:
2933             case TypeReference.CLASS_TYPE_PARAMETER_BOUND:
2934             case TypeReference.METHOD_TYPE_PARAMETER_BOUND:
2935             case TypeReference.THROWS:
2936             case TypeReference.EXCEPTION_PARAMETER:
2937                 targetType &= 0xFFFFFF00;
2938                 currentOffset += 3;
2939                 break;
2940             case TypeReference.INSTANCEOF:
2941             case TypeReference.NEW:
2942             case TypeReference.CONSTRUCTOR_REFERENCE:
2943             case TypeReference.METHOD_REFERENCE:
2944                 targetType &= 0xFF000000;
2945                 currentOffset += 3;
2946                 break;
2947             default:
2948                 throw new IllegalArgumentException();
2949         }
2950         context.currentTypeAnnotationTarget = targetType;
2951         // Parse and store the target_path structure.
2952         int pathLength = readByte(currentOffset);
2953         context.currentTypeAnnotationTargetPath =
2954                 pathLength == 0 ? null : new TypePath(classFileBuffer, currentOffset);
2955         // Return the start offset of the rest of the type_annotation structure.
2956         return currentOffset + 1 + 2 * pathLength;
2957     }
2958 
2959     /**
2960       * Reads a Runtime[In]VisibleParameterAnnotations attribute and makes the given visitor visit it.
2961       *
2962       * @param methodVisitor the visitor that must visit the parameter annotations.
2963       * @param context information about the class being parsed.
2964       * @param runtimeParameterAnnotationsOffset the start offset of a
2965       *     Runtime[In]VisibleParameterAnnotations attribute, excluding the attribute_info's
2966       *     attribute_name_index and attribute_length fields.
2967       * @param visible true if the attribute to parse is a RuntimeVisibleParameterAnnotations
2968       *     attribute, false it is a RuntimeInvisibleParameterAnnotations attribute.
2969       */
2970     private void readParameterAnnotations(
2971             final MethodVisitor methodVisitor,
2972             final Context context,
2973             final int runtimeParameterAnnotationsOffset,
2974             final boolean visible) {
2975         int currentOffset = runtimeParameterAnnotationsOffset;
2976         int numParameters = classFileBuffer[currentOffset++] & 0xFF;
2977         methodVisitor.visitAnnotableParameterCount(numParameters, visible);
2978         char[] charBuffer = context.charBuffer;
2979         for (int i = 0; i < numParameters; ++i) {
2980             int numAnnotations = readUnsignedShort(currentOffset);
2981             currentOffset += 2;
2982             while (numAnnotations-- > 0) {
2983                 // Parse the type_index field.
2984                 String annotationDescriptor = readUTF8(currentOffset, charBuffer);
2985                 currentOffset += 2;
2986                 // Parse num_element_value_pairs and element_value_pairs and visit these values.
2987                 currentOffset =
2988                         readElementValues(
2989                                 methodVisitor.visitParameterAnnotation(i, annotationDescriptor, visible),
2990                                 currentOffset,
2991                                 /* named = */ true,
2992                                 charBuffer);
2993             }
2994         }
2995     }
2996 
2997     /**
2998       * Reads the element values of a JVMS 'annotation' structure and makes the given visitor visit
2999       * them. This method can also be used to read the values of the JVMS 'array_value' field of an
3000       * annotation's 'element_value'.
3001       *
3002       * @param annotationVisitor the visitor that must visit the values.
3003       * @param annotationOffset the start offset of an 'annotation' structure (excluding its type_index
3004       *     field) or of an 'array_value' structure.
3005       * @param named if the annotation values are named or not. This should be true to parse the values
3006       *     of a JVMS 'annotation' structure, and false to parse the JVMS 'array_value' of an
3007       *     annotation's element_value.
3008       * @param charBuffer the buffer used to read strings in the constant pool.
3009       * @return the end offset of the JVMS 'annotation' or 'array_value' structure.
3010       */
3011     private int readElementValues(
3012             final AnnotationVisitor annotationVisitor,
3013             final int annotationOffset,
3014             final boolean named,
3015             final char[] charBuffer) {
3016         int currentOffset = annotationOffset;
3017         // Read the num_element_value_pairs field (or num_values field for an array_value).
3018         int numElementValuePairs = readUnsignedShort(currentOffset);
3019         currentOffset += 2;
3020         if (named) {
3021             // Parse the element_value_pairs array.
3022             while (numElementValuePairs-- > 0) {
3023                 String elementName = readUTF8(currentOffset, charBuffer);
3024                 currentOffset =
3025                         readElementValue(annotationVisitor, currentOffset + 2, elementName, charBuffer);
3026             }
3027         } else {
3028             // Parse the array_value array.
3029             while (numElementValuePairs-- > 0) {
3030                 currentOffset =
3031                         readElementValue(annotationVisitor, currentOffset, /* elementName= */ null, charBuffer);
3032             }
3033         }
3034         if (annotationVisitor != null) {
3035             annotationVisitor.visitEnd();
3036         }
3037         return currentOffset;
3038     }
3039 
3040     /**
3041       * Reads a JVMS 'element_value' structure and makes the given visitor visit it.
3042       *
3043       * @param annotationVisitor the visitor that must visit the element_value structure.
3044       * @param elementValueOffset the start offset in {@link #classFileBuffer} of the element_value
3045       *     structure to be read.
3046       * @param elementName the name of the element_value structure to be read, or {@literal null}.
3047       * @param charBuffer the buffer used to read strings in the constant pool.
3048       * @return the end offset of the JVMS 'element_value' structure.
3049       */
3050     private int readElementValue(
3051             final AnnotationVisitor annotationVisitor,
3052             final int elementValueOffset,
3053             final String elementName,
3054             final char[] charBuffer) {
3055         int currentOffset = elementValueOffset;
3056         if (annotationVisitor == null) {
3057             switch (classFileBuffer[currentOffset] & 0xFF) {
3058                 case 'e': // enum_const_value
3059                     return currentOffset + 5;
3060                 case '@': // annotation_value
3061                     return readElementValues(null, currentOffset + 3, /* named = */ true, charBuffer);
3062                 case '[': // array_value
3063                     return readElementValues(null, currentOffset + 1, /* named = */ false, charBuffer);
3064                 default:
3065                     return currentOffset + 3;
3066             }
3067         }
3068         switch (classFileBuffer[currentOffset++] & 0xFF) {
3069             case 'B': // const_value_index, CONSTANT_Integer
3070                 annotationVisitor.visit(
3071                         elementName, (byte) readInt(cpInfoOffsets[readUnsignedShort(currentOffset)]));
3072                 currentOffset += 2;
3073                 break;
3074             case 'C': // const_value_index, CONSTANT_Integer
3075                 annotationVisitor.visit(
3076                         elementName, (char) readInt(cpInfoOffsets[readUnsignedShort(currentOffset)]));
3077                 currentOffset += 2;
3078                 break;
3079             case 'D': // const_value_index, CONSTANT_Double
3080             case 'F': // const_value_index, CONSTANT_Float
3081             case 'I': // const_value_index, CONSTANT_Integer
3082             case 'J': // const_value_index, CONSTANT_Long
3083                 annotationVisitor.visit(
3084                         elementName, readConst(readUnsignedShort(currentOffset), charBuffer));
3085                 currentOffset += 2;
3086                 break;
3087             case 'S': // const_value_index, CONSTANT_Integer
3088                 annotationVisitor.visit(
3089                         elementName, (short) readInt(cpInfoOffsets[readUnsignedShort(currentOffset)]));
3090                 currentOffset += 2;
3091                 break;
3092 
3093             case 'Z': // const_value_index, CONSTANT_Integer
3094                 annotationVisitor.visit(
3095                         elementName,
3096                         readInt(cpInfoOffsets[readUnsignedShort(currentOffset)]) == 0
3097                                 ? Boolean.FALSE
3098                                 : Boolean.TRUE);
3099                 currentOffset += 2;
3100                 break;
3101             case 's': // const_value_index, CONSTANT_Utf8
3102                 annotationVisitor.visit(elementName, readUTF8(currentOffset, charBuffer));
3103                 currentOffset += 2;
3104                 break;
3105             case 'e': // enum_const_value
3106                 annotationVisitor.visitEnum(
3107                         elementName,
3108                         readUTF8(currentOffset, charBuffer),
3109                         readUTF8(currentOffset + 2, charBuffer));
3110                 currentOffset += 4;
3111                 break;
3112             case 'c': // class_info
3113                 annotationVisitor.visit(elementName, Type.getType(readUTF8(currentOffset, charBuffer)));
3114                 currentOffset += 2;
3115                 break;
3116             case '@': // annotation_value
3117                 currentOffset =
3118                         readElementValues(
3119                                 annotationVisitor.visitAnnotation(elementName, readUTF8(currentOffset, charBuffer)),
3120                                 currentOffset + 2,
3121                                 true,
3122                                 charBuffer);
3123                 break;
3124             case '[': // array_value
3125                 int numValues = readUnsignedShort(currentOffset);
3126                 currentOffset += 2;
3127                 if (numValues == 0) {
3128                     return readElementValues(
3129                             annotationVisitor.visitArray(elementName),
3130                             currentOffset - 2,
3131                             /* named = */ false,
3132                             charBuffer);
3133                 }
3134                 switch (classFileBuffer[currentOffset] & 0xFF) {
3135                     case 'B':
3136                         byte[] byteValues = new byte[numValues];
3137                         for (int i = 0; i < numValues; i++) {
3138                             byteValues[i] = (byte) readInt(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]);
3139                             currentOffset += 3;
3140                         }
3141                         annotationVisitor.visit(elementName, byteValues);
3142                         break;
3143                     case 'Z':
3144                         boolean[] booleanValues = new boolean[numValues];
3145                         for (int i = 0; i < numValues; i++) {
3146                             booleanValues[i] = readInt(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]) != 0;
3147                             currentOffset += 3;
3148                         }
3149                         annotationVisitor.visit(elementName, booleanValues);
3150                         break;
3151                     case 'S':
3152                         short[] shortValues = new short[numValues];
3153                         for (int i = 0; i < numValues; i++) {
3154                             shortValues[i] = (short) readInt(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]);
3155                             currentOffset += 3;
3156                         }
3157                         annotationVisitor.visit(elementName, shortValues);
3158                         break;
3159                     case 'C':
3160                         char[] charValues = new char[numValues];
3161                         for (int i = 0; i < numValues; i++) {
3162                             charValues[i] = (char) readInt(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]);
3163                             currentOffset += 3;
3164                         }
3165                         annotationVisitor.visit(elementName, charValues);
3166                         break;
3167                     case 'I':
3168                         int[] intValues = new int[numValues];
3169                         for (int i = 0; i < numValues; i++) {
3170                             intValues[i] = readInt(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]);
3171                             currentOffset += 3;
3172                         }
3173                         annotationVisitor.visit(elementName, intValues);
3174                         break;
3175                     case 'J':
3176                         long[] longValues = new long[numValues];
3177                         for (int i = 0; i < numValues; i++) {
3178                             longValues[i] = readLong(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]);
3179                             currentOffset += 3;
3180                         }
3181                         annotationVisitor.visit(elementName, longValues);
3182                         break;
3183                     case 'F':
3184                         float[] floatValues = new float[numValues];
3185                         for (int i = 0; i < numValues; i++) {
3186                             floatValues[i] =
3187                                     Float.intBitsToFloat(
3188                                             readInt(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]));
3189                             currentOffset += 3;
3190                         }
3191                         annotationVisitor.visit(elementName, floatValues);
3192                         break;
3193                     case 'D':
3194                         double[] doubleValues = new double[numValues];
3195                         for (int i = 0; i < numValues; i++) {
3196                             doubleValues[i] =
3197                                     Double.longBitsToDouble(
3198                                             readLong(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]));
3199                             currentOffset += 3;
3200                         }
3201                         annotationVisitor.visit(elementName, doubleValues);
3202                         break;
3203                     default:
3204                         currentOffset =
3205                                 readElementValues(
3206                                         annotationVisitor.visitArray(elementName),
3207                                         currentOffset - 2,
3208                                         /* named = */ false,
3209                                         charBuffer);
3210                         break;
3211                 }
3212                 break;
3213             default:
3214                 throw new IllegalArgumentException();
3215         }
3216         return currentOffset;
3217     }
3218 
3219     // ----------------------------------------------------------------------------------------------
3220     // Methods to parse stack map frames
3221     // ----------------------------------------------------------------------------------------------
3222 
3223     /**
3224       * Computes the implicit frame of the method currently being parsed (as defined in the given
3225       * {@link Context}) and stores it in the given context.
3226       *
3227       * @param context information about the class being parsed.
3228       */
3229     private void computeImplicitFrame(final Context context) {
3230         String methodDescriptor = context.currentMethodDescriptor;
3231         Object[] locals = context.currentFrameLocalTypes;
3232         int numLocal = 0;
3233         if ((context.currentMethodAccessFlags & Opcodes.ACC_STATIC) == 0) {
3234             if ("<init>".equals(context.currentMethodName)) {
3235                 locals[numLocal++] = Opcodes.UNINITIALIZED_THIS;
3236             } else {
3237                 locals[numLocal++] = readClass(header + 2, context.charBuffer);
3238             }
3239         }
3240         // Parse the method descriptor, one argument type descriptor at each iteration. Start by
3241         // skipping the first method descriptor character, which is always '('.
3242         int currentMethodDescritorOffset = 1;
3243         while (true) {
3244             int currentArgumentDescriptorStartOffset = currentMethodDescritorOffset;
3245             switch (methodDescriptor.charAt(currentMethodDescritorOffset++)) {
3246                 case 'Z':
3247                 case 'C':
3248                 case 'B':
3249                 case 'S':
3250                 case 'I':
3251                     locals[numLocal++] = Opcodes.INTEGER;
3252                     break;
3253                 case 'F':
3254                     locals[numLocal++] = Opcodes.FLOAT;
3255                     break;
3256                 case 'J':
3257                     locals[numLocal++] = Opcodes.LONG;
3258                     break;
3259                 case 'D':
3260                     locals[numLocal++] = Opcodes.DOUBLE;
3261                     break;
3262                 case '[':
3263                     while (methodDescriptor.charAt(currentMethodDescritorOffset) == '[') {
3264                         ++currentMethodDescritorOffset;
3265                     }
3266                     if (methodDescriptor.charAt(currentMethodDescritorOffset) == 'L') {
3267                         ++currentMethodDescritorOffset;
3268                         while (methodDescriptor.charAt(currentMethodDescritorOffset) != ';') {
3269                             ++currentMethodDescritorOffset;
3270                         }
3271                     }
3272                     locals[numLocal++] =
3273                             methodDescriptor.substring(
3274                                     currentArgumentDescriptorStartOffset, ++currentMethodDescritorOffset);
3275                     break;
3276                 case 'L':
3277                     while (methodDescriptor.charAt(currentMethodDescritorOffset) != ';') {
3278                         ++currentMethodDescritorOffset;
3279                     }
3280                     locals[numLocal++] =
3281                             methodDescriptor.substring(
3282                                     currentArgumentDescriptorStartOffset + 1, currentMethodDescritorOffset++);
3283                     break;
3284                 default:
3285                     context.currentFrameLocalCount = numLocal;
3286                     return;
3287             }
3288         }
3289     }
3290 
3291     /**
3292       * Reads a JVMS 'stack_map_frame' structure and stores the result in the given {@link Context}
3293       * object. This method can also be used to read a full_frame structure, excluding its frame_type
3294       * field (this is used to parse the legacy StackMap attributes).
3295       *
3296       * @param stackMapFrameOffset the start offset in {@link #classFileBuffer} of the
3297       *     stack_map_frame_value structure to be read, or the start offset of a full_frame structure
3298       *     (excluding its frame_type field).
3299       * @param compressed true to read a 'stack_map_frame' structure, false to read a 'full_frame'
3300       *     structure without its frame_type field.
3301       * @param expand if the stack map frame must be expanded. See {@link #EXPAND_FRAMES}.
3302       * @param context where the parsed stack map frame must be stored.
3303       * @return the end offset of the JVMS 'stack_map_frame' or 'full_frame' structure.
3304       */
3305     private int readStackMapFrame(
3306             final int stackMapFrameOffset,
3307             final boolean compressed,
3308             final boolean expand,
3309             final Context context) {
3310         int currentOffset = stackMapFrameOffset;
3311         final char[] charBuffer = context.charBuffer;
3312         final Label[] labels = context.currentMethodLabels;
3313         int frameType;
3314         if (compressed) {
3315             // Read the frame_type field.
3316             frameType = classFileBuffer[currentOffset++] & 0xFF;
3317         } else {
3318             frameType = Frame.FULL_FRAME;
3319             context.currentFrameOffset = -1;
3320         }
3321         int offsetDelta;
3322         context.currentFrameLocalCountDelta = 0;
3323         if (frameType < Frame.SAME_LOCALS_1_STACK_ITEM_FRAME) {
3324             offsetDelta = frameType;
3325             context.currentFrameType = Opcodes.F_SAME;
3326             context.currentFrameStackCount = 0;
3327         } else if (frameType < Frame.RESERVED) {
3328             offsetDelta = frameType - Frame.SAME_LOCALS_1_STACK_ITEM_FRAME;
3329             currentOffset =
3330                     readVerificationTypeInfo(
3331                             currentOffset, context.currentFrameStackTypes, 0, charBuffer, labels);
3332             context.currentFrameType = Opcodes.F_SAME1;
3333             context.currentFrameStackCount = 1;
3334         } else if (frameType >= Frame.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) {
3335             offsetDelta = readUnsignedShort(currentOffset);
3336             currentOffset += 2;
3337             if (frameType == Frame.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) {
3338                 currentOffset =
3339                         readVerificationTypeInfo(
3340                                 currentOffset, context.currentFrameStackTypes, 0, charBuffer, labels);
3341                 context.currentFrameType = Opcodes.F_SAME1;
3342                 context.currentFrameStackCount = 1;
3343             } else if (frameType >= Frame.CHOP_FRAME && frameType < Frame.SAME_FRAME_EXTENDED) {
3344                 context.currentFrameType = Opcodes.F_CHOP;
3345                 context.currentFrameLocalCountDelta = Frame.SAME_FRAME_EXTENDED - frameType;
3346                 context.currentFrameLocalCount -= context.currentFrameLocalCountDelta;
3347                 context.currentFrameStackCount = 0;
3348             } else if (frameType == Frame.SAME_FRAME_EXTENDED) {
3349                 context.currentFrameType = Opcodes.F_SAME;
3350                 context.currentFrameStackCount = 0;
3351             } else if (frameType < Frame.FULL_FRAME) {
3352                 int local = expand ? context.currentFrameLocalCount : 0;
3353                 for (int k = frameType - Frame.SAME_FRAME_EXTENDED; k > 0; k--) {
3354                     currentOffset =
3355                             readVerificationTypeInfo(
3356                                     currentOffset, context.currentFrameLocalTypes, local++, charBuffer, labels);
3357                 }
3358                 context.currentFrameType = Opcodes.F_APPEND;
3359                 context.currentFrameLocalCountDelta = frameType - Frame.SAME_FRAME_EXTENDED;
3360                 context.currentFrameLocalCount += context.currentFrameLocalCountDelta;
3361                 context.currentFrameStackCount = 0;
3362             } else {
3363                 final int numberOfLocals = readUnsignedShort(currentOffset);
3364                 currentOffset += 2;
3365                 context.currentFrameType = Opcodes.F_FULL;
3366                 context.currentFrameLocalCountDelta = numberOfLocals;
3367                 context.currentFrameLocalCount = numberOfLocals;
3368                 for (int local = 0; local < numberOfLocals; ++local) {
3369                     currentOffset =
3370                             readVerificationTypeInfo(
3371                                     currentOffset, context.currentFrameLocalTypes, local, charBuffer, labels);
3372                 }
3373                 final int numberOfStackItems = readUnsignedShort(currentOffset);
3374                 currentOffset += 2;
3375                 context.currentFrameStackCount = numberOfStackItems;
3376                 for (int stack = 0; stack < numberOfStackItems; ++stack) {
3377                     currentOffset =
3378                             readVerificationTypeInfo(
3379                                     currentOffset, context.currentFrameStackTypes, stack, charBuffer, labels);
3380                 }
3381             }
3382         } else {
3383             throw new IllegalArgumentException();
3384         }
3385         context.currentFrameOffset += offsetDelta + 1;
3386         createLabel(context.currentFrameOffset, labels);
3387         return currentOffset;
3388     }
3389 
3390     /**
3391       * Reads a JVMS 'verification_type_info' structure and stores it at the given index in the given
3392       * array.
3393       *
3394       * @param verificationTypeInfoOffset the start offset of the 'verification_type_info' structure to
3395       *     read.
3396       * @param frame the array where the parsed type must be stored.
3397       * @param index the index in 'frame' where the parsed type must be stored.
3398       * @param charBuffer the buffer used to read strings in the constant pool.
3399       * @param labels the labels of the method currently being parsed, indexed by their offset. If the
3400       *     parsed type is an ITEM_Uninitialized, a new label for the corresponding NEW instruction is
3401       *     stored in this array if it does not already exist.
3402       * @return the end offset of the JVMS 'verification_type_info' structure.
3403       */
3404     private int readVerificationTypeInfo(
3405             final int verificationTypeInfoOffset,
3406             final Object[] frame,
3407             final int index,
3408             final char[] charBuffer,
3409             final Label[] labels) {
3410         int currentOffset = verificationTypeInfoOffset;
3411         int tag = classFileBuffer[currentOffset++] & 0xFF;
3412         switch (tag) {
3413             case Frame.ITEM_TOP:
3414                 frame[index] = Opcodes.TOP;
3415                 break;
3416             case Frame.ITEM_INTEGER:
3417                 frame[index] = Opcodes.INTEGER;
3418                 break;
3419             case Frame.ITEM_FLOAT:
3420                 frame[index] = Opcodes.FLOAT;
3421                 break;
3422             case Frame.ITEM_DOUBLE:
3423                 frame[index] = Opcodes.DOUBLE;
3424                 break;
3425             case Frame.ITEM_LONG:
3426                 frame[index] = Opcodes.LONG;
3427                 break;
3428             case Frame.ITEM_NULL:
3429                 frame[index] = Opcodes.NULL;
3430                 break;
3431             case Frame.ITEM_UNINITIALIZED_THIS:
3432                 frame[index] = Opcodes.UNINITIALIZED_THIS;
3433                 break;
3434             case Frame.ITEM_OBJECT:
3435                 frame[index] = readClass(currentOffset, charBuffer);
3436                 currentOffset += 2;
3437                 break;
3438             case Frame.ITEM_UNINITIALIZED:
3439                 frame[index] = createLabel(readUnsignedShort(currentOffset), labels);
3440                 currentOffset += 2;
3441                 break;
3442             default:
3443                 throw new IllegalArgumentException();
3444         }
3445         return currentOffset;
3446     }
3447 
3448     // ----------------------------------------------------------------------------------------------
3449     // Methods to parse attributes
3450     // ----------------------------------------------------------------------------------------------
3451 
3452     /**
3453       * Returns the offset in {@link #classFileBuffer} of the first ClassFile's 'attributes' array
3454       * field entry.
3455       *
3456       * @return the offset in {@link #classFileBuffer} of the first ClassFile's 'attributes' array
3457       *     field entry.
3458       */
3459     final int getFirstAttributeOffset() {
3460         // Skip the access_flags, this_class, super_class, and interfaces_count fields (using 2 bytes
3461         // each), as well as the interfaces array field (2 bytes per interface).
3462         int currentOffset = header + 8 + readUnsignedShort(header + 6) * 2;
3463 
3464         // Read the fields_count field.
3465         int fieldsCount = readUnsignedShort(currentOffset);
3466         currentOffset += 2;
3467         // Skip the 'fields' array field.
3468         while (fieldsCount-- > 0) {
3469             // Invariant: currentOffset is the offset of a field_info structure.
3470             // Skip the access_flags, name_index and descriptor_index fields (2 bytes each), and read the
3471             // attributes_count field.
3472             int attributesCount = readUnsignedShort(currentOffset + 6);
3473             currentOffset += 8;
3474             // Skip the 'attributes' array field.
3475             while (attributesCount-- > 0) {
3476                 // Invariant: currentOffset is the offset of an attribute_info structure.
3477                 // Read the attribute_length field (2 bytes after the start of the attribute_info) and skip
3478                 // this many bytes, plus 6 for the attribute_name_index and attribute_length fields
3479                 // (yielding the total size of the attribute_info structure).
3480                 currentOffset += 6 + readInt(currentOffset + 2);
3481             }
3482         }
3483 
3484         // Skip the methods_count and 'methods' fields, using the same method as above.
3485         int methodsCount = readUnsignedShort(currentOffset);
3486         currentOffset += 2;
3487         while (methodsCount-- > 0) {
3488             int attributesCount = readUnsignedShort(currentOffset + 6);
3489             currentOffset += 8;
3490             while (attributesCount-- > 0) {
3491                 currentOffset += 6 + readInt(currentOffset + 2);
3492             }
3493         }
3494 
3495         // Skip the ClassFile's attributes_count field.
3496         return currentOffset + 2;
3497     }
3498 
3499     /**
3500       * Reads the BootstrapMethods attribute to compute the offset of each bootstrap method.
3501       *
3502       * @param maxStringLength a conservative estimate of the maximum length of the strings contained
3503       *     in the constant pool of the class.
3504       * @return the offsets of the bootstrap methods.
3505       */
3506     private int[] readBootstrapMethodsAttribute(final int maxStringLength) {
3507         char[] charBuffer = new char[maxStringLength];
3508         int currentAttributeOffset = getFirstAttributeOffset();
3509         for (int i = readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) {
3510             // Read the attribute_info's attribute_name and attribute_length fields.
3511             String attributeName = readUTF8(currentAttributeOffset, charBuffer);
3512             int attributeLength = readInt(currentAttributeOffset + 2);
3513             currentAttributeOffset += 6;
3514             if (Constants.BOOTSTRAP_METHODS.equals(attributeName)) {
3515                 // Read the num_bootstrap_methods field and create an array of this size.
3516                 int[] result = new int[readUnsignedShort(currentAttributeOffset)];
3517                 // Compute and store the offset of each 'bootstrap_methods' array field entry.
3518                 int currentBootstrapMethodOffset = currentAttributeOffset + 2;
3519                 for (int j = 0; j < result.length; ++j) {
3520                     result[j] = currentBootstrapMethodOffset;
3521                     // Skip the bootstrap_method_ref and num_bootstrap_arguments fields (2 bytes each),
3522                     // as well as the bootstrap_arguments array field (of size num_bootstrap_arguments * 2).
3523                     currentBootstrapMethodOffset +=
3524                             4 + readUnsignedShort(currentBootstrapMethodOffset + 2) * 2;
3525                 }
3526                 return result;
3527             }
3528             currentAttributeOffset += attributeLength;
3529         }
3530         throw new IllegalArgumentException();
3531     }
3532 
3533     /**
3534       * Reads a non standard JVMS 'attribute' structure in {@link #classFileBuffer}.
3535       *
3536       * @param attributePrototypes prototypes of the attributes that must be parsed during the visit of
3537       *     the class. Any attribute whose type is not equal to the type of one the prototypes will not
3538       *     be parsed: its byte array value will be passed unchanged to the ClassWriter.
3539       * @param type the type of the attribute.
3540       * @param offset the start offset of the JVMS 'attribute' structure in {@link #classFileBuffer}.
3541       *     The 6 attribute header bytes (attribute_name_index and attribute_length) are not taken into
3542       *     account here.
3543       * @param length the length of the attribute's content (excluding the 6 attribute header bytes).
3544       * @param charBuffer the buffer to be used to read strings in the constant pool.
3545       * @param codeAttributeOffset the start offset of the enclosing Code attribute in {@link
3546       *     #classFileBuffer}, or -1 if the attribute to be read is not a code attribute. The 6
3547       *     attribute header bytes (attribute_name_index and attribute_length) are not taken into
3548       *     account here.
3549       * @param labels the labels of the method's code, or {@literal null} if the attribute to be read
3550       *     is not a code attribute.
3551       * @return the attribute that has been read.
3552       */
3553     private Attribute readAttribute(
3554             final Attribute[] attributePrototypes,
3555             final String type,
3556             final int offset,
3557             final int length,
3558             final char[] charBuffer,
3559             final int codeAttributeOffset,
3560             final Label[] labels) {
3561         for (Attribute attributePrototype : attributePrototypes) {
3562             if (attributePrototype.type.equals(type)) {
3563                 return attributePrototype.read(
3564                         this, offset, length, charBuffer, codeAttributeOffset, labels);
3565             }
3566         }
3567         return new Attribute(type).read(this, offset, length, null, -1, null);
3568     }
3569 
3570     // -----------------------------------------------------------------------------------------------
3571     // Utility methods: low level parsing
3572     // -----------------------------------------------------------------------------------------------
3573 
3574     /**
3575       * Returns the number of entries in the class's constant pool table.
3576       *
3577       * @return the number of entries in the class's constant pool table.
3578       */
3579     public int getItemCount() {
3580         return cpInfoOffsets.length;
3581     }
3582 
3583     /**
3584       * Returns the start offset in this {@link ClassReader} of a JVMS 'cp_info' structure (i.e. a
3585       * constant pool entry), plus one. <i>This method is intended for {@link Attribute} sub classes,
3586       * and is normally not needed by class generators or adapters.</i>
3587       *
3588       * @param constantPoolEntryIndex the index a constant pool entry in the class's constant pool
3589       *     table.
3590       * @return the start offset in this {@link ClassReader} of the corresponding JVMS 'cp_info'
3591       *     structure, plus one.
3592       */
3593     public int getItem(final int constantPoolEntryIndex) {
3594         return cpInfoOffsets[constantPoolEntryIndex];
3595     }
3596 
3597     /**
3598       * Returns a conservative estimate of the maximum length of the strings contained in the class's
3599       * constant pool table.
3600       *
3601       * @return a conservative estimate of the maximum length of the strings contained in the class's
3602       *     constant pool table.
3603       */
3604     public int getMaxStringLength() {
3605         return maxStringLength;
3606     }
3607 
3608     /**
3609       * Reads a byte value in this {@link ClassReader}. <i>This method is intended for {@link
3610       * Attribute} sub classes, and is normally not needed by class generators or adapters.</i>
3611       *
3612       * @param offset the start offset of the value to be read in this {@link ClassReader}.
3613       * @return the read value.
3614       */
3615     public int readByte(final int offset) {
3616         return classFileBuffer[offset] & 0xFF;
3617     }
3618 
3619     /**
3620       * Reads an unsigned short value in this {@link ClassReader}. <i>This method is intended for
3621       * {@link Attribute} sub classes, and is normally not needed by class generators or adapters.</i>
3622       *
3623       * @param offset the start index of the value to be read in this {@link ClassReader}.
3624       * @return the read value.
3625       */
3626     public int readUnsignedShort(final int offset) {
3627         byte[] classBuffer = classFileBuffer;
3628         return ((classBuffer[offset] & 0xFF) << 8) | (classBuffer[offset + 1] & 0xFF);
3629     }
3630 
3631     /**
3632       * Reads a signed short value in this {@link ClassReader}. <i>This method is intended for {@link
3633       * Attribute} sub classes, and is normally not needed by class generators or adapters.</i>
3634       *
3635       * @param offset the start offset of the value to be read in this {@link ClassReader}.
3636       * @return the read value.
3637       */
3638     public short readShort(final int offset) {
3639         byte[] classBuffer = classFileBuffer;
3640         return (short) (((classBuffer[offset] & 0xFF) << 8) | (classBuffer[offset + 1] & 0xFF));
3641     }
3642 
3643     /**
3644       * Reads a signed int value in this {@link ClassReader}. <i>This method is intended for {@link
3645       * Attribute} sub classes, and is normally not needed by class generators or adapters.</i>
3646       *
3647       * @param offset the start offset of the value to be read in this {@link ClassReader}.
3648       * @return the read value.
3649       */
3650     public int readInt(final int offset) {
3651         byte[] classBuffer = classFileBuffer;
3652         return ((classBuffer[offset] & 0xFF) << 24)
3653                 | ((classBuffer[offset + 1] & 0xFF) << 16)
3654                 | ((classBuffer[offset + 2] & 0xFF) << 8)
3655                 | (classBuffer[offset + 3] & 0xFF);
3656     }
3657 
3658     /**
3659       * Reads a signed long value in this {@link ClassReader}. <i>This method is intended for {@link
3660       * Attribute} sub classes, and is normally not needed by class generators or adapters.</i>
3661       *
3662       * @param offset the start offset of the value to be read in this {@link ClassReader}.
3663       * @return the read value.
3664       */
3665     public long readLong(final int offset) {
3666         long l1 = readInt(offset);
3667         long l0 = readInt(offset + 4) & 0xFFFFFFFFL;
3668         return (l1 << 32) | l0;
3669     }
3670 
3671     /**
3672       * Reads a CONSTANT_Utf8 constant pool entry in this {@link ClassReader}. <i>This method is
3673       * intended for {@link Attribute} sub classes, and is normally not needed by class generators or
3674       * adapters.</i>
3675       *
3676       * @param offset the start offset of an unsigned short value in this {@link ClassReader}, whose
3677       *     value is the index of a CONSTANT_Utf8 entry in the class's constant pool table.
3678       * @param charBuffer the buffer to be used to read the string. This buffer must be sufficiently
3679       *     large. It is not automatically resized.
3680       * @return the String corresponding to the specified CONSTANT_Utf8 entry.
3681       */
3682     // DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility).
3683     public String readUTF8(final int offset, final char[] charBuffer) {
3684         int constantPoolEntryIndex = readUnsignedShort(offset);
3685         if (offset == 0 || constantPoolEntryIndex == 0) {
3686             return null;
3687         }
3688         return readUtf(constantPoolEntryIndex, charBuffer);
3689     }
3690 
3691     /**
3692       * Reads a CONSTANT_Utf8 constant pool entry in {@link #classFileBuffer}.
3693       *
3694       * @param constantPoolEntryIndex the index of a CONSTANT_Utf8 entry in the class's constant pool
3695       *     table.
3696       * @param charBuffer the buffer to be used to read the string. This buffer must be sufficiently
3697       *     large. It is not automatically resized.
3698       * @return the String corresponding to the specified CONSTANT_Utf8 entry.
3699       */
3700     final String readUtf(final int constantPoolEntryIndex, final char[] charBuffer) {
3701         String value = constantUtf8Values[constantPoolEntryIndex];
3702         if (value != null) {
3703             return value;
3704         }
3705         int cpInfoOffset = cpInfoOffsets[constantPoolEntryIndex];
3706         return constantUtf8Values[constantPoolEntryIndex] =
3707                 readUtf(cpInfoOffset + 2, readUnsignedShort(cpInfoOffset), charBuffer);
3708     }
3709 
3710     /**
3711       * Reads an UTF8 string in {@link #classFileBuffer}.
3712       *
3713       * @param utfOffset the start offset of the UTF8 string to be read.
3714       * @param utfLength the length of the UTF8 string to be read.
3715       * @param charBuffer the buffer to be used to read the string. This buffer must be sufficiently
3716       *     large. It is not automatically resized.
3717       * @return the String corresponding to the specified UTF8 string.
3718       */
3719     private String readUtf(final int utfOffset, final int utfLength, final char[] charBuffer) {
3720         int currentOffset = utfOffset;
3721         int endOffset = currentOffset + utfLength;
3722         int strLength = 0;
3723         byte[] classBuffer = classFileBuffer;
3724         while (currentOffset < endOffset) {
3725             int currentByte = classBuffer[currentOffset++];
3726             if ((currentByte & 0x80) == 0) {
3727                 charBuffer[strLength++] = (char) (currentByte & 0x7F);
3728             } else if ((currentByte & 0xE0) == 0xC0) {
3729                 charBuffer[strLength++] =
3730                         (char) (((currentByte & 0x1F) << 6) + (classBuffer[currentOffset++] & 0x3F));
3731             } else {
3732                 charBuffer[strLength++] =
3733                         (char)
3734                                 (((currentByte & 0xF) << 12)
3735                                         + ((classBuffer[currentOffset++] & 0x3F) << 6)
3736                                         + (classBuffer[currentOffset++] & 0x3F));
3737             }
3738         }
3739         return new String(charBuffer, 0, strLength);
3740     }
3741 
3742     /**
3743       * Reads a CONSTANT_Class, CONSTANT_String, CONSTANT_MethodType, CONSTANT_Module or
3744       * CONSTANT_Package constant pool entry in {@link #classFileBuffer}. <i>This method is intended
3745       * for {@link Attribute} sub classes, and is normally not needed by class generators or
3746       * adapters.</i>
3747       *
3748       * @param offset the start offset of an unsigned short value in {@link #classFileBuffer}, whose
3749       *     value is the index of a CONSTANT_Class, CONSTANT_String, CONSTANT_MethodType,
3750       *     CONSTANT_Module or CONSTANT_Package entry in class's constant pool table.
3751       * @param charBuffer the buffer to be used to read the item. This buffer must be sufficiently
3752       *     large. It is not automatically resized.
3753       * @return the String corresponding to the specified constant pool entry.
3754       */
3755     private String readStringish(final int offset, final char[] charBuffer) {
3756         // Get the start offset of the cp_info structure (plus one), and read the CONSTANT_Utf8 entry
3757         // designated by the first two bytes of this cp_info.
3758         return readUTF8(cpInfoOffsets[readUnsignedShort(offset)], charBuffer);
3759     }
3760 
3761     /**
3762       * Reads a CONSTANT_Class constant pool entry in this {@link ClassReader}. <i>This method is
3763       * intended for {@link Attribute} sub classes, and is normally not needed by class generators or
3764       * adapters.</i>
3765       *
3766       * @param offset the start offset of an unsigned short value in this {@link ClassReader}, whose
3767       *     value is the index of a CONSTANT_Class entry in class's constant pool table.
3768       * @param charBuffer the buffer to be used to read the item. This buffer must be sufficiently
3769       *     large. It is not automatically resized.
3770       * @return the String corresponding to the specified CONSTANT_Class entry.
3771       */
3772     public String readClass(final int offset, final char[] charBuffer) {
3773         return readStringish(offset, charBuffer);
3774     }
3775 
3776     /**
3777       * Reads a CONSTANT_Module constant pool entry in this {@link ClassReader}. <i>This method is
3778       * intended for {@link Attribute} sub classes, and is normally not needed by class generators or
3779       * adapters.</i>
3780       *
3781       * @param offset the start offset of an unsigned short value in this {@link ClassReader}, whose
3782       *     value is the index of a CONSTANT_Module entry in class's constant pool table.
3783       * @param charBuffer the buffer to be used to read the item. This buffer must be sufficiently
3784       *     large. It is not automatically resized.
3785       * @return the String corresponding to the specified CONSTANT_Module entry.
3786       */
3787     public String readModule(final int offset, final char[] charBuffer) {
3788         return readStringish(offset, charBuffer);
3789     }
3790 
3791     /**
3792       * Reads a CONSTANT_Package constant pool entry in this {@link ClassReader}. <i>This method is
3793       * intended for {@link Attribute} sub classes, and is normally not needed by class generators or
3794       * adapters.</i>
3795       *
3796       * @param offset the start offset of an unsigned short value in this {@link ClassReader}, whose
3797       *     value is the index of a CONSTANT_Package entry in class's constant pool table.
3798       * @param charBuffer the buffer to be used to read the item. This buffer must be sufficiently
3799       *     large. It is not automatically resized.
3800       * @return the String corresponding to the specified CONSTANT_Package entry.
3801       */
3802     public String readPackage(final int offset, final char[] charBuffer) {
3803         return readStringish(offset, charBuffer);
3804     }
3805 
3806     /**
3807       * Reads a CONSTANT_Dynamic constant pool entry in {@link #classFileBuffer}.
3808       *
3809       * @param constantPoolEntryIndex the index of a CONSTANT_Dynamic entry in the class's constant
3810       *     pool table.
3811       * @param charBuffer the buffer to be used to read the string. This buffer must be sufficiently
3812       *     large. It is not automatically resized.
3813       * @return the ConstantDynamic corresponding to the specified CONSTANT_Dynamic entry.
3814       */
3815     private ConstantDynamic readConstantDynamic(
3816             final int constantPoolEntryIndex, final char[] charBuffer) {
3817         ConstantDynamic constantDynamic = constantDynamicValues[constantPoolEntryIndex];
3818         if (constantDynamic != null) {
3819             return constantDynamic;
3820         }
3821         int cpInfoOffset = cpInfoOffsets[constantPoolEntryIndex];
3822         int nameAndTypeCpInfoOffset = cpInfoOffsets[readUnsignedShort(cpInfoOffset + 2)];
3823         String name = readUTF8(nameAndTypeCpInfoOffset, charBuffer);
3824         String descriptor = readUTF8(nameAndTypeCpInfoOffset + 2, charBuffer);
3825         int bootstrapMethodOffset = bootstrapMethodOffsets[readUnsignedShort(cpInfoOffset)];
3826         Handle handle = (Handle) readConst(readUnsignedShort(bootstrapMethodOffset), charBuffer);
3827         Object[] bootstrapMethodArguments = new Object[readUnsignedShort(bootstrapMethodOffset + 2)];
3828         bootstrapMethodOffset += 4;
3829         for (int i = 0; i < bootstrapMethodArguments.length; i++) {
3830             bootstrapMethodArguments[i] = readConst(readUnsignedShort(bootstrapMethodOffset), charBuffer);
3831             bootstrapMethodOffset += 2;
3832         }
3833         return constantDynamicValues[constantPoolEntryIndex] =
3834                 new ConstantDynamic(name, descriptor, handle, bootstrapMethodArguments);
3835     }
3836 
3837     /**
3838       * Reads a numeric or string constant pool entry in this {@link ClassReader}. <i>This method is
3839       * intended for {@link Attribute} sub classes, and is normally not needed by class generators or
3840       * adapters.</i>
3841       *
3842       * @param constantPoolEntryIndex the index of a CONSTANT_Integer, CONSTANT_Float, CONSTANT_Long,
3843       *     CONSTANT_Double, CONSTANT_Class, CONSTANT_String, CONSTANT_MethodType,
3844       *     CONSTANT_MethodHandle or CONSTANT_Dynamic entry in the class's constant pool.
3845       * @param charBuffer the buffer to be used to read strings. This buffer must be sufficiently
3846       *     large. It is not automatically resized.
3847       * @return the {@link Integer}, {@link Float}, {@link Long}, {@link Double}, {@link String},
3848       *     {@link Type}, {@link Handle} or {@link ConstantDynamic} corresponding to the specified
3849       *     constant pool entry.
3850       */
3851     public Object readConst(final int constantPoolEntryIndex, final char[] charBuffer) {
3852         int cpInfoOffset = cpInfoOffsets[constantPoolEntryIndex];
3853         switch (classFileBuffer[cpInfoOffset - 1]) {
3854             case Symbol.CONSTANT_INTEGER_TAG:
3855                 return readInt(cpInfoOffset);
3856             case Symbol.CONSTANT_FLOAT_TAG:
3857                 return Float.intBitsToFloat(readInt(cpInfoOffset));
3858             case Symbol.CONSTANT_LONG_TAG:
3859                 return readLong(cpInfoOffset);
3860             case Symbol.CONSTANT_DOUBLE_TAG:
3861                 return Double.longBitsToDouble(readLong(cpInfoOffset));
3862             case Symbol.CONSTANT_CLASS_TAG:
3863                 return Type.getObjectType(readUTF8(cpInfoOffset, charBuffer));
3864             case Symbol.CONSTANT_STRING_TAG:
3865                 return readUTF8(cpInfoOffset, charBuffer);
3866             case Symbol.CONSTANT_METHOD_TYPE_TAG:
3867                 return Type.getMethodType(readUTF8(cpInfoOffset, charBuffer));
3868             case Symbol.CONSTANT_METHOD_HANDLE_TAG:
3869                 int referenceKind = readByte(cpInfoOffset);
3870                 int referenceCpInfoOffset = cpInfoOffsets[readUnsignedShort(cpInfoOffset + 1)];
3871                 int nameAndTypeCpInfoOffset = cpInfoOffsets[readUnsignedShort(referenceCpInfoOffset + 2)];
3872                 String owner = readClass(referenceCpInfoOffset, charBuffer);
3873                 String name = readUTF8(nameAndTypeCpInfoOffset, charBuffer);
3874                 String descriptor = readUTF8(nameAndTypeCpInfoOffset + 2, charBuffer);
3875                 boolean isInterface =
3876                         classFileBuffer[referenceCpInfoOffset - 1] == Symbol.CONSTANT_INTERFACE_METHODREF_TAG;
3877                 return new Handle(referenceKind, owner, name, descriptor, isInterface);
3878             case Symbol.CONSTANT_DYNAMIC_TAG:
3879                 return readConstantDynamic(constantPoolEntryIndex, charBuffer);
3880             default:
3881                 throw new IllegalArgumentException();
3882         }
3883     }
3884 }
3885