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