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