src/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java

Print this page




 124     public static final int SKIP_FRAMES = 4;
 125 
 126     /**
 127      * Flag to expand the stack map frames. By default stack map frames are
 128      * visited in their original format (i.e. "expanded" for classes whose
 129      * version is less than V1_6, and "compressed" for the other classes). If
 130      * this flag is set, stack map frames are always visited in expanded format
 131      * (this option adds a decompression/recompression step in ClassReader and
 132      * ClassWriter which degrades performances quite a lot).
 133      */
 134     public static final int EXPAND_FRAMES = 8;
 135 
 136     /**
 137      * The class to be parsed. <i>The content of this array must not be
 138      * modified. This field is intended for {@link Attribute} sub classes, and
 139      * is normally not needed by class generators or adapters.</i>
 140      */
 141     public final byte[] b;
 142 
 143     /**
 144      * The start index of each constant pool item in {@link #b b}, plus one.
 145      * The one byte offset skips the constant pool item tag that indicates its
 146      * type.
 147      */
 148     private final int[] items;
 149 
 150     /**
 151      * The String objects corresponding to the CONSTANT_Utf8 items. This cache
 152      * avoids multiple parsing of a given CONSTANT_Utf8 constant pool item,
 153      * which GREATLY improves performances (by a factor 2 to 3). This caching
 154      * strategy could be extended to all constant pool items, but its benefit
 155      * would not be so great for these items (because they are much less
 156      * expensive to parse than CONSTANT_Utf8 items).
 157      */
 158     private final String[] strings;
 159 
 160     /**
 161      * Maximum length of the strings contained in the constant pool of the
 162      * class.
 163      */
 164     private final int maxStringLength;
 165 
 166     /**
 167      * Start index of the class header information (access, name...) in
 168      * {@link #b b}.
 169      */
 170     public final int header;
 171 
 172     // ------------------------------------------------------------------------
 173     // Constructors
 174     // ------------------------------------------------------------------------
 175 
 176     /**
 177      * Constructs a new {@link ClassReader} object.
 178      *
 179      * @param b the bytecode of the class to be read.

 180      */
 181     public ClassReader(final byte[] b) {
 182         this(b, 0, b.length);
 183     }
 184 
 185     /**
 186      * Constructs a new {@link ClassReader} object.
 187      *
 188      * @param b the bytecode of the class to be read.
 189      * @param off the start offset of the class data.
 190      * @param len the length of the class data.



 191      */
 192     public ClassReader(final byte[] b, final int off, final int len) {
 193         this.b = b;
 194         // checks the class version
 195         if (readShort(6) > Opcodes.V1_7) {
 196             throw new IllegalArgumentException();
 197         }
 198         // parses the constant pool
 199         items = new int[readUnsignedShort(off + 8)];
 200         int n = items.length;
 201         strings = new String[n];
 202         int max = 0;
 203         int index = off + 10;
 204         for (int i = 1; i < n; ++i) {
 205             items[i] = index + 1;
 206             int size;
 207             switch (b[index]) {
 208                 case ClassWriter.FIELD:
 209                 case ClassWriter.METH:
 210                 case ClassWriter.IMETH:
 211                 case ClassWriter.INT:
 212                 case ClassWriter.FLOAT:
 213                 case ClassWriter.NAME_TYPE:
 214                 case ClassWriter.INDY:
 215                     size = 5;


 261      *
 262      * @return the internal class name
 263      *
 264      * @see ClassVisitor#visit(int, int, String, String, String, String[])
 265      */
 266     public String getClassName() {
 267         return readClass(header + 2, new char[maxStringLength]);
 268     }
 269 
 270     /**
 271      * Returns the internal of name of the super class (see
 272      * {@link Type#getInternalName() getInternalName}). For interfaces, the
 273      * super class is {@link Object}.
 274      *
 275      * @return the internal name of super class, or <tt>null</tt> for
 276      *         {@link Object} class.
 277      *
 278      * @see ClassVisitor#visit(int, int, String, String, String, String[])
 279      */
 280     public String getSuperName() {
 281         int n = items[readUnsignedShort(header + 4)];
 282         return n == 0 ? null : readUTF8(n, new char[maxStringLength]);
 283     }
 284 
 285     /**
 286      * Returns the internal names of the class's interfaces (see
 287      * {@link Type#getInternalName() getInternalName}).
 288      *
 289      * @return the array of internal names for all implemented interfaces or
 290      *         <tt>null</tt>.
 291      *
 292      * @see ClassVisitor#visit(int, int, String, String, String, String[])
 293      */
 294     public String[] getInterfaces() {
 295         int index = header + 6;
 296         int n = readUnsignedShort(index);
 297         String[] interfaces = new String[n];
 298         if (n > 0) {
 299             char[] buf = new char[maxStringLength];
 300             for (int i = 0; i < n; ++i) {
 301                 index += 2;
 302                 interfaces[i] = readClass(index, buf);
 303             }
 304         }
 305         return interfaces;
 306     }
 307 
 308     /**
 309      * Copies the constant pool data into the given {@link ClassWriter}. Should
 310      * be called before the {@link #accept(ClassVisitor,int)} method.
 311      *
 312      * @param classWriter the {@link ClassWriter} to copy constant pool into.

 313      */
 314     void copyPool(final ClassWriter classWriter) {
 315         char[] buf = new char[maxStringLength];
 316         int ll = items.length;
 317         Item[] items2 = new Item[ll];
 318         for (int i = 1; i < ll; i++) {
 319             int index = items[i];
 320             int tag = b[index - 1];
 321             Item item = new Item(i);
 322             int nameType;
 323             switch (tag) {
 324                 case ClassWriter.FIELD:
 325                 case ClassWriter.METH:
 326                 case ClassWriter.IMETH:
 327                     nameType = items[readUnsignedShort(index + 2)];
 328                     item.set(tag,
 329                             readClass(index, buf),
 330                             readUTF8(nameType, buf),
 331                             readUTF8(nameType + 2, buf));
 332                     break;
 333 
 334                 case ClassWriter.INT:
 335                     item.set(readInt(index));
 336                     break;
 337 
 338                 case ClassWriter.FLOAT:
 339                     item.set(Float.intBitsToFloat(readInt(index)));
 340                     break;
 341 
 342                 case ClassWriter.NAME_TYPE:
 343                     item.set(tag,
 344                             readUTF8(index, buf),
 345                             readUTF8(index + 2, buf),
 346                             null);
 347                     break;
 348 
 349                 case ClassWriter.LONG:
 350                     item.set(readLong(index));
 351                     ++i;
 352                     break;
 353 
 354                 case ClassWriter.DOUBLE:
 355                     item.set(Double.longBitsToDouble(readLong(index)));
 356                     ++i;
 357                     break;
 358 
 359                 case ClassWriter.UTF8: {
 360                     String s = strings[i];
 361                     if (s == null) {
 362                         index = items[i];
 363                         s = strings[i] = readUTF(index + 2,
 364                                 readUnsignedShort(index),
 365                                 buf);
 366                     }
 367                     item.set(tag, s, null, null);
 368                 }
 369                     break;
 370 
 371                 case ClassWriter.HANDLE: {
 372                     int fieldOrMethodRef = items[readUnsignedShort(index + 1)];
 373                     nameType = items[readUnsignedShort(fieldOrMethodRef + 2)];
 374                     item.set(ClassWriter.HANDLE_BASE + readByte(index),
 375                             readClass(fieldOrMethodRef, buf),
 376                             readUTF8(nameType, buf),
 377                             readUTF8(nameType + 2, buf));
 378 
 379                 }
 380                     break;
 381 
 382 
 383                 case ClassWriter.INDY:
 384                     if (classWriter.bootstrapMethods == null) {
 385                         copyBootstrapMethods(classWriter, items2, buf);
 386                     }
 387                     nameType = items[readUnsignedShort(index + 2)];
 388                     item.set(readUTF8(nameType, buf),
 389                             readUTF8(nameType + 2, buf),
 390                             readUnsignedShort(index));
 391                     break;
 392 
 393 
 394                 // case ClassWriter.STR:
 395                 // case ClassWriter.CLASS:
 396                 // case ClassWriter.MTYPE
 397                 default:
 398                     item.set(tag, readUTF8(index, buf), null, null);
 399                     break;
 400             }
 401 
 402             int index2 = item.hashCode % items2.length;
 403             item.next = items2[index2];
 404             items2[index2] = item;
 405         }
 406 
 407         int off = items[1] - 1;
 408         classWriter.pool.putByteArray(b, off, header - off);
 409         classWriter.items = items2;
 410         classWriter.threshold = (int) (0.75d * ll);
 411         classWriter.index = ll;
 412     }
 413 
 414     private void copyBootstrapMethods(ClassWriter classWriter, Item[] items2, char[] buf) {
 415         int i, j, k, u, v;
 416 
 417         // skip class header
 418         v = header;
 419         v += 8 + (readUnsignedShort(v + 6) << 1);
 420 
 421         // skips fields and methods
 422         i = readUnsignedShort(v);
 423         v += 2;
 424         for (; i > 0; --i) {
 425             j = readUnsignedShort(v + 6);
 426             v += 8;
 427             for (; j > 0; --j) {
 428                 v += 6 + readInt(v + 2);


 429             }

 430         }
 431         i = readUnsignedShort(v);
 432         v += 2;
 433         for (; i > 0; --i) {
 434             j = readUnsignedShort(v + 6);
 435             v += 8;
 436             for (; j > 0; --j) {
 437                 v += 6 + readInt(v + 2);
 438             }
 439         }
 440 
 441         // read class attributes
 442         i = readUnsignedShort(v);



 443         v += 2;
 444         for (; i > 0; --i) {
 445             String attrName = readUTF8(v, buf);
 446             int size = readInt(v + 2);
 447             if ("BootstrapMethods".equals(attrName)) {
 448                 int boostrapMethodCount = readUnsignedShort(v + 6);
 449                 int x = v + 8;
 450                 for (j = 0; j < boostrapMethodCount; j++) {
 451                     int hashCode = readConst(readUnsignedShort(x), buf).hashCode();
 452                     k = readUnsignedShort(x + 2);
 453                     u = x + 4;
 454                     for(; k > 0; --k) {
 455                         hashCode ^= readConst(readUnsignedShort(u), buf).hashCode();
 456                         u += 2;
 457                     }

 458                     Item item = new Item(j);
 459                     item.set(x - v - 8, hashCode & 0x7FFFFFFF);
 460 
 461                     int index2 = item.hashCode % items2.length;
 462                     item.next = items2[index2];
 463                     items2[index2] = item;
 464 
 465                     x = u;
 466                 }
 467 


 468                 classWriter.bootstrapMethodsCount = boostrapMethodCount;
 469                 ByteVector bootstrapMethods = new ByteVector(size + 62);
 470                 bootstrapMethods.putByteArray(b, v + 8, size - 2);
 471                 classWriter.bootstrapMethods = bootstrapMethods;
 472                 return;
 473             }
 474             v += 6 + size;
 475         }
 476 
 477         // we are in trouble !!!
 478     }
 479 
 480     /**
 481      * Constructs a new {@link ClassReader} object.
 482      *
 483      * @param is an input stream from which to read the class.
 484      * @throws IOException if a problem occurs during reading.


 485      */
 486     public ClassReader(final InputStream is) throws IOException {
 487         this(readClass(is, false));
 488     }
 489 
 490     /**
 491      * Constructs a new {@link ClassReader} object.
 492      *
 493      * @param name the binary qualified name of the class to be read.
 494      * @throws IOException if an exception occurs during reading.


 495      */
 496     public ClassReader(final String name) throws IOException {
 497         this(readClass(ClassLoader.getSystemResourceAsStream(name.replace('.', '/')

 498                 + ".class"), true));
 499     }
 500 
 501     /**
 502      * Reads the bytecode of a class.
 503      *
 504      * @param is an input stream from which to read the class.
 505      * @param close true to close the input stream after reading.


 506      * @return the bytecode read from the given input stream.
 507      * @throws IOException if a problem occurs during reading.

 508      */
 509     private static byte[] readClass(final InputStream is, boolean close)
 510             throws IOException
 511     {
 512         if (is == null) {
 513             throw new IOException("Class not found");
 514         }
 515         try {
 516             byte[] b = new byte[is.available()];
 517             int len = 0;
 518             while (true) {
 519                 int n = is.read(b, len, b.length - len);
 520                 if (n == -1) {
 521                     if (len < b.length) {
 522                         byte[] c = new byte[len];
 523                         System.arraycopy(b, 0, c, 0, len);
 524                         b = c;
 525                     }
 526                     return b;
 527                 }
 528                 len += n;
 529                 if (len == b.length) {
 530                     int last = is.read();
 531                     if (last < 0) {
 532                         return b;
 533                     }
 534                     byte[] c = new byte[b.length + 1000];
 535                     System.arraycopy(b, 0, c, 0, len);
 536                     c[len++] = (byte) last;
 537                     b = c;
 538                 }
 539             }
 540         } finally {
 541             if (close) {
 542                 is.close();
 543             }
 544         }
 545     }
 546 
 547     // ------------------------------------------------------------------------
 548     // Public methods
 549     // ------------------------------------------------------------------------
 550 
 551     /**
 552      * Makes the given visitor visit the Java class of this {@link ClassReader}.
 553      * This class is the one specified in the constructor (see
 554      * {@link #ClassReader(byte[]) ClassReader}).
 555      *
 556      * @param classVisitor the visitor that must visit this class.
 557      * @param flags option flags that can be used to modify the default behavior
 558      *        of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES},
 559      *        {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.


 560      */
 561     public void accept(final ClassVisitor classVisitor, final int flags) {
 562         accept(classVisitor, new Attribute[0], flags);
 563     }
 564 
 565     /**
 566      * Makes the given visitor visit the Java class of this {@link ClassReader}.
 567      * This class is the one specified in the constructor (see
 568      * {@link #ClassReader(byte[]) ClassReader}).
 569      *
 570      * @param classVisitor the visitor that must visit this class.
 571      * @param attrs prototypes of the attributes that must be parsed during the
 572      *        visit of the class. Any attribute whose type is not equal to the
 573      *        type of one the prototypes will not be parsed: its byte array
 574      *        value will be passed unchanged to the ClassWriter. <i>This may
 575      *        corrupt it if this value contains references to the constant pool,
 576      *        or has syntactic or semantic links with a class element that has
 577      *        been transformed by a class adapter between the reader and the
 578      *        writer</i>.
 579      * @param flags option flags that can be used to modify the default behavior
 580      *        of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES},
 581      *        {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.



 582      */
 583     public void accept(
 584         final ClassVisitor classVisitor,
 585         final Attribute[] attrs,
 586         final int flags)
 587     {
 588         byte[] b = this.b; // the bytecode array
 589         char[] c = new char[maxStringLength]; // buffer used to read strings
 590         int i, j, k; // loop variables
 591         int u, v, w; // indexes in b
 592         Attribute attr;
 593 
 594         int access;
 595         String name;
 596         String desc;
 597         String attrName;
 598         String signature;
 599         int anns = 0;
 600         int ianns = 0;
 601         Attribute cattrs = null;
 602 
 603         // visits the header
 604         u = header;
 605         access = readUnsignedShort(u);
 606         name = readClass(u + 2, c);
 607         v = items[readUnsignedShort(u + 4)];
 608         String superClassName = v == 0 ? null : readUTF8(v, c);
 609         String[] implementedItfs = new String[readUnsignedShort(u + 6)];
 610         w = 0;
 611         u += 8;
 612         for (i = 0; i < implementedItfs.length; ++i) {
 613             implementedItfs[i] = readClass(u, c);
 614             u += 2;
 615         }
 616 
 617         boolean skipCode = (flags & SKIP_CODE) != 0;
 618         boolean skipDebug = (flags & SKIP_DEBUG) != 0;
 619         boolean unzip = (flags & EXPAND_FRAMES) != 0;
 620 
 621         // skips fields and methods
 622         v = u;
 623         i = readUnsignedShort(v);
 624         v += 2;
 625         for (; i > 0; --i) {
 626             j = readUnsignedShort(v + 6);
 627             v += 8;
 628             for (; j > 0; --j) {
 629                 v += 6 + readInt(v + 2);
 630             }
 631         }
 632         i = readUnsignedShort(v);
 633         v += 2;
 634         for (; i > 0; --i) {
 635             j = readUnsignedShort(v + 6);
 636             v += 8;
 637             for (; j > 0; --j) {
 638                 v += 6 + readInt(v + 2);
 639             }
 640         }
 641         // reads the class's attributes
 642         signature = null;
 643         String sourceFile = null;
 644         String sourceDebug = null;
 645         String enclosingOwner = null;
 646         String enclosingName = null;
 647         String enclosingDesc = null;
 648         int[] bootstrapMethods = null;  // start indexed of the bsms





 649 
 650         i = readUnsignedShort(v);
 651         v += 2;
 652         for (; i > 0; --i) {
 653             attrName = readUTF8(v, c);
 654             // tests are sorted in decreasing frequency order
 655             // (based on frequencies observed on typical classes)
 656             if ("SourceFile".equals(attrName)) {
 657                 sourceFile = readUTF8(v + 6, c);
 658             } else if ("InnerClasses".equals(attrName)) {
 659                 w = v + 6;
 660             } else if ("EnclosingMethod".equals(attrName)) {
 661                 enclosingOwner = readClass(v + 6, c);
 662                 int item = readUnsignedShort(v + 8);
 663                 if (item != 0) {
 664                     enclosingName = readUTF8(items[item], c);
 665                     enclosingDesc = readUTF8(items[item] + 2, c);
 666                 }
 667             } else if (SIGNATURES && "Signature".equals(attrName)) {
 668                 signature = readUTF8(v + 6, c);
 669             } else if (ANNOTATIONS && "RuntimeVisibleAnnotations".equals(attrName)) {
 670                 anns = v + 6;




 671             } else if ("Deprecated".equals(attrName)) {
 672                 access |= Opcodes.ACC_DEPRECATED;
 673             } else if ("Synthetic".equals(attrName)) {
 674                 access |= Opcodes.ACC_SYNTHETIC | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;

 675             } else if ("SourceDebugExtension".equals(attrName)) {
 676                 int len = readInt(v + 2);
 677                 sourceDebug = readUTF(v + 6, len, new char[len]);
 678             } else if (ANNOTATIONS && "RuntimeInvisibleAnnotations".equals(attrName)) {
 679                 ianns = v + 6;




 680             } else if ("BootstrapMethods".equals(attrName)) {
 681                 int boostrapMethodCount = readUnsignedShort(v + 6);
 682                 bootstrapMethods = new int[boostrapMethodCount];
 683                 int x = v + 8;
 684                 for (j = 0; j < boostrapMethodCount; j++) {
 685                     bootstrapMethods[j] = x;
 686                     x += 2 + readUnsignedShort(x + 2) << 1;
 687                 }

 688             } else {
 689                 attr = readAttribute(attrs,
 690                         attrName,
 691                         v + 6,
 692                         readInt(v + 2),
 693                         c,
 694                         -1,
 695                         null);
 696                 if (attr != null) {
 697                     attr.next = cattrs;
 698                     cattrs = attr;
 699                 }
 700             }
 701             v += 6 + readInt(v + 2);
 702         }
 703         // calls the visit method
 704         classVisitor.visit(readInt(4),
 705                 access,
 706                 name,
 707                 signature,
 708                 superClassName,
 709                 implementedItfs);
 710 
 711         // calls the visitSource method
 712         if (!skipDebug && (sourceFile != null || sourceDebug != null)) {





 713             classVisitor.visitSource(sourceFile, sourceDebug);
 714         }
 715 
 716         // calls the visitOuterClass method
 717         if (enclosingOwner != null) {
 718             classVisitor.visitOuterClass(enclosingOwner,
 719                     enclosingName,
 720                     enclosingDesc);
 721         }
 722 
 723         // visits the class annotations
 724         if (ANNOTATIONS) {
 725             for (i = 1; i >= 0; --i) {
 726                 v = i == 0 ? ianns : anns;
 727                 if (v != 0) {
 728                     j = readUnsignedShort(v);
 729                     v += 2;
 730                     for (; j > 0; --j) {
 731                         v = readAnnotationValues(v + 2,
 732                                 c,
 733                                 true,
 734                                 classVisitor.visitAnnotation(readUTF8(v, c), i != 0));
 735                     }
 736                 }




 737             }
 738         }
















 739 
 740         // visits the class attributes
 741         while (cattrs != null) {
 742             attr = cattrs.next;
 743             cattrs.next = null;
 744             classVisitor.visitAttribute(cattrs);
 745             cattrs = attr;
 746         }
 747 
 748         // calls the visitInnerClass method
 749         if (w != 0) {
 750             i = readUnsignedShort(w);
 751             w += 2;
 752             for (; i > 0; --i) {
 753                 classVisitor.visitInnerClass(readUnsignedShort(w) == 0
 754                         ? null
 755                         : readClass(w, c), readUnsignedShort(w + 2) == 0
 756                         ? null
 757                         : readClass(w + 2, c), readUnsignedShort(w + 4) == 0
 758                         ? null
 759                         : readUTF8(w + 4, c), readUnsignedShort(w + 6));
 760                 w += 8;
 761             }
 762         }
 763 
 764         // visits the fields
 765         i = readUnsignedShort(u);



 766         u += 2;
 767         for (; i > 0; --i) {
 768             access = readUnsignedShort(u);
 769             name = readUTF8(u + 2, c);
 770             desc = readUTF8(u + 4, c);
 771             // visits the field's attributes and looks for a ConstantValue
 772             // attribute
 773             int fieldValueItem = 0;
 774             signature = null;
 775             anns = 0;
 776             ianns = 0;
 777             cattrs = null;
 778 
 779             j = readUnsignedShort(u + 6);
 780             u += 8;
 781             for (; j > 0; --j) {
 782                 attrName = readUTF8(u, c);































 783                 // tests are sorted in decreasing frequency order
 784                 // (based on frequencies observed on typical classes)
 785                 if ("ConstantValue".equals(attrName)) {
 786                     fieldValueItem = readUnsignedShort(u + 6);

 787                 } else if (SIGNATURES && "Signature".equals(attrName)) {
 788                     signature = readUTF8(u + 6, c);
 789                 } else if ("Deprecated".equals(attrName)) {
 790                     access |= Opcodes.ACC_DEPRECATED;
 791                 } else if ("Synthetic".equals(attrName)) {
 792                     access |= Opcodes.ACC_SYNTHETIC  | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
 793                 } else if (ANNOTATIONS && "RuntimeVisibleAnnotations".equals(attrName)) {
 794                     anns = u + 6;
 795                 } else if (ANNOTATIONS && "RuntimeInvisibleAnnotations".equals(attrName)) {
 796                     ianns = u + 6;









 797                 } else {
 798                     attr = readAttribute(attrs,
 799                             attrName,
 800                             u + 6,
 801                             readInt(u + 2),
 802                             c,
 803                             -1,
 804                             null);
 805                     if (attr != null) {
 806                         attr.next = cattrs;
 807                         cattrs = attr;
 808                     }
 809                 }
 810                 u += 6 + readInt(u + 2);
 811             }
 812             // visits the field
 813             FieldVisitor fv = classVisitor.visitField(access,
 814                     name,
 815                     desc,
 816                     signature,
 817                     fieldValueItem == 0 ? null : readConst(fieldValueItem, c));
 818             // visits the field annotations and attributes
 819             if (fv != null) {
 820                 if (ANNOTATIONS) {
 821                     for (j = 1; j >= 0; --j) {
 822                         v = j == 0 ? ianns : anns;
 823                         if (v != 0) {
 824                             k = readUnsignedShort(v);
 825                             v += 2;
 826                             for (; k > 0; --k) {
 827                                 v = readAnnotationValues(v + 2,
 828                                         c,
 829                                         true,
 830                                         fv.visitAnnotation(readUTF8(v, c), j != 0));
 831                             }






 832                         }
 833                     }




 834                 }
 835                 while (cattrs != null) {
 836                     attr = cattrs.next;
 837                     cattrs.next = null;
 838                     fv.visitAttribute(cattrs);
 839                     cattrs = attr;
 840                 }
 841                 fv.visitEnd();





 842             }
 843         }








 844 
 845         // visits the methods
 846         i = readUnsignedShort(u);
 847         u += 2;
 848         for (; i > 0; --i) {
 849             int u0 = u + 6;
 850             access = readUnsignedShort(u);
 851             name = readUTF8(u + 2, c);
 852             desc = readUTF8(u + 4, c);
 853             signature = null;
 854             anns = 0;
 855             ianns = 0;

































 856             int dann = 0;
 857             int mpanns = 0;
 858             int impanns = 0;
 859             cattrs = null;
 860             v = 0;
 861             w = 0;
 862 
 863             // looks for Code and Exceptions attributes
 864             j = readUnsignedShort(u + 6);
 865             u += 8;
 866             for (; j > 0; --j) {
 867                 attrName = readUTF8(u, c);
 868                 int attrSize = readInt(u + 2);
 869                 u += 6;
 870                 // tests are sorted in decreasing frequency order
 871                 // (based on frequencies observed on typical classes)
 872                 if ("Code".equals(attrName)) {
 873                     if (!skipCode) {
 874                         v = u;
 875                     }
 876                 } else if ("Exceptions".equals(attrName)) {
 877                     w = u;





 878                 } else if (SIGNATURES && "Signature".equals(attrName)) {
 879                     signature = readUTF8(u, c);
 880                 } else if ("Deprecated".equals(attrName)) {
 881                     access |= Opcodes.ACC_DEPRECATED;
 882                 } else if (ANNOTATIONS && "RuntimeVisibleAnnotations".equals(attrName)) {
 883                     anns = u;




 884                 } else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) {
 885                     dann = u;
 886                 } else if ("Synthetic".equals(attrName)) {
 887                     access |= Opcodes.ACC_SYNTHETIC | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
 888                 } else if (ANNOTATIONS && "RuntimeInvisibleAnnotations".equals(attrName)) {
 889                     ianns = u;
 890                 } else if (ANNOTATIONS && "RuntimeVisibleParameterAnnotations".equals(attrName))
 891                 {
 892                     mpanns = u;
 893                 } else if (ANNOTATIONS && "RuntimeInvisibleParameterAnnotations".equals(attrName))
 894                 {
 895                     impanns = u;







 896                 } else {
 897                     attr = readAttribute(attrs,
 898                             attrName,
 899                             u,
 900                             attrSize,
 901                             c,
 902                             -1,
 903                             null);
 904                     if (attr != null) {
 905                         attr.next = cattrs;
 906                         cattrs = attr;
 907                     }
 908                 }
 909                 u += attrSize;
 910             }
 911             // reads declared exceptions
 912             String[] exceptions;
 913             if (w == 0) {
 914                 exceptions = null;
 915             } else {
 916                 exceptions = new String[readUnsignedShort(w)];
 917                 w += 2;
 918                 for (j = 0; j < exceptions.length; ++j) {
 919                     exceptions[j] = readClass(w, c);
 920                     w += 2;
 921                 }
 922             }
 923 
 924             // visits the method's code, if any
 925             MethodVisitor mv = classVisitor.visitMethod(access,
 926                     name,
 927                     desc,
 928                     signature,
 929                     exceptions);
 930 
 931             if (mv != null) {
 932                 /*
 933                  * if the returned MethodVisitor is in fact a MethodWriter, it
 934                  * means there is no method adapter between the reader and the
 935                  * writer. If, in addition, the writer's constant pool was
 936                  * copied from this reader (mw.cw.cr == this), and the signature
 937                  * and exceptions of the method have not been changed, then it
 938                  * is possible to skip all visit events and just copy the
 939                  * original code of the method to the writer (the access, name
 940                  * and descriptor can have been changed, this is not important
 941                  * since they are not copied as is from the reader).
 942                  */
 943                 if (WRITER && mv instanceof MethodWriter) {
 944                     MethodWriter mw = (MethodWriter) mv;
 945                     if (mw.cw.cr == this) {
 946                         if (signature == mw.signature) {
 947                             boolean sameExceptions = false;
 948                             if (exceptions == null) {
 949                                 sameExceptions = mw.exceptionCount == 0;
 950                             } else {
 951                                 if (exceptions.length == mw.exceptionCount) {
 952                                     sameExceptions = true;
 953                                     for (j = exceptions.length - 1; j >= 0; --j)
 954                                     {
 955                                         w -= 2;
 956                                         if (mw.exceptions[j] != readUnsignedShort(w))
 957                                         {
 958                                             sameExceptions = false;
 959                                             break;
 960                                         }
 961                                     }
 962                                 }
 963                             }
 964                             if (sameExceptions) {
 965                                 /*
 966                                  * we do not copy directly the code into
 967                                  * MethodWriter to save a byte array copy
 968                                  * operation. The real copy will be done in
 969                                  * ClassWriter.toByteArray().
 970                                  */
 971                                 mw.classReaderOffset = u0;
 972                                 mw.classReaderLength = u - u0;
 973                                 continue;
 974                             }
 975                         }
 976                     }





 977                 }

 978 

 979                 if (ANNOTATIONS && dann != 0) {
 980                     AnnotationVisitor dv = mv.visitAnnotationDefault();
 981                     readAnnotationValue(dann, c, null, dv);
 982                     if (dv != null) {
 983                         dv.visitEnd();
 984                     }
 985                 }
 986                 if (ANNOTATIONS) {
 987                     for (j = 1; j >= 0; --j) {
 988                         w = j == 0 ? ianns : anns;
 989                         if (w != 0) {
 990                             k = readUnsignedShort(w);
 991                             w += 2;
 992                             for (; k > 0; --k) {
 993                                 w = readAnnotationValues(w + 2,
 994                                         c,
 995                                         true,
 996                                         mv.visitAnnotation(readUTF8(w, c), j != 0));
 997                             }
 998                         }




 999                     }
1000                 }
















1001                 if (ANNOTATIONS && mpanns != 0) {
1002                     readParameterAnnotations(mpanns, desc, c, true, mv);
1003                 }
1004                 if (ANNOTATIONS && impanns != 0) {
1005                     readParameterAnnotations(impanns, desc, c, false, mv);
1006                 }
1007                 while (cattrs != null) {
1008                     attr = cattrs.next;
1009                     cattrs.next = null;
1010                     mv.visitAttribute(cattrs);
1011                     cattrs = attr;


1012                 }





1013             }
1014 
1015             if (mv != null && v != 0) {
1016                 int maxStack = readUnsignedShort(v);
1017                 int maxLocals = readUnsignedShort(v + 2);
1018                 int codeLength = readInt(v + 4);
1019                 v += 8;
1020 
1021                 int codeStart = v;
1022                 int codeEnd = v + codeLength;
1023 
1024                 mv.visitCode();

















1025 
1026                 // 1st phase: finds the labels
1027                 int label;
1028                 Label[] labels = new Label[codeLength + 2];

1029                 readLabel(codeLength + 1, labels);
1030                 while (v < codeEnd) {
1031                     w = v - codeStart;
1032                     int opcode = b[v] & 0xFF;
1033                     switch (ClassWriter.TYPE[opcode]) {
1034                         case ClassWriter.NOARG_INSN:
1035                         case ClassWriter.IMPLVAR_INSN:
1036                             v += 1;
1037                             break;
1038                         case ClassWriter.LABEL_INSN:
1039                             readLabel(w + readShort(v + 1), labels);
1040                             v += 3;
1041                             break;
1042                         case ClassWriter.LABELW_INSN:
1043                             readLabel(w + readInt(v + 1), labels);
1044                             v += 5;
1045                             break;
1046                         case ClassWriter.WIDE_INSN:
1047                             opcode = b[v + 1] & 0xFF;
1048                             if (opcode == Opcodes.IINC) {
1049                                 v += 6;
1050                             } else {
1051                                 v += 4;
1052                             }
1053                             break;
1054                         case ClassWriter.TABL_INSN:
1055                             // skips 0 to 3 padding bytes*
1056                             v = v + 4 - (w & 3);
1057                             // reads instruction
1058                             readLabel(w + readInt(v), labels);
1059                             j = readInt(v + 8) - readInt(v + 4) + 1;
1060                             v += 12;
1061                             for (; j > 0; --j) {
1062                                 readLabel(w + readInt(v), labels);
1063                                 v += 4;
1064                             }

1065                             break;
1066                         case ClassWriter.LOOK_INSN:
1067                             // skips 0 to 3 padding bytes*
1068                             v = v + 4 - (w & 3);
1069                             // reads instruction
1070                             readLabel(w + readInt(v), labels);
1071                             j = readInt(v + 4);
1072                             v += 8;
1073                             for (; j > 0; --j) {
1074                                 readLabel(w + readInt(v + 4), labels);
1075                                 v += 8;
1076                             }

1077                             break;
1078                         case ClassWriter.VAR_INSN:
1079                         case ClassWriter.SBYTE_INSN:
1080                         case ClassWriter.LDC_INSN:
1081                             v += 2;
1082                             break;
1083                         case ClassWriter.SHORT_INSN:
1084                         case ClassWriter.LDCW_INSN:
1085                         case ClassWriter.FIELDORMETH_INSN:
1086                         case ClassWriter.TYPE_INSN:
1087                         case ClassWriter.IINC_INSN:
1088                             v += 3;
1089                             break;
1090                         case ClassWriter.ITFMETH_INSN:
1091                         case ClassWriter.INDYMETH_INSN:
1092                             v += 5;
1093                             break;
1094                         // case MANA_INSN:
1095                         default:
1096                             v += 4;
1097                             break;
1098                     }
1099                 }
1100                 // parses the try catch entries
1101                 j = readUnsignedShort(v);
1102                 v += 2;
1103                 for (; j > 0; --j) {
1104                     Label start = readLabel(readUnsignedShort(v), labels);
1105                     Label end = readLabel(readUnsignedShort(v + 2), labels);
1106                     Label handler = readLabel(readUnsignedShort(v + 4), labels);
1107                     int type = readUnsignedShort(v + 6);
1108                     if (type == 0) {
1109                         mv.visitTryCatchBlock(start, end, handler, null);
1110                     } else {
1111                         mv.visitTryCatchBlock(start,
1112                                 end,
1113                                 handler,
1114                                 readUTF8(items[type], c));
1115                     }
1116                     v += 8;
1117                 }
1118                 // parses the local variable, line number tables, and code
1119                 // attributes





1120                 int varTable = 0;
1121                 int varTypeTable = 0;


1122                 int stackMap = 0;
1123                 int stackMapSize = 0;
1124                 int frameCount = 0;
1125                 int frameMode = 0;
1126                 int frameOffset = 0;
1127                 int frameLocalCount = 0;
1128                 int frameLocalDiff = 0;
1129                 int frameStackCount = 0;
1130                 Object[] frameLocal = null;
1131                 Object[] frameStack = null;
1132                 boolean zip = true;
1133                 cattrs = null;
1134                 j = readUnsignedShort(v);
1135                 v += 2;
1136                 for (; j > 0; --j) {
1137                     attrName = readUTF8(v, c);
1138                     if ("LocalVariableTable".equals(attrName)) {
1139                         if (!skipDebug) {
1140                             varTable = v + 6;
1141                             k = readUnsignedShort(v + 6);
1142                             w = v + 8;
1143                             for (; k > 0; --k) {
1144                                 label = readUnsignedShort(w);
1145                                 if (labels[label] == null) {
1146                                     readLabel(label, labels).status |= Label.DEBUG;
1147                                 }
1148                                 label += readUnsignedShort(w + 2);
1149                                 if (labels[label] == null) {
1150                                     readLabel(label, labels).status |= Label.DEBUG;
1151                                 }
1152                                 w += 10;
1153                             }
1154                         }
1155                     } else if ("LocalVariableTypeTable".equals(attrName)) {
1156                         varTypeTable = v + 6;
1157                     } else if ("LineNumberTable".equals(attrName)) {
1158                         if (!skipDebug) {
1159                             k = readUnsignedShort(v + 6);
1160                             w = v + 8;
1161                             for (; k > 0; --k) {
1162                                 label = readUnsignedShort(w);
1163                                 if (labels[label] == null) {
1164                                     readLabel(label, labels).status |= Label.DEBUG;
1165                                 }
1166                                 labels[label].line = readUnsignedShort(w + 2);
1167                                 w += 4;
1168                             }
1169                         }










1170                     } else if (FRAMES && "StackMapTable".equals(attrName)) {
1171                         if ((flags & SKIP_FRAMES) == 0) {
1172                             stackMap = v + 8;
1173                             stackMapSize = readInt(v + 2);
1174                             frameCount = readUnsignedShort(v + 6);
1175                         }
1176                         /*
1177                          * here we do not extract the labels corresponding to
1178                          * the attribute content. This would require a full
1179                          * parsing of the attribute, which would need to be
1180                          * repeated in the second phase (see below). Instead the
1181                          * content of the attribute is read one frame at a time
1182                          * (i.e. after a frame has been visited, the next frame
1183                          * is read), and the labels it contains are also
1184                          * extracted one frame at a time. Thanks to the ordering
1185                          * of frames, having only a "one frame lookahead" is not
1186                          * a problem, i.e. it is not possible to see an offset
1187                          * smaller than the offset of the current insn and for
1188                          * which no Label exist.
1189                          */
1190                         /*
1191                          * This is not true for UNINITIALIZED type offsets. We
1192                          * solve this by parsing the stack map table without a
1193                          * full decoding (see below).
1194                          */
1195                     } else if (FRAMES && "StackMap".equals(attrName)) {
1196                         if ((flags & SKIP_FRAMES) == 0) {
1197                             stackMap = v + 8;
1198                             stackMapSize = readInt(v + 2);
1199                             frameCount = readUnsignedShort(v + 6);
1200                             zip = false;



1201                         }
1202                         /*
1203                          * IMPORTANT! here we assume that the frames are
1204                          * ordered, as in the StackMapTable attribute, although
1205                          * this is not guaranteed by the attribute format.
1206                          */
1207                     } else {
1208                         for (k = 0; k < attrs.length; ++k) {
1209                             if (attrs[k].type.equals(attrName)) {
1210                                 attr = attrs[k].read(this,
1211                                         v + 6,
1212                                         readInt(v + 2),
1213                                         c,
1214                                         codeStart - 8,
1215                                         labels);
1216                                 if (attr != null) {
1217                                     attr.next = cattrs;
1218                                     cattrs = attr;
1219                                 }
1220                             }
1221                         }
1222                     }
1223                     v += 6 + readInt(v + 2);
1224                 }

1225 
1226                 // 2nd phase: visits each instruction
1227                 if (FRAMES && stackMap != 0) {
1228                     // creates the very first (implicit) frame from the method
1229                     // descriptor
1230                     frameLocal = new Object[maxLocals];
1231                     frameStack = new Object[maxStack];









1232                     if (unzip) {
1233                         int local = 0;
1234                         if ((access & Opcodes.ACC_STATIC) == 0) {
1235                             if ("<init>".equals(name)) {
1236                                 frameLocal[local++] = Opcodes.UNINITIALIZED_THIS;
1237                             } else {
1238                                 frameLocal[local++] = readClass(header + 2, c);
1239                             }
1240                         }
1241                         j = 1;
1242                         loop: while (true) {
1243                             k = j;
1244                             switch (desc.charAt(j++)) {
1245                                 case 'Z':
1246                                 case 'C':
1247                                 case 'B':
1248                                 case 'S':
1249                                 case 'I':
1250                                     frameLocal[local++] = Opcodes.INTEGER;
1251                                     break;
1252                                 case 'F':
1253                                     frameLocal[local++] = Opcodes.FLOAT;
1254                                     break;
1255                                 case 'J':
1256                                     frameLocal[local++] = Opcodes.LONG;
1257                                     break;
1258                                 case 'D':
1259                                     frameLocal[local++] = Opcodes.DOUBLE;
1260                                     break;
1261                                 case '[':
1262                                     while (desc.charAt(j) == '[') {
1263                                         ++j;
1264                                     }
1265                                     if (desc.charAt(j) == 'L') {
1266                                         ++j;
1267                                         while (desc.charAt(j) != ';') {
1268                                             ++j;
1269                                         }
1270                                     }
1271                                     frameLocal[local++] = desc.substring(k, ++j);
1272                                     break;
1273                                 case 'L':
1274                                     while (desc.charAt(j) != ';') {
1275                                         ++j;
1276                                     }
1277                                     frameLocal[local++] = desc.substring(k + 1,
1278                                             j++);
1279                                     break;
1280                                 default:
1281                                     break loop;
1282                             }
1283                         }
1284                         frameLocalCount = local;
1285                     }
1286                     /*
1287                      * for the first explicit frame the offset is not
1288                      * offset_delta + 1 but only offset_delta; setting the
1289                      * implicit frame offset to -1 allow the use of the
1290                      * "offset_delta + 1" rule in all cases





1291                      */
1292                     frameOffset = -1;
1293                     /*
1294                      * Finds labels for UNINITIALIZED frame types. Instead of
1295                      * decoding each element of the stack map table, we look
1296                      * for 3 consecutive bytes that "look like" an UNINITIALIZED
1297                      * type (tag 8, offset within code bounds, NEW instruction
1298                      * at this offset). We may find false positives (i.e. not
1299                      * real UNINITIALIZED types), but this should be rare, and
1300                      * the only consequence will be the creation of an unneeded
1301                      * label. This is better than creating a label for each NEW
1302                      * instruction, and faster than fully decoding the whole
1303                      * stack map table.
1304                      */
1305                     for (j = stackMap; j < stackMap + stackMapSize - 2; ++j) {
1306                         if (b[j] == 8) { // UNINITIALIZED FRAME TYPE
1307                             k = readUnsignedShort(j + 1);
1308                             if (k >= 0 && k < codeLength) { // potential offset
1309                                 if ((b[codeStart + k] & 0xFF) == Opcodes.NEW) { // NEW at this offset
1310                                     readLabel(k, labels);
1311                                 }
1312                             }
1313                         }
1314                     }
1315                 }
1316                 v = codeStart;
1317                 Label l;
1318                 while (v < codeEnd) {
1319                     w = v - codeStart;
1320 
1321                     l = labels[w];






1322                     if (l != null) {
1323                         mv.visitLabel(l);
1324                         if (!skipDebug && l.line > 0) {
1325                             mv.visitLineNumber(l.line, l);
1326                         }
1327                     }
1328 
1329                     while (FRAMES && frameLocal != null
1330                             && (frameOffset == w || frameOffset == -1))
1331                     {
1332                         // if there is a frame for this offset,
1333                         // makes the visitor visit it,
1334                         // and reads the next frame if there is one.
1335                         if (!zip || unzip) {
1336                             mv.visitFrame(Opcodes.F_NEW,
1337                                     frameLocalCount,
1338                                     frameLocal,
1339                                     frameStackCount,
1340                                     frameStack);
1341                         } else if (frameOffset != -1) {
1342                             mv.visitFrame(frameMode,
1343                                     frameLocalDiff,
1344                                     frameLocal,
1345                                     frameStackCount,
1346                                     frameStack);
1347                         }
1348 
1349                         if (frameCount > 0) {
1350                             int tag, delta, n;
1351                             if (zip) {
1352                                 tag = b[stackMap++] & 0xFF;
1353                             } else {
1354                                 tag = MethodWriter.FULL_FRAME;
1355                                 frameOffset = -1;
1356                             }
1357                             frameLocalDiff = 0;
1358                             if (tag < MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME)
1359                             {
1360                                 delta = tag;
1361                                 frameMode = Opcodes.F_SAME;
1362                                 frameStackCount = 0;
1363                             } else if (tag < MethodWriter.RESERVED) {
1364                                 delta = tag
1365                                         - MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME;
1366                                 stackMap = readFrameType(frameStack,
1367                                         0,
1368                                         stackMap,
1369                                         c,
1370                                         labels);
1371                                 frameMode = Opcodes.F_SAME1;
1372                                 frameStackCount = 1;
1373                             } else {
1374                                 delta = readUnsignedShort(stackMap);
1375                                 stackMap += 2;
1376                                 if (tag == MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
1377                                 {
1378                                     stackMap = readFrameType(frameStack,
1379                                             0,
1380                                             stackMap,
1381                                             c,
1382                                             labels);
1383                                     frameMode = Opcodes.F_SAME1;
1384                                     frameStackCount = 1;
1385                                 } else if (tag >= MethodWriter.CHOP_FRAME
1386                                         && tag < MethodWriter.SAME_FRAME_EXTENDED)
1387                                 {
1388                                     frameMode = Opcodes.F_CHOP;
1389                                     frameLocalDiff = MethodWriter.SAME_FRAME_EXTENDED
1390                                             - tag;
1391                                     frameLocalCount -= frameLocalDiff;
1392                                     frameStackCount = 0;
1393                                 } else if (tag == MethodWriter.SAME_FRAME_EXTENDED)
1394                                 {
1395                                     frameMode = Opcodes.F_SAME;
1396                                     frameStackCount = 0;
1397                                 } else if (tag < MethodWriter.FULL_FRAME) {
1398                                     j = unzip ? frameLocalCount : 0;
1399                                     for (k = tag
1400                                             - MethodWriter.SAME_FRAME_EXTENDED; k > 0; k--)
1401                                     {
1402                                         stackMap = readFrameType(frameLocal,
1403                                                 j++,
1404                                                 stackMap,
1405                                                 c,
1406                                                 labels);
1407                                     }
1408                                     frameMode = Opcodes.F_APPEND;
1409                                     frameLocalDiff = tag
1410                                             - MethodWriter.SAME_FRAME_EXTENDED;
1411                                     frameLocalCount += frameLocalDiff;
1412                                     frameStackCount = 0;
1413                                 } else { // if (tag == FULL_FRAME) {
1414                                     frameMode = Opcodes.F_FULL;
1415                                     n = frameLocalDiff = frameLocalCount = readUnsignedShort(stackMap);
1416                                     stackMap += 2;
1417                                     for (j = 0; n > 0; n--) {
1418                                         stackMap = readFrameType(frameLocal,
1419                                                 j++,
1420                                                 stackMap,
1421                                                 c,
1422                                                 labels);
1423                                     }
1424                                     n = frameStackCount = readUnsignedShort(stackMap);
1425                                     stackMap += 2;
1426                                     for (j = 0; n > 0; n--) {
1427                                         stackMap = readFrameType(frameStack,
1428                                                 j++,
1429                                                 stackMap,
1430                                                 c,
1431                                                 labels);
1432                                     }
1433                                 }
1434                             }
1435                             frameOffset += delta + 1;
1436                             readLabel(frameOffset, labels);
1437 
1438                             --frameCount;
1439                         } else {
1440                             frameLocal = null;
1441                         }
1442                     }
1443 
1444                     int opcode = b[v] & 0xFF;

1445                     switch (ClassWriter.TYPE[opcode]) {
1446                         case ClassWriter.NOARG_INSN:
1447                             mv.visitInsn(opcode);
1448                             v += 1;
1449                             break;
1450                         case ClassWriter.IMPLVAR_INSN:
1451                             if (opcode > Opcodes.ISTORE) {
1452                                 opcode -= 59; // ISTORE_0
1453                                 mv.visitVarInsn(Opcodes.ISTORE + (opcode >> 2),
1454                                         opcode & 0x3);
1455                             } else {
1456                                 opcode -= 26; // ILOAD_0
1457                                 mv.visitVarInsn(Opcodes.ILOAD + (opcode >> 2),
1458                                         opcode & 0x3);
1459                             }
1460                             v += 1;
1461                             break;
1462                         case ClassWriter.LABEL_INSN:
1463                             mv.visitJumpInsn(opcode, labels[w
1464                                     + readShort(v + 1)]);
1465                             v += 3;
1466                             break;
1467                         case ClassWriter.LABELW_INSN:
1468                             mv.visitJumpInsn(opcode - 33, labels[w
1469                                     + readInt(v + 1)]);
1470                             v += 5;
1471                             break;
1472                         case ClassWriter.WIDE_INSN:
1473                             opcode = b[v + 1] & 0xFF;
1474                             if (opcode == Opcodes.IINC) {
1475                                 mv.visitIincInsn(readUnsignedShort(v + 2),
1476                                         readShort(v + 4));
1477                                 v += 6;
1478                             } else {
1479                                 mv.visitVarInsn(opcode,
1480                                         readUnsignedShort(v + 2));
1481                                 v += 4;
1482                             }
1483                             break;
1484                         case ClassWriter.TABL_INSN:
1485                             // skips 0 to 3 padding bytes
1486                             v = v + 4 - (w & 3);
1487                             // reads instruction
1488                             label = w + readInt(v);
1489                             int min = readInt(v + 4);
1490                             int max = readInt(v + 8);
1491                             v += 12;
1492                             Label[] table = new Label[max - min + 1];
1493                             for (j = 0; j < table.length; ++j) {
1494                                 table[j] = labels[w + readInt(v)];
1495                                 v += 4;

1496                             }
1497                             mv.visitTableSwitchInsn(min,
1498                                     max,
1499                                     labels[label],
1500                                     table);
1501                             break;
1502                         case ClassWriter.LOOK_INSN:

1503                             // skips 0 to 3 padding bytes
1504                             v = v + 4 - (w & 3);
1505                             // reads instruction
1506                             label = w + readInt(v);
1507                             j = readInt(v + 4);
1508                             v += 8;
1509                             int[] keys = new int[j];
1510                             Label[] values = new Label[j];
1511                             for (j = 0; j < keys.length; ++j) {
1512                                 keys[j] = readInt(v);
1513                                 values[j] = labels[w + readInt(v + 4)];
1514                                 v += 8;
1515                             }
1516                             mv.visitLookupSwitchInsn(labels[label],
1517                                     keys,
1518                                     values);
1519                             break;

1520                         case ClassWriter.VAR_INSN:
1521                             mv.visitVarInsn(opcode, b[v + 1] & 0xFF);
1522                             v += 2;
1523                             break;
1524                         case ClassWriter.SBYTE_INSN:
1525                             mv.visitIntInsn(opcode, b[v + 1]);
1526                             v += 2;
1527                             break;
1528                         case ClassWriter.SHORT_INSN:
1529                             mv.visitIntInsn(opcode, readShort(v + 1));
1530                             v += 3;
1531                             break;
1532                         case ClassWriter.LDC_INSN:
1533                             mv.visitLdcInsn(readConst(b[v + 1] & 0xFF, c));
1534                             v += 2;
1535                             break;
1536                         case ClassWriter.LDCW_INSN:
1537                             mv.visitLdcInsn(readConst(readUnsignedShort(v + 1),
1538                                     c));
1539                             v += 3;
1540                             break;
1541                         case ClassWriter.FIELDORMETH_INSN:
1542                         case ClassWriter.ITFMETH_INSN: {
1543                             int cpIndex = items[readUnsignedShort(v + 1)];
1544                             String iowner = readClass(cpIndex, c);
1545                             cpIndex = items[readUnsignedShort(cpIndex + 2)];
1546                             String iname = readUTF8(cpIndex, c);
1547                             String idesc = readUTF8(cpIndex + 2, c);
1548                             if (opcode < Opcodes.INVOKEVIRTUAL) {
1549                                 mv.visitFieldInsn(opcode, iowner, iname, idesc);
1550                             } else {
1551                                 mv.visitMethodInsn(opcode, iowner, iname, idesc);
1552                             }
1553                             if (opcode == Opcodes.INVOKEINTERFACE) {
1554                                 v += 5;
1555                             } else {
1556                                 v += 3;
1557                             }
1558                             break;
1559                         }
1560                         case ClassWriter.INDYMETH_INSN: {
1561                             int cpIndex = items[readUnsignedShort(v + 1)];
1562                             int bsmIndex = bootstrapMethods[readUnsignedShort(cpIndex)];
1563                             cpIndex = items[readUnsignedShort(cpIndex + 2)];
1564                             String iname = readUTF8(cpIndex, c);
1565                             String idesc = readUTF8(cpIndex + 2, c);
1566 
1567                             int mhIndex = readUnsignedShort(bsmIndex);
1568                             Handle bsm = (Handle) readConst(mhIndex, c);
1569                             int bsmArgCount = readUnsignedShort(bsmIndex + 2);
1570                             Object[] bsmArgs = new Object[bsmArgCount];
1571                             bsmIndex += 4;
1572                             for(int a = 0; a < bsmArgCount; a++) {
1573                                 int argIndex = readUnsignedShort(bsmIndex);
1574                                 bsmArgs[a] = readConst(argIndex, c);
1575                                 bsmIndex += 2;
1576                             }



1577                             mv.visitInvokeDynamicInsn(iname, idesc, bsm, bsmArgs);
1578 
1579                             v += 5;
1580                             break;
1581                         }
1582                         case ClassWriter.TYPE_INSN:
1583                             mv.visitTypeInsn(opcode, readClass(v + 1, c));
1584                             v += 3;
1585                             break;
1586                         case ClassWriter.IINC_INSN:
1587                             mv.visitIincInsn(b[v + 1] & 0xFF, b[v + 2]);
1588                             v += 3;
1589                             break;
1590                         // case MANA_INSN:
1591                         default:
1592                             mv.visitMultiANewArrayInsn(readClass(v + 1, c),
1593                                     b[v + 3] & 0xFF);
1594                             v += 4;
1595                             break;
1596                     }








1597                 }
1598                 l = labels[codeEnd - codeStart];
1599                 if (l != null) {
1600                     mv.visitLabel(l);
1601                 }
















1602                 // visits the local variable tables
1603                 if (!skipDebug && varTable != 0) {
1604                     int[] typeTable = null;
1605                     if (varTypeTable != 0) {
1606                         k = readUnsignedShort(varTypeTable) * 3;
1607                         w = varTypeTable + 2;
1608                         typeTable = new int[k];
1609                         while (k > 0) {
1610                             typeTable[--k] = w + 6; // signature
1611                             typeTable[--k] = readUnsignedShort(w + 8); // index
1612                             typeTable[--k] = readUnsignedShort(w); // start
1613                             w += 10;
1614                         }
1615                     }
1616                     k = readUnsignedShort(varTable);
1617                     w = varTable + 2;
1618                     for (; k > 0; --k) {
1619                         int start = readUnsignedShort(w);
1620                         int length = readUnsignedShort(w + 2);
1621                         int index = readUnsignedShort(w + 8);
1622                         String vsignature = null;
1623                         if (typeTable != null) {
1624                             for (int a = 0; a < typeTable.length; a += 3) {
1625                                 if (typeTable[a] == start
1626                                         && typeTable[a + 1] == index)
1627                                 {
1628                                     vsignature = readUTF8(typeTable[a + 2], c);
1629                                     break;
1630                                 }
1631                             }
1632                         }
1633                         mv.visitLocalVariable(readUTF8(w + 4, c),
1634                                 readUTF8(w + 6, c),
1635                                 vsignature,
1636                                 labels[start],
1637                                 labels[start + length],
1638                                 index);
1639                         w += 10;
1640                     }
1641                 }
1642                 // visits the other attributes
1643                 while (cattrs != null) {
1644                     attr = cattrs.next;
1645                     cattrs.next = null;
1646                     mv.visitAttribute(cattrs);
1647                     cattrs = attr;





1648                 }























1649                 // visits the max stack and max locals values
1650                 mv.visitMaxs(maxStack, maxLocals);
1651             }
1652 
1653             if (mv != null) {
1654                 mv.visitEnd();









































1655             }





















1656         }













1657 
1658         // visits the end of the class
1659         classVisitor.visitEnd();










































1660     }





























1661 
1662     /**
1663      * Reads parameter annotations and makes the given visitor visit them.
1664      *
1665      * @param v start offset in {@link #b b} of the annotations to be read.
1666      * @param desc the method descriptor.
1667      * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
1668      *        {@link #readClass(int,char[]) readClass} or
1669      *        {@link #readConst readConst}.
1670      * @param visible <tt>true</tt> if the annotations to be read are visible
1671      *        at runtime.
1672      * @param mv the visitor that must visit the annotations.

1673      */
1674     private void readParameterAnnotations(
1675         int v,
1676         final String desc,
1677         final char[] buf,
1678         final boolean visible,
1679         final MethodVisitor mv)
1680     {
1681         int i;
1682         int n = b[v++] & 0xFF;
1683         // workaround for a bug in javac (javac compiler generates a parameter
1684         // annotation array whose size is equal to the number of parameters in
1685         // the Java source file, while it should generate an array whose size is
1686         // equal to the number of parameters in the method descriptor - which
1687         // includes the synthetic parameters added by the compiler). This work-
1688         // around supposes that the synthetic parameters are the first ones.
1689         int synthetics = Type.getArgumentTypes(desc).length - n;
1690         AnnotationVisitor av;
1691         for (i = 0; i < synthetics; ++i) {
1692             // virtual annotation to detect synthetic parameters in MethodWriter
1693             av = mv.visitParameterAnnotation(i, "Ljava/lang/Synthetic;", false);
1694             if (av != null) {
1695                 av.visitEnd();
1696             }
1697         }

1698         for (; i < n + synthetics; ++i) {
1699             int j = readUnsignedShort(v);
1700             v += 2;
1701             for (; j > 0; --j) {
1702                 av = mv.visitParameterAnnotation(i, readUTF8(v, buf), visible);
1703                 v = readAnnotationValues(v + 2, buf, true, av);
1704             }
1705         }
1706     }
1707 
1708     /**
1709      * Reads the values of an annotation and makes the given visitor visit them.
1710      *
1711      * @param v the start offset in {@link #b b} of the values to be read
1712      *        (including the unsigned short that gives the number of values).
1713      * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
1714      *        {@link #readClass(int,char[]) readClass} or
1715      *        {@link #readConst readConst}.
1716      * @param named if the annotation values are named or not.
1717      * @param av the visitor that must visit the values.





1718      * @return the end offset of the annotation values.
1719      */
1720     private int readAnnotationValues(
1721         int v,
1722         final char[] buf,
1723         final boolean named,
1724         final AnnotationVisitor av)
1725     {
1726         int i = readUnsignedShort(v);
1727         v += 2;
1728         if (named) {
1729             for (; i > 0; --i) {
1730                 v = readAnnotationValue(v + 2, buf, readUTF8(v, buf), av);
1731             }
1732         } else {
1733             for (; i > 0; --i) {
1734                 v = readAnnotationValue(v, buf, null, av);
1735             }
1736         }
1737         if (av != null) {
1738             av.visitEnd();
1739         }
1740         return v;
1741     }
1742 
1743     /**
1744      * Reads a value of an annotation and makes the given visitor visit it.
1745      *
1746      * @param v the start offset in {@link #b b} of the value to be read (<i>not
1747      *        including the value name constant pool index</i>).
1748      * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
1749      *        {@link #readClass(int,char[]) readClass} or
1750      *        {@link #readConst readConst}.
1751      * @param name the name of the value to be read.
1752      * @param av the visitor that must visit the value.




1753      * @return the end offset of the annotation value.
1754      */
1755     private int readAnnotationValue(
1756         int v,
1757         final char[] buf,
1758         final String name,
1759         final AnnotationVisitor av)
1760     {
1761         int i;
1762         if (av == null) {
1763             switch (b[v] & 0xFF) {
1764                 case 'e': // enum_const_value
1765                     return v + 5;
1766                 case '@': // annotation_value
1767                     return readAnnotationValues(v + 3, buf, true, null);
1768                 case '[': // array_value
1769                     return readAnnotationValues(v + 1, buf, false, null);
1770                 default:
1771                     return v + 3;
1772             }
1773         }
1774         switch (b[v++] & 0xFF) {
1775             case 'I': // pointer to CONSTANT_Integer
1776             case 'J': // pointer to CONSTANT_Long
1777             case 'F': // pointer to CONSTANT_Float
1778             case 'D': // pointer to CONSTANT_Double
1779                 av.visit(name, readConst(readUnsignedShort(v), buf));
1780                 v += 2;
1781                 break;
1782             case 'B': // pointer to CONSTANT_Byte
1783                 av.visit(name,
1784                         new Byte((byte) readInt(items[readUnsignedShort(v)])));
1785                 v += 2;
1786                 break;
1787             case 'Z': // pointer to CONSTANT_Boolean
1788                 av.visit(name, readInt(items[readUnsignedShort(v)]) == 0
1789                         ? Boolean.FALSE
1790                         : Boolean.TRUE);
1791                 v += 2;
1792                 break;
1793             case 'S': // pointer to CONSTANT_Short
1794                 av.visit(name,
1795                         new Short((short) readInt(items[readUnsignedShort(v)])));
1796                 v += 2;
1797                 break;
1798             case 'C': // pointer to CONSTANT_Char
1799                 av.visit(name,
1800                         new Character((char) readInt(items[readUnsignedShort(v)])));
1801                 v += 2;
1802                 break;
1803             case 's': // pointer to CONSTANT_Utf8
1804                 av.visit(name, readUTF8(v, buf));
1805                 v += 2;
1806                 break;
1807             case 'e': // enum_const_value
1808                 av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf));
1809                 v += 4;
1810                 break;
1811             case 'c': // class_info
1812                 av.visit(name, Type.getType(readUTF8(v, buf)));
1813                 v += 2;
1814                 break;
1815             case '@': // annotation_value
1816                 v = readAnnotationValues(v + 2,
1817                         buf,
1818                         true,
1819                         av.visitAnnotation(name, readUTF8(v, buf)));
1820                 break;
1821             case '[': // array_value
1822                 int size = readUnsignedShort(v);
1823                 v += 2;
1824                 if (size == 0) {
1825                     return readAnnotationValues(v - 2,
1826                             buf,
1827                             false,
1828                             av.visitArray(name));
1829                 }
1830                 switch (this.b[v++] & 0xFF) {
1831                     case 'B':
1832                         byte[] bv = new byte[size];
1833                         for (i = 0; i < size; i++) {
1834                             bv[i] = (byte) readInt(items[readUnsignedShort(v)]);
1835                             v += 3;
1836                         }
1837                         av.visit(name, bv);
1838                         --v;
1839                         break;
1840                     case 'Z':
1841                         boolean[] zv = new boolean[size];
1842                         for (i = 0; i < size; i++) {
1843                             zv[i] = readInt(items[readUnsignedShort(v)]) != 0;
1844                             v += 3;
1845                         }
1846                         av.visit(name, zv);
1847                         --v;


1868                         int[] iv = new int[size];
1869                         for (i = 0; i < size; i++) {
1870                             iv[i] = readInt(items[readUnsignedShort(v)]);
1871                             v += 3;
1872                         }
1873                         av.visit(name, iv);
1874                         --v;
1875                         break;
1876                     case 'J':
1877                         long[] lv = new long[size];
1878                         for (i = 0; i < size; i++) {
1879                             lv[i] = readLong(items[readUnsignedShort(v)]);
1880                             v += 3;
1881                         }
1882                         av.visit(name, lv);
1883                         --v;
1884                         break;
1885                     case 'F':
1886                         float[] fv = new float[size];
1887                         for (i = 0; i < size; i++) {
1888                             fv[i] = Float.intBitsToFloat(readInt(items[readUnsignedShort(v)]));

1889                             v += 3;
1890                         }
1891                         av.visit(name, fv);
1892                         --v;
1893                         break;
1894                     case 'D':
1895                         double[] dv = new double[size];
1896                         for (i = 0; i < size; i++) {
1897                             dv[i] = Double.longBitsToDouble(readLong(items[readUnsignedShort(v)]));

1898                             v += 3;
1899                         }
1900                         av.visit(name, dv);
1901                         --v;
1902                         break;
1903                     default:
1904                         v = readAnnotationValues(v - 3,
1905                                 buf,
1906                                 false,
1907                                 av.visitArray(name));
1908                 }
1909         }
1910         return v;
1911     }
1912 
1913     private int readFrameType(
1914         final Object[] frame,
1915         final int index,
1916         int v,
1917         final char[] buf,
1918         final Label[] labels)
1919     {



































































































































































1920         int type = b[v++] & 0xFF;
1921         switch (type) {
1922             case 0:
1923                 frame[index] = Opcodes.TOP;
1924                 break;
1925             case 1:
1926                 frame[index] = Opcodes.INTEGER;
1927                 break;
1928             case 2:
1929                 frame[index] = Opcodes.FLOAT;
1930                 break;
1931             case 3:
1932                 frame[index] = Opcodes.DOUBLE;
1933                 break;
1934             case 4:
1935                 frame[index] = Opcodes.LONG;
1936                 break;
1937             case 5:
1938                 frame[index] = Opcodes.NULL;
1939                 break;
1940             case 6:
1941                 frame[index] = Opcodes.UNINITIALIZED_THIS;
1942                 break;
1943             case 7: // Object
1944                 frame[index] = readClass(v, buf);
1945                 v += 2;
1946                 break;
1947             default: // Uninitialized
1948                 frame[index] = readLabel(readUnsignedShort(v), labels);
1949                 v += 2;
1950         }
1951         return v;
1952     }
1953 
1954     /**
1955      * Returns the label corresponding to the given offset. The default
1956      * implementation of this method creates a label for the given offset if it
1957      * has not been already created.
1958      *
1959      * @param offset a bytecode offset in a method.
1960      * @param labels the already created labels, indexed by their offset. If a
1961      *        label already exists for offset this method must not create a new
1962      *        one. Otherwise it must store the new label in this array.


1963      * @return a non null Label, which must be equal to labels[offset].
1964      */
1965     protected Label readLabel(int offset, Label[] labels) {
1966         if (labels[offset] == null) {
1967             labels[offset] = new Label();
1968         }
1969         return labels[offset];
1970     }
1971 
1972     /**


























1973      * Reads an attribute in {@link #b b}.
1974      *
1975      * @param attrs prototypes of the attributes that must be parsed during the
1976      *        visit of the class. Any attribute whose type is not equal to the
1977      *        type of one the prototypes is ignored (i.e. an empty

1978      *        {@link Attribute} instance is returned).
1979      * @param type the type of the attribute.
1980      * @param off index of the first byte of the attribute's content in
1981      *        {@link #b b}. The 6 attribute header bytes, containing the type
1982      *        and the length of the attribute, are not taken into account here
1983      *        (they have already been read).
1984      * @param len the length of the attribute's content.
1985      * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
1986      *        {@link #readClass(int,char[]) readClass} or
1987      *        {@link #readConst readConst}.
1988      * @param codeOff index of the first byte of code's attribute content in





1989      *        {@link #b b}, or -1 if the attribute to be read is not a code
1990      *        attribute. The 6 attribute header bytes, containing the type and
1991      *        the length of the attribute, are not taken into account here.
1992      * @param labels the labels of the method's code, or <tt>null</tt> if the


1993      *        attribute to be read is not a code attribute.
1994      * @return the attribute that has been read, or <tt>null</tt> to skip this
1995      *         attribute.
1996      */
1997     private Attribute readAttribute(
1998         final Attribute[] attrs,
1999         final String type,
2000         final int off,
2001         final int len,
2002         final char[] buf,
2003         final int codeOff,
2004         final Label[] labels)
2005     {
2006         for (int i = 0; i < attrs.length; ++i) {
2007             if (attrs[i].type.equals(type)) {
2008                 return attrs[i].read(this, off, len, buf, codeOff, labels);
2009             }
2010         }
2011         return new Attribute(type).read(this, off, len, null, -1, null);
2012     }
2013 
2014     // ------------------------------------------------------------------------
2015     // Utility methods: low level parsing
2016     // ------------------------------------------------------------------------
2017 
2018     /**
2019      *  Returns the number of constant pool items in {@link #b b}.
2020      *
2021      *  @return the number of constant pool items in {@link #b b}.
2022      */
2023     public int getItemCount() {
2024         return items.length;
2025     }
2026 
2027     /**
2028      * Returns the start index of the constant pool item in {@link #b b}, plus
2029      * one. <i>This method is intended for {@link Attribute} sub classes, and is
2030      * normally not needed by class generators or adapters.</i>
2031      *
2032      * @param item the index a constant pool item.

2033      * @return the start index of the constant pool item in {@link #b b}, plus
2034      *         one.
2035      */
2036     public int getItem(final int item) {
2037         return items[item];
2038     }
2039 
2040     /**
2041      * Returns the maximum length of the strings contained in the constant pool
2042      * of the class.
2043      *
2044      * @return the maximum length of the strings contained in the constant pool
2045      *         of the class.
2046      */
2047     public int getMaxStringLength() {
2048         return maxStringLength;
2049     }
2050 
2051     /**
2052      * Reads a byte value in {@link #b b}. <i>This method is intended for
2053      * {@link Attribute} sub classes, and is normally not needed by class
2054      * generators or adapters.</i>
2055      *
2056      * @param index the start index of the value to be read in {@link #b b}.

2057      * @return the read value.
2058      */
2059     public int readByte(final int index) {
2060         return b[index] & 0xFF;
2061     }
2062 
2063     /**
2064      * Reads an unsigned short value in {@link #b b}. <i>This method is
2065      * intended for {@link Attribute} sub classes, and is normally not needed by
2066      * class generators or adapters.</i>
2067      *
2068      * @param index the start index of the value to be read in {@link #b b}.

2069      * @return the read value.
2070      */
2071     public int readUnsignedShort(final int index) {
2072         byte[] b = this.b;
2073         return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF);
2074     }
2075 
2076     /**
2077      * Reads a signed short value in {@link #b b}. <i>This method is intended
2078      * for {@link Attribute} sub classes, and is normally not needed by class
2079      * generators or adapters.</i>
2080      *
2081      * @param index the start index of the value to be read in {@link #b b}.

2082      * @return the read value.
2083      */
2084     public short readShort(final int index) {
2085         byte[] b = this.b;
2086         return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF));
2087     }
2088 
2089     /**
2090      * Reads a signed int value in {@link #b b}. <i>This method is intended for
2091      * {@link Attribute} sub classes, and is normally not needed by class
2092      * generators or adapters.</i>
2093      *
2094      * @param index the start index of the value to be read in {@link #b b}.

2095      * @return the read value.
2096      */
2097     public int readInt(final int index) {
2098         byte[] b = this.b;
2099         return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16)
2100                 | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF);
2101     }
2102 
2103     /**
2104      * Reads a signed long value in {@link #b b}. <i>This method is intended
2105      * for {@link Attribute} sub classes, and is normally not needed by class
2106      * generators or adapters.</i>
2107      *
2108      * @param index the start index of the value to be read in {@link #b b}.

2109      * @return the read value.
2110      */
2111     public long readLong(final int index) {
2112         long l1 = readInt(index);
2113         long l0 = readInt(index + 4) & 0xFFFFFFFFL;
2114         return (l1 << 32) | l0;
2115     }
2116 
2117     /**
2118      * Reads an UTF8 string constant pool item in {@link #b b}. <i>This method
2119      * is intended for {@link Attribute} sub classes, and is normally not needed
2120      * by class generators or adapters.</i>
2121      *
2122      * @param index the start index of an unsigned short value in {@link #b b},

2123      *        whose value is the index of an UTF8 constant pool item.
2124      * @param buf buffer to be used to read the item. This buffer must be

2125      *        sufficiently large. It is not automatically resized.
2126      * @return the String corresponding to the specified UTF8 item.
2127      */
2128     public String readUTF8(int index, final char[] buf) {
2129         int item = readUnsignedShort(index);



2130         String s = strings[item];
2131         if (s != null) {
2132             return s;
2133         }
2134         index = items[item];
2135         return strings[item] = readUTF(index + 2, readUnsignedShort(index), buf);
2136     }
2137 
2138     /**
2139      * Reads UTF8 string in {@link #b b}.
2140      *
2141      * @param index start offset of the UTF8 string to be read.
2142      * @param utfLen length of the UTF8 string to be read.
2143      * @param buf buffer to be used to read the string. This buffer must be



2144      *        sufficiently large. It is not automatically resized.
2145      * @return the String corresponding to the specified UTF8 string.
2146      */
2147     private String readUTF(int index, final int utfLen, final char[] buf) {
2148         int endIndex = index + utfLen;
2149         byte[] b = this.b;
2150         int strLen = 0;
2151         int c;
2152         int st = 0;
2153         char cc = 0;
2154         while (index < endIndex) {
2155             c = b[index++];
2156             switch (st) {
2157                 case 0:
2158                     c = c & 0xFF;
2159                     if (c < 0x80) {  // 0xxxxxxx
2160                         buf[strLen++] = (char) c;
2161                     } else if (c < 0xE0 && c > 0xBF) {  // 110x xxxx 10xx xxxx
2162                         cc = (char) (c & 0x1F);
2163                         st = 1;


2169 
2170                 case 1:  // byte 2 of 2-byte char or byte 3 of 3-byte char
2171                     buf[strLen++] = (char) ((cc << 6) | (c & 0x3F));
2172                     st = 0;
2173                     break;
2174 
2175                 case 2:  // byte 2 of 3-byte char
2176                     cc = (char) ((cc << 6) | (c & 0x3F));
2177                     st = 1;
2178                     break;
2179             }
2180         }
2181         return new String(buf, 0, strLen);
2182     }
2183 
2184     /**
2185      * Reads a class constant pool item in {@link #b b}. <i>This method is
2186      * intended for {@link Attribute} sub classes, and is normally not needed by
2187      * class generators or adapters.</i>
2188      *
2189      * @param index the start index of an unsigned short value in {@link #b b},

2190      *        whose value is the index of a class constant pool item.
2191      * @param buf buffer to be used to read the item. This buffer must be

2192      *        sufficiently large. It is not automatically resized.
2193      * @return the String corresponding to the specified class item.
2194      */
2195     public String readClass(final int index, final char[] buf) {
2196         // computes the start index of the CONSTANT_Class item in b
2197         // and reads the CONSTANT_Utf8 item designated by
2198         // the first two bytes of this CONSTANT_Class item
2199         return readUTF8(items[readUnsignedShort(index)], buf);
2200     }
2201 
2202     /**
2203      * Reads a numeric or string constant pool item in {@link #b b}. <i>This
2204      * method is intended for {@link Attribute} sub classes, and is normally not
2205      * needed by class generators or adapters.</i>
2206      *
2207      * @param item the index of a constant pool item.
2208      * @param buf buffer to be used to read the item. This buffer must be


2209      *        sufficiently large. It is not automatically resized.
2210      * @return the {@link Integer}, {@link Float}, {@link Long}, {@link Double},
2211      *         {@link String}, {@link Type} or {@link Handle} corresponding to
2212      *         the given constant pool item.
2213      */
2214     public Object readConst(final int item, final char[] buf) {
2215         int index = items[item];
2216         switch (b[index - 1]) {
2217             case ClassWriter.INT:
2218                 return new Integer(readInt(index));
2219             case ClassWriter.FLOAT:
2220                 return new Float(Float.intBitsToFloat(readInt(index)));
2221             case ClassWriter.LONG:
2222                 return new Long(readLong(index));
2223             case ClassWriter.DOUBLE:
2224                 return new Double(Double.longBitsToDouble(readLong(index)));
2225             case ClassWriter.CLASS:
2226                 return Type.getObjectType(readUTF8(index, buf));
2227             case ClassWriter.STR:
2228                 return readUTF8(index, buf);
2229             case ClassWriter.MTYPE:
2230                 return Type.getMethodType(readUTF8(index, buf));
2231 
2232             //case ClassWriter.HANDLE_BASE + [1..9]:
2233             default: {
2234                 int tag = readByte(index);
2235                 int[] items = this.items;
2236                 int cpIndex = items[readUnsignedShort(index + 1)];
2237                 String owner = readClass(cpIndex, buf);
2238                 cpIndex = items[readUnsignedShort(cpIndex + 2)];
2239                 String name = readUTF8(cpIndex, buf);
2240                 String desc = readUTF8(cpIndex + 2, buf);
2241                 return new Handle(tag, owner, name, desc);
2242             }
2243         }
2244     }
2245 }


 124     public static final int SKIP_FRAMES = 4;
 125 
 126     /**
 127      * Flag to expand the stack map frames. By default stack map frames are
 128      * visited in their original format (i.e. "expanded" for classes whose
 129      * version is less than V1_6, and "compressed" for the other classes). If
 130      * this flag is set, stack map frames are always visited in expanded format
 131      * (this option adds a decompression/recompression step in ClassReader and
 132      * ClassWriter which degrades performances quite a lot).
 133      */
 134     public static final int EXPAND_FRAMES = 8;
 135 
 136     /**
 137      * The class to be parsed. <i>The content of this array must not be
 138      * modified. This field is intended for {@link Attribute} sub classes, and
 139      * is normally not needed by class generators or adapters.</i>
 140      */
 141     public final byte[] b;
 142 
 143     /**
 144      * The start index of each constant pool item in {@link #b b}, plus one. The
 145      * one byte offset skips the constant pool item tag that indicates its type.

 146      */
 147     private final int[] items;
 148 
 149     /**
 150      * The String objects corresponding to the CONSTANT_Utf8 items. This cache
 151      * avoids multiple parsing of a given CONSTANT_Utf8 constant pool item,
 152      * which GREATLY improves performances (by a factor 2 to 3). This caching
 153      * strategy could be extended to all constant pool items, but its benefit
 154      * would not be so great for these items (because they are much less
 155      * expensive to parse than CONSTANT_Utf8 items).
 156      */
 157     private final String[] strings;
 158 
 159     /**
 160      * Maximum length of the strings contained in the constant pool of the
 161      * class.
 162      */
 163     private final int maxStringLength;
 164 
 165     /**
 166      * Start index of the class header information (access, name...) in
 167      * {@link #b b}.
 168      */
 169     public final int header;
 170 
 171     // ------------------------------------------------------------------------
 172     // Constructors
 173     // ------------------------------------------------------------------------
 174 
 175     /**
 176      * Constructs a new {@link ClassReader} object.
 177      *
 178      * @param b
 179      *            the bytecode of the class to be read.
 180      */
 181     public ClassReader(final byte[] b) {
 182         this(b, 0, b.length);
 183     }
 184 
 185     /**
 186      * Constructs a new {@link ClassReader} object.
 187      *
 188      * @param b
 189      *            the bytecode of the class to be read.
 190      * @param off
 191      *            the start offset of the class data.
 192      * @param len
 193      *            the length of the class data.
 194      */
 195     public ClassReader(final byte[] b, final int off, final int len) {
 196         this.b = b;
 197         // checks the class version
 198         if (readShort(off + 6) > Opcodes.V1_8) {
 199             throw new IllegalArgumentException();
 200         }
 201         // parses the constant pool
 202         items = new int[readUnsignedShort(off + 8)];
 203         int n = items.length;
 204         strings = new String[n];
 205         int max = 0;
 206         int index = off + 10;
 207         for (int i = 1; i < n; ++i) {
 208             items[i] = index + 1;
 209             int size;
 210             switch (b[index]) {
 211             case ClassWriter.FIELD:
 212             case ClassWriter.METH:
 213             case ClassWriter.IMETH:
 214             case ClassWriter.INT:
 215             case ClassWriter.FLOAT:
 216             case ClassWriter.NAME_TYPE:
 217             case ClassWriter.INDY:
 218                 size = 5;


 264      *
 265      * @return the internal class name
 266      *
 267      * @see ClassVisitor#visit(int, int, String, String, String, String[])
 268      */
 269     public String getClassName() {
 270         return readClass(header + 2, new char[maxStringLength]);
 271     }
 272 
 273     /**
 274      * Returns the internal of name of the super class (see
 275      * {@link Type#getInternalName() getInternalName}). For interfaces, the
 276      * super class is {@link Object}.
 277      *
 278      * @return the internal name of super class, or <tt>null</tt> for
 279      *         {@link Object} class.
 280      *
 281      * @see ClassVisitor#visit(int, int, String, String, String, String[])
 282      */
 283     public String getSuperName() {
 284         return readClass(header + 4, new char[maxStringLength]);

 285     }
 286 
 287     /**
 288      * Returns the internal names of the class's interfaces (see
 289      * {@link Type#getInternalName() getInternalName}).
 290      *
 291      * @return the array of internal names for all implemented interfaces or
 292      *         <tt>null</tt>.
 293      *
 294      * @see ClassVisitor#visit(int, int, String, String, String, String[])
 295      */
 296     public String[] getInterfaces() {
 297         int index = header + 6;
 298         int n = readUnsignedShort(index);
 299         String[] interfaces = new String[n];
 300         if (n > 0) {
 301             char[] buf = new char[maxStringLength];
 302             for (int i = 0; i < n; ++i) {
 303                 index += 2;
 304                 interfaces[i] = readClass(index, buf);
 305             }
 306         }
 307         return interfaces;
 308     }
 309 
 310     /**
 311      * Copies the constant pool data into the given {@link ClassWriter}. Should
 312      * be called before the {@link #accept(ClassVisitor,int)} method.
 313      *
 314      * @param classWriter
 315      *            the {@link ClassWriter} to copy constant pool into.
 316      */
 317     void copyPool(final ClassWriter classWriter) {
 318         char[] buf = new char[maxStringLength];
 319         int ll = items.length;
 320         Item[] items2 = new Item[ll];
 321         for (int i = 1; i < ll; i++) {
 322             int index = items[i];
 323             int tag = b[index - 1];
 324             Item item = new Item(i);
 325             int nameType;
 326             switch (tag) {
 327             case ClassWriter.FIELD:
 328             case ClassWriter.METH:
 329             case ClassWriter.IMETH:
 330                 nameType = items[readUnsignedShort(index + 2)];
 331                 item.set(tag, readClass(index, buf), readUTF8(nameType, buf),


 332                         readUTF8(nameType + 2, buf));
 333                 break;

 334             case ClassWriter.INT:
 335                 item.set(readInt(index));
 336                 break;

 337             case ClassWriter.FLOAT:
 338                 item.set(Float.intBitsToFloat(readInt(index)));
 339                 break;

 340             case ClassWriter.NAME_TYPE:
 341                 item.set(tag, readUTF8(index, buf), readUTF8(index + 2, buf),


 342                         null);
 343                 break;

 344             case ClassWriter.LONG:
 345                 item.set(readLong(index));
 346                 ++i;
 347                 break;

 348             case ClassWriter.DOUBLE:
 349                 item.set(Double.longBitsToDouble(readLong(index)));
 350                 ++i;
 351                 break;

 352             case ClassWriter.UTF8: {
 353                 String s = strings[i];
 354                 if (s == null) {
 355                     index = items[i];
 356                     s = strings[i] = readUTF(index + 2,
 357                             readUnsignedShort(index), buf);

 358                 }
 359                 item.set(tag, s, null, null);

 360                 break;
 361             }
 362             case ClassWriter.HANDLE: {
 363                 int fieldOrMethodRef = items[readUnsignedShort(index + 1)];
 364                 nameType = items[readUnsignedShort(fieldOrMethodRef + 2)];
 365                 item.set(ClassWriter.HANDLE_BASE + readByte(index),
 366                         readClass(fieldOrMethodRef, buf),
 367                         readUTF8(nameType, buf), readUTF8(nameType + 2, buf));



 368                 break;
 369             }

 370             case ClassWriter.INDY:
 371                 if (classWriter.bootstrapMethods == null) {
 372                     copyBootstrapMethods(classWriter, items2, buf);
 373                 }
 374                 nameType = items[readUnsignedShort(index + 2)];
 375                 item.set(readUTF8(nameType, buf), readUTF8(nameType + 2, buf),

 376                         readUnsignedShort(index));
 377                 break;


 378             // case ClassWriter.STR:
 379             // case ClassWriter.CLASS:
 380             // case ClassWriter.MTYPE
 381             default:
 382                 item.set(tag, readUTF8(index, buf), null, null);
 383                 break;
 384             }
 385 
 386             int index2 = item.hashCode % items2.length;
 387             item.next = items2[index2];
 388             items2[index2] = item;
 389         }
 390 
 391         int off = items[1] - 1;
 392         classWriter.pool.putByteArray(b, off, header - off);
 393         classWriter.items = items2;
 394         classWriter.threshold = (int) (0.75d * ll);
 395         classWriter.index = ll;
 396     }
 397 
 398     /**
 399      * Copies the bootstrap method data into the given {@link ClassWriter}.
 400      * Should be called before the {@link #accept(ClassVisitor,int)} method.
 401      *
 402      * @param classWriter
 403      *            the {@link ClassWriter} to copy bootstrap methods into.
 404      */
 405     private void copyBootstrapMethods(final ClassWriter classWriter,
 406             final Item[] items, final char[] c) {
 407         // finds the "BootstrapMethods" attribute
 408         int u = getAttributes();
 409         boolean found = false;
 410         for (int i = readUnsignedShort(u); i > 0; --i) {
 411             String attrName = readUTF8(u + 2, c);
 412             if ("BootstrapMethods".equals(attrName)) {
 413                 found = true;
 414                 break;
 415             }
 416             u += 6 + readInt(u + 4);
 417         }
 418         if (!found) {
 419             return;





 420         }
 421         // copies the bootstrap methods in the class writer
 422         int boostrapMethodCount = readUnsignedShort(u + 8);
 423         for (int j = 0, v = u + 10; j < boostrapMethodCount; j++) {
 424             int position = v - u - 10;
 425             int hashCode = readConst(readUnsignedShort(v), c).hashCode();
 426             for (int k = readUnsignedShort(v + 2); k > 0; --k) {
 427                 hashCode ^= readConst(readUnsignedShort(v + 4), c).hashCode();
 428                 v += 2;













 429             }
 430             v += 4;
 431             Item item = new Item(j);
 432             item.set(position, hashCode & 0x7FFFFFFF);
 433             int index = item.hashCode % items.length;
 434             item.next = items[index];
 435             items[index] = item;



 436         }
 437         int attrSize = readInt(u + 4);
 438         ByteVector bootstrapMethods = new ByteVector(attrSize + 62);
 439         bootstrapMethods.putByteArray(b, u + 10, attrSize - 2);
 440         classWriter.bootstrapMethodsCount = boostrapMethodCount;


 441         classWriter.bootstrapMethods = bootstrapMethods;

 442     }


 443 



 444     /**
 445      * Constructs a new {@link ClassReader} object.
 446      *
 447      * @param is
 448      *            an input stream from which to read the class.
 449      * @throws IOException
 450      *             if a problem occurs during reading.
 451      */
 452     public ClassReader(final InputStream is) throws IOException {
 453         this(readClass(is, false));
 454     }
 455 
 456     /**
 457      * Constructs a new {@link ClassReader} object.
 458      *
 459      * @param name
 460      *            the binary qualified name of the class to be read.
 461      * @throws IOException
 462      *             if an exception occurs during reading.
 463      */
 464     public ClassReader(final String name) throws IOException {
 465         this(readClass(
 466                 ClassLoader.getSystemResourceAsStream(name.replace('.', '/')
 467                         + ".class"), true));
 468     }
 469 
 470     /**
 471      * Reads the bytecode of a class.
 472      *
 473      * @param is
 474      *            an input stream from which to read the class.
 475      * @param close
 476      *            true to close the input stream after reading.
 477      * @return the bytecode read from the given input stream.
 478      * @throws IOException
 479      *             if a problem occurs during reading.
 480      */
 481     private static byte[] readClass(final InputStream is, boolean close)
 482             throws IOException {

 483         if (is == null) {
 484             throw new IOException("Class not found");
 485         }
 486         try {
 487             byte[] b = new byte[is.available()];
 488             int len = 0;
 489             while (true) {
 490                 int n = is.read(b, len, b.length - len);
 491                 if (n == -1) {
 492                     if (len < b.length) {
 493                         byte[] c = new byte[len];
 494                         System.arraycopy(b, 0, c, 0, len);
 495                         b = c;
 496                     }
 497                     return b;
 498                 }
 499                 len += n;
 500                 if (len == b.length) {
 501                     int last = is.read();
 502                     if (last < 0) {
 503                         return b;
 504                     }
 505                     byte[] c = new byte[b.length + 1000];
 506                     System.arraycopy(b, 0, c, 0, len);
 507                     c[len++] = (byte) last;
 508                     b = c;
 509                 }
 510             }
 511         } finally {
 512             if (close) {
 513                 is.close();
 514             }
 515         }
 516     }
 517 
 518     // ------------------------------------------------------------------------
 519     // Public methods
 520     // ------------------------------------------------------------------------
 521 
 522     /**
 523      * Makes the given visitor visit the Java class of this {@link ClassReader}
 524      * . This class is the one specified in the constructor (see
 525      * {@link #ClassReader(byte[]) ClassReader}).
 526      *
 527      * @param classVisitor
 528      *            the visitor that must visit this class.
 529      * @param flags
 530      *            option flags that can be used to modify the default behavior
 531      *            of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES}
 532      *            , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
 533      */
 534     public void accept(final ClassVisitor classVisitor, final int flags) {
 535         accept(classVisitor, new Attribute[0], flags);
 536     }
 537 
 538     /**
 539      * Makes the given visitor visit the Java class of this {@link ClassReader}.
 540      * This class is the one specified in the constructor (see
 541      * {@link #ClassReader(byte[]) ClassReader}).
 542      *
 543      * @param classVisitor
 544      *            the visitor that must visit this class.
 545      * @param attrs
 546      *            prototypes of the attributes that must be parsed during the
 547      *            visit of the class. Any attribute whose type is not equal to
 548      *            the type of one the prototypes will not be parsed: its byte
 549      *            array value will be passed unchanged to the ClassWriter.
 550      *            <i>This may corrupt it if this value contains references to
 551      *            the constant pool, or has syntactic or semantic links with a
 552      *            class element that has been transformed by a class adapter
 553      *            between the reader and the writer</i>.
 554      * @param flags
 555      *            option flags that can be used to modify the default behavior
 556      *            of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES}
 557      *            , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
 558      */
 559     public void accept(final ClassVisitor classVisitor,
 560             final Attribute[] attrs, final int flags) {
 561         int u = header; // current offset in the class file



 562         char[] c = new char[maxStringLength]; // buffer used to read strings



 563 
 564         Context context = new Context();
 565         context.attrs = attrs;
 566         context.flags = flags;
 567         context.buffer = c;




 568 
 569         // reads the class declaration
 570         int access = readUnsignedShort(u);
 571         String name = readClass(u + 2, c);
 572         String superClass = readClass(u + 4, c);
 573         String[] interfaces = new String[readUnsignedShort(u + 6)];



 574         u += 8;
 575         for (int i = 0; i < interfaces.length; ++i) {
 576             interfaces[i] = readClass(u, c);
 577             u += 2;
 578         }
 579 
 580         // reads the class attributes
 581         String signature = null;
























 582         String sourceFile = null;
 583         String sourceDebug = null;
 584         String enclosingOwner = null;
 585         String enclosingName = null;
 586         String enclosingDesc = null;
 587         int anns = 0;
 588         int ianns = 0;
 589         int tanns = 0;
 590         int itanns = 0;
 591         int innerClasses = 0;
 592         Attribute attributes = null;
 593 
 594         u = getAttributes();
 595         for (int i = readUnsignedShort(u); i > 0; --i) {
 596             String attrName = readUTF8(u + 2, c);

 597             // tests are sorted in decreasing frequency order
 598             // (based on frequencies observed on typical classes)
 599             if ("SourceFile".equals(attrName)) {
 600                 sourceFile = readUTF8(u + 8, c);
 601             } else if ("InnerClasses".equals(attrName)) {
 602                 innerClasses = u + 8;
 603             } else if ("EnclosingMethod".equals(attrName)) {
 604                 enclosingOwner = readClass(u + 8, c);
 605                 int item = readUnsignedShort(u + 10);
 606                 if (item != 0) {
 607                     enclosingName = readUTF8(items[item], c);
 608                     enclosingDesc = readUTF8(items[item] + 2, c);
 609                 }
 610             } else if (SIGNATURES && "Signature".equals(attrName)) {
 611                 signature = readUTF8(u + 8, c);
 612             } else if (ANNOTATIONS
 613                     && "RuntimeVisibleAnnotations".equals(attrName)) {
 614                 anns = u + 8;
 615             } else if (ANNOTATIONS
 616                     && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
 617                 tanns = u + 8;
 618             } else if ("Deprecated".equals(attrName)) {
 619                 access |= Opcodes.ACC_DEPRECATED;
 620             } else if ("Synthetic".equals(attrName)) {
 621                 access |= Opcodes.ACC_SYNTHETIC
 622                         | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
 623             } else if ("SourceDebugExtension".equals(attrName)) {
 624                 int len = readInt(u + 4);
 625                 sourceDebug = readUTF(u + 8, len, new char[len]);
 626             } else if (ANNOTATIONS
 627                     && "RuntimeInvisibleAnnotations".equals(attrName)) {
 628                 ianns = u + 8;
 629             } else if (ANNOTATIONS
 630                     && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
 631                 itanns = u + 8;
 632             } else if ("BootstrapMethods".equals(attrName)) {
 633                 int[] bootstrapMethods = new int[readUnsignedShort(u + 8)];
 634                 for (int j = 0, v = u + 10; j < bootstrapMethods.length; j++) {
 635                     bootstrapMethods[j] = v;
 636                     v += 2 + readUnsignedShort(v + 2) << 1;


 637                 }
 638                 context.bootstrapMethods = bootstrapMethods;
 639             } else {
 640                 Attribute attr = readAttribute(attrs, attrName, u + 8,
 641                         readInt(u + 4), c, -1, null);





 642                 if (attr != null) {
 643                     attr.next = attributes;
 644                     attributes = attr;
 645                 }
 646             }
 647             u += 6 + readInt(u + 4);
 648         }







 649 
 650         // visits the class declaration
 651         classVisitor.visit(readInt(items[1] - 7), access, name, signature,
 652                 superClass, interfaces);
 653 
 654         // visits the source and debug info
 655         if ((flags & SKIP_DEBUG) == 0
 656                 && (sourceFile != null || sourceDebug != null)) {
 657             classVisitor.visitSource(sourceFile, sourceDebug);
 658         }
 659 
 660         // visits the outer class
 661         if (enclosingOwner != null) {
 662             classVisitor.visitOuterClass(enclosingOwner, enclosingName,

 663                     enclosingDesc);
 664         }
 665 
 666         // visits the class annotations and type annotations
 667         if (ANNOTATIONS && anns != 0) {
 668             for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
 669                 v = readAnnotationValues(v + 2, c, true,
 670                         classVisitor.visitAnnotation(readUTF8(v, c), true));







 671             }
 672         }
 673         if (ANNOTATIONS && ianns != 0) {
 674             for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
 675                 v = readAnnotationValues(v + 2, c, true,
 676                         classVisitor.visitAnnotation(readUTF8(v, c), false));
 677             }
 678         }
 679         if (ANNOTATIONS && tanns != 0) {
 680             for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
 681                 v = readAnnotationTarget(context, v);
 682                 v = readAnnotationValues(v + 2, c, true,
 683                         classVisitor.visitTypeAnnotation(context.typeRef,
 684                                 context.typePath, readUTF8(v, c), true));
 685             }
 686         }
 687         if (ANNOTATIONS && itanns != 0) {
 688             for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
 689                 v = readAnnotationTarget(context, v);
 690                 v = readAnnotationValues(v + 2, c, true,
 691                         classVisitor.visitTypeAnnotation(context.typeRef,
 692                                 context.typePath, readUTF8(v, c), false));
 693             }
 694         }
 695 
 696         // visits the attributes
 697         while (attributes != null) {
 698             Attribute attr = attributes.next;
 699             attributes.next = null;
 700             classVisitor.visitAttribute(attributes);
 701             attributes = attr;
 702         }
 703 
 704         // visits the inner classes
 705         if (innerClasses != 0) {
 706             int v = innerClasses + 2;
 707             for (int i = readUnsignedShort(innerClasses); i > 0; --i) {
 708                 classVisitor.visitInnerClass(readClass(v, c),
 709                         readClass(v + 2, c), readUTF8(v + 4, c),
 710                         readUnsignedShort(v + 6));
 711                 v += 8;





 712             }
 713         }
 714 
 715         // visits the fields and methods
 716         u = header + 10 + 2 * interfaces.length;
 717         for (int i = readUnsignedShort(u - 2); i > 0; --i) {
 718             u = readField(classVisitor, context, u);
 719         }
 720         u += 2;
 721         for (int i = readUnsignedShort(u - 2); i > 0; --i) {
 722             u = readMethod(classVisitor, context, u);
 723         }








 724 
 725         // visits the end of the class
 726         classVisitor.visitEnd();
 727     }
 728 
 729     /**
 730      * Reads a field and makes the given visitor visit it.
 731      *
 732      * @param classVisitor
 733      *            the visitor that must visit the field.
 734      * @param context
 735      *            information about the class being parsed.
 736      * @param u
 737      *            the start offset of the field in the class file.
 738      * @return the offset of the first byte following the field in the class.
 739      */
 740     private int readField(final ClassVisitor classVisitor,
 741             final Context context, int u) {
 742         // reads the field declaration
 743         char[] c = context.buffer;
 744         int access = readUnsignedShort(u);
 745         String name = readUTF8(u + 2, c);
 746         String desc = readUTF8(u + 4, c);
 747         u += 6;
 748 
 749         // reads the field attributes
 750         String signature = null;
 751         int anns = 0;
 752         int ianns = 0;
 753         int tanns = 0;
 754         int itanns = 0;
 755         Object value = null;
 756         Attribute attributes = null;
 757 
 758         for (int i = readUnsignedShort(u); i > 0; --i) {
 759             String attrName = readUTF8(u + 2, c);
 760             // tests are sorted in decreasing frequency order
 761             // (based on frequencies observed on typical classes)
 762             if ("ConstantValue".equals(attrName)) {
 763                 int item = readUnsignedShort(u + 8);
 764                 value = item == 0 ? null : readConst(item, c);
 765             } else if (SIGNATURES && "Signature".equals(attrName)) {
 766                 signature = readUTF8(u + 8, c);
 767             } else if ("Deprecated".equals(attrName)) {
 768                 access |= Opcodes.ACC_DEPRECATED;
 769             } else if ("Synthetic".equals(attrName)) {
 770                 access |= Opcodes.ACC_SYNTHETIC
 771                         | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
 772             } else if (ANNOTATIONS
 773                     && "RuntimeVisibleAnnotations".equals(attrName)) {
 774                 anns = u + 8;
 775             } else if (ANNOTATIONS
 776                     && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
 777                 tanns = u + 8;
 778             } else if (ANNOTATIONS
 779                     && "RuntimeInvisibleAnnotations".equals(attrName)) {
 780                 ianns = u + 8;
 781             } else if (ANNOTATIONS
 782                     && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
 783                 itanns = u + 8;
 784             } else {
 785                 Attribute attr = readAttribute(context.attrs, attrName, u + 8,
 786                         readInt(u + 4), c, -1, null);





 787                 if (attr != null) {
 788                     attr.next = attributes;
 789                     attributes = attr;
 790                 }
 791             }
 792             u += 6 + readInt(u + 4);
 793         }
 794         u += 2;
 795 
 796         // visits the field declaration
 797         FieldVisitor fv = classVisitor.visitField(access, name, desc,
 798                 signature, value);
 799         if (fv == null) {
 800             return u;












 801         }
 802 
 803         // visits the field annotations and type annotations
 804         if (ANNOTATIONS && anns != 0) {
 805             for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
 806                 v = readAnnotationValues(v + 2, c, true,
 807                         fv.visitAnnotation(readUTF8(v, c), true));
 808             }
 809         }
 810         if (ANNOTATIONS && ianns != 0) {
 811             for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
 812                 v = readAnnotationValues(v + 2, c, true,
 813                         fv.visitAnnotation(readUTF8(v, c), false));
 814             }





 815         }
 816         if (ANNOTATIONS && tanns != 0) {
 817             for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
 818                 v = readAnnotationTarget(context, v);
 819                 v = readAnnotationValues(v + 2, c, true,
 820                         fv.visitTypeAnnotation(context.typeRef,
 821                                 context.typePath, readUTF8(v, c), true));
 822             }
 823         }
 824         if (ANNOTATIONS && itanns != 0) {
 825             for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
 826                 v = readAnnotationTarget(context, v);
 827                 v = readAnnotationValues(v + 2, c, true,
 828                         fv.visitTypeAnnotation(context.typeRef,
 829                                 context.typePath, readUTF8(v, c), false));
 830             }
 831         }
 832 
 833         // visits the field attributes
 834         while (attributes != null) {
 835             Attribute attr = attributes.next;
 836             attributes.next = null;
 837             fv.visitAttribute(attributes);
 838             attributes = attr;
 839         }
 840 
 841         // visits the end of the field
 842         fv.visitEnd();
 843 
 844         return u;
 845     }
 846 
 847     /**
 848      * Reads a method and makes the given visitor visit it.
 849      *
 850      * @param classVisitor
 851      *            the visitor that must visit the method.
 852      * @param context
 853      *            information about the class being parsed.
 854      * @param u
 855      *            the start offset of the method in the class file.
 856      * @return the offset of the first byte following the method in the class.
 857      */
 858     private int readMethod(final ClassVisitor classVisitor,
 859             final Context context, int u) {
 860         // reads the method declaration
 861         char[] c = context.buffer;
 862         context.access = readUnsignedShort(u);
 863         context.name = readUTF8(u + 2, c);
 864         context.desc = readUTF8(u + 4, c);
 865         u += 6;
 866 
 867         // reads the method attributes
 868         int code = 0;
 869         int exception = 0;
 870         String[] exceptions = null;
 871         String signature = null;
 872         int methodParameters = 0;
 873         int anns = 0;
 874         int ianns = 0;
 875         int tanns = 0;
 876         int itanns = 0;
 877         int dann = 0;
 878         int mpanns = 0;
 879         int impanns = 0;
 880         int firstAttribute = u;
 881         Attribute attributes = null;

 882 
 883         for (int i = readUnsignedShort(u); i > 0; --i) {
 884             String attrName = readUTF8(u + 2, c);





 885             // tests are sorted in decreasing frequency order
 886             // (based on frequencies observed on typical classes)
 887             if ("Code".equals(attrName)) {
 888                 if ((context.flags & SKIP_CODE) == 0) {
 889                     code = u + 8;
 890                 }
 891             } else if ("Exceptions".equals(attrName)) {
 892                 exceptions = new String[readUnsignedShort(u + 8)];
 893                 exception = u + 10;
 894                 for (int j = 0; j < exceptions.length; ++j) {
 895                     exceptions[j] = readClass(exception, c);
 896                     exception += 2;
 897                 }
 898             } else if (SIGNATURES && "Signature".equals(attrName)) {
 899                 signature = readUTF8(u + 8, c);
 900             } else if ("Deprecated".equals(attrName)) {
 901                 context.access |= Opcodes.ACC_DEPRECATED;
 902             } else if (ANNOTATIONS
 903                     && "RuntimeVisibleAnnotations".equals(attrName)) {
 904                 anns = u + 8;
 905             } else if (ANNOTATIONS
 906                     && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
 907                 tanns = u + 8;
 908             } else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) {
 909                 dann = u + 8;
 910             } else if ("Synthetic".equals(attrName)) {
 911                 context.access |= Opcodes.ACC_SYNTHETIC
 912                         | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
 913             } else if (ANNOTATIONS
 914                     && "RuntimeInvisibleAnnotations".equals(attrName)) {
 915                 ianns = u + 8;
 916             } else if (ANNOTATIONS
 917                     && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
 918                 itanns = u + 8;
 919             } else if (ANNOTATIONS
 920                     && "RuntimeVisibleParameterAnnotations".equals(attrName)) {
 921                 mpanns = u + 8;
 922             } else if (ANNOTATIONS
 923                     && "RuntimeInvisibleParameterAnnotations".equals(attrName)) {
 924                 impanns = u + 8;
 925             } else if ("MethodParameters".equals(attrName)) {
 926                 methodParameters = u + 8;
 927             } else {
 928                 Attribute attr = readAttribute(context.attrs, attrName, u + 8,
 929                         readInt(u + 4), c, -1, null);





 930                 if (attr != null) {
 931                     attr.next = attributes;
 932                     attributes = attr;
 933                 }
 934             }
 935             u += 6 + readInt(u + 4);
 936         }
 937         u += 2;
 938 
 939         // visits the method declaration
 940         MethodVisitor mv = classVisitor.visitMethod(context.access,
 941                 context.name, context.desc, signature, exceptions);
 942         if (mv == null) {
 943             return u;



 944         }

 945 








 946         /*
 947          * if the returned MethodVisitor is in fact a MethodWriter, it means
 948          * there is no method adapter between the reader and the writer. If, in
 949          * addition, the writer's constant pool was copied from this reader
 950          * (mw.cw.cr == this), and the signature and exceptions of the method
 951          * have not been changed, then it is possible to skip all visit events
 952          * and just copy the original code of the method to the writer (the
 953          * access, name and descriptor can have been changed, this is not
 954          * important since they are not copied as is from the reader).

 955          */
 956         if (WRITER && mv instanceof MethodWriter) {
 957             MethodWriter mw = (MethodWriter) mv;
 958             if (mw.cw.cr == this && signature == mw.signature) {

 959                 boolean sameExceptions = false;
 960                 if (exceptions == null) {
 961                     sameExceptions = mw.exceptionCount == 0;
 962                 } else if (exceptions.length == mw.exceptionCount) {

 963                     sameExceptions = true;
 964                     for (int j = exceptions.length - 1; j >= 0; --j) {
 965                         exception -= 2;
 966                         if (mw.exceptions[j] != readUnsignedShort(exception)) {


 967                             sameExceptions = false;
 968                             break;
 969                         }
 970                     }
 971                 }

 972                 if (sameExceptions) {
 973                     /*
 974                      * we do not copy directly the code into MethodWriter to
 975                      * save a byte array copy operation. The real copy will be
 976                      * done in ClassWriter.toByteArray().

 977                      */
 978                     mw.classReaderOffset = firstAttribute;
 979                     mw.classReaderLength = u - firstAttribute;
 980                     return u;
 981                 }
 982             }
 983         }
 984 
 985         // visit the method parameters
 986         if (methodParameters != 0) {
 987             for (int i = b[methodParameters] & 0xFF, v = methodParameters + 1; i > 0; --i, v = v + 4) {
 988                 mv.visitParameter(readUTF8(v, c), readUnsignedShort(v + 2));
 989             }
 990         }
 991 
 992         // visits the method annotations
 993         if (ANNOTATIONS && dann != 0) {
 994             AnnotationVisitor dv = mv.visitAnnotationDefault();
 995             readAnnotationValue(dann, c, null, dv);
 996             if (dv != null) {
 997                 dv.visitEnd();
 998             }
 999         }
1000         if (ANNOTATIONS && anns != 0) {
1001             for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
1002                 v = readAnnotationValues(v + 2, c, true,
1003                         mv.visitAnnotation(readUTF8(v, c), true));







1004             }
1005         }
1006         if (ANNOTATIONS && ianns != 0) {
1007             for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
1008                 v = readAnnotationValues(v + 2, c, true,
1009                         mv.visitAnnotation(readUTF8(v, c), false));
1010             }
1011         }
1012         if (ANNOTATIONS && tanns != 0) {
1013             for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
1014                 v = readAnnotationTarget(context, v);
1015                 v = readAnnotationValues(v + 2, c, true,
1016                         mv.visitTypeAnnotation(context.typeRef,
1017                                 context.typePath, readUTF8(v, c), true));
1018             }
1019         }
1020         if (ANNOTATIONS && itanns != 0) {
1021             for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
1022                 v = readAnnotationTarget(context, v);
1023                 v = readAnnotationValues(v + 2, c, true,
1024                         mv.visitTypeAnnotation(context.typeRef,
1025                                 context.typePath, readUTF8(v, c), false));
1026             }
1027         }
1028         if (ANNOTATIONS && mpanns != 0) {
1029             readParameterAnnotations(mv, context, mpanns, true);
1030         }
1031         if (ANNOTATIONS && impanns != 0) {
1032             readParameterAnnotations(mv, context, impanns, false);
1033         }
1034 
1035         // visits the method attributes
1036         while (attributes != null) {
1037             Attribute attr = attributes.next;
1038             attributes.next = null;
1039             mv.visitAttribute(attributes);
1040             attributes = attr;
1041         }
1042 
1043         // visits the method code
1044         if (code != 0) {
1045             mv.visitCode();
1046             readCode(mv, context, code);
1047         }
1048 
1049         // visits the end of the method
1050         mv.visitEnd();



1051 
1052         return u;
1053     }
1054 
1055     /**
1056      * Reads the bytecode of a method and makes the given visitor visit it.
1057      *
1058      * @param mv
1059      *            the visitor that must visit the method's code.
1060      * @param context
1061      *            information about the class being parsed.
1062      * @param u
1063      *            the start offset of the code attribute in the class file.
1064      */
1065     private void readCode(final MethodVisitor mv, final Context context, int u) {
1066         // reads the header
1067         byte[] b = this.b;
1068         char[] c = context.buffer;
1069         int maxStack = readUnsignedShort(u);
1070         int maxLocals = readUnsignedShort(u + 2);
1071         int codeLength = readInt(u + 4);
1072         u += 8;
1073 
1074         // reads the bytecode to find the labels
1075         int codeStart = u;
1076         int codeEnd = u + codeLength;
1077         Label[] labels = context.labels = new Label[codeLength + 2];
1078         readLabel(codeLength + 1, labels);
1079         while (u < codeEnd) {
1080             int offset = u - codeStart;
1081             int opcode = b[u] & 0xFF;
1082             switch (ClassWriter.TYPE[opcode]) {
1083             case ClassWriter.NOARG_INSN:
1084             case ClassWriter.IMPLVAR_INSN:
1085                 u += 1;
1086                 break;
1087             case ClassWriter.LABEL_INSN:
1088                 readLabel(offset + readShort(u + 1), labels);
1089                 u += 3;
1090                 break;
1091             case ClassWriter.LABELW_INSN:
1092                 readLabel(offset + readInt(u + 1), labels);
1093                 u += 5;
1094                 break;
1095             case ClassWriter.WIDE_INSN:
1096                 opcode = b[u + 1] & 0xFF;
1097                 if (opcode == Opcodes.IINC) {
1098                     u += 6;
1099                 } else {
1100                     u += 4;
1101                 }
1102                 break;
1103             case ClassWriter.TABL_INSN:
1104                 // skips 0 to 3 padding bytes
1105                 u = u + 4 - (offset & 3);
1106                 // reads instruction
1107                 readLabel(offset + readInt(u), labels);
1108                 for (int i = readInt(u + 8) - readInt(u + 4) + 1; i > 0; --i) {
1109                     readLabel(offset + readInt(u + 12), labels);
1110                     u += 4;


1111                 }
1112                 u += 12;
1113                 break;
1114             case ClassWriter.LOOK_INSN:
1115                 // skips 0 to 3 padding bytes
1116                 u = u + 4 - (offset & 3);
1117                 // reads instruction
1118                 readLabel(offset + readInt(u), labels);
1119                 for (int i = readInt(u + 4); i > 0; --i) {
1120                     readLabel(offset + readInt(u + 12), labels);
1121                     u += 8;


1122                 }
1123                 u += 8;
1124                 break;
1125             case ClassWriter.VAR_INSN:
1126             case ClassWriter.SBYTE_INSN:
1127             case ClassWriter.LDC_INSN:
1128                 u += 2;
1129                 break;
1130             case ClassWriter.SHORT_INSN:
1131             case ClassWriter.LDCW_INSN:
1132             case ClassWriter.FIELDORMETH_INSN:
1133             case ClassWriter.TYPE_INSN:
1134             case ClassWriter.IINC_INSN:
1135                 u += 3;
1136                 break;
1137             case ClassWriter.ITFMETH_INSN:
1138             case ClassWriter.INDYMETH_INSN:
1139                 u += 5;
1140                 break;
1141             // case MANA_INSN:
1142             default:
1143                 u += 4;
1144                 break;
1145             }
1146         }
1147 
1148         // reads the try catch entries to find the labels, and also visits them
1149         for (int i = readUnsignedShort(u); i > 0; --i) {
1150             Label start = readLabel(readUnsignedShort(u + 2), labels);
1151             Label end = readLabel(readUnsignedShort(u + 4), labels);
1152             Label handler = readLabel(readUnsignedShort(u + 6), labels);
1153             String type = readUTF8(items[readUnsignedShort(u + 8)], c);
1154             mv.visitTryCatchBlock(start, end, handler, type);
1155             u += 8;






1156         }
1157         u += 2;
1158 
1159         // reads the code attributes
1160         int[] tanns = null; // start index of each visible type annotation
1161         int[] itanns = null; // start index of each invisible type annotation
1162         int tann = 0; // current index in tanns array
1163         int itann = 0; // current index in itanns array
1164         int ntoff = -1; // next visible type annotation code offset
1165         int nitoff = -1; // next invisible type annotation code offset
1166         int varTable = 0;
1167         int varTypeTable = 0;
1168         boolean zip = true;
1169         boolean unzip = (context.flags & EXPAND_FRAMES) != 0;
1170         int stackMap = 0;
1171         int stackMapSize = 0;
1172         int frameCount = 0;
1173         Context frame = null;
1174         Attribute attributes = null;
1175 
1176         for (int i = readUnsignedShort(u); i > 0; --i) {
1177             String attrName = readUTF8(u + 2, c);








1178             if ("LocalVariableTable".equals(attrName)) {
1179                 if ((context.flags & SKIP_DEBUG) == 0) {
1180                     varTable = u + 8;
1181                     for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
1182                         int label = readUnsignedShort(v + 10);


1183                         if (labels[label] == null) {
1184                             readLabel(label, labels).status |= Label.DEBUG;
1185                         }
1186                         label += readUnsignedShort(v + 12);
1187                         if (labels[label] == null) {
1188                             readLabel(label, labels).status |= Label.DEBUG;
1189                         }
1190                         v += 10;
1191                     }
1192                 }
1193             } else if ("LocalVariableTypeTable".equals(attrName)) {
1194                 varTypeTable = u + 8;
1195             } else if ("LineNumberTable".equals(attrName)) {
1196                 if ((context.flags & SKIP_DEBUG) == 0) {
1197                     for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
1198                         int label = readUnsignedShort(v + 10);


1199                         if (labels[label] == null) {
1200                             readLabel(label, labels).status |= Label.DEBUG;
1201                         }
1202                         labels[label].line = readUnsignedShort(v + 12);
1203                         v += 4;
1204                     }
1205                 }
1206             } else if (ANNOTATIONS
1207                     && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
1208                 tanns = readTypeAnnotations(mv, context, u + 8, true);
1209                 ntoff = tanns.length == 0 || readByte(tanns[0]) < 0x43 ? -1
1210                         : readUnsignedShort(tanns[0] + 1);
1211             } else if (ANNOTATIONS
1212                     && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
1213                 itanns = readTypeAnnotations(mv, context, u + 8, false);
1214                 nitoff = itanns.length == 0 || readByte(itanns[0]) < 0x43 ? -1
1215                         : readUnsignedShort(itanns[0] + 1);
1216             } else if (FRAMES && "StackMapTable".equals(attrName)) {
1217                 if ((context.flags & SKIP_FRAMES) == 0) {
1218                     stackMap = u + 10;
1219                     stackMapSize = readInt(u + 4);
1220                     frameCount = readUnsignedShort(u + 8);
1221                 }
1222                 /*
1223                  * here we do not extract the labels corresponding to the
1224                  * attribute content. This would require a full parsing of the
1225                  * attribute, which would need to be repeated in the second
1226                  * phase (see below). Instead the content of the attribute is
1227                  * read one frame at a time (i.e. after a frame has been
1228                  * visited, the next frame is read), and the labels it contains
1229                  * are also extracted one frame at a time. Thanks to the
1230                  * ordering of frames, having only a "one frame lookahead" is
1231                  * not a problem, i.e. it is not possible to see an offset
1232                  * smaller than the offset of the current insn and for which no
1233                  * Label exist.

1234                  */
1235                 /*
1236                  * This is not true for UNINITIALIZED type offsets. We solve
1237                  * this by parsing the stack map table without a full decoding
1238                  * (see below).
1239                  */
1240             } else if (FRAMES && "StackMap".equals(attrName)) {
1241                 if ((context.flags & SKIP_FRAMES) == 0) {



1242                     zip = false;
1243                     stackMap = u + 10;
1244                     stackMapSize = readInt(u + 4);
1245                     frameCount = readUnsignedShort(u + 8);
1246                 }
1247                 /*
1248                  * IMPORTANT! here we assume that the frames are ordered, as in
1249                  * the StackMapTable attribute, although this is not guaranteed
1250                  * by the attribute format.
1251                  */
1252             } else {
1253                 for (int j = 0; j < context.attrs.length; ++j) {
1254                     if (context.attrs[j].type.equals(attrName)) {
1255                         Attribute attr = context.attrs[j].read(this, u + 8,
1256                                 readInt(u + 4), c, codeStart - 8, labels);




1257                         if (attr != null) {
1258                             attr.next = attributes;
1259                             attributes = attr;
1260                         }
1261                     }
1262                 }
1263             }
1264             u += 6 + readInt(u + 4);
1265         }
1266         u += 2;
1267 
1268         // generates the first (implicit) stack map frame
1269         if (FRAMES && (stackMap != 0 || unzip)) {
1270             /*
1271              * for the first explicit frame the offset is not offset_delta + 1
1272              * but only offset_delta; setting the implicit frame offset to -1
1273              * allow the use of the "offset_delta + 1" rule in all cases
1274              */
1275             frame = context;
1276             frame.offset = -1;
1277             frame.mode = 0;
1278             frame.localCount = 0;
1279             frame.localDiff = 0;
1280             frame.stackCount = 0;
1281             frame.local = new Object[maxLocals];
1282             frame.stack = new Object[maxStack];
1283             if (unzip) {
1284                 getImplicitFrame(context);





1285             }
1286         }
1287         if (FRAMES && stackMap != 0) {












































1288             /*
1289              * Finds labels for UNINITIALIZED frame types. Instead of decoding
1290              * each element of the stack map table, we look for 3 consecutive
1291              * bytes that "look like" an UNINITIALIZED type (tag 8, offset
1292              * within code bounds, NEW instruction at this offset). We may find
1293              * false positives (i.e. not real UNINITIALIZED types), but this
1294              * should be rare, and the only consequence will be the creation of
1295              * an unneeded label. This is better than creating a label for each
1296              * NEW instruction, and faster than fully decoding the whole stack
1297              * map table.
1298              */
1299             for (int i = stackMap; i < stackMap + stackMapSize - 2; ++i) {
1300                 if (b[i] == 8) { // UNINITIALIZED FRAME TYPE
1301                     int v = readUnsignedShort(i + 1);
1302                     if (v >= 0 && v < codeLength) {
1303                         if ((b[codeStart + v] & 0xFF) == Opcodes.NEW) {
1304                             readLabel(v, labels);













1305                         }
1306                     }
1307                 }
1308             }
1309         }




1310 
1311         // visits the instructions
1312         u = codeStart;
1313         while (u < codeEnd) {
1314             int offset = u - codeStart;
1315 
1316             // visits the label and line number for this offset, if any
1317             Label l = labels[offset];
1318             if (l != null) {
1319                 mv.visitLabel(l);
1320                 if ((context.flags & SKIP_DEBUG) == 0 && l.line > 0) {
1321                     mv.visitLineNumber(l.line, l);
1322                 }
1323             }
1324 
1325             // visits the frame(s) for this offset, if any
1326             while (FRAMES && frame != null
1327                     && (frame.offset == offset || frame.offset == -1)) {
1328                 // if there is a frame for this offset, makes the visitor visit
1329                 // it, and reads the next frame if there is one.

1330                 if (!zip || unzip) {
1331                     mv.visitFrame(Opcodes.F_NEW, frame.localCount, frame.local,
1332                             frame.stackCount, frame.stack);
1333                 } else if (frame.offset != -1) {
1334                     mv.visitFrame(frame.mode, frame.localDiff, frame.local,
1335                             frame.stackCount, frame.stack);






1336                 }

1337                 if (frameCount > 0) {
1338                     stackMap = readFrame(stackMap, zip, unzip, frame);























































































1339                     --frameCount;
1340                 } else {
1341                     frame = null;
1342                 }
1343             }
1344 
1345             // visits the instruction at this offset
1346             int opcode = b[u] & 0xFF;
1347             switch (ClassWriter.TYPE[opcode]) {
1348             case ClassWriter.NOARG_INSN:
1349                 mv.visitInsn(opcode);
1350                 u += 1;
1351                 break;
1352             case ClassWriter.IMPLVAR_INSN:
1353                 if (opcode > Opcodes.ISTORE) {
1354                     opcode -= 59; // ISTORE_0
1355                     mv.visitVarInsn(Opcodes.ISTORE + (opcode >> 2),
1356                             opcode & 0x3);
1357                 } else {
1358                     opcode -= 26; // ILOAD_0
1359                     mv.visitVarInsn(Opcodes.ILOAD + (opcode >> 2), opcode & 0x3);

1360                 }
1361                 u += 1;
1362                 break;
1363             case ClassWriter.LABEL_INSN:
1364                 mv.visitJumpInsn(opcode, labels[offset + readShort(u + 1)]);
1365                 u += 3;

1366                 break;
1367             case ClassWriter.LABELW_INSN:
1368                 mv.visitJumpInsn(opcode - 33, labels[offset + readInt(u + 1)]);
1369                 u += 5;

1370                 break;
1371             case ClassWriter.WIDE_INSN:
1372                 opcode = b[u + 1] & 0xFF;
1373                 if (opcode == Opcodes.IINC) {
1374                     mv.visitIincInsn(readUnsignedShort(u + 2), readShort(u + 4));
1375                     u += 6;

1376                 } else {
1377                     mv.visitVarInsn(opcode, readUnsignedShort(u + 2));
1378                     u += 4;

1379                 }
1380                 break;
1381             case ClassWriter.TABL_INSN: {
1382                 // skips 0 to 3 padding bytes
1383                 u = u + 4 - (offset & 3);
1384                 // reads instruction
1385                 int label = offset + readInt(u);
1386                 int min = readInt(u + 4);
1387                 int max = readInt(u + 8);

1388                 Label[] table = new Label[max - min + 1];
1389                 u += 12;
1390                 for (int i = 0; i < table.length; ++i) {
1391                     table[i] = labels[offset + readInt(u)];
1392                     u += 4;
1393                 }
1394                 mv.visitTableSwitchInsn(min, max, labels[label], table);



1395                 break;
1396             }
1397             case ClassWriter.LOOK_INSN: {
1398                 // skips 0 to 3 padding bytes
1399                 u = u + 4 - (offset & 3);
1400                 // reads instruction
1401                 int label = offset + readInt(u);
1402                 int len = readInt(u + 4);
1403                 int[] keys = new int[len];
1404                 Label[] values = new Label[len];
1405                 u += 8;
1406                 for (int i = 0; i < len; ++i) {
1407                     keys[i] = readInt(u);
1408                     values[i] = labels[offset + readInt(u + 4)];
1409                     u += 8;
1410                 }
1411                 mv.visitLookupSwitchInsn(labels[label], keys, values);


1412                 break;
1413             }
1414             case ClassWriter.VAR_INSN:
1415                 mv.visitVarInsn(opcode, b[u + 1] & 0xFF);
1416                 u += 2;
1417                 break;
1418             case ClassWriter.SBYTE_INSN:
1419                 mv.visitIntInsn(opcode, b[u + 1]);
1420                 u += 2;
1421                 break;
1422             case ClassWriter.SHORT_INSN:
1423                 mv.visitIntInsn(opcode, readShort(u + 1));
1424                 u += 3;
1425                 break;
1426             case ClassWriter.LDC_INSN:
1427                 mv.visitLdcInsn(readConst(b[u + 1] & 0xFF, c));
1428                 u += 2;
1429                 break;
1430             case ClassWriter.LDCW_INSN:
1431                 mv.visitLdcInsn(readConst(readUnsignedShort(u + 1), c));
1432                 u += 3;

1433                 break;
1434             case ClassWriter.FIELDORMETH_INSN:
1435             case ClassWriter.ITFMETH_INSN: {
1436                 int cpIndex = items[readUnsignedShort(u + 1)];
1437                 String iowner = readClass(cpIndex, c);
1438                 cpIndex = items[readUnsignedShort(cpIndex + 2)];
1439                 String iname = readUTF8(cpIndex, c);
1440                 String idesc = readUTF8(cpIndex + 2, c);
1441                 if (opcode < Opcodes.INVOKEVIRTUAL) {
1442                     mv.visitFieldInsn(opcode, iowner, iname, idesc);
1443                 } else {
1444                     mv.visitMethodInsn(opcode, iowner, iname, idesc);
1445                 }
1446                 if (opcode == Opcodes.INVOKEINTERFACE) {
1447                     u += 5;
1448                 } else {
1449                     u += 3;
1450                 }
1451                 break;
1452             }
1453             case ClassWriter.INDYMETH_INSN: {
1454                 int cpIndex = items[readUnsignedShort(u + 1)];
1455                 int bsmIndex = context.bootstrapMethods[readUnsignedShort(cpIndex)];
1456                 Handle bsm = (Handle) readConst(readUnsignedShort(bsmIndex), c);





1457                 int bsmArgCount = readUnsignedShort(bsmIndex + 2);
1458                 Object[] bsmArgs = new Object[bsmArgCount];
1459                 bsmIndex += 4;
1460                 for (int i = 0; i < bsmArgCount; i++) {
1461                     bsmArgs[i] = readConst(readUnsignedShort(bsmIndex), c);

1462                     bsmIndex += 2;
1463                 }
1464                 cpIndex = items[readUnsignedShort(cpIndex + 2)];
1465                 String iname = readUTF8(cpIndex, c);
1466                 String idesc = readUTF8(cpIndex + 2, c);
1467                 mv.visitInvokeDynamicInsn(iname, idesc, bsm, bsmArgs);
1468                 u += 5;

1469                 break;
1470             }
1471             case ClassWriter.TYPE_INSN:
1472                 mv.visitTypeInsn(opcode, readClass(u + 1, c));
1473                 u += 3;
1474                 break;
1475             case ClassWriter.IINC_INSN:
1476                 mv.visitIincInsn(b[u + 1] & 0xFF, b[u + 2]);
1477                 u += 3;
1478                 break;
1479             // case MANA_INSN:
1480             default:
1481                 mv.visitMultiANewArrayInsn(readClass(u + 1, c), b[u + 3] & 0xFF);
1482                 u += 4;

1483                 break;
1484             }
1485 
1486             // visit the instruction annotations, if any
1487             while (tanns != null && tann < tanns.length && ntoff <= offset) {
1488                 if (ntoff == offset) {
1489                     int v = readAnnotationTarget(context, tanns[tann]);
1490                     readAnnotationValues(v + 2, c, true,
1491                             mv.visitInsnAnnotation(context.typeRef,
1492                                     context.typePath, readUTF8(v, c), true));
1493                 }
1494                 ntoff = ++tann >= tanns.length || readByte(tanns[tann]) < 0x43 ? -1
1495                         : readUnsignedShort(tanns[tann] + 1);

1496             }
1497             while (itanns != null && itann < itanns.length && nitoff <= offset) {
1498                 if (nitoff == offset) {
1499                     int v = readAnnotationTarget(context, itanns[itann]);
1500                     readAnnotationValues(v + 2, c, true,
1501                             mv.visitInsnAnnotation(context.typeRef,
1502                                     context.typePath, readUTF8(v, c), false));
1503                 }
1504                 nitoff = ++itann >= itanns.length
1505                         || readByte(itanns[itann]) < 0x43 ? -1
1506                         : readUnsignedShort(itanns[itann] + 1);
1507             }
1508         }
1509         if (labels[codeLength] != null) {
1510             mv.visitLabel(labels[codeLength]);
1511         }
1512 
1513         // visits the local variable tables
1514         if ((context.flags & SKIP_DEBUG) == 0 && varTable != 0) {
1515             int[] typeTable = null;
1516             if (varTypeTable != 0) {
1517                 u = varTypeTable + 2;
1518                 typeTable = new int[readUnsignedShort(varTypeTable) * 3];
1519                 for (int i = typeTable.length; i > 0;) {
1520                     typeTable[--i] = u + 6; // signature
1521                     typeTable[--i] = readUnsignedShort(u + 8); // index
1522                     typeTable[--i] = readUnsignedShort(u); // start
1523                     u += 10;

1524                 }
1525             }
1526             u = varTable + 2;
1527             for (int i = readUnsignedShort(varTable); i > 0; --i) {
1528                 int start = readUnsignedShort(u);
1529                 int length = readUnsignedShort(u + 2);
1530                 int index = readUnsignedShort(u + 8);

1531                 String vsignature = null;
1532                 if (typeTable != null) {
1533                     for (int j = 0; j < typeTable.length; j += 3) {
1534                         if (typeTable[j] == start && typeTable[j + 1] == index) {
1535                             vsignature = readUTF8(typeTable[j + 2], c);


1536                             break;
1537                         }
1538                     }
1539                 }
1540                 mv.visitLocalVariable(readUTF8(u + 4, c), readUTF8(u + 6, c),
1541                         vsignature, labels[start], labels[start + length],



1542                         index);
1543                 u += 10;
1544             }
1545         }
1546 
1547         // visits the local variables type annotations
1548         if (tanns != null) {
1549             for (int i = 0; i < tanns.length; ++i) {
1550                 if ((readByte(tanns[i]) >> 1) == (0x40 >> 1)) {
1551                     int v = readAnnotationTarget(context, tanns[i]);
1552                     v = readAnnotationValues(v + 2, c, true,
1553                             mv.visitLocalVariableAnnotation(context.typeRef,
1554                                     context.typePath, context.start,
1555                                     context.end, context.index, readUTF8(v, c),
1556                                     true));
1557                 }
1558             }
1559         }
1560         if (itanns != null) {
1561             for (int i = 0; i < itanns.length; ++i) {
1562                 if ((readByte(itanns[i]) >> 1) == (0x40 >> 1)) {
1563                     int v = readAnnotationTarget(context, itanns[i]);
1564                     v = readAnnotationValues(v + 2, c, true,
1565                             mv.visitLocalVariableAnnotation(context.typeRef,
1566                                     context.typePath, context.start,
1567                                     context.end, context.index, readUTF8(v, c),
1568                                     false));
1569                 }
1570             }
1571         }
1572 
1573         // visits the code attributes
1574         while (attributes != null) {
1575             Attribute attr = attributes.next;
1576             attributes.next = null;
1577             mv.visitAttribute(attributes);
1578             attributes = attr;
1579         }
1580 
1581         // visits the max stack and max locals values
1582         mv.visitMaxs(maxStack, maxLocals);
1583     }
1584 
1585     /**
1586      * Parses a type annotation table to find the labels, and to visit the try
1587      * catch block annotations.
1588      *
1589      * @param u
1590      *            the start offset of a type annotation table.
1591      * @param mv
1592      *            the method visitor to be used to visit the try catch block
1593      *            annotations.
1594      * @param context
1595      *            information about the class being parsed.
1596      * @param visible
1597      *            if the type annotation table to parse contains runtime visible
1598      *            annotations.
1599      * @return the start offset of each type annotation in the parsed table.
1600      */
1601     private int[] readTypeAnnotations(final MethodVisitor mv,
1602             final Context context, int u, boolean visible) {
1603         char[] c = context.buffer;
1604         int[] offsets = new int[readUnsignedShort(u)];
1605         u += 2;
1606         for (int i = 0; i < offsets.length; ++i) {
1607             offsets[i] = u;
1608             int target = readInt(u);
1609             switch (target >>> 24) {
1610             case 0x00: // CLASS_TYPE_PARAMETER
1611             case 0x01: // METHOD_TYPE_PARAMETER
1612             case 0x16: // METHOD_FORMAL_PARAMETER
1613                 u += 2;
1614                 break;
1615             case 0x13: // FIELD
1616             case 0x14: // METHOD_RETURN
1617             case 0x15: // METHOD_RECEIVER
1618                 u += 1;
1619                 break;
1620             case 0x40: // LOCAL_VARIABLE
1621             case 0x41: // RESOURCE_VARIABLE
1622                 for (int j = readUnsignedShort(u + 1); j > 0; --j) {
1623                     int start = readUnsignedShort(u + 3);
1624                     int length = readUnsignedShort(u + 5);
1625                     readLabel(start, context.labels);
1626                     readLabel(start + length, context.labels);
1627                     u += 6;
1628                 }
1629                 u += 3;
1630                 break;
1631             case 0x47: // CAST
1632             case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
1633             case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT
1634             case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
1635             case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT
1636                 u += 4;
1637                 break;
1638             // case 0x10: // CLASS_EXTENDS
1639             // case 0x11: // CLASS_TYPE_PARAMETER_BOUND
1640             // case 0x12: // METHOD_TYPE_PARAMETER_BOUND
1641             // case 0x17: // THROWS
1642             // case 0x42: // EXCEPTION_PARAMETER
1643             // case 0x43: // INSTANCEOF
1644             // case 0x44: // NEW
1645             // case 0x45: // CONSTRUCTOR_REFERENCE
1646             // case 0x46: // METHOD_REFERENCE
1647             default:
1648                 u += 3;
1649                 break;
1650             }
1651             int pathLength = readByte(u);
1652             if ((target >>> 24) == 0x42) {
1653                 TypePath path = pathLength == 0 ? null : new TypePath(b, u);
1654                 u += 1 + 2 * pathLength;
1655                 u = readAnnotationValues(u + 2, c, true,
1656                         mv.visitTryCatchAnnotation(target, path,
1657                                 readUTF8(u, c), visible));
1658             } else {
1659                 u = readAnnotationValues(u + 3 + 2 * pathLength, c, true, null);
1660             }
1661         }
1662         return offsets;
1663     }
1664 
1665     /**
1666      * Parses the header of a type annotation to extract its target_type and
1667      * target_path (the result is stored in the given context), and returns the
1668      * start offset of the rest of the type_annotation structure (i.e. the
1669      * offset to the type_index field, which is followed by
1670      * num_element_value_pairs and then the name,value pairs).
1671      *
1672      * @param context
1673      *            information about the class being parsed. This is where the
1674      *            extracted target_type and target_path must be stored.
1675      * @param u
1676      *            the start offset of a type_annotation structure.
1677      * @return the start offset of the rest of the type_annotation structure.
1678      */
1679     private int readAnnotationTarget(final Context context, int u) {
1680         int target = readInt(u);
1681         switch (target >>> 24) {
1682         case 0x00: // CLASS_TYPE_PARAMETER
1683         case 0x01: // METHOD_TYPE_PARAMETER
1684         case 0x16: // METHOD_FORMAL_PARAMETER
1685             target &= 0xFFFF0000;
1686             u += 2;
1687             break;
1688         case 0x13: // FIELD
1689         case 0x14: // METHOD_RETURN
1690         case 0x15: // METHOD_RECEIVER
1691             target &= 0xFF000000;
1692             u += 1;
1693             break;
1694         case 0x40: // LOCAL_VARIABLE
1695         case 0x41: { // RESOURCE_VARIABLE
1696             target &= 0xFF000000;
1697             int n = readUnsignedShort(u + 1);
1698             context.start = new Label[n];
1699             context.end = new Label[n];
1700             context.index = new int[n];
1701             u += 3;
1702             for (int i = 0; i < n; ++i) {
1703                 int start = readUnsignedShort(u);
1704                 int length = readUnsignedShort(u + 2);
1705                 context.start[i] = readLabel(start, context.labels);
1706                 context.end[i] = readLabel(start + length, context.labels);
1707                 context.index[i] = readUnsignedShort(u + 4);
1708                 u += 6;
1709             }
1710             break;
1711         }
1712         case 0x47: // CAST
1713         case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
1714         case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT
1715         case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
1716         case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT
1717             target &= 0xFF0000FF;
1718             u += 4;
1719             break;
1720         // case 0x10: // CLASS_EXTENDS
1721         // case 0x11: // CLASS_TYPE_PARAMETER_BOUND
1722         // case 0x12: // METHOD_TYPE_PARAMETER_BOUND
1723         // case 0x17: // THROWS
1724         // case 0x42: // EXCEPTION_PARAMETER
1725         // case 0x43: // INSTANCEOF
1726         // case 0x44: // NEW
1727         // case 0x45: // CONSTRUCTOR_REFERENCE
1728         // case 0x46: // METHOD_REFERENCE
1729         default:
1730             target &= (target >>> 24) < 0x43 ? 0xFFFFFF00 : 0xFF000000;
1731             u += 3;
1732             break;
1733         }
1734         int pathLength = readByte(u);
1735         context.typeRef = target;
1736         context.typePath = pathLength == 0 ? null : new TypePath(b, u);
1737         return u + 1 + 2 * pathLength;
1738     }
1739 
1740     /**
1741      * Reads parameter annotations and makes the given visitor visit them.
1742      *
1743      * @param mv
1744      *            the visitor that must visit the annotations.
1745      * @param context
1746      *            information about the class being parsed.
1747      * @param v
1748      *            start offset in {@link #b b} of the annotations to be read.
1749      * @param visible
1750      *            <tt>true</tt> if the annotations to be read are visible at
1751      *            runtime.
1752      */
1753     private void readParameterAnnotations(final MethodVisitor mv,
1754             final Context context, int v, final boolean visible) {





1755         int i;
1756         int n = b[v++] & 0xFF;
1757         // workaround for a bug in javac (javac compiler generates a parameter
1758         // annotation array whose size is equal to the number of parameters in
1759         // the Java source file, while it should generate an array whose size is
1760         // equal to the number of parameters in the method descriptor - which
1761         // includes the synthetic parameters added by the compiler). This work-
1762         // around supposes that the synthetic parameters are the first ones.
1763         int synthetics = Type.getArgumentTypes(context.desc).length - n;
1764         AnnotationVisitor av;
1765         for (i = 0; i < synthetics; ++i) {
1766             // virtual annotation to detect synthetic parameters in MethodWriter
1767             av = mv.visitParameterAnnotation(i, "Ljava/lang/Synthetic;", false);
1768             if (av != null) {
1769                 av.visitEnd();
1770             }
1771         }
1772         char[] c = context.buffer;
1773         for (; i < n + synthetics; ++i) {
1774             int j = readUnsignedShort(v);
1775             v += 2;
1776             for (; j > 0; --j) {
1777                 av = mv.visitParameterAnnotation(i, readUTF8(v, c), visible);
1778                 v = readAnnotationValues(v + 2, c, true, av);
1779             }
1780         }
1781     }
1782 
1783     /**
1784      * Reads the values of an annotation and makes the given visitor visit them.
1785      *
1786      * @param v
1787      *            the start offset in {@link #b b} of the values to be read
1788      *            (including the unsigned short that gives the number of
1789      *            values).
1790      * @param buf
1791      *            buffer to be used to call {@link #readUTF8 readUTF8},
1792      *            {@link #readClass(int,char[]) readClass} or {@link #readConst
1793      *            readConst}.
1794      * @param named
1795      *            if the annotation values are named or not.
1796      * @param av
1797      *            the visitor that must visit the values.
1798      * @return the end offset of the annotation values.
1799      */
1800     private int readAnnotationValues(int v, final char[] buf,
1801             final boolean named, final AnnotationVisitor av) {




1802         int i = readUnsignedShort(v);
1803         v += 2;
1804         if (named) {
1805             for (; i > 0; --i) {
1806                 v = readAnnotationValue(v + 2, buf, readUTF8(v, buf), av);
1807             }
1808         } else {
1809             for (; i > 0; --i) {
1810                 v = readAnnotationValue(v, buf, null, av);
1811             }
1812         }
1813         if (av != null) {
1814             av.visitEnd();
1815         }
1816         return v;
1817     }
1818 
1819     /**
1820      * Reads a value of an annotation and makes the given visitor visit it.
1821      *
1822      * @param v
1823      *            the start offset in {@link #b b} of the value to be read
1824      *            (<i>not including the value name constant pool index</i>).
1825      * @param buf
1826      *            buffer to be used to call {@link #readUTF8 readUTF8},
1827      *            {@link #readClass(int,char[]) readClass} or {@link #readConst
1828      *            readConst}.
1829      * @param name
1830      *            the name of the value to be read.
1831      * @param av
1832      *            the visitor that must visit the value.
1833      * @return the end offset of the annotation value.
1834      */
1835     private int readAnnotationValue(int v, final char[] buf, final String name,
1836             final AnnotationVisitor av) {




1837         int i;
1838         if (av == null) {
1839             switch (b[v] & 0xFF) {
1840             case 'e': // enum_const_value
1841                 return v + 5;
1842             case '@': // annotation_value
1843                 return readAnnotationValues(v + 3, buf, true, null);
1844             case '[': // array_value
1845                 return readAnnotationValues(v + 1, buf, false, null);
1846             default:
1847                 return v + 3;
1848             }
1849         }
1850         switch (b[v++] & 0xFF) {
1851         case 'I': // pointer to CONSTANT_Integer
1852         case 'J': // pointer to CONSTANT_Long
1853         case 'F': // pointer to CONSTANT_Float
1854         case 'D': // pointer to CONSTANT_Double
1855             av.visit(name, readConst(readUnsignedShort(v), buf));
1856             v += 2;
1857             break;
1858         case 'B': // pointer to CONSTANT_Byte
1859             av.visit(name,
1860                     new Byte((byte) readInt(items[readUnsignedShort(v)])));
1861             v += 2;
1862             break;
1863         case 'Z': // pointer to CONSTANT_Boolean
1864             av.visit(name,
1865                     readInt(items[readUnsignedShort(v)]) == 0 ? Boolean.FALSE
1866                             : Boolean.TRUE);
1867             v += 2;
1868             break;
1869         case 'S': // pointer to CONSTANT_Short
1870             av.visit(name, new Short(
1871                     (short) readInt(items[readUnsignedShort(v)])));
1872             v += 2;
1873             break;
1874         case 'C': // pointer to CONSTANT_Char
1875             av.visit(name, new Character(
1876                     (char) readInt(items[readUnsignedShort(v)])));
1877             v += 2;
1878             break;
1879         case 's': // pointer to CONSTANT_Utf8
1880             av.visit(name, readUTF8(v, buf));
1881             v += 2;
1882             break;
1883         case 'e': // enum_const_value
1884             av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf));
1885             v += 4;
1886             break;
1887         case 'c': // class_info
1888             av.visit(name, Type.getType(readUTF8(v, buf)));
1889             v += 2;
1890             break;
1891         case '@': // annotation_value
1892             v = readAnnotationValues(v + 2, buf, true,


1893                     av.visitAnnotation(name, readUTF8(v, buf)));
1894             break;
1895         case '[': // array_value
1896             int size = readUnsignedShort(v);
1897             v += 2;
1898             if (size == 0) {
1899                 return readAnnotationValues(v - 2, buf, false,


1900                         av.visitArray(name));
1901             }
1902             switch (this.b[v++] & 0xFF) {
1903             case 'B':
1904                 byte[] bv = new byte[size];
1905                 for (i = 0; i < size; i++) {
1906                     bv[i] = (byte) readInt(items[readUnsignedShort(v)]);
1907                     v += 3;
1908                 }
1909                 av.visit(name, bv);
1910                 --v;
1911                 break;
1912             case 'Z':
1913                 boolean[] zv = new boolean[size];
1914                 for (i = 0; i < size; i++) {
1915                     zv[i] = readInt(items[readUnsignedShort(v)]) != 0;
1916                     v += 3;
1917                 }
1918                 av.visit(name, zv);
1919                 --v;


1940                 int[] iv = new int[size];
1941                 for (i = 0; i < size; i++) {
1942                     iv[i] = readInt(items[readUnsignedShort(v)]);
1943                     v += 3;
1944                 }
1945                 av.visit(name, iv);
1946                 --v;
1947                 break;
1948             case 'J':
1949                 long[] lv = new long[size];
1950                 for (i = 0; i < size; i++) {
1951                     lv[i] = readLong(items[readUnsignedShort(v)]);
1952                     v += 3;
1953                 }
1954                 av.visit(name, lv);
1955                 --v;
1956                 break;
1957             case 'F':
1958                 float[] fv = new float[size];
1959                 for (i = 0; i < size; i++) {
1960                     fv[i] = Float
1961                             .intBitsToFloat(readInt(items[readUnsignedShort(v)]));
1962                     v += 3;
1963                 }
1964                 av.visit(name, fv);
1965                 --v;
1966                 break;
1967             case 'D':
1968                 double[] dv = new double[size];
1969                 for (i = 0; i < size; i++) {
1970                     dv[i] = Double
1971                             .longBitsToDouble(readLong(items[readUnsignedShort(v)]));
1972                     v += 3;
1973                 }
1974                 av.visit(name, dv);
1975                 --v;
1976                 break;
1977             default:
1978                 v = readAnnotationValues(v - 3, buf, false, av.visitArray(name));



1979             }
1980         }
1981         return v;
1982     }
1983 
1984     /**
1985      * Computes the implicit frame of the method currently being parsed (as
1986      * defined in the given {@link Context}) and stores it in the given context.
1987      *
1988      * @param frame
1989      *            information about the class being parsed.
1990      */
1991     private void getImplicitFrame(final Context frame) {
1992         String desc = frame.desc;
1993         Object[] locals = frame.local;
1994         int local = 0;
1995         if ((frame.access & Opcodes.ACC_STATIC) == 0) {
1996             if ("<init>".equals(frame.name)) {
1997                 locals[local++] = Opcodes.UNINITIALIZED_THIS;
1998             } else {
1999                 locals[local++] = readClass(header + 2, frame.buffer);
2000             }
2001         }
2002         int i = 1;
2003         loop: while (true) {
2004             int j = i;
2005             switch (desc.charAt(i++)) {
2006             case 'Z':
2007             case 'C':
2008             case 'B':
2009             case 'S':
2010             case 'I':
2011                 locals[local++] = Opcodes.INTEGER;
2012                 break;
2013             case 'F':
2014                 locals[local++] = Opcodes.FLOAT;
2015                 break;
2016             case 'J':
2017                 locals[local++] = Opcodes.LONG;
2018                 break;
2019             case 'D':
2020                 locals[local++] = Opcodes.DOUBLE;
2021                 break;
2022             case '[':
2023                 while (desc.charAt(i) == '[') {
2024                     ++i;
2025                 }
2026                 if (desc.charAt(i) == 'L') {
2027                     ++i;
2028                     while (desc.charAt(i) != ';') {
2029                         ++i;
2030                     }
2031                 }
2032                 locals[local++] = desc.substring(j, ++i);
2033                 break;
2034             case 'L':
2035                 while (desc.charAt(i) != ';') {
2036                     ++i;
2037                 }
2038                 locals[local++] = desc.substring(j + 1, i++);
2039                 break;
2040             default:
2041                 break loop;
2042             }
2043         }
2044         frame.localCount = local;
2045     }
2046 
2047     /**
2048      * Reads a stack map frame and stores the result in the given
2049      * {@link Context} object.
2050      *
2051      * @param stackMap
2052      *            the start offset of a stack map frame in the class file.
2053      * @param zip
2054      *            if the stack map frame at stackMap is compressed or not.
2055      * @param unzip
2056      *            if the stack map frame must be uncompressed.
2057      * @param frame
2058      *            where the parsed stack map frame must be stored.
2059      * @return the offset of the first byte following the parsed frame.
2060      */
2061     private int readFrame(int stackMap, boolean zip, boolean unzip,
2062             Context frame) {
2063         char[] c = frame.buffer;
2064         Label[] labels = frame.labels;
2065         int tag;
2066         int delta;
2067         if (zip) {
2068             tag = b[stackMap++] & 0xFF;
2069         } else {
2070             tag = MethodWriter.FULL_FRAME;
2071             frame.offset = -1;
2072         }
2073         frame.localDiff = 0;
2074         if (tag < MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME) {
2075             delta = tag;
2076             frame.mode = Opcodes.F_SAME;
2077             frame.stackCount = 0;
2078         } else if (tag < MethodWriter.RESERVED) {
2079             delta = tag - MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME;
2080             stackMap = readFrameType(frame.stack, 0, stackMap, c, labels);
2081             frame.mode = Opcodes.F_SAME1;
2082             frame.stackCount = 1;
2083         } else {
2084             delta = readUnsignedShort(stackMap);
2085             stackMap += 2;
2086             if (tag == MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) {
2087                 stackMap = readFrameType(frame.stack, 0, stackMap, c, labels);
2088                 frame.mode = Opcodes.F_SAME1;
2089                 frame.stackCount = 1;
2090             } else if (tag >= MethodWriter.CHOP_FRAME
2091                     && tag < MethodWriter.SAME_FRAME_EXTENDED) {
2092                 frame.mode = Opcodes.F_CHOP;
2093                 frame.localDiff = MethodWriter.SAME_FRAME_EXTENDED - tag;
2094                 frame.localCount -= frame.localDiff;
2095                 frame.stackCount = 0;
2096             } else if (tag == MethodWriter.SAME_FRAME_EXTENDED) {
2097                 frame.mode = Opcodes.F_SAME;
2098                 frame.stackCount = 0;
2099             } else if (tag < MethodWriter.FULL_FRAME) {
2100                 int local = unzip ? frame.localCount : 0;
2101                 for (int i = tag - MethodWriter.SAME_FRAME_EXTENDED; i > 0; i--) {
2102                     stackMap = readFrameType(frame.local, local++, stackMap, c,
2103                             labels);
2104                 }
2105                 frame.mode = Opcodes.F_APPEND;
2106                 frame.localDiff = tag - MethodWriter.SAME_FRAME_EXTENDED;
2107                 frame.localCount += frame.localDiff;
2108                 frame.stackCount = 0;
2109             } else { // if (tag == FULL_FRAME) {
2110                 frame.mode = Opcodes.F_FULL;
2111                 int n = readUnsignedShort(stackMap);
2112                 stackMap += 2;
2113                 frame.localDiff = n;
2114                 frame.localCount = n;
2115                 for (int local = 0; n > 0; n--) {
2116                     stackMap = readFrameType(frame.local, local++, stackMap, c,
2117                             labels);
2118                 }
2119                 n = readUnsignedShort(stackMap);
2120                 stackMap += 2;
2121                 frame.stackCount = n;
2122                 for (int stack = 0; n > 0; n--) {
2123                     stackMap = readFrameType(frame.stack, stack++, stackMap, c,
2124                             labels);
2125                 }
2126             }
2127         }
2128         frame.offset += delta + 1;
2129         readLabel(frame.offset, labels);
2130         return stackMap;
2131     }
2132 
2133     /**
2134      * Reads a stack map frame type and stores it at the given index in the
2135      * given array.
2136      *
2137      * @param frame
2138      *            the array where the parsed type must be stored.
2139      * @param index
2140      *            the index in 'frame' where the parsed type must be stored.
2141      * @param v
2142      *            the start offset of the stack map frame type to read.
2143      * @param buf
2144      *            a buffer to read strings.
2145      * @param labels
2146      *            the labels of the method currently being parsed, indexed by
2147      *            their offset. If the parsed type is an Uninitialized type, a
2148      *            new label for the corresponding NEW instruction is stored in
2149      *            this array if it does not already exist.
2150      * @return the offset of the first byte after the parsed type.
2151      */
2152     private int readFrameType(final Object[] frame, final int index, int v,
2153             final char[] buf, final Label[] labels) {
2154         int type = b[v++] & 0xFF;
2155         switch (type) {
2156         case 0:
2157             frame[index] = Opcodes.TOP;
2158             break;
2159         case 1:
2160             frame[index] = Opcodes.INTEGER;
2161             break;
2162         case 2:
2163             frame[index] = Opcodes.FLOAT;
2164             break;
2165         case 3:
2166             frame[index] = Opcodes.DOUBLE;
2167             break;
2168         case 4:
2169             frame[index] = Opcodes.LONG;
2170             break;
2171         case 5:
2172             frame[index] = Opcodes.NULL;
2173             break;
2174         case 6:
2175             frame[index] = Opcodes.UNINITIALIZED_THIS;
2176             break;
2177         case 7: // Object
2178             frame[index] = readClass(v, buf);
2179             v += 2;
2180             break;
2181         default: // Uninitialized
2182             frame[index] = readLabel(readUnsignedShort(v), labels);
2183             v += 2;
2184         }
2185         return v;
2186     }
2187 
2188     /**
2189      * Returns the label corresponding to the given offset. The default
2190      * implementation of this method creates a label for the given offset if it
2191      * has not been already created.
2192      *
2193      * @param offset
2194      *            a bytecode offset in a method.
2195      * @param labels
2196      *            the already created labels, indexed by their offset. If a
2197      *            label already exists for offset this method must not create a
2198      *            new one. Otherwise it must store the new label in this array.
2199      * @return a non null Label, which must be equal to labels[offset].
2200      */
2201     protected Label readLabel(int offset, Label[] labels) {
2202         if (labels[offset] == null) {
2203             labels[offset] = new Label();
2204         }
2205         return labels[offset];
2206     }
2207 
2208     /**
2209      * Returns the start index of the attribute_info structure of this class.
2210      *
2211      * @return the start index of the attribute_info structure of this class.
2212      */
2213     private int getAttributes() {
2214         // skips the header
2215         int u = header + 8 + readUnsignedShort(header + 6) * 2;
2216         // skips fields and methods
2217         for (int i = readUnsignedShort(u); i > 0; --i) {
2218             for (int j = readUnsignedShort(u + 8); j > 0; --j) {
2219                 u += 6 + readInt(u + 12);
2220             }
2221             u += 8;
2222         }
2223         u += 2;
2224         for (int i = readUnsignedShort(u); i > 0; --i) {
2225             for (int j = readUnsignedShort(u + 8); j > 0; --j) {
2226                 u += 6 + readInt(u + 12);
2227             }
2228             u += 8;
2229         }
2230         // the attribute_info structure starts just after the methods
2231         return u + 2;
2232     }
2233 
2234     /**
2235      * Reads an attribute in {@link #b b}.
2236      *
2237      * @param attrs
2238      *            prototypes of the attributes that must be parsed during the
2239      *            visit of the class. Any attribute whose type is not equal to
2240      *            the type of one the prototypes is ignored (i.e. an empty
2241      *            {@link Attribute} instance is returned).
2242      * @param type
2243      *            the type of the attribute.
2244      * @param off
2245      *            index of the first byte of the attribute's content in
2246      *            {@link #b b}. The 6 attribute header bytes, containing the
2247      *            type and the length of the attribute, are not taken into
2248      *            account here (they have already been read).
2249      * @param len
2250      *            the length of the attribute's content.
2251      * @param buf
2252      *            buffer to be used to call {@link #readUTF8 readUTF8},
2253      *            {@link #readClass(int,char[]) readClass} or {@link #readConst
2254      *            readConst}.
2255      * @param codeOff
2256      *            index of the first byte of code's attribute content in
2257      *            {@link #b b}, or -1 if the attribute to be read is not a code
2258      *            attribute. The 6 attribute header bytes, containing the type
2259      *            and the length of the attribute, are not taken into account
2260      *            here.
2261      * @param labels
2262      *            the labels of the method's code, or <tt>null</tt> if the
2263      *            attribute to be read is not a code attribute.
2264      * @return the attribute that has been read, or <tt>null</tt> to skip this
2265      *         attribute.
2266      */
2267     private Attribute readAttribute(final Attribute[] attrs, final String type,
2268             final int off, final int len, final char[] buf, final int codeOff,
2269             final Label[] labels) {






2270         for (int i = 0; i < attrs.length; ++i) {
2271             if (attrs[i].type.equals(type)) {
2272                 return attrs[i].read(this, off, len, buf, codeOff, labels);
2273             }
2274         }
2275         return new Attribute(type).read(this, off, len, null, -1, null);
2276     }
2277 
2278     // ------------------------------------------------------------------------
2279     // Utility methods: low level parsing
2280     // ------------------------------------------------------------------------
2281 
2282     /**
2283      * Returns the number of constant pool items in {@link #b b}.
2284      *
2285      * @return the number of constant pool items in {@link #b b}.
2286      */
2287     public int getItemCount() {
2288         return items.length;
2289     }
2290 
2291     /**
2292      * Returns the start index of the constant pool item in {@link #b b}, plus
2293      * one. <i>This method is intended for {@link Attribute} sub classes, and is
2294      * normally not needed by class generators or adapters.</i>
2295      *
2296      * @param item
2297      *            the index a constant pool item.
2298      * @return the start index of the constant pool item in {@link #b b}, plus
2299      *         one.
2300      */
2301     public int getItem(final int item) {
2302         return items[item];
2303     }
2304 
2305     /**
2306      * Returns the maximum length of the strings contained in the constant pool
2307      * of the class.
2308      *
2309      * @return the maximum length of the strings contained in the constant pool
2310      *         of the class.
2311      */
2312     public int getMaxStringLength() {
2313         return maxStringLength;
2314     }
2315 
2316     /**
2317      * Reads a byte value in {@link #b b}. <i>This method is intended for
2318      * {@link Attribute} sub classes, and is normally not needed by class
2319      * generators or adapters.</i>
2320      *
2321      * @param index
2322      *            the start index of the value to be read in {@link #b b}.
2323      * @return the read value.
2324      */
2325     public int readByte(final int index) {
2326         return b[index] & 0xFF;
2327     }
2328 
2329     /**
2330      * Reads an unsigned short value in {@link #b b}. <i>This method is intended
2331      * for {@link Attribute} sub classes, and is normally not needed by class
2332      * generators or adapters.</i>
2333      *
2334      * @param index
2335      *            the start index of the value to be read in {@link #b b}.
2336      * @return the read value.
2337      */
2338     public int readUnsignedShort(final int index) {
2339         byte[] b = this.b;
2340         return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF);
2341     }
2342 
2343     /**
2344      * Reads a signed short value in {@link #b b}. <i>This method is intended
2345      * for {@link Attribute} sub classes, and is normally not needed by class
2346      * generators or adapters.</i>
2347      *
2348      * @param index
2349      *            the start index of the value to be read in {@link #b b}.
2350      * @return the read value.
2351      */
2352     public short readShort(final int index) {
2353         byte[] b = this.b;
2354         return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF));
2355     }
2356 
2357     /**
2358      * Reads a signed int value in {@link #b b}. <i>This method is intended for
2359      * {@link Attribute} sub classes, and is normally not needed by class
2360      * generators or adapters.</i>
2361      *
2362      * @param index
2363      *            the start index of the value to be read in {@link #b b}.
2364      * @return the read value.
2365      */
2366     public int readInt(final int index) {
2367         byte[] b = this.b;
2368         return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16)
2369                 | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF);
2370     }
2371 
2372     /**
2373      * Reads a signed long value in {@link #b b}. <i>This method is intended for
2374      * {@link Attribute} sub classes, and is normally not needed by class
2375      * generators or adapters.</i>
2376      *
2377      * @param index
2378      *            the start index of the value to be read in {@link #b b}.
2379      * @return the read value.
2380      */
2381     public long readLong(final int index) {
2382         long l1 = readInt(index);
2383         long l0 = readInt(index + 4) & 0xFFFFFFFFL;
2384         return (l1 << 32) | l0;
2385     }
2386 
2387     /**
2388      * Reads an UTF8 string constant pool item in {@link #b b}. <i>This method
2389      * is intended for {@link Attribute} sub classes, and is normally not needed
2390      * by class generators or adapters.</i>
2391      *
2392      * @param index
2393      *            the start index of an unsigned short value in {@link #b b},
2394      *            whose value is the index of an UTF8 constant pool item.
2395      * @param buf
2396      *            buffer to be used to read the item. This buffer must be
2397      *            sufficiently large. It is not automatically resized.
2398      * @return the String corresponding to the specified UTF8 item.
2399      */
2400     public String readUTF8(int index, final char[] buf) {
2401         int item = readUnsignedShort(index);
2402         if (index == 0 || item == 0) {
2403             return null;
2404         }
2405         String s = strings[item];
2406         if (s != null) {
2407             return s;
2408         }
2409         index = items[item];
2410         return strings[item] = readUTF(index + 2, readUnsignedShort(index), buf);
2411     }
2412 
2413     /**
2414      * Reads UTF8 string in {@link #b b}.
2415      *
2416      * @param index
2417      *            start offset of the UTF8 string to be read.
2418      * @param utfLen
2419      *            length of the UTF8 string to be read.
2420      * @param buf
2421      *            buffer to be used to read the string. This buffer must be
2422      *            sufficiently large. It is not automatically resized.
2423      * @return the String corresponding to the specified UTF8 string.
2424      */
2425     private String readUTF(int index, final int utfLen, final char[] buf) {
2426         int endIndex = index + utfLen;
2427         byte[] b = this.b;
2428         int strLen = 0;
2429         int c;
2430         int st = 0;
2431         char cc = 0;
2432         while (index < endIndex) {
2433             c = b[index++];
2434             switch (st) {
2435             case 0:
2436                 c = c & 0xFF;
2437                 if (c < 0x80) { // 0xxxxxxx
2438                     buf[strLen++] = (char) c;
2439                 } else if (c < 0xE0 && c > 0xBF) { // 110x xxxx 10xx xxxx
2440                     cc = (char) (c & 0x1F);
2441                     st = 1;


2447 
2448             case 1: // byte 2 of 2-byte char or byte 3 of 3-byte char
2449                 buf[strLen++] = (char) ((cc << 6) | (c & 0x3F));
2450                 st = 0;
2451                 break;
2452 
2453             case 2: // byte 2 of 3-byte char
2454                 cc = (char) ((cc << 6) | (c & 0x3F));
2455                 st = 1;
2456                 break;
2457             }
2458         }
2459         return new String(buf, 0, strLen);
2460     }
2461 
2462     /**
2463      * Reads a class constant pool item in {@link #b b}. <i>This method is
2464      * intended for {@link Attribute} sub classes, and is normally not needed by
2465      * class generators or adapters.</i>
2466      *
2467      * @param index
2468      *            the start index of an unsigned short value in {@link #b b},
2469      *            whose value is the index of a class constant pool item.
2470      * @param buf
2471      *            buffer to be used to read the item. This buffer must be
2472      *            sufficiently large. It is not automatically resized.
2473      * @return the String corresponding to the specified class item.
2474      */
2475     public String readClass(final int index, final char[] buf) {
2476         // computes the start index of the CONSTANT_Class item in b
2477         // and reads the CONSTANT_Utf8 item designated by
2478         // the first two bytes of this CONSTANT_Class item
2479         return readUTF8(items[readUnsignedShort(index)], buf);
2480     }
2481 
2482     /**
2483      * Reads a numeric or string constant pool item in {@link #b b}. <i>This
2484      * method is intended for {@link Attribute} sub classes, and is normally not
2485      * needed by class generators or adapters.</i>
2486      *
2487      * @param item
2488      *            the index of a constant pool item.
2489      * @param buf
2490      *            buffer to be used to read the item. This buffer must be
2491      *            sufficiently large. It is not automatically resized.
2492      * @return the {@link Integer}, {@link Float}, {@link Long}, {@link Double},
2493      *         {@link String}, {@link Type} or {@link Handle} corresponding to
2494      *         the given constant pool item.
2495      */
2496     public Object readConst(final int item, final char[] buf) {
2497         int index = items[item];
2498         switch (b[index - 1]) {
2499         case ClassWriter.INT:
2500             return new Integer(readInt(index));
2501         case ClassWriter.FLOAT:
2502             return new Float(Float.intBitsToFloat(readInt(index)));
2503         case ClassWriter.LONG:
2504             return new Long(readLong(index));
2505         case ClassWriter.DOUBLE:
2506             return new Double(Double.longBitsToDouble(readLong(index)));
2507         case ClassWriter.CLASS:
2508             return Type.getObjectType(readUTF8(index, buf));
2509         case ClassWriter.STR:
2510             return readUTF8(index, buf);
2511         case ClassWriter.MTYPE:
2512             return Type.getMethodType(readUTF8(index, buf));
2513         default: // case ClassWriter.HANDLE_BASE + [1..9]:


2514             int tag = readByte(index);
2515             int[] items = this.items;
2516             int cpIndex = items[readUnsignedShort(index + 1)];
2517             String owner = readClass(cpIndex, buf);
2518             cpIndex = items[readUnsignedShort(cpIndex + 2)];
2519             String name = readUTF8(cpIndex, buf);
2520             String desc = readUTF8(cpIndex + 2, buf);
2521             return new Handle(tag, owner, name, desc);
2522         }
2523     }

2524 }