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.V22) {
 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.DEFAULT:
1858                 case Opcodes.WITHFIELD:
1859                 case Opcodes.INVOKEVIRTUAL:
1860                 case Opcodes.INVOKESPECIAL:
1861                 case Opcodes.INVOKESTATIC:
1862                 case Opcodes.NEW:
1863                 case Opcodes.ANEWARRAY:
1864                 case Opcodes.CHECKCAST:
1865                 case Opcodes.INSTANCEOF:
1866                 case Opcodes.IINC:
1867                     currentOffset += 3;
1868                     break;
1869                 case Opcodes.INVOKEINTERFACE:
1870                 case Opcodes.INVOKEDYNAMIC:
1871                     currentOffset += 5;
1872                     break;
1873                 case Opcodes.MULTIANEWARRAY:
1874                     currentOffset += 4;
1875                     break;
1876                 default:
1877                     throw new IllegalArgumentException();
1878             }
1879         }
1880 
1881         // Read the 'exception_table_length' and 'exception_table' field to create a label for each
1882         // referenced instruction, and to make methodVisitor visit the corresponding try catch blocks.
1883         int exceptionTableLength = readUnsignedShort(currentOffset);
1884         currentOffset += 2;
1885         while (exceptionTableLength-- > 0) {
1886             Label start = createLabel(readUnsignedShort(currentOffset), labels);
1887             Label end = createLabel(readUnsignedShort(currentOffset + 2), labels);
1888             Label handler = createLabel(readUnsignedShort(currentOffset + 4), labels);
1889             String catchType = readUTF8(cpInfoOffsets[readUnsignedShort(currentOffset + 6)], charBuffer);
1890             currentOffset += 8;
1891             methodVisitor.visitTryCatchBlock(start, end, handler, catchType);
1892         }
1893 
1894         // Read the Code attributes to create a label for each referenced instruction (the variables
1895         // are ordered as in Section 4.7 of the JVMS). Attribute offsets exclude the
1896         // attribute_name_index and attribute_length fields.
1897         // - The offset of the current 'stack_map_frame' in the StackMap[Table] attribute, or 0.
1898         // Initially, this is the offset of the first 'stack_map_frame' entry. Then this offset is
1899         // updated after each stack_map_frame is read.
1900         int stackMapFrameOffset = 0;
1901         // - The end offset of the StackMap[Table] attribute, or 0.
1902         int stackMapTableEndOffset = 0;
1903         // - Whether the stack map frames are compressed (i.e. in a StackMapTable) or not.
1904         boolean compressedFrames = true;
1905         // - The offset of the LocalVariableTable attribute, or 0.
1906         int localVariableTableOffset = 0;
1907         // - The offset of the LocalVariableTypeTable attribute, or 0.
1908         int localVariableTypeTableOffset = 0;
1909         // - The offset of each 'type_annotation' entry in the RuntimeVisibleTypeAnnotations
1910         // attribute, or null.
1911         int[] visibleTypeAnnotationOffsets = null;
1912         // - The offset of each 'type_annotation' entry in the RuntimeInvisibleTypeAnnotations
1913         // attribute, or null.
1914         int[] invisibleTypeAnnotationOffsets = null;
1915         // - The non standard attributes (linked with their {@link Attribute#nextAttribute} field).
1916         //   This list in the <i>reverse order</i> or their order in the ClassFile structure.
1917         Attribute attributes = null;
1918 
1919         int attributesCount = readUnsignedShort(currentOffset);
1920         currentOffset += 2;
1921         while (attributesCount-- > 0) {
1922             // Read the attribute_info's attribute_name and attribute_length fields.
1923             String attributeName = readUTF8(currentOffset, charBuffer);
1924             int attributeLength = readInt(currentOffset + 2);
1925             currentOffset += 6;
1926             if (Constants.LOCAL_VARIABLE_TABLE.equals(attributeName)) {
1927                 if ((context.parsingOptions & SKIP_DEBUG) == 0) {
1928                     localVariableTableOffset = currentOffset;
1929                     // Parse the attribute to find the corresponding (debug only) labels.
1930                     int currentLocalVariableTableOffset = currentOffset;
1931                     int localVariableTableLength = readUnsignedShort(currentLocalVariableTableOffset);
1932                     currentLocalVariableTableOffset += 2;
1933                     while (localVariableTableLength-- > 0) {
1934                         int startPc = readUnsignedShort(currentLocalVariableTableOffset);
1935                         createDebugLabel(startPc, labels);
1936                         int length = readUnsignedShort(currentLocalVariableTableOffset + 2);
1937                         createDebugLabel(startPc + length, labels);
1938                         // Skip the name_index, descriptor_index and index fields (2 bytes each).
1939                         currentLocalVariableTableOffset += 10;
1940                     }
1941                 }
1942             } else if (Constants.LOCAL_VARIABLE_TYPE_TABLE.equals(attributeName)) {
1943                 localVariableTypeTableOffset = currentOffset;
1944                 // Here we do not extract the labels corresponding to the attribute content. We assume they
1945                 // are the same or a subset of those of the LocalVariableTable attribute.
1946             } else if (Constants.LINE_NUMBER_TABLE.equals(attributeName)) {
1947                 if ((context.parsingOptions & SKIP_DEBUG) == 0) {
1948                     // Parse the attribute to find the corresponding (debug only) labels.
1949                     int currentLineNumberTableOffset = currentOffset;
1950                     int lineNumberTableLength = readUnsignedShort(currentLineNumberTableOffset);
1951                     currentLineNumberTableOffset += 2;
1952                     while (lineNumberTableLength-- > 0) {
1953                         int startPc = readUnsignedShort(currentLineNumberTableOffset);
1954                         int lineNumber = readUnsignedShort(currentLineNumberTableOffset + 2);
1955                         currentLineNumberTableOffset += 4;
1956                         createDebugLabel(startPc, labels);
1957                         labels[startPc].addLineNumber(lineNumber);
1958                     }
1959                 }
1960             } else if (Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
1961                 visibleTypeAnnotationOffsets =
1962                         readTypeAnnotations(methodVisitor, context, currentOffset, /* visible = */ true);
1963                 // Here we do not extract the labels corresponding to the attribute content. This would
1964                 // require a full parsing of the attribute, which would need to be repeated when parsing
1965                 // the bytecode instructions (see below). Instead, the content of the attribute is read one
1966                 // type annotation at a time (i.e. after a type annotation has been visited, the next type
1967                 // annotation is read), and the labels it contains are also extracted one annotation at a
1968                 // time. This assumes that type annotations are ordered by increasing bytecode offset.
1969             } else if (Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
1970                 invisibleTypeAnnotationOffsets =
1971                         readTypeAnnotations(methodVisitor, context, currentOffset, /* visible = */ false);
1972                 // Same comment as above for the RuntimeVisibleTypeAnnotations attribute.
1973             } else if (Constants.STACK_MAP_TABLE.equals(attributeName)) {
1974                 if ((context.parsingOptions & SKIP_FRAMES) == 0) {
1975                     stackMapFrameOffset = currentOffset + 2;
1976                     stackMapTableEndOffset = currentOffset + attributeLength;
1977                 }
1978                 // Here we do not extract the labels corresponding to the attribute content. This would
1979                 // require a full parsing of the attribute, which would need to be repeated when parsing
1980                 // the bytecode instructions (see below). Instead, the content of the attribute is read one
1981                 // frame at a time (i.e. after a frame has been visited, the next frame is read), and the
1982                 // labels it contains are also extracted one frame at a time. Thanks to the ordering of
1983                 // frames, having only a "one frame lookahead" is not a problem, i.e. it is not possible to
1984                 // see an offset smaller than the offset of the current instruction and for which no Label
1985                 // exist. Except for UNINITIALIZED type offsets. We solve this by parsing the stack map
1986                 // table without a full decoding (see below).
1987             } else if ("StackMap".equals(attributeName)) {
1988                 if ((context.parsingOptions & SKIP_FRAMES) == 0) {
1989                     stackMapFrameOffset = currentOffset + 2;
1990                     stackMapTableEndOffset = currentOffset + attributeLength;
1991                     compressedFrames = false;
1992                 }
1993                 // IMPORTANT! Here we assume that the frames are ordered, as in the StackMapTable attribute,
1994                 // although this is not guaranteed by the attribute format. This allows an incremental
1995                 // extraction of the labels corresponding to this attribute (see the comment above for the
1996                 // StackMapTable attribute).
1997             } else {
1998                 Attribute attribute =
1999                         readAttribute(
2000                                 context.attributePrototypes,
2001                                 attributeName,
2002                                 currentOffset,
2003                                 attributeLength,
2004                                 charBuffer,
2005                                 codeOffset,
2006                                 labels);
2007                 attribute.nextAttribute = attributes;
2008                 attributes = attribute;
2009             }
2010             currentOffset += attributeLength;
2011         }
2012 
2013         // Initialize the context fields related to stack map frames, and generate the first
2014         // (implicit) stack map frame, if needed.
2015         final boolean expandFrames = (context.parsingOptions & EXPAND_FRAMES) != 0;
2016         if (stackMapFrameOffset != 0) {
2017             // The bytecode offset of the first explicit frame is not offset_delta + 1 but only
2018             // offset_delta. Setting the implicit frame offset to -1 allows us to use of the
2019             // "offset_delta + 1" rule in all cases.
2020             context.currentFrameOffset = -1;
2021             context.currentFrameType = 0;
2022             context.currentFrameLocalCount = 0;
2023             context.currentFrameLocalCountDelta = 0;
2024             context.currentFrameLocalTypes = new Object[maxLocals];
2025             context.currentFrameStackCount = 0;
2026             context.currentFrameStackTypes = new Object[maxStack];
2027             if (expandFrames) {
2028                 computeImplicitFrame(context);
2029             }
2030             // Find the labels for UNINITIALIZED frame types. Instead of decoding each element of the
2031             // stack map table, we look for 3 consecutive bytes that "look like" an UNINITIALIZED type
2032             // (tag ITEM_Uninitialized, offset within bytecode bounds, NEW instruction at this offset).
2033             // We may find false positives (i.e. not real UNINITIALIZED types), but this should be rare,
2034             // and the only consequence will be the creation of an unneeded label. This is better than
2035             // creating a label for each NEW instruction, and faster than fully decoding the whole stack
2036             // map table.
2037             for (int offset = stackMapFrameOffset; offset < stackMapTableEndOffset - 2; ++offset) {
2038                 if (classBuffer[offset] == Frame.ITEM_UNINITIALIZED) {
2039                     int potentialBytecodeOffset = readUnsignedShort(offset + 1);
2040                     if (potentialBytecodeOffset >= 0
2041                             && potentialBytecodeOffset < codeLength
2042                             && (classBuffer[bytecodeStartOffset + potentialBytecodeOffset] & 0xFF)
2043                                     == Opcodes.NEW) {
2044                         createLabel(potentialBytecodeOffset, labels);
2045                     }
2046                 }
2047             }
2048         }
2049         if (expandFrames && (context.parsingOptions & EXPAND_ASM_INSNS) != 0) {
2050             // Expanding the ASM specific instructions can introduce F_INSERT frames, even if the method
2051             // does not currently have any frame. These inserted frames must be computed by simulating the
2052             // effect of the bytecode instructions, one by one, starting from the implicit first frame.
2053             // For this, MethodWriter needs to know maxLocals before the first instruction is visited. To
2054             // ensure this, we visit the implicit first frame here (passing only maxLocals - the rest is
2055             // computed in MethodWriter).
2056             methodVisitor.visitFrame(Opcodes.F_NEW, maxLocals, null, 0, null);
2057         }
2058 
2059         // Visit the bytecode instructions. First, introduce state variables for the incremental parsing
2060         // of the type annotations.
2061 
2062         // Index of the next runtime visible type annotation to read (in the
2063         // visibleTypeAnnotationOffsets array).
2064         int currentVisibleTypeAnnotationIndex = 0;
2065         // The bytecode offset of the next runtime visible type annotation to read, or -1.
2066         int currentVisibleTypeAnnotationBytecodeOffset =
2067                 getTypeAnnotationBytecodeOffset(visibleTypeAnnotationOffsets, 0);
2068         // Index of the next runtime invisible type annotation to read (in the
2069         // invisibleTypeAnnotationOffsets array).
2070         int currentInvisibleTypeAnnotationIndex = 0;
2071         // The bytecode offset of the next runtime invisible type annotation to read, or -1.
2072         int currentInvisibleTypeAnnotationBytecodeOffset =
2073                 getTypeAnnotationBytecodeOffset(invisibleTypeAnnotationOffsets, 0);
2074 
2075         // Whether a F_INSERT stack map frame must be inserted before the current instruction.
2076         boolean insertFrame = false;
2077 
2078         // The delta to subtract from a goto_w or jsr_w opcode to get the corresponding goto or jsr
2079         // opcode, or 0 if goto_w and jsr_w must be left unchanged (i.e. when expanding ASM specific
2080         // instructions).
2081         final int wideJumpOpcodeDelta =
2082                 (context.parsingOptions & EXPAND_ASM_INSNS) == 0 ? Constants.WIDE_JUMP_OPCODE_DELTA : 0;
2083 
2084         currentOffset = bytecodeStartOffset;
2085         while (currentOffset < bytecodeEndOffset) {
2086             final int currentBytecodeOffset = currentOffset - bytecodeStartOffset;
2087 
2088             // Visit the label and the line number(s) for this bytecode offset, if any.
2089             Label currentLabel = labels[currentBytecodeOffset];
2090             if (currentLabel != null) {
2091                 currentLabel.accept(methodVisitor, (context.parsingOptions & SKIP_DEBUG) == 0);
2092             }
2093 
2094             // Visit the stack map frame for this bytecode offset, if any.
2095             while (stackMapFrameOffset != 0
2096                     && (context.currentFrameOffset == currentBytecodeOffset
2097                             || context.currentFrameOffset == -1)) {
2098                 // If there is a stack map frame for this offset, make methodVisitor visit it, and read the
2099                 // next stack map frame if there is one.
2100                 if (context.currentFrameOffset != -1) {
2101                     if (!compressedFrames || expandFrames) {
2102                         methodVisitor.visitFrame(
2103                                 Opcodes.F_NEW,
2104                                 context.currentFrameLocalCount,
2105                                 context.currentFrameLocalTypes,
2106                                 context.currentFrameStackCount,
2107                                 context.currentFrameStackTypes);
2108                     } else {
2109                         methodVisitor.visitFrame(
2110                                 context.currentFrameType,
2111                                 context.currentFrameLocalCountDelta,
2112                                 context.currentFrameLocalTypes,
2113                                 context.currentFrameStackCount,
2114                                 context.currentFrameStackTypes);
2115                     }
2116                     // Since there is already a stack map frame for this bytecode offset, there is no need to
2117                     // insert a new one.
2118                     insertFrame = false;
2119                 }
2120                 if (stackMapFrameOffset < stackMapTableEndOffset) {
2121                     stackMapFrameOffset =
2122                             readStackMapFrame(stackMapFrameOffset, compressedFrames, expandFrames, context);
2123                 } else {
2124                     stackMapFrameOffset = 0;
2125                 }
2126             }
2127 
2128             // Insert a stack map frame for this bytecode offset, if requested by setting insertFrame to
2129             // true during the previous iteration. The actual frame content is computed in MethodWriter.
2130             if (insertFrame) {
2131                 if ((context.parsingOptions & EXPAND_FRAMES) != 0) {
2132                     methodVisitor.visitFrame(Constants.F_INSERT, 0, null, 0, null);
2133                 }
2134                 insertFrame = false;
2135             }
2136 
2137             // Visit the instruction at this bytecode offset.
2138             int opcode = classBuffer[currentOffset] & 0xFF;
2139             switch (opcode) {
2140                 case Opcodes.NOP:
2141                 case Opcodes.ACONST_NULL:
2142                 case Opcodes.ICONST_M1:
2143                 case Opcodes.ICONST_0:
2144                 case Opcodes.ICONST_1:
2145                 case Opcodes.ICONST_2:
2146                 case Opcodes.ICONST_3:
2147                 case Opcodes.ICONST_4:
2148                 case Opcodes.ICONST_5:
2149                 case Opcodes.LCONST_0:
2150                 case Opcodes.LCONST_1:
2151                 case Opcodes.FCONST_0:
2152                 case Opcodes.FCONST_1:
2153                 case Opcodes.FCONST_2:
2154                 case Opcodes.DCONST_0:
2155                 case Opcodes.DCONST_1:
2156                 case Opcodes.IALOAD:
2157                 case Opcodes.LALOAD:
2158                 case Opcodes.FALOAD:
2159                 case Opcodes.DALOAD:
2160                 case Opcodes.AALOAD:
2161                 case Opcodes.BALOAD:
2162                 case Opcodes.CALOAD:
2163                 case Opcodes.SALOAD:
2164                 case Opcodes.IASTORE:
2165                 case Opcodes.LASTORE:
2166                 case Opcodes.FASTORE:
2167                 case Opcodes.DASTORE:
2168                 case Opcodes.AASTORE:
2169                 case Opcodes.BASTORE:
2170                 case Opcodes.CASTORE:
2171                 case Opcodes.SASTORE:
2172                 case Opcodes.POP:
2173                 case Opcodes.POP2:
2174                 case Opcodes.DUP:
2175                 case Opcodes.DUP_X1:
2176                 case Opcodes.DUP_X2:
2177                 case Opcodes.DUP2:
2178                 case Opcodes.DUP2_X1:
2179                 case Opcodes.DUP2_X2:
2180                 case Opcodes.SWAP:
2181                 case Opcodes.IADD:
2182                 case Opcodes.LADD:
2183                 case Opcodes.FADD:
2184                 case Opcodes.DADD:
2185                 case Opcodes.ISUB:
2186                 case Opcodes.LSUB:
2187                 case Opcodes.FSUB:
2188                 case Opcodes.DSUB:
2189                 case Opcodes.IMUL:
2190                 case Opcodes.LMUL:
2191                 case Opcodes.FMUL:
2192                 case Opcodes.DMUL:
2193                 case Opcodes.IDIV:
2194                 case Opcodes.LDIV:
2195                 case Opcodes.FDIV:
2196                 case Opcodes.DDIV:
2197                 case Opcodes.IREM:
2198                 case Opcodes.LREM:
2199                 case Opcodes.FREM:
2200                 case Opcodes.DREM:
2201                 case Opcodes.INEG:
2202                 case Opcodes.LNEG:
2203                 case Opcodes.FNEG:
2204                 case Opcodes.DNEG:
2205                 case Opcodes.ISHL:
2206                 case Opcodes.LSHL:
2207                 case Opcodes.ISHR:
2208                 case Opcodes.LSHR:
2209                 case Opcodes.IUSHR:
2210                 case Opcodes.LUSHR:
2211                 case Opcodes.IAND:
2212                 case Opcodes.LAND:
2213                 case Opcodes.IOR:
2214                 case Opcodes.LOR:
2215                 case Opcodes.IXOR:
2216                 case Opcodes.LXOR:
2217                 case Opcodes.I2L:
2218                 case Opcodes.I2F:
2219                 case Opcodes.I2D:
2220                 case Opcodes.L2I:
2221                 case Opcodes.L2F:
2222                 case Opcodes.L2D:
2223                 case Opcodes.F2I:
2224                 case Opcodes.F2L:
2225                 case Opcodes.F2D:
2226                 case Opcodes.D2I:
2227                 case Opcodes.D2L:
2228                 case Opcodes.D2F:
2229                 case Opcodes.I2B:
2230                 case Opcodes.I2C:
2231                 case Opcodes.I2S:
2232                 case Opcodes.LCMP:
2233                 case Opcodes.FCMPL:
2234                 case Opcodes.FCMPG:
2235                 case Opcodes.DCMPL:
2236                 case Opcodes.DCMPG:
2237                 case Opcodes.IRETURN:
2238                 case Opcodes.LRETURN:
2239                 case Opcodes.FRETURN:
2240                 case Opcodes.DRETURN:
2241                 case Opcodes.ARETURN:
2242                 case Opcodes.RETURN:
2243                 case Opcodes.ARRAYLENGTH:
2244                 case Opcodes.ATHROW:
2245                 case Opcodes.MONITORENTER:
2246                 case Opcodes.MONITOREXIT:
2247                     methodVisitor.visitInsn(opcode);
2248                     currentOffset += 1;
2249                     break;
2250                 case Constants.ILOAD_0:
2251                 case Constants.ILOAD_1:
2252                 case Constants.ILOAD_2:
2253                 case Constants.ILOAD_3:
2254                 case Constants.LLOAD_0:
2255                 case Constants.LLOAD_1:
2256                 case Constants.LLOAD_2:
2257                 case Constants.LLOAD_3:
2258                 case Constants.FLOAD_0:
2259                 case Constants.FLOAD_1:
2260                 case Constants.FLOAD_2:
2261                 case Constants.FLOAD_3:
2262                 case Constants.DLOAD_0:
2263                 case Constants.DLOAD_1:
2264                 case Constants.DLOAD_2:
2265                 case Constants.DLOAD_3:
2266                 case Constants.ALOAD_0:
2267                 case Constants.ALOAD_1:
2268                 case Constants.ALOAD_2:
2269                 case Constants.ALOAD_3:
2270                     opcode -= Constants.ILOAD_0;
2271                     methodVisitor.visitVarInsn(Opcodes.ILOAD + (opcode >> 2), opcode & 0x3);
2272                     currentOffset += 1;
2273                     break;
2274                 case Constants.ISTORE_0:
2275                 case Constants.ISTORE_1:
2276                 case Constants.ISTORE_2:
2277                 case Constants.ISTORE_3:
2278                 case Constants.LSTORE_0:
2279                 case Constants.LSTORE_1:
2280                 case Constants.LSTORE_2:
2281                 case Constants.LSTORE_3:
2282                 case Constants.FSTORE_0:
2283                 case Constants.FSTORE_1:
2284                 case Constants.FSTORE_2:
2285                 case Constants.FSTORE_3:
2286                 case Constants.DSTORE_0:
2287                 case Constants.DSTORE_1:
2288                 case Constants.DSTORE_2:
2289                 case Constants.DSTORE_3:
2290                 case Constants.ASTORE_0:
2291                 case Constants.ASTORE_1:
2292                 case Constants.ASTORE_2:
2293                 case Constants.ASTORE_3:
2294                     opcode -= Constants.ISTORE_0;
2295                     methodVisitor.visitVarInsn(Opcodes.ISTORE + (opcode >> 2), opcode & 0x3);
2296                     currentOffset += 1;
2297                     break;
2298                 case Opcodes.IFEQ:
2299                 case Opcodes.IFNE:
2300                 case Opcodes.IFLT:
2301                 case Opcodes.IFGE:
2302                 case Opcodes.IFGT:
2303                 case Opcodes.IFLE:
2304                 case Opcodes.IF_ICMPEQ:
2305                 case Opcodes.IF_ICMPNE:
2306                 case Opcodes.IF_ICMPLT:
2307                 case Opcodes.IF_ICMPGE:
2308                 case Opcodes.IF_ICMPGT:
2309                 case Opcodes.IF_ICMPLE:
2310                 case Opcodes.IF_ACMPEQ:
2311                 case Opcodes.IF_ACMPNE:
2312                 case Opcodes.GOTO:
2313                 case Opcodes.JSR:
2314                 case Opcodes.IFNULL:
2315                 case Opcodes.IFNONNULL:
2316                     methodVisitor.visitJumpInsn(
2317                             opcode, labels[currentBytecodeOffset + readShort(currentOffset + 1)]);
2318                     currentOffset += 3;
2319                     break;
2320                 case Constants.GOTO_W:
2321                 case Constants.JSR_W:
2322                     methodVisitor.visitJumpInsn(
2323                             opcode - wideJumpOpcodeDelta,
2324                             labels[currentBytecodeOffset + readInt(currentOffset + 1)]);
2325                     currentOffset += 5;
2326                     break;
2327                 case Constants.ASM_IFEQ:
2328                 case Constants.ASM_IFNE:
2329                 case Constants.ASM_IFLT:
2330                 case Constants.ASM_IFGE:
2331                 case Constants.ASM_IFGT:
2332                 case Constants.ASM_IFLE:
2333                 case Constants.ASM_IF_ICMPEQ:
2334                 case Constants.ASM_IF_ICMPNE:
2335                 case Constants.ASM_IF_ICMPLT:
2336                 case Constants.ASM_IF_ICMPGE:
2337                 case Constants.ASM_IF_ICMPGT:
2338                 case Constants.ASM_IF_ICMPLE:
2339                 case Constants.ASM_IF_ACMPEQ:
2340                 case Constants.ASM_IF_ACMPNE:
2341                 case Constants.ASM_GOTO:
2342                 case Constants.ASM_JSR:
2343                 case Constants.ASM_IFNULL:
2344                 case Constants.ASM_IFNONNULL:
2345                     {
2346                         // A forward jump with an offset > 32767. In this case we automatically replace ASM_GOTO
2347                         // with GOTO_W, ASM_JSR with JSR_W and ASM_IFxxx <l> with IFNOTxxx <L> GOTO_W <l> L:...,
2348                         // where IFNOTxxx is the "opposite" opcode of ASMS_IFxxx (e.g. IFNE for ASM_IFEQ) and
2349                         // where <L> designates the instruction just after the GOTO_W.
2350                         // First, change the ASM specific opcodes ASM_IFEQ ... ASM_JSR, ASM_IFNULL and
2351                         // ASM_IFNONNULL to IFEQ ... JSR, IFNULL and IFNONNULL.
2352                         opcode =
2353                                 opcode < Constants.ASM_IFNULL
2354                                         ? opcode - Constants.ASM_OPCODE_DELTA
2355                                         : opcode - Constants.ASM_IFNULL_OPCODE_DELTA;
2356                         Label target = labels[currentBytecodeOffset + readUnsignedShort(currentOffset + 1)];
2357                         if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
2358                             // Replace GOTO with GOTO_W and JSR with JSR_W.
2359                             methodVisitor.visitJumpInsn(opcode + Constants.WIDE_JUMP_OPCODE_DELTA, target);
2360                         } else {
2361                             // Compute the "opposite" of opcode. This can be done by flipping the least
2362                             // significant bit for IFNULL and IFNONNULL, and similarly for IFEQ ... IF_ACMPEQ
2363                             // (with a pre and post offset by 1).
2364                             opcode = opcode < Opcodes.GOTO ? ((opcode + 1) ^ 1) - 1 : opcode ^ 1;
2365                             Label endif = createLabel(currentBytecodeOffset + 3, labels);
2366                             methodVisitor.visitJumpInsn(opcode, endif);
2367                             methodVisitor.visitJumpInsn(Constants.GOTO_W, target);
2368                             // endif designates the instruction just after GOTO_W, and is visited as part of the
2369                             // next instruction. Since it is a jump target, we need to insert a frame here.
2370                             insertFrame = true;
2371                         }
2372                         currentOffset += 3;
2373                         break;
2374                     }
2375                 case Constants.ASM_GOTO_W:
2376                     // Replace ASM_GOTO_W with GOTO_W.
2377                     methodVisitor.visitJumpInsn(
2378                             Constants.GOTO_W, labels[currentBytecodeOffset + readInt(currentOffset + 1)]);
2379                     // The instruction just after is a jump target (because ASM_GOTO_W is used in patterns
2380                     // IFNOTxxx <L> ASM_GOTO_W <l> L:..., see MethodWriter), so we need to insert a frame
2381                     // here.
2382                     insertFrame = true;
2383                     currentOffset += 5;
2384                     break;
2385                 case Constants.WIDE:
2386                     opcode = classBuffer[currentOffset + 1] & 0xFF;
2387                     if (opcode == Opcodes.IINC) {
2388                         methodVisitor.visitIincInsn(
2389                                 readUnsignedShort(currentOffset + 2), readShort(currentOffset + 4));
2390                         currentOffset += 6;
2391                     } else {
2392                         methodVisitor.visitVarInsn(opcode, readUnsignedShort(currentOffset + 2));
2393                         currentOffset += 4;
2394                     }
2395                     break;
2396                 case Opcodes.TABLESWITCH:
2397                     {
2398                         // Skip 0 to 3 padding bytes.
2399                         currentOffset += 4 - (currentBytecodeOffset & 3);
2400                         // Read the instruction.
2401                         Label defaultLabel = labels[currentBytecodeOffset + readInt(currentOffset)];
2402                         int low = readInt(currentOffset + 4);
2403                         int high = readInt(currentOffset + 8);
2404                         currentOffset += 12;
2405                         Label[] table = new Label[high - low + 1];
2406                         for (int i = 0; i < table.length; ++i) {
2407                             table[i] = labels[currentBytecodeOffset + readInt(currentOffset)];
2408                             currentOffset += 4;
2409                         }
2410                         methodVisitor.visitTableSwitchInsn(low, high, defaultLabel, table);
2411                         break;
2412                     }
2413                 case Opcodes.LOOKUPSWITCH:
2414                     {
2415                         // Skip 0 to 3 padding bytes.
2416                         currentOffset += 4 - (currentBytecodeOffset & 3);
2417                         // Read the instruction.
2418                         Label defaultLabel = labels[currentBytecodeOffset + readInt(currentOffset)];
2419                         int numPairs = readInt(currentOffset + 4);
2420                         currentOffset += 8;
2421                         int[] keys = new int[numPairs];
2422                         Label[] values = new Label[numPairs];
2423                         for (int i = 0; i < numPairs; ++i) {
2424                             keys[i] = readInt(currentOffset);
2425                             values[i] = labels[currentBytecodeOffset + readInt(currentOffset + 4)];
2426                             currentOffset += 8;
2427                         }
2428                         methodVisitor.visitLookupSwitchInsn(defaultLabel, keys, values);
2429                         break;
2430                     }
2431                 case Opcodes.ILOAD:
2432                 case Opcodes.LLOAD:
2433                 case Opcodes.FLOAD:
2434                 case Opcodes.DLOAD:
2435                 case Opcodes.ALOAD:
2436                 case Opcodes.ISTORE:
2437                 case Opcodes.LSTORE:
2438                 case Opcodes.FSTORE:
2439                 case Opcodes.DSTORE:
2440                 case Opcodes.ASTORE:
2441                 case Opcodes.RET:
2442                     methodVisitor.visitVarInsn(opcode, classBuffer[currentOffset + 1] & 0xFF);
2443                     currentOffset += 2;
2444                     break;
2445                 case Opcodes.BIPUSH:
2446                 case Opcodes.NEWARRAY:
2447                     methodVisitor.visitIntInsn(opcode, classBuffer[currentOffset + 1]);
2448                     currentOffset += 2;
2449                     break;
2450                 case Opcodes.SIPUSH:
2451                     methodVisitor.visitIntInsn(opcode, readShort(currentOffset + 1));
2452                     currentOffset += 3;
2453                     break;
2454                 case Opcodes.LDC:
2455                     methodVisitor.visitLdcInsn(readConst(classBuffer[currentOffset + 1] & 0xFF, charBuffer));
2456                     currentOffset += 2;
2457                     break;
2458                 case Constants.LDC_W:
2459                 case Constants.LDC2_W:
2460                     methodVisitor.visitLdcInsn(readConst(readUnsignedShort(currentOffset + 1), charBuffer));
2461                     currentOffset += 3;
2462                     break;
2463                 case Opcodes.GETSTATIC:
2464                 case Opcodes.PUTSTATIC:
2465                 case Opcodes.GETFIELD:
2466                 case Opcodes.PUTFIELD:
2467                 case Opcodes.INVOKEVIRTUAL:
2468                 case Opcodes.INVOKESPECIAL:
2469                 case Opcodes.INVOKESTATIC:
2470                 case Opcodes.INVOKEINTERFACE:
2471                 case Opcodes.WITHFIELD:
2472                     {
2473                         int cpInfoOffset = cpInfoOffsets[readUnsignedShort(currentOffset + 1)];
2474                         int nameAndTypeCpInfoOffset = cpInfoOffsets[readUnsignedShort(cpInfoOffset + 2)];
2475                         String owner = readClass(cpInfoOffset, charBuffer);
2476                         String name = readUTF8(nameAndTypeCpInfoOffset, charBuffer);
2477                         String descriptor = readUTF8(nameAndTypeCpInfoOffset + 2, charBuffer);
2478                         if (opcode >= Opcodes.INVOKEVIRTUAL && opcode <= Opcodes.INVOKEINTERFACE) {
2479                             boolean isInterface =
2480                                     classBuffer[cpInfoOffset - 1] == Symbol.CONSTANT_INTERFACE_METHODREF_TAG;
2481                             methodVisitor.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
2482                         } else {
2483                             methodVisitor.visitFieldInsn(opcode, owner, name, descriptor);
2484                         }
2485                         if (opcode == Opcodes.INVOKEINTERFACE) {
2486                             currentOffset += 5;
2487                         } else {
2488                             currentOffset += 3;
2489                         }
2490                         break;
2491                     }
2492                 case Opcodes.INVOKEDYNAMIC:
2493                     {
2494                         int cpInfoOffset = cpInfoOffsets[readUnsignedShort(currentOffset + 1)];
2495                         int nameAndTypeCpInfoOffset = cpInfoOffsets[readUnsignedShort(cpInfoOffset + 2)];
2496                         String name = readUTF8(nameAndTypeCpInfoOffset, charBuffer);
2497                         String descriptor = readUTF8(nameAndTypeCpInfoOffset + 2, charBuffer);
2498                         int bootstrapMethodOffset = bootstrapMethodOffsets[readUnsignedShort(cpInfoOffset)];
2499                         Handle handle =
2500                                 (Handle) readConst(readUnsignedShort(bootstrapMethodOffset), charBuffer);
2501                         Object[] bootstrapMethodArguments =
2502                                 new Object[readUnsignedShort(bootstrapMethodOffset + 2)];
2503                         bootstrapMethodOffset += 4;
2504                         for (int i = 0; i < bootstrapMethodArguments.length; i++) {
2505                             bootstrapMethodArguments[i] =
2506                                     readConst(readUnsignedShort(bootstrapMethodOffset), charBuffer);
2507                             bootstrapMethodOffset += 2;
2508                         }
2509                         methodVisitor.visitInvokeDynamicInsn(
2510                                 name, descriptor, handle, bootstrapMethodArguments);
2511                         currentOffset += 5;
2512                         break;
2513                     }
2514                 case Opcodes.NEW:
2515                 case Opcodes.ANEWARRAY:
2516                 case Opcodes.CHECKCAST:
2517                 case Opcodes.INSTANCEOF:
2518                 case Opcodes.DEFAULT:
2519                     methodVisitor.visitTypeInsn(opcode, readClass(currentOffset + 1, charBuffer));
2520                     currentOffset += 3;
2521                     break;
2522                 case Opcodes.IINC:
2523                     methodVisitor.visitIincInsn(
2524                             classBuffer[currentOffset + 1] & 0xFF, classBuffer[currentOffset + 2]);
2525                     currentOffset += 3;
2526                     break;
2527                 case Opcodes.MULTIANEWARRAY:
2528                     methodVisitor.visitMultiANewArrayInsn(
2529                             readClass(currentOffset + 1, charBuffer), classBuffer[currentOffset + 3] & 0xFF);
2530                     currentOffset += 4;
2531                     break;
2532                 default:
2533                     throw new AssertionError();
2534             }
2535 
2536             // Visit the runtime visible instruction annotations, if any.
2537             while (visibleTypeAnnotationOffsets != null
2538                     && currentVisibleTypeAnnotationIndex < visibleTypeAnnotationOffsets.length
2539                     && currentVisibleTypeAnnotationBytecodeOffset <= currentBytecodeOffset) {
2540                 if (currentVisibleTypeAnnotationBytecodeOffset == currentBytecodeOffset) {
2541                     // Parse the target_type, target_info and target_path fields.
2542                     int currentAnnotationOffset =
2543                             readTypeAnnotationTarget(
2544                                     context, visibleTypeAnnotationOffsets[currentVisibleTypeAnnotationIndex]);
2545                     // Parse the type_index field.
2546                     String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
2547                     currentAnnotationOffset += 2;
2548                     // Parse num_element_value_pairs and element_value_pairs and visit these values.
2549                     readElementValues(
2550                             methodVisitor.visitInsnAnnotation(
2551                                     context.currentTypeAnnotationTarget,
2552                                     context.currentTypeAnnotationTargetPath,
2553                                     annotationDescriptor,
2554                                     /* visible = */ true),
2555                             currentAnnotationOffset,
2556                             /* named = */ true,
2557                             charBuffer);
2558                 }
2559                 currentVisibleTypeAnnotationBytecodeOffset =
2560                         getTypeAnnotationBytecodeOffset(
2561                                 visibleTypeAnnotationOffsets, ++currentVisibleTypeAnnotationIndex);
2562             }
2563 
2564             // Visit the runtime invisible instruction annotations, if any.
2565             while (invisibleTypeAnnotationOffsets != null
2566                     && currentInvisibleTypeAnnotationIndex < invisibleTypeAnnotationOffsets.length
2567                     && currentInvisibleTypeAnnotationBytecodeOffset <= currentBytecodeOffset) {
2568                 if (currentInvisibleTypeAnnotationBytecodeOffset == currentBytecodeOffset) {
2569                     // Parse the target_type, target_info and target_path fields.
2570                     int currentAnnotationOffset =
2571                             readTypeAnnotationTarget(
2572                                     context, invisibleTypeAnnotationOffsets[currentInvisibleTypeAnnotationIndex]);
2573                     // Parse the type_index field.
2574                     String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
2575                     currentAnnotationOffset += 2;
2576                     // Parse num_element_value_pairs and element_value_pairs and visit these values.
2577                     readElementValues(
2578                             methodVisitor.visitInsnAnnotation(
2579                                     context.currentTypeAnnotationTarget,
2580                                     context.currentTypeAnnotationTargetPath,
2581                                     annotationDescriptor,
2582                                     /* visible = */ false),
2583                             currentAnnotationOffset,
2584                             /* named = */ true,
2585                             charBuffer);
2586                 }
2587                 currentInvisibleTypeAnnotationBytecodeOffset =
2588                         getTypeAnnotationBytecodeOffset(
2589                                 invisibleTypeAnnotationOffsets, ++currentInvisibleTypeAnnotationIndex);
2590             }
2591         }
2592         if (labels[codeLength] != null) {
2593             methodVisitor.visitLabel(labels[codeLength]);
2594         }
2595 
2596         // Visit LocalVariableTable and LocalVariableTypeTable attributes.
2597         if (localVariableTableOffset != 0 && (context.parsingOptions & SKIP_DEBUG) == 0) {
2598             // The (start_pc, index, signature_index) fields of each entry of the LocalVariableTypeTable.
2599             int[] typeTable = null;
2600             if (localVariableTypeTableOffset != 0) {
2601                 typeTable = new int[readUnsignedShort(localVariableTypeTableOffset) * 3];
2602                 currentOffset = localVariableTypeTableOffset + 2;
2603                 int typeTableIndex = typeTable.length;
2604                 while (typeTableIndex > 0) {
2605                     // Store the offset of 'signature_index', and the value of 'index' and 'start_pc'.
2606                     typeTable[--typeTableIndex] = currentOffset + 6;
2607                     typeTable[--typeTableIndex] = readUnsignedShort(currentOffset + 8);
2608                     typeTable[--typeTableIndex] = readUnsignedShort(currentOffset);
2609                     currentOffset += 10;
2610                 }
2611             }
2612             int localVariableTableLength = readUnsignedShort(localVariableTableOffset);
2613             currentOffset = localVariableTableOffset + 2;
2614             while (localVariableTableLength-- > 0) {
2615                 int startPc = readUnsignedShort(currentOffset);
2616                 int length = readUnsignedShort(currentOffset + 2);
2617                 String name = readUTF8(currentOffset + 4, charBuffer);
2618                 String descriptor = readUTF8(currentOffset + 6, charBuffer);
2619                 int index = readUnsignedShort(currentOffset + 8);
2620                 currentOffset += 10;
2621                 String signature = null;
2622                 if (typeTable != null) {
2623                     for (int i = 0; i < typeTable.length; i += 3) {
2624                         if (typeTable[i] == startPc && typeTable[i + 1] == index) {
2625                             signature = readUTF8(typeTable[i + 2], charBuffer);
2626                             break;
2627                         }
2628                     }
2629                 }
2630                 methodVisitor.visitLocalVariable(
2631                         name, descriptor, signature, labels[startPc], labels[startPc + length], index);
2632             }
2633         }
2634 
2635         // Visit the local variable type annotations of the RuntimeVisibleTypeAnnotations attribute.
2636         if (visibleTypeAnnotationOffsets != null) {
2637             for (int typeAnnotationOffset : visibleTypeAnnotationOffsets) {
2638                 int targetType = readByte(typeAnnotationOffset);
2639                 if (targetType == TypeReference.LOCAL_VARIABLE
2640                         || targetType == TypeReference.RESOURCE_VARIABLE) {
2641                     // Parse the target_type, target_info and target_path fields.
2642                     currentOffset = readTypeAnnotationTarget(context, typeAnnotationOffset);
2643                     // Parse the type_index field.
2644                     String annotationDescriptor = readUTF8(currentOffset, charBuffer);
2645                     currentOffset += 2;
2646                     // Parse num_element_value_pairs and element_value_pairs and visit these values.
2647                     readElementValues(
2648                             methodVisitor.visitLocalVariableAnnotation(
2649                                     context.currentTypeAnnotationTarget,
2650                                     context.currentTypeAnnotationTargetPath,
2651                                     context.currentLocalVariableAnnotationRangeStarts,
2652                                     context.currentLocalVariableAnnotationRangeEnds,
2653                                     context.currentLocalVariableAnnotationRangeIndices,
2654                                     annotationDescriptor,
2655                                     /* visible = */ true),
2656                             currentOffset,
2657                             /* named = */ true,
2658                             charBuffer);
2659                 }
2660             }
2661         }
2662 
2663         // Visit the local variable type annotations of the RuntimeInvisibleTypeAnnotations attribute.
2664         if (invisibleTypeAnnotationOffsets != null) {
2665             for (int typeAnnotationOffset : invisibleTypeAnnotationOffsets) {
2666                 int targetType = readByte(typeAnnotationOffset);
2667                 if (targetType == TypeReference.LOCAL_VARIABLE
2668                         || targetType == TypeReference.RESOURCE_VARIABLE) {
2669                     // Parse the target_type, target_info and target_path fields.
2670                     currentOffset = readTypeAnnotationTarget(context, typeAnnotationOffset);
2671                     // Parse the type_index field.
2672                     String annotationDescriptor = readUTF8(currentOffset, charBuffer);
2673                     currentOffset += 2;
2674                     // Parse num_element_value_pairs and element_value_pairs and visit these values.
2675                     readElementValues(
2676                             methodVisitor.visitLocalVariableAnnotation(
2677                                     context.currentTypeAnnotationTarget,
2678                                     context.currentTypeAnnotationTargetPath,
2679                                     context.currentLocalVariableAnnotationRangeStarts,
2680                                     context.currentLocalVariableAnnotationRangeEnds,
2681                                     context.currentLocalVariableAnnotationRangeIndices,
2682                                     annotationDescriptor,
2683                                     /* visible = */ false),
2684                             currentOffset,
2685                             /* named = */ true,
2686                             charBuffer);
2687                 }
2688             }
2689         }
2690 
2691         // Visit the non standard attributes.
2692         while (attributes != null) {
2693             // Copy and reset the nextAttribute field so that it can also be used in MethodWriter.
2694             Attribute nextAttribute = attributes.nextAttribute;
2695             attributes.nextAttribute = null;
2696             methodVisitor.visitAttribute(attributes);
2697             attributes = nextAttribute;
2698         }
2699 
2700         // Visit the max stack and max locals values.
2701         methodVisitor.visitMaxs(maxStack, maxLocals);
2702     }
2703 
2704     /**
2705       * Returns the label corresponding to the given bytecode offset. The default implementation of
2706       * this method creates a label for the given offset if it has not been already created.
2707       *
2708       * @param bytecodeOffset a bytecode offset in a method.
2709       * @param labels the already created labels, indexed by their offset. If a label already exists
2710       *     for bytecodeOffset this method must not create a new one. Otherwise it must store the new
2711       *     label in this array.
2712       * @return a non null Label, which must be equal to labels[bytecodeOffset].
2713       */
2714     protected Label readLabel(final int bytecodeOffset, final Label[] labels) {
2715         if (labels[bytecodeOffset] == null) {
2716             labels[bytecodeOffset] = new Label();
2717         }
2718         return labels[bytecodeOffset];
2719     }
2720 
2721     /**
2722       * Creates a label without the {@link Label#FLAG_DEBUG_ONLY} flag set, for the given bytecode
2723       * offset. The label is created with a call to {@link #readLabel} and its {@link
2724       * Label#FLAG_DEBUG_ONLY} flag is cleared.
2725       *
2726       * @param bytecodeOffset a bytecode offset in a method.
2727       * @param labels the already created labels, indexed by their offset.
2728       * @return a Label without the {@link Label#FLAG_DEBUG_ONLY} flag set.
2729       */
2730     private Label createLabel(final int bytecodeOffset, final Label[] labels) {
2731         Label label = readLabel(bytecodeOffset, labels);
2732         label.flags &= ~Label.FLAG_DEBUG_ONLY;
2733         return label;
2734     }
2735 
2736     /**
2737       * Creates a label with the {@link Label#FLAG_DEBUG_ONLY} flag set, if there is no already
2738       * existing label for the given bytecode offset (otherwise does nothing). The label is created
2739       * with a call to {@link #readLabel}.
2740       *
2741       * @param bytecodeOffset a bytecode offset in a method.
2742       * @param labels the already created labels, indexed by their offset.
2743       */
2744     private void createDebugLabel(final int bytecodeOffset, final Label[] labels) {
2745         if (labels[bytecodeOffset] == null) {
2746             readLabel(bytecodeOffset, labels).flags |= Label.FLAG_DEBUG_ONLY;
2747         }
2748     }
2749 
2750     // ----------------------------------------------------------------------------------------------
2751     // Methods to parse annotations, type annotations and parameter annotations
2752     // ----------------------------------------------------------------------------------------------
2753 
2754     /**
2755       * Parses a Runtime[In]VisibleTypeAnnotations attribute to find the offset of each type_annotation
2756       * entry it contains, to find the corresponding labels, and to visit the try catch block
2757       * annotations.
2758       *
2759       * @param methodVisitor the method visitor to be used to visit the try catch block annotations.
2760       * @param context information about the class being parsed.
2761       * @param runtimeTypeAnnotationsOffset the start offset of a Runtime[In]VisibleTypeAnnotations
2762       *     attribute, excluding the attribute_info's attribute_name_index and attribute_length fields.
2763       * @param visible true if the attribute to parse is a RuntimeVisibleTypeAnnotations attribute,
2764       *     false it is a RuntimeInvisibleTypeAnnotations attribute.
2765       * @return the start offset of each entry of the Runtime[In]VisibleTypeAnnotations_attribute's
2766       *     'annotations' array field.
2767       */
2768     private int[] readTypeAnnotations(
2769             final MethodVisitor methodVisitor,
2770             final Context context,
2771             final int runtimeTypeAnnotationsOffset,
2772             final boolean visible) {
2773         char[] charBuffer = context.charBuffer;
2774         int currentOffset = runtimeTypeAnnotationsOffset;
2775         // Read the num_annotations field and create an array to store the type_annotation offsets.
2776         int[] typeAnnotationsOffsets = new int[readUnsignedShort(currentOffset)];
2777         currentOffset += 2;
2778         // Parse the 'annotations' array field.
2779         for (int i = 0; i < typeAnnotationsOffsets.length; ++i) {
2780             typeAnnotationsOffsets[i] = currentOffset;
2781             // Parse the type_annotation's target_type and the target_info fields. The size of the
2782             // target_info field depends on the value of target_type.
2783             int targetType = readInt(currentOffset);
2784             switch (targetType >>> 24) {
2785                 case TypeReference.LOCAL_VARIABLE:
2786                 case TypeReference.RESOURCE_VARIABLE:
2787                     // A localvar_target has a variable size, which depends on the value of their table_length
2788                     // field. It also references bytecode offsets, for which we need labels.
2789                     int tableLength = readUnsignedShort(currentOffset + 1);
2790                     currentOffset += 3;
2791                     while (tableLength-- > 0) {
2792                         int startPc = readUnsignedShort(currentOffset);
2793                         int length = readUnsignedShort(currentOffset + 2);
2794                         // Skip the index field (2 bytes).
2795                         currentOffset += 6;
2796                         createLabel(startPc, context.currentMethodLabels);
2797                         createLabel(startPc + length, context.currentMethodLabels);
2798                     }
2799                     break;
2800                 case TypeReference.CAST:
2801                 case TypeReference.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
2802                 case TypeReference.METHOD_INVOCATION_TYPE_ARGUMENT:
2803                 case TypeReference.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
2804                 case TypeReference.METHOD_REFERENCE_TYPE_ARGUMENT:
2805                     currentOffset += 4;
2806                     break;
2807                 case TypeReference.CLASS_EXTENDS:
2808                 case TypeReference.CLASS_TYPE_PARAMETER_BOUND:
2809                 case TypeReference.METHOD_TYPE_PARAMETER_BOUND:
2810                 case TypeReference.THROWS:
2811                 case TypeReference.EXCEPTION_PARAMETER:
2812                 case TypeReference.INSTANCEOF:
2813                 case TypeReference.NEW:
2814                 case TypeReference.CONSTRUCTOR_REFERENCE:
2815                 case TypeReference.METHOD_REFERENCE:
2816                     currentOffset += 3;
2817                     break;
2818                 case TypeReference.CLASS_TYPE_PARAMETER:
2819                 case TypeReference.METHOD_TYPE_PARAMETER:
2820                 case TypeReference.METHOD_FORMAL_PARAMETER:
2821                 case TypeReference.FIELD:
2822                 case TypeReference.METHOD_RETURN:
2823                 case TypeReference.METHOD_RECEIVER:
2824                 default:
2825                     // TypeReference type which can't be used in Code attribute, or which is unknown.
2826                     throw new IllegalArgumentException();
2827             }
2828             // Parse the rest of the type_annotation structure, starting with the target_path structure
2829             // (whose size depends on its path_length field).
2830             int pathLength = readByte(currentOffset);
2831             if ((targetType >>> 24) == TypeReference.EXCEPTION_PARAMETER) {
2832                 // Parse the target_path structure and create a corresponding TypePath.
2833                 TypePath path = pathLength == 0 ? null : new TypePath(classFileBuffer, currentOffset);
2834                 currentOffset += 1 + 2 * pathLength;
2835                 // Parse the type_index field.
2836                 String annotationDescriptor = readUTF8(currentOffset, charBuffer);
2837                 currentOffset += 2;
2838                 // Parse num_element_value_pairs and element_value_pairs and visit these values.
2839                 currentOffset =
2840                         readElementValues(
2841                                 methodVisitor.visitTryCatchAnnotation(
2842                                         targetType & 0xFFFFFF00, path, annotationDescriptor, visible),
2843                                 currentOffset,
2844                                 /* named = */ true,
2845                                 charBuffer);
2846             } else {
2847                 // We don't want to visit the other target_type annotations, so we just skip them (which
2848                 // requires some parsing because the element_value_pairs array has a variable size). First,
2849                 // skip the target_path structure:
2850                 currentOffset += 3 + 2 * pathLength;
2851                 // Then skip the num_element_value_pairs and element_value_pairs fields (by reading them
2852                 // with a null AnnotationVisitor).
2853                 currentOffset =
2854                         readElementValues(
2855                                 /* annotationVisitor = */ null, currentOffset, /* named = */ true, charBuffer);
2856             }
2857         }
2858         return typeAnnotationsOffsets;
2859     }
2860 
2861     /**
2862       * Returns the bytecode offset corresponding to the specified JVMS 'type_annotation' structure, or
2863       * -1 if there is no such type_annotation of if it does not have a bytecode offset.
2864       *
2865       * @param typeAnnotationOffsets the offset of each 'type_annotation' entry in a
2866       *     Runtime[In]VisibleTypeAnnotations attribute, or {@literal null}.
2867       * @param typeAnnotationIndex the index a 'type_annotation' entry in typeAnnotationOffsets.
2868       * @return bytecode offset corresponding to the specified JVMS 'type_annotation' structure, or -1
2869       *     if there is no such type_annotation of if it does not have a bytecode offset.
2870       */
2871     private int getTypeAnnotationBytecodeOffset(
2872             final int[] typeAnnotationOffsets, final int typeAnnotationIndex) {
2873         if (typeAnnotationOffsets == null
2874                 || typeAnnotationIndex >= typeAnnotationOffsets.length
2875                 || readByte(typeAnnotationOffsets[typeAnnotationIndex]) < TypeReference.INSTANCEOF) {
2876             return -1;
2877         }
2878         return readUnsignedShort(typeAnnotationOffsets[typeAnnotationIndex] + 1);
2879     }
2880 
2881     /**
2882       * Parses the header of a JVMS type_annotation structure to extract its target_type, target_info
2883       * and target_path (the result is stored in the given context), and returns the start offset of
2884       * the rest of the type_annotation structure.
2885       *
2886       * @param context information about the class being parsed. This is where the extracted
2887       *     target_type and target_path must be stored.
2888       * @param typeAnnotationOffset the start offset of a type_annotation structure.
2889       * @return the start offset of the rest of the type_annotation structure.
2890       */
2891     private int readTypeAnnotationTarget(final Context context, final int typeAnnotationOffset) {
2892         int currentOffset = typeAnnotationOffset;
2893         // Parse and store the target_type structure.
2894         int targetType = readInt(typeAnnotationOffset);
2895         switch (targetType >>> 24) {
2896             case TypeReference.CLASS_TYPE_PARAMETER:
2897             case TypeReference.METHOD_TYPE_PARAMETER:
2898             case TypeReference.METHOD_FORMAL_PARAMETER:
2899                 targetType &= 0xFFFF0000;
2900                 currentOffset += 2;
2901                 break;
2902             case TypeReference.FIELD:
2903             case TypeReference.METHOD_RETURN:
2904             case TypeReference.METHOD_RECEIVER:
2905                 targetType &= 0xFF000000;
2906                 currentOffset += 1;
2907                 break;
2908             case TypeReference.LOCAL_VARIABLE:
2909             case TypeReference.RESOURCE_VARIABLE:
2910                 targetType &= 0xFF000000;
2911                 int tableLength = readUnsignedShort(currentOffset + 1);
2912                 currentOffset += 3;
2913                 context.currentLocalVariableAnnotationRangeStarts = new Label[tableLength];
2914                 context.currentLocalVariableAnnotationRangeEnds = new Label[tableLength];
2915                 context.currentLocalVariableAnnotationRangeIndices = new int[tableLength];
2916                 for (int i = 0; i < tableLength; ++i) {
2917                     int startPc = readUnsignedShort(currentOffset);
2918                     int length = readUnsignedShort(currentOffset + 2);
2919                     int index = readUnsignedShort(currentOffset + 4);
2920                     currentOffset += 6;
2921                     context.currentLocalVariableAnnotationRangeStarts[i] =
2922                             createLabel(startPc, context.currentMethodLabels);
2923                     context.currentLocalVariableAnnotationRangeEnds[i] =
2924                             createLabel(startPc + length, context.currentMethodLabels);
2925                     context.currentLocalVariableAnnotationRangeIndices[i] = index;
2926                 }
2927                 break;
2928             case TypeReference.CAST:
2929             case TypeReference.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
2930             case TypeReference.METHOD_INVOCATION_TYPE_ARGUMENT:
2931             case TypeReference.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
2932             case TypeReference.METHOD_REFERENCE_TYPE_ARGUMENT:
2933                 targetType &= 0xFF0000FF;
2934                 currentOffset += 4;
2935                 break;
2936             case TypeReference.CLASS_EXTENDS:
2937             case TypeReference.CLASS_TYPE_PARAMETER_BOUND:
2938             case TypeReference.METHOD_TYPE_PARAMETER_BOUND:
2939             case TypeReference.THROWS:
2940             case TypeReference.EXCEPTION_PARAMETER:
2941                 targetType &= 0xFFFFFF00;
2942                 currentOffset += 3;
2943                 break;
2944             case TypeReference.INSTANCEOF:
2945             case TypeReference.NEW:
2946             case TypeReference.CONSTRUCTOR_REFERENCE:
2947             case TypeReference.METHOD_REFERENCE:
2948                 targetType &= 0xFF000000;
2949                 currentOffset += 3;
2950                 break;
2951             default:
2952                 throw new IllegalArgumentException();
2953         }
2954         context.currentTypeAnnotationTarget = targetType;
2955         // Parse and store the target_path structure.
2956         int pathLength = readByte(currentOffset);
2957         context.currentTypeAnnotationTargetPath =
2958                 pathLength == 0 ? null : new TypePath(classFileBuffer, currentOffset);
2959         // Return the start offset of the rest of the type_annotation structure.
2960         return currentOffset + 1 + 2 * pathLength;
2961     }
2962 
2963     /**
2964       * Reads a Runtime[In]VisibleParameterAnnotations attribute and makes the given visitor visit it.
2965       *
2966       * @param methodVisitor the visitor that must visit the parameter annotations.
2967       * @param context information about the class being parsed.
2968       * @param runtimeParameterAnnotationsOffset the start offset of a
2969       *     Runtime[In]VisibleParameterAnnotations attribute, excluding the attribute_info's
2970       *     attribute_name_index and attribute_length fields.
2971       * @param visible true if the attribute to parse is a RuntimeVisibleParameterAnnotations
2972       *     attribute, false it is a RuntimeInvisibleParameterAnnotations attribute.
2973       */
2974     private void readParameterAnnotations(
2975             final MethodVisitor methodVisitor,
2976             final Context context,
2977             final int runtimeParameterAnnotationsOffset,
2978             final boolean visible) {
2979         int currentOffset = runtimeParameterAnnotationsOffset;
2980         int numParameters = classFileBuffer[currentOffset++] & 0xFF;
2981         methodVisitor.visitAnnotableParameterCount(numParameters, visible);
2982         char[] charBuffer = context.charBuffer;
2983         for (int i = 0; i < numParameters; ++i) {
2984             int numAnnotations = readUnsignedShort(currentOffset);
2985             currentOffset += 2;
2986             while (numAnnotations-- > 0) {
2987                 // Parse the type_index field.
2988                 String annotationDescriptor = readUTF8(currentOffset, charBuffer);
2989                 currentOffset += 2;
2990                 // Parse num_element_value_pairs and element_value_pairs and visit these values.
2991                 currentOffset =
2992                         readElementValues(
2993                                 methodVisitor.visitParameterAnnotation(i, annotationDescriptor, visible),
2994                                 currentOffset,
2995                                 /* named = */ true,
2996                                 charBuffer);
2997             }
2998         }
2999     }
3000 
3001     /**
3002       * Reads the element values of a JVMS 'annotation' structure and makes the given visitor visit
3003       * them. This method can also be used to read the values of the JVMS 'array_value' field of an
3004       * annotation's 'element_value'.
3005       *
3006       * @param annotationVisitor the visitor that must visit the values.
3007       * @param annotationOffset the start offset of an 'annotation' structure (excluding its type_index
3008       *     field) or of an 'array_value' structure.
3009       * @param named if the annotation values are named or not. This should be true to parse the values
3010       *     of a JVMS 'annotation' structure, and false to parse the JVMS 'array_value' of an
3011       *     annotation's element_value.
3012       * @param charBuffer the buffer used to read strings in the constant pool.
3013       * @return the end offset of the JVMS 'annotation' or 'array_value' structure.
3014       */
3015     private int readElementValues(
3016             final AnnotationVisitor annotationVisitor,
3017             final int annotationOffset,
3018             final boolean named,
3019             final char[] charBuffer) {
3020         int currentOffset = annotationOffset;
3021         // Read the num_element_value_pairs field (or num_values field for an array_value).
3022         int numElementValuePairs = readUnsignedShort(currentOffset);
3023         currentOffset += 2;
3024         if (named) {
3025             // Parse the element_value_pairs array.
3026             while (numElementValuePairs-- > 0) {
3027                 String elementName = readUTF8(currentOffset, charBuffer);
3028                 currentOffset =
3029                         readElementValue(annotationVisitor, currentOffset + 2, elementName, charBuffer);
3030             }
3031         } else {
3032             // Parse the array_value array.
3033             while (numElementValuePairs-- > 0) {
3034                 currentOffset =
3035                         readElementValue(annotationVisitor, currentOffset, /* elementName= */ null, charBuffer);
3036             }
3037         }
3038         if (annotationVisitor != null) {
3039             annotationVisitor.visitEnd();
3040         }
3041         return currentOffset;
3042     }
3043 
3044     /**
3045       * Reads a JVMS 'element_value' structure and makes the given visitor visit it.
3046       *
3047       * @param annotationVisitor the visitor that must visit the element_value structure.
3048       * @param elementValueOffset the start offset in {@link #classFileBuffer} of the element_value
3049       *     structure to be read.
3050       * @param elementName the name of the element_value structure to be read, or {@literal null}.
3051       * @param charBuffer the buffer used to read strings in the constant pool.
3052       * @return the end offset of the JVMS 'element_value' structure.
3053       */
3054     private int readElementValue(
3055             final AnnotationVisitor annotationVisitor,
3056             final int elementValueOffset,
3057             final String elementName,
3058             final char[] charBuffer) {
3059         int currentOffset = elementValueOffset;
3060         if (annotationVisitor == null) {
3061             switch (classFileBuffer[currentOffset] & 0xFF) {
3062                 case 'e': // enum_const_value
3063                     return currentOffset + 5;
3064                 case '@': // annotation_value
3065                     return readElementValues(null, currentOffset + 3, /* named = */ true, charBuffer);
3066                 case '[': // array_value
3067                     return readElementValues(null, currentOffset + 1, /* named = */ false, charBuffer);
3068                 default:
3069                     return currentOffset + 3;
3070             }
3071         }
3072         switch (classFileBuffer[currentOffset++] & 0xFF) {
3073             case 'B': // const_value_index, CONSTANT_Integer
3074                 annotationVisitor.visit(
3075                         elementName, (byte) readInt(cpInfoOffsets[readUnsignedShort(currentOffset)]));
3076                 currentOffset += 2;
3077                 break;
3078             case 'C': // const_value_index, CONSTANT_Integer
3079                 annotationVisitor.visit(
3080                         elementName, (char) readInt(cpInfoOffsets[readUnsignedShort(currentOffset)]));
3081                 currentOffset += 2;
3082                 break;
3083             case 'D': // const_value_index, CONSTANT_Double
3084             case 'F': // const_value_index, CONSTANT_Float
3085             case 'I': // const_value_index, CONSTANT_Integer
3086             case 'J': // const_value_index, CONSTANT_Long
3087                 annotationVisitor.visit(
3088                         elementName, readConst(readUnsignedShort(currentOffset), charBuffer));
3089                 currentOffset += 2;
3090                 break;
3091             case 'S': // const_value_index, CONSTANT_Integer
3092                 annotationVisitor.visit(
3093                         elementName, (short) readInt(cpInfoOffsets[readUnsignedShort(currentOffset)]));
3094                 currentOffset += 2;
3095                 break;
3096 
3097             case 'Z': // const_value_index, CONSTANT_Integer
3098                 annotationVisitor.visit(
3099                         elementName,
3100                         readInt(cpInfoOffsets[readUnsignedShort(currentOffset)]) == 0
3101                                 ? Boolean.FALSE
3102                                 : Boolean.TRUE);
3103                 currentOffset += 2;
3104                 break;
3105             case 's': // const_value_index, CONSTANT_Utf8
3106                 annotationVisitor.visit(elementName, readUTF8(currentOffset, charBuffer));
3107                 currentOffset += 2;
3108                 break;
3109             case 'e': // enum_const_value
3110                 annotationVisitor.visitEnum(
3111                         elementName,
3112                         readUTF8(currentOffset, charBuffer),
3113                         readUTF8(currentOffset + 2, charBuffer));
3114                 currentOffset += 4;
3115                 break;
3116             case 'c': // class_info
3117                 annotationVisitor.visit(elementName, Type.getType(readUTF8(currentOffset, charBuffer)));
3118                 currentOffset += 2;
3119                 break;
3120             case '@': // annotation_value
3121                 currentOffset =
3122                         readElementValues(
3123                                 annotationVisitor.visitAnnotation(elementName, readUTF8(currentOffset, charBuffer)),
3124                                 currentOffset + 2,
3125                                 true,
3126                                 charBuffer);
3127                 break;
3128             case '[': // array_value
3129                 int numValues = readUnsignedShort(currentOffset);
3130                 currentOffset += 2;
3131                 if (numValues == 0) {
3132                     return readElementValues(
3133                             annotationVisitor.visitArray(elementName),
3134                             currentOffset - 2,
3135                             /* named = */ false,
3136                             charBuffer);
3137                 }
3138                 switch (classFileBuffer[currentOffset] & 0xFF) {
3139                     case 'B':
3140                         byte[] byteValues = new byte[numValues];
3141                         for (int i = 0; i < numValues; i++) {
3142                             byteValues[i] = (byte) readInt(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]);
3143                             currentOffset += 3;
3144                         }
3145                         annotationVisitor.visit(elementName, byteValues);
3146                         break;
3147                     case 'Z':
3148                         boolean[] booleanValues = new boolean[numValues];
3149                         for (int i = 0; i < numValues; i++) {
3150                             booleanValues[i] = readInt(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]) != 0;
3151                             currentOffset += 3;
3152                         }
3153                         annotationVisitor.visit(elementName, booleanValues);
3154                         break;
3155                     case 'S':
3156                         short[] shortValues = new short[numValues];
3157                         for (int i = 0; i < numValues; i++) {
3158                             shortValues[i] = (short) readInt(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]);
3159                             currentOffset += 3;
3160                         }
3161                         annotationVisitor.visit(elementName, shortValues);
3162                         break;
3163                     case 'C':
3164                         char[] charValues = new char[numValues];
3165                         for (int i = 0; i < numValues; i++) {
3166                             charValues[i] = (char) readInt(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]);
3167                             currentOffset += 3;
3168                         }
3169                         annotationVisitor.visit(elementName, charValues);
3170                         break;
3171                     case 'I':
3172                         int[] intValues = new int[numValues];
3173                         for (int i = 0; i < numValues; i++) {
3174                             intValues[i] = readInt(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]);
3175                             currentOffset += 3;
3176                         }
3177                         annotationVisitor.visit(elementName, intValues);
3178                         break;
3179                     case 'J':
3180                         long[] longValues = new long[numValues];
3181                         for (int i = 0; i < numValues; i++) {
3182                             longValues[i] = readLong(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]);
3183                             currentOffset += 3;
3184                         }
3185                         annotationVisitor.visit(elementName, longValues);
3186                         break;
3187                     case 'F':
3188                         float[] floatValues = new float[numValues];
3189                         for (int i = 0; i < numValues; i++) {
3190                             floatValues[i] =
3191                                     Float.intBitsToFloat(
3192                                             readInt(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]));
3193                             currentOffset += 3;
3194                         }
3195                         annotationVisitor.visit(elementName, floatValues);
3196                         break;
3197                     case 'D':
3198                         double[] doubleValues = new double[numValues];
3199                         for (int i = 0; i < numValues; i++) {
3200                             doubleValues[i] =
3201                                     Double.longBitsToDouble(
3202                                             readLong(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]));
3203                             currentOffset += 3;
3204                         }
3205                         annotationVisitor.visit(elementName, doubleValues);
3206                         break;
3207                     default:
3208                         currentOffset =
3209                                 readElementValues(
3210                                         annotationVisitor.visitArray(elementName),
3211                                         currentOffset - 2,
3212                                         /* named = */ false,
3213                                         charBuffer);
3214                         break;
3215                 }
3216                 break;
3217             default:
3218                 throw new IllegalArgumentException();
3219         }
3220         return currentOffset;
3221     }
3222 
3223     // ----------------------------------------------------------------------------------------------
3224     // Methods to parse stack map frames
3225     // ----------------------------------------------------------------------------------------------
3226 
3227     /**
3228       * Computes the implicit frame of the method currently being parsed (as defined in the given
3229       * {@link Context}) and stores it in the given context.
3230       *
3231       * @param context information about the class being parsed.
3232       */
3233     private void computeImplicitFrame(final Context context) {
3234         String methodDescriptor = context.currentMethodDescriptor;
3235         Object[] locals = context.currentFrameLocalTypes;
3236         int numLocal = 0;
3237         if ((context.currentMethodAccessFlags & Opcodes.ACC_STATIC) == 0) {
3238             if ("<init>".equals(context.currentMethodName)) {
3239                 locals[numLocal++] = Opcodes.UNINITIALIZED_THIS;
3240             } else {
3241                 locals[numLocal++] = readClass(header + 2, context.charBuffer);
3242             }
3243         }
3244         // Parse the method descriptor, one argument type descriptor at each iteration. Start by
3245         // skipping the first method descriptor character, which is always '('.
3246         int currentMethodDescritorOffset = 1;
3247         while (true) {
3248             int currentArgumentDescriptorStartOffset = currentMethodDescritorOffset;
3249             switch (methodDescriptor.charAt(currentMethodDescritorOffset++)) {
3250                 case 'Z':
3251                 case 'C':
3252                 case 'B':
3253                 case 'S':
3254                 case 'I':
3255                     locals[numLocal++] = Opcodes.INTEGER;
3256                     break;
3257                 case 'F':
3258                     locals[numLocal++] = Opcodes.FLOAT;
3259                     break;
3260                 case 'J':
3261                     locals[numLocal++] = Opcodes.LONG;
3262                     break;
3263                 case 'D':
3264                     locals[numLocal++] = Opcodes.DOUBLE;
3265                     break;
3266                 case '[':
3267                     while (methodDescriptor.charAt(currentMethodDescritorOffset) == '[') {
3268                         ++currentMethodDescritorOffset;
3269                     }
3270                     char descType = methodDescriptor.charAt(currentMethodDescritorOffset);
3271                     if (descType == 'L' || descType == 'Q') {
3272                         ++currentMethodDescritorOffset;
3273                         while (methodDescriptor.charAt(currentMethodDescritorOffset) != ';') {
3274                             ++currentMethodDescritorOffset;
3275                         }
3276                     }
3277                     locals[numLocal++] =
3278                             methodDescriptor.substring(
3279                                     currentArgumentDescriptorStartOffset, ++currentMethodDescritorOffset);
3280                     break;
3281                 case 'L':
3282                     while (methodDescriptor.charAt(currentMethodDescritorOffset) != ';') {
3283                         ++currentMethodDescritorOffset;
3284                     }
3285                     locals[numLocal++] =
3286                             methodDescriptor.substring(
3287                                     currentArgumentDescriptorStartOffset + 1, currentMethodDescritorOffset++);
3288                     break;
3289                 default:
3290                     context.currentFrameLocalCount = numLocal;
3291                     return;
3292             }
3293         }
3294     }
3295 
3296     /**
3297       * Reads a JVMS 'stack_map_frame' structure and stores the result in the given {@link Context}
3298       * object. This method can also be used to read a full_frame structure, excluding its frame_type
3299       * field (this is used to parse the legacy StackMap attributes).
3300       *
3301       * @param stackMapFrameOffset the start offset in {@link #classFileBuffer} of the
3302       *     stack_map_frame_value structure to be read, or the start offset of a full_frame structure
3303       *     (excluding its frame_type field).
3304       * @param compressed true to read a 'stack_map_frame' structure, false to read a 'full_frame'
3305       *     structure without its frame_type field.
3306       * @param expand if the stack map frame must be expanded. See {@link #EXPAND_FRAMES}.
3307       * @param context where the parsed stack map frame must be stored.
3308       * @return the end offset of the JVMS 'stack_map_frame' or 'full_frame' structure.
3309       */
3310     private int readStackMapFrame(
3311             final int stackMapFrameOffset,
3312             final boolean compressed,
3313             final boolean expand,
3314             final Context context) {
3315         int currentOffset = stackMapFrameOffset;
3316         final char[] charBuffer = context.charBuffer;
3317         final Label[] labels = context.currentMethodLabels;
3318         int frameType;
3319         if (compressed) {
3320             // Read the frame_type field.
3321             frameType = classFileBuffer[currentOffset++] & 0xFF;
3322         } else {
3323             frameType = Frame.FULL_FRAME;
3324             context.currentFrameOffset = -1;
3325         }
3326         int offsetDelta;
3327         context.currentFrameLocalCountDelta = 0;
3328         if (frameType < Frame.SAME_LOCALS_1_STACK_ITEM_FRAME) {
3329             offsetDelta = frameType;
3330             context.currentFrameType = Opcodes.F_SAME;
3331             context.currentFrameStackCount = 0;
3332         } else if (frameType < Frame.RESERVED) {
3333             offsetDelta = frameType - Frame.SAME_LOCALS_1_STACK_ITEM_FRAME;
3334             currentOffset =
3335                     readVerificationTypeInfo(
3336                             currentOffset, context.currentFrameStackTypes, 0, charBuffer, labels);
3337             context.currentFrameType = Opcodes.F_SAME1;
3338             context.currentFrameStackCount = 1;
3339         } else if (frameType >= Frame.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) {
3340             offsetDelta = readUnsignedShort(currentOffset);
3341             currentOffset += 2;
3342             if (frameType == Frame.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) {
3343                 currentOffset =
3344                         readVerificationTypeInfo(
3345                                 currentOffset, context.currentFrameStackTypes, 0, charBuffer, labels);
3346                 context.currentFrameType = Opcodes.F_SAME1;
3347                 context.currentFrameStackCount = 1;
3348             } else if (frameType >= Frame.CHOP_FRAME && frameType < Frame.SAME_FRAME_EXTENDED) {
3349                 context.currentFrameType = Opcodes.F_CHOP;
3350                 context.currentFrameLocalCountDelta = Frame.SAME_FRAME_EXTENDED - frameType;
3351                 context.currentFrameLocalCount -= context.currentFrameLocalCountDelta;
3352                 context.currentFrameStackCount = 0;
3353             } else if (frameType == Frame.SAME_FRAME_EXTENDED) {
3354                 context.currentFrameType = Opcodes.F_SAME;
3355                 context.currentFrameStackCount = 0;
3356             } else if (frameType < Frame.FULL_FRAME) {
3357                 int local = expand ? context.currentFrameLocalCount : 0;
3358                 for (int k = frameType - Frame.SAME_FRAME_EXTENDED; k > 0; k--) {
3359                     currentOffset =
3360                             readVerificationTypeInfo(
3361                                     currentOffset, context.currentFrameLocalTypes, local++, charBuffer, labels);
3362                 }
3363                 context.currentFrameType = Opcodes.F_APPEND;
3364                 context.currentFrameLocalCountDelta = frameType - Frame.SAME_FRAME_EXTENDED;
3365                 context.currentFrameLocalCount += context.currentFrameLocalCountDelta;
3366                 context.currentFrameStackCount = 0;
3367             } else {
3368                 final int numberOfLocals = readUnsignedShort(currentOffset);
3369                 currentOffset += 2;
3370                 context.currentFrameType = Opcodes.F_FULL;
3371                 context.currentFrameLocalCountDelta = numberOfLocals;
3372                 context.currentFrameLocalCount = numberOfLocals;
3373                 for (int local = 0; local < numberOfLocals; ++local) {
3374                     currentOffset =
3375                             readVerificationTypeInfo(
3376                                     currentOffset, context.currentFrameLocalTypes, local, charBuffer, labels);
3377                 }
3378                 final int numberOfStackItems = readUnsignedShort(currentOffset);
3379                 currentOffset += 2;
3380                 context.currentFrameStackCount = numberOfStackItems;
3381                 for (int stack = 0; stack < numberOfStackItems; ++stack) {
3382                     currentOffset =
3383                             readVerificationTypeInfo(
3384                                     currentOffset, context.currentFrameStackTypes, stack, charBuffer, labels);
3385                 }
3386             }
3387         } else {
3388             throw new IllegalArgumentException();
3389         }
3390         context.currentFrameOffset += offsetDelta + 1;
3391         createLabel(context.currentFrameOffset, labels);
3392         return currentOffset;
3393     }
3394 
3395     /**
3396       * Reads a JVMS 'verification_type_info' structure and stores it at the given index in the given
3397       * array.
3398       *
3399       * @param verificationTypeInfoOffset the start offset of the 'verification_type_info' structure to
3400       *     read.
3401       * @param frame the array where the parsed type must be stored.
3402       * @param index the index in 'frame' where the parsed type must be stored.
3403       * @param charBuffer the buffer used to read strings in the constant pool.
3404       * @param labels the labels of the method currently being parsed, indexed by their offset. If the
3405       *     parsed type is an ITEM_Uninitialized, a new label for the corresponding NEW instruction is
3406       *     stored in this array if it does not already exist.
3407       * @return the end offset of the JVMS 'verification_type_info' structure.
3408       */
3409     private int readVerificationTypeInfo(
3410             final int verificationTypeInfoOffset,
3411             final Object[] frame,
3412             final int index,
3413             final char[] charBuffer,
3414             final Label[] labels) {
3415         int currentOffset = verificationTypeInfoOffset;
3416         int tag = classFileBuffer[currentOffset++] & 0xFF;
3417         switch (tag) {
3418             case Frame.ITEM_TOP:
3419                 frame[index] = Opcodes.TOP;
3420                 break;
3421             case Frame.ITEM_INTEGER:
3422                 frame[index] = Opcodes.INTEGER;
3423                 break;
3424             case Frame.ITEM_FLOAT:
3425                 frame[index] = Opcodes.FLOAT;
3426                 break;
3427             case Frame.ITEM_DOUBLE:
3428                 frame[index] = Opcodes.DOUBLE;
3429                 break;
3430             case Frame.ITEM_LONG:
3431                 frame[index] = Opcodes.LONG;
3432                 break;
3433             case Frame.ITEM_NULL:
3434                 frame[index] = Opcodes.NULL;
3435                 break;
3436             case Frame.ITEM_UNINITIALIZED_THIS:
3437                 frame[index] = Opcodes.UNINITIALIZED_THIS;
3438                 break;
3439             case Frame.ITEM_OBJECT:
3440                 frame[index] = readClass(currentOffset, charBuffer);
3441                 currentOffset += 2;
3442                 break;
3443             case Frame.ITEM_UNINITIALIZED:
3444                 frame[index] = createLabel(readUnsignedShort(currentOffset), labels);
3445                 currentOffset += 2;
3446                 break;
3447             default:
3448                 throw new IllegalArgumentException();
3449         }
3450         return currentOffset;
3451     }
3452 
3453     // ----------------------------------------------------------------------------------------------
3454     // Methods to parse attributes
3455     // ----------------------------------------------------------------------------------------------
3456 
3457     /**
3458       * Returns the offset in {@link #classFileBuffer} of the first ClassFile's 'attributes' array
3459       * field entry.
3460       *
3461       * @return the offset in {@link #classFileBuffer} of the first ClassFile's 'attributes' array
3462       *     field entry.
3463       */
3464     final int getFirstAttributeOffset() {
3465         // Skip the access_flags, this_class, super_class, and interfaces_count fields (using 2 bytes
3466         // each), as well as the interfaces array field (2 bytes per interface).
3467         int currentOffset = header + 8 + readUnsignedShort(header + 6) * 2;
3468 
3469         // Read the fields_count field.
3470         int fieldsCount = readUnsignedShort(currentOffset);
3471         currentOffset += 2;
3472         // Skip the 'fields' array field.
3473         while (fieldsCount-- > 0) {
3474             // Invariant: currentOffset is the offset of a field_info structure.
3475             // Skip the access_flags, name_index and descriptor_index fields (2 bytes each), and read the
3476             // attributes_count field.
3477             int attributesCount = readUnsignedShort(currentOffset + 6);
3478             currentOffset += 8;
3479             // Skip the 'attributes' array field.
3480             while (attributesCount-- > 0) {
3481                 // Invariant: currentOffset is the offset of an attribute_info structure.
3482                 // Read the attribute_length field (2 bytes after the start of the attribute_info) and skip
3483                 // this many bytes, plus 6 for the attribute_name_index and attribute_length fields
3484                 // (yielding the total size of the attribute_info structure).
3485                 currentOffset += 6 + readInt(currentOffset + 2);
3486             }
3487         }
3488 
3489         // Skip the methods_count and 'methods' fields, using the same method as above.
3490         int methodsCount = readUnsignedShort(currentOffset);
3491         currentOffset += 2;
3492         while (methodsCount-- > 0) {
3493             int attributesCount = readUnsignedShort(currentOffset + 6);
3494             currentOffset += 8;
3495             while (attributesCount-- > 0) {
3496                 currentOffset += 6 + readInt(currentOffset + 2);
3497             }
3498         }
3499 
3500         // Skip the ClassFile's attributes_count field.
3501         return currentOffset + 2;
3502     }
3503 
3504     /**
3505       * Reads the BootstrapMethods attribute to compute the offset of each bootstrap method.
3506       *
3507       * @param maxStringLength a conservative estimate of the maximum length of the strings contained
3508       *     in the constant pool of the class.
3509       * @return the offsets of the bootstrap methods.
3510       */
3511     private int[] readBootstrapMethodsAttribute(final int maxStringLength) {
3512         char[] charBuffer = new char[maxStringLength];
3513         int currentAttributeOffset = getFirstAttributeOffset();
3514         for (int i = readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) {
3515             // Read the attribute_info's attribute_name and attribute_length fields.
3516             String attributeName = readUTF8(currentAttributeOffset, charBuffer);
3517             int attributeLength = readInt(currentAttributeOffset + 2);
3518             currentAttributeOffset += 6;
3519             if (Constants.BOOTSTRAP_METHODS.equals(attributeName)) {
3520                 // Read the num_bootstrap_methods field and create an array of this size.
3521                 int[] result = new int[readUnsignedShort(currentAttributeOffset)];
3522                 // Compute and store the offset of each 'bootstrap_methods' array field entry.
3523                 int currentBootstrapMethodOffset = currentAttributeOffset + 2;
3524                 for (int j = 0; j < result.length; ++j) {
3525                     result[j] = currentBootstrapMethodOffset;
3526                     // Skip the bootstrap_method_ref and num_bootstrap_arguments fields (2 bytes each),
3527                     // as well as the bootstrap_arguments array field (of size num_bootstrap_arguments * 2).
3528                     currentBootstrapMethodOffset +=
3529                             4 + readUnsignedShort(currentBootstrapMethodOffset + 2) * 2;
3530                 }
3531                 return result;
3532             }
3533             currentAttributeOffset += attributeLength;
3534         }
3535         throw new IllegalArgumentException();
3536     }
3537 
3538     /**
3539       * Reads a non standard JVMS 'attribute' structure in {@link #classFileBuffer}.
3540       *
3541       * @param attributePrototypes prototypes of the attributes that must be parsed during the visit of
3542       *     the class. Any attribute whose type is not equal to the type of one the prototypes will not
3543       *     be parsed: its byte array value will be passed unchanged to the ClassWriter.
3544       * @param type the type of the attribute.
3545       * @param offset the start offset of the JVMS 'attribute' structure in {@link #classFileBuffer}.
3546       *     The 6 attribute header bytes (attribute_name_index and attribute_length) are not taken into
3547       *     account here.
3548       * @param length the length of the attribute's content (excluding the 6 attribute header bytes).
3549       * @param charBuffer the buffer to be used to read strings in the constant pool.
3550       * @param codeAttributeOffset the start offset of the enclosing Code attribute in {@link
3551       *     #classFileBuffer}, or -1 if the attribute to be read is not a code attribute. The 6
3552       *     attribute header bytes (attribute_name_index and attribute_length) are not taken into
3553       *     account here.
3554       * @param labels the labels of the method's code, or {@literal null} if the attribute to be read
3555       *     is not a code attribute.
3556       * @return the attribute that has been read.
3557       */
3558     private Attribute readAttribute(
3559             final Attribute[] attributePrototypes,
3560             final String type,
3561             final int offset,
3562             final int length,
3563             final char[] charBuffer,
3564             final int codeAttributeOffset,
3565             final Label[] labels) {
3566         for (Attribute attributePrototype : attributePrototypes) {
3567             if (attributePrototype.type.equals(type)) {
3568                 return attributePrototype.read(
3569                         this, offset, length, charBuffer, codeAttributeOffset, labels);
3570             }
3571         }
3572         return new Attribute(type).read(this, offset, length, null, -1, null);
3573     }
3574 
3575     // -----------------------------------------------------------------------------------------------
3576     // Utility methods: low level parsing
3577     // -----------------------------------------------------------------------------------------------
3578 
3579     /**
3580       * Returns the number of entries in the class's constant pool table.
3581       *
3582       * @return the number of entries in the class's constant pool table.
3583       */
3584     public int getItemCount() {
3585         return cpInfoOffsets.length;
3586     }
3587 
3588     /**
3589       * Returns the start offset in this {@link ClassReader} of a JVMS 'cp_info' structure (i.e. a
3590       * constant pool entry), plus one. <i>This method is intended for {@link Attribute} sub classes,
3591       * and is normally not needed by class generators or adapters.</i>
3592       *
3593       * @param constantPoolEntryIndex the index a constant pool entry in the class's constant pool
3594       *     table.
3595       * @return the start offset in this {@link ClassReader} of the corresponding JVMS 'cp_info'
3596       *     structure, plus one.
3597       */
3598     public int getItem(final int constantPoolEntryIndex) {
3599         return cpInfoOffsets[constantPoolEntryIndex];
3600     }
3601 
3602     /**
3603       * Returns a conservative estimate of the maximum length of the strings contained in the class's
3604       * constant pool table.
3605       *
3606       * @return a conservative estimate of the maximum length of the strings contained in the class's
3607       *     constant pool table.
3608       */
3609     public int getMaxStringLength() {
3610         return maxStringLength;
3611     }
3612 
3613     /**
3614       * Reads a byte value in this {@link ClassReader}. <i>This method is intended for {@link
3615       * Attribute} sub classes, and is normally not needed by class generators or adapters.</i>
3616       *
3617       * @param offset the start offset of the value to be read in this {@link ClassReader}.
3618       * @return the read value.
3619       */
3620     public int readByte(final int offset) {
3621         return classFileBuffer[offset] & 0xFF;
3622     }
3623 
3624     /**
3625       * Reads an unsigned short value in this {@link ClassReader}. <i>This method is intended for
3626       * {@link Attribute} sub classes, and is normally not needed by class generators or adapters.</i>
3627       *
3628       * @param offset the start index of the value to be read in this {@link ClassReader}.
3629       * @return the read value.
3630       */
3631     public int readUnsignedShort(final int offset) {
3632         byte[] classBuffer = classFileBuffer;
3633         return ((classBuffer[offset] & 0xFF) << 8) | (classBuffer[offset + 1] & 0xFF);
3634     }
3635 
3636     /**
3637       * Reads a signed short value in this {@link ClassReader}. <i>This method is intended for {@link
3638       * Attribute} sub classes, and is normally not needed by class generators or adapters.</i>
3639       *
3640       * @param offset the start offset of the value to be read in this {@link ClassReader}.
3641       * @return the read value.
3642       */
3643     public short readShort(final int offset) {
3644         byte[] classBuffer = classFileBuffer;
3645         return (short) (((classBuffer[offset] & 0xFF) << 8) | (classBuffer[offset + 1] & 0xFF));
3646     }
3647 
3648     /**
3649       * Reads a signed int value in this {@link ClassReader}. <i>This method is intended for {@link
3650       * Attribute} sub classes, and is normally not needed by class generators or adapters.</i>
3651       *
3652       * @param offset the start offset of the value to be read in this {@link ClassReader}.
3653       * @return the read value.
3654       */
3655     public int readInt(final int offset) {
3656         byte[] classBuffer = classFileBuffer;
3657         return ((classBuffer[offset] & 0xFF) << 24)
3658                 | ((classBuffer[offset + 1] & 0xFF) << 16)
3659                 | ((classBuffer[offset + 2] & 0xFF) << 8)
3660                 | (classBuffer[offset + 3] & 0xFF);
3661     }
3662 
3663     /**
3664       * Reads a signed long value in this {@link ClassReader}. <i>This method is intended for {@link
3665       * Attribute} sub classes, and is normally not needed by class generators or adapters.</i>
3666       *
3667       * @param offset the start offset of the value to be read in this {@link ClassReader}.
3668       * @return the read value.
3669       */
3670     public long readLong(final int offset) {
3671         long l1 = readInt(offset);
3672         long l0 = readInt(offset + 4) & 0xFFFFFFFFL;
3673         return (l1 << 32) | l0;
3674     }
3675 
3676     /**
3677       * Reads a CONSTANT_Utf8 constant pool entry in this {@link ClassReader}. <i>This method is
3678       * intended for {@link Attribute} sub classes, and is normally not needed by class generators or
3679       * adapters.</i>
3680       *
3681       * @param offset the start offset of an unsigned short value in this {@link ClassReader}, whose
3682       *     value is the index of a CONSTANT_Utf8 entry in the class's constant pool table.
3683       * @param charBuffer the buffer to be used to read the string. This buffer must be sufficiently
3684       *     large. It is not automatically resized.
3685       * @return the String corresponding to the specified CONSTANT_Utf8 entry.
3686       */
3687     // DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility).
3688     public String readUTF8(final int offset, final char[] charBuffer) {
3689         int constantPoolEntryIndex = readUnsignedShort(offset);
3690         if (offset == 0 || constantPoolEntryIndex == 0) {
3691             return null;
3692         }
3693         return readUtf(constantPoolEntryIndex, charBuffer);
3694     }
3695 
3696     /**
3697       * Reads a CONSTANT_Utf8 constant pool entry in {@link #classFileBuffer}.
3698       *
3699       * @param constantPoolEntryIndex the index of a CONSTANT_Utf8 entry in the class's constant pool
3700       *     table.
3701       * @param charBuffer the buffer to be used to read the string. This buffer must be sufficiently
3702       *     large. It is not automatically resized.
3703       * @return the String corresponding to the specified CONSTANT_Utf8 entry.
3704       */
3705     final String readUtf(final int constantPoolEntryIndex, final char[] charBuffer) {
3706         String value = constantUtf8Values[constantPoolEntryIndex];
3707         if (value != null) {
3708             return value;
3709         }
3710         int cpInfoOffset = cpInfoOffsets[constantPoolEntryIndex];
3711         return constantUtf8Values[constantPoolEntryIndex] =
3712                 readUtf(cpInfoOffset + 2, readUnsignedShort(cpInfoOffset), charBuffer);
3713     }
3714 
3715     /**
3716       * Reads an UTF8 string in {@link #classFileBuffer}.
3717       *
3718       * @param utfOffset the start offset of the UTF8 string to be read.
3719       * @param utfLength the length of the UTF8 string to be read.
3720       * @param charBuffer the buffer to be used to read the string. This buffer must be sufficiently
3721       *     large. It is not automatically resized.
3722       * @return the String corresponding to the specified UTF8 string.
3723       */
3724     private String readUtf(final int utfOffset, final int utfLength, final char[] charBuffer) {
3725         int currentOffset = utfOffset;
3726         int endOffset = currentOffset + utfLength;
3727         int strLength = 0;
3728         byte[] classBuffer = classFileBuffer;
3729         while (currentOffset < endOffset) {
3730             int currentByte = classBuffer[currentOffset++];
3731             if ((currentByte & 0x80) == 0) {
3732                 charBuffer[strLength++] = (char) (currentByte & 0x7F);
3733             } else if ((currentByte & 0xE0) == 0xC0) {
3734                 charBuffer[strLength++] =
3735                         (char) (((currentByte & 0x1F) << 6) + (classBuffer[currentOffset++] & 0x3F));
3736             } else {
3737                 charBuffer[strLength++] =
3738                         (char)
3739                                 (((currentByte & 0xF) << 12)
3740                                         + ((classBuffer[currentOffset++] & 0x3F) << 6)
3741                                         + (classBuffer[currentOffset++] & 0x3F));
3742             }
3743         }
3744         return new String(charBuffer, 0, strLength);
3745     }
3746 
3747     /**
3748       * Reads a CONSTANT_Class, CONSTANT_String, CONSTANT_MethodType, CONSTANT_Module or
3749       * CONSTANT_Package constant pool entry in {@link #classFileBuffer}. <i>This method is intended
3750       * for {@link Attribute} sub classes, and is normally not needed by class generators or
3751       * adapters.</i>
3752       *
3753       * @param offset the start offset of an unsigned short value in {@link #classFileBuffer}, whose
3754       *     value is the index of a CONSTANT_Class, CONSTANT_String, CONSTANT_MethodType,
3755       *     CONSTANT_Module or CONSTANT_Package entry in class's constant pool table.
3756       * @param charBuffer the buffer to be used to read the item. This buffer must be sufficiently
3757       *     large. It is not automatically resized.
3758       * @return the String corresponding to the specified constant pool entry.
3759       */
3760     private String readStringish(final int offset, final char[] charBuffer) {
3761         // Get the start offset of the cp_info structure (plus one), and read the CONSTANT_Utf8 entry
3762         // designated by the first two bytes of this cp_info.
3763         return readUTF8(cpInfoOffsets[readUnsignedShort(offset)], charBuffer);
3764     }
3765 
3766     /**
3767       * Reads a CONSTANT_Class constant pool entry in this {@link ClassReader}. <i>This method is
3768       * intended for {@link Attribute} sub classes, and is normally not needed by class generators or
3769       * adapters.</i>
3770       *
3771       * @param offset the start offset of an unsigned short value in this {@link ClassReader}, whose
3772       *     value is the index of a CONSTANT_Class entry in class's constant pool table.
3773       * @param charBuffer the buffer to be used to read the item. This buffer must be sufficiently
3774       *     large. It is not automatically resized.
3775       * @return the String corresponding to the specified CONSTANT_Class entry.
3776       */
3777     public String readClass(final int offset, final char[] charBuffer) {
3778         return readStringish(offset, charBuffer);
3779     }
3780 
3781     /**
3782       * Reads a CONSTANT_Module constant pool entry in this {@link ClassReader}. <i>This method is
3783       * intended for {@link Attribute} sub classes, and is normally not needed by class generators or
3784       * adapters.</i>
3785       *
3786       * @param offset the start offset of an unsigned short value in this {@link ClassReader}, whose
3787       *     value is the index of a CONSTANT_Module entry in class's constant pool table.
3788       * @param charBuffer the buffer to be used to read the item. This buffer must be sufficiently
3789       *     large. It is not automatically resized.
3790       * @return the String corresponding to the specified CONSTANT_Module entry.
3791       */
3792     public String readModule(final int offset, final char[] charBuffer) {
3793         return readStringish(offset, charBuffer);
3794     }
3795 
3796     /**
3797       * Reads a CONSTANT_Package constant pool entry in this {@link ClassReader}. <i>This method is
3798       * intended for {@link Attribute} sub classes, and is normally not needed by class generators or
3799       * adapters.</i>
3800       *
3801       * @param offset the start offset of an unsigned short value in this {@link ClassReader}, whose
3802       *     value is the index of a CONSTANT_Package entry in class's constant pool table.
3803       * @param charBuffer the buffer to be used to read the item. This buffer must be sufficiently
3804       *     large. It is not automatically resized.
3805       * @return the String corresponding to the specified CONSTANT_Package entry.
3806       */
3807     public String readPackage(final int offset, final char[] charBuffer) {
3808         return readStringish(offset, charBuffer);
3809     }
3810 
3811     /**
3812       * Reads a CONSTANT_Dynamic constant pool entry in {@link #classFileBuffer}.
3813       *
3814       * @param constantPoolEntryIndex the index of a CONSTANT_Dynamic entry in the class's constant
3815       *     pool table.
3816       * @param charBuffer the buffer to be used to read the string. This buffer must be sufficiently
3817       *     large. It is not automatically resized.
3818       * @return the ConstantDynamic corresponding to the specified CONSTANT_Dynamic entry.
3819       */
3820     private ConstantDynamic readConstantDynamic(
3821             final int constantPoolEntryIndex, final char[] charBuffer) {
3822         ConstantDynamic constantDynamic = constantDynamicValues[constantPoolEntryIndex];
3823         if (constantDynamic != null) {
3824             return constantDynamic;
3825         }
3826         int cpInfoOffset = cpInfoOffsets[constantPoolEntryIndex];
3827         int nameAndTypeCpInfoOffset = cpInfoOffsets[readUnsignedShort(cpInfoOffset + 2)];
3828         String name = readUTF8(nameAndTypeCpInfoOffset, charBuffer);
3829         String descriptor = readUTF8(nameAndTypeCpInfoOffset + 2, charBuffer);
3830         int bootstrapMethodOffset = bootstrapMethodOffsets[readUnsignedShort(cpInfoOffset)];
3831         Handle handle = (Handle) readConst(readUnsignedShort(bootstrapMethodOffset), charBuffer);
3832         Object[] bootstrapMethodArguments = new Object[readUnsignedShort(bootstrapMethodOffset + 2)];
3833         bootstrapMethodOffset += 4;
3834         for (int i = 0; i < bootstrapMethodArguments.length; i++) {
3835             bootstrapMethodArguments[i] = readConst(readUnsignedShort(bootstrapMethodOffset), charBuffer);
3836             bootstrapMethodOffset += 2;
3837         }
3838         return constantDynamicValues[constantPoolEntryIndex] =
3839                 new ConstantDynamic(name, descriptor, handle, bootstrapMethodArguments);
3840     }
3841 
3842     /**
3843       * Reads a numeric or string constant pool entry in this {@link ClassReader}. <i>This method is
3844       * intended for {@link Attribute} sub classes, and is normally not needed by class generators or
3845       * adapters.</i>
3846       *
3847       * @param constantPoolEntryIndex the index of a CONSTANT_Integer, CONSTANT_Float, CONSTANT_Long,
3848       *     CONSTANT_Double, CONSTANT_Class, CONSTANT_String, CONSTANT_MethodType,
3849       *     CONSTANT_MethodHandle or CONSTANT_Dynamic entry in the class's constant pool.
3850       * @param charBuffer the buffer to be used to read strings. This buffer must be sufficiently
3851       *     large. It is not automatically resized.
3852       * @return the {@link Integer}, {@link Float}, {@link Long}, {@link Double}, {@link String},
3853       *     {@link Type}, {@link Handle} or {@link ConstantDynamic} corresponding to the specified
3854       *     constant pool entry.
3855       */
3856     public Object readConst(final int constantPoolEntryIndex, final char[] charBuffer) {
3857         int cpInfoOffset = cpInfoOffsets[constantPoolEntryIndex];
3858         switch (classFileBuffer[cpInfoOffset - 1]) {
3859             case Symbol.CONSTANT_INTEGER_TAG:
3860                 return readInt(cpInfoOffset);
3861             case Symbol.CONSTANT_FLOAT_TAG:
3862                 return Float.intBitsToFloat(readInt(cpInfoOffset));
3863             case Symbol.CONSTANT_LONG_TAG:
3864                 return readLong(cpInfoOffset);
3865             case Symbol.CONSTANT_DOUBLE_TAG:
3866                 return Double.longBitsToDouble(readLong(cpInfoOffset));
3867             case Symbol.CONSTANT_CLASS_TAG:
3868                 return Type.getObjectType(readUTF8(cpInfoOffset, charBuffer));
3869             case Symbol.CONSTANT_STRING_TAG:
3870                 return readUTF8(cpInfoOffset, charBuffer);
3871             case Symbol.CONSTANT_METHOD_TYPE_TAG:
3872                 return Type.getMethodType(readUTF8(cpInfoOffset, charBuffer));
3873             case Symbol.CONSTANT_METHOD_HANDLE_TAG:
3874                 int referenceKind = readByte(cpInfoOffset);
3875                 int referenceCpInfoOffset = cpInfoOffsets[readUnsignedShort(cpInfoOffset + 1)];
3876                 int nameAndTypeCpInfoOffset = cpInfoOffsets[readUnsignedShort(referenceCpInfoOffset + 2)];
3877                 String owner = readClass(referenceCpInfoOffset, charBuffer);
3878                 String name = readUTF8(nameAndTypeCpInfoOffset, charBuffer);
3879                 String descriptor = readUTF8(nameAndTypeCpInfoOffset + 2, charBuffer);
3880                 boolean isInterface =
3881                         classFileBuffer[referenceCpInfoOffset - 1] == Symbol.CONSTANT_INTERFACE_METHODREF_TAG;
3882                 return new Handle(referenceKind, owner, name, descriptor, isInterface);
3883             case Symbol.CONSTANT_DYNAMIC_TAG:
3884                 return readConstantDynamic(constantPoolEntryIndex, charBuffer);
3885             default:
3886                 throw new IllegalArgumentException();
3887         }
3888     }
3889 }
3890