1 /*** 2 * ASM: a very small and fast Java bytecode manipulation framework 3 * Copyright (c) 2000-2011 INRIA, France Telecom 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of the copyright holders nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 package org.objectweb.asm; 31 32 import java.io.IOException; 33 import java.io.InputStream; 34 35 /** 36 * A Java class parser to make a {@link ClassVisitor} visit an existing class. 37 * This class parses a byte array conforming to the Java class file format and 38 * calls the appropriate visit methods of a given class visitor for each field, 39 * method and bytecode instruction encountered. 40 * 41 * @author Eric Bruneton 42 * @author Eugene Kuleshov 43 */ 44 public class ClassReader { 45 46 /** 47 * True to enable signatures support. 48 */ 49 static final boolean SIGNATURES = true; 50 51 /** 52 * True to enable annotations support. 53 */ 54 static final boolean ANNOTATIONS = true; 55 56 /** 57 * True to enable stack map frames support. 58 */ 59 static final boolean FRAMES = true; 60 61 /** 62 * True to enable bytecode writing support. 63 */ 64 static final boolean WRITER = true; 65 66 /** 67 * True to enable JSR_W and GOTO_W support. 68 */ 69 static final boolean RESIZE = true; 70 71 /** 72 * Flag to skip method code. If this class is set <code>CODE</code> 73 * attribute won't be visited. This can be used, for example, to retrieve 74 * annotations for methods and method parameters. 75 */ 76 public static final int SKIP_CODE = 1; 77 78 /** 79 * Flag to skip the debug information in the class. If this flag is set the 80 * debug information of the class is not visited, i.e. the 81 * {@link MethodVisitor#visitLocalVariable visitLocalVariable} and 82 * {@link MethodVisitor#visitLineNumber visitLineNumber} methods will not be 83 * called. 84 */ 85 public static final int SKIP_DEBUG = 2; 86 87 /** 88 * Flag to skip the stack map frames in the class. If this flag is set the 89 * stack map frames of the class is not visited, i.e. the 90 * {@link MethodVisitor#visitFrame visitFrame} method will not be called. 91 * This flag is useful when the {@link ClassWriter#COMPUTE_FRAMES} option is 92 * used: it avoids visiting frames that will be ignored and recomputed from 93 * scratch in the class writer. 94 */ 95 public static final int SKIP_FRAMES = 4; 96 97 /** 98 * Flag to expand the stack map frames. By default stack map frames are 99 * visited in their original format (i.e. "expanded" for classes whose 100 * version is less than V1_6, and "compressed" for the other classes). If 101 * this flag is set, stack map frames are always visited in expanded format 102 * (this option adds a decompression/recompression step in ClassReader and 103 * ClassWriter which degrades performances quite a lot). 104 */ 105 public static final int EXPAND_FRAMES = 8; 106 107 /** 108 * The class to be parsed. <i>The content of this array must not be 109 * modified. This field is intended for {@link Attribute} sub classes, and 110 * is normally not needed by class generators or adapters.</i> 111 */ 112 public final byte[] b; 113 114 /** 115 * The start index of each constant pool item in {@link #b b}, plus one. The 116 * one byte offset skips the constant pool item tag that indicates its type. 117 */ 118 private final int[] items; 119 120 /** 121 * The String objects corresponding to the CONSTANT_Utf8 items. This cache 122 * avoids multiple parsing of a given CONSTANT_Utf8 constant pool item, 123 * which GREATLY improves performances (by a factor 2 to 3). This caching 124 * strategy could be extended to all constant pool items, but its benefit 125 * would not be so great for these items (because they are much less 126 * expensive to parse than CONSTANT_Utf8 items). 127 */ 128 private final String[] strings; 129 130 /** 131 * Maximum length of the strings contained in the constant pool of the 132 * class. 133 */ 134 private final int maxStringLength; 135 136 /** 137 * Start index of the class header information (access, name...) in 138 * {@link #b b}. 139 */ 140 public final int header; 141 142 // ------------------------------------------------------------------------ 143 // Constructors 144 // ------------------------------------------------------------------------ 145 146 /** 147 * Constructs a new {@link ClassReader} object. 148 * 149 * @param b 150 * the bytecode of the class to be read. 151 */ ClassReader(final byte[] b)152 public ClassReader(final byte[] b) { 153 this(b, 0, b.length); 154 } 155 156 /** 157 * Constructs a new {@link ClassReader} object. 158 * 159 * @param b 160 * the bytecode of the class to be read. 161 * @param off 162 * the start offset of the class data. 163 * @param len 164 * the length of the class data. 165 */ ClassReader(final byte[] b, final int off, final int len)166 public ClassReader(final byte[] b, final int off, final int len) { 167 this.b = b; 168 // checks the class version 169 if (readShort(off + 6) > Opcodes.V1_8) { 170 throw new IllegalArgumentException(); 171 } 172 // parses the constant pool 173 items = new int[readUnsignedShort(off + 8)]; 174 int n = items.length; 175 strings = new String[n]; 176 int max = 0; 177 int index = off + 10; 178 for (int i = 1; i < n; ++i) { 179 items[i] = index + 1; 180 int size; 181 switch (b[index]) { 182 case ClassWriter.FIELD: 183 case ClassWriter.METH: 184 case ClassWriter.IMETH: 185 case ClassWriter.INT: 186 case ClassWriter.FLOAT: 187 case ClassWriter.NAME_TYPE: 188 case ClassWriter.INDY: 189 size = 5; 190 break; 191 case ClassWriter.LONG: 192 case ClassWriter.DOUBLE: 193 size = 9; 194 ++i; 195 break; 196 case ClassWriter.UTF8: 197 size = 3 + readUnsignedShort(index + 1); 198 if (size > max) { 199 max = size; 200 } 201 break; 202 case ClassWriter.HANDLE: 203 size = 4; 204 break; 205 // case ClassWriter.CLASS: 206 // case ClassWriter.STR: 207 // case ClassWriter.MTYPE 208 default: 209 size = 3; 210 break; 211 } 212 index += size; 213 } 214 maxStringLength = max; 215 // the class header information starts just after the constant pool 216 header = index; 217 } 218 219 /** 220 * Returns the class's access flags (see {@link Opcodes}). This value may 221 * not reflect Deprecated and Synthetic flags when bytecode is before 1.5 222 * and those flags are represented by attributes. 223 * 224 * @return the class access flags 225 * 226 * @see ClassVisitor#visit(int, int, String, String, String, String[]) 227 */ getAccess()228 public int getAccess() { 229 return readUnsignedShort(header); 230 } 231 232 /** 233 * Returns the internal name of the class (see 234 * {@link Type#getInternalName() getInternalName}). 235 * 236 * @return the internal class name 237 * 238 * @see ClassVisitor#visit(int, int, String, String, String, String[]) 239 */ getClassName()240 public String getClassName() { 241 return readClass(header + 2, new char[maxStringLength]); 242 } 243 244 /** 245 * Returns the internal of name of the super class (see 246 * {@link Type#getInternalName() getInternalName}). For interfaces, the 247 * super class is {@link Object}. 248 * 249 * @return the internal name of super class, or <tt>null</tt> for 250 * {@link Object} class. 251 * 252 * @see ClassVisitor#visit(int, int, String, String, String, String[]) 253 */ getSuperName()254 public String getSuperName() { 255 return readClass(header + 4, new char[maxStringLength]); 256 } 257 258 /** 259 * Returns the internal names of the class's interfaces (see 260 * {@link Type#getInternalName() getInternalName}). 261 * 262 * @return the array of internal names for all implemented interfaces or 263 * <tt>null</tt>. 264 * 265 * @see ClassVisitor#visit(int, int, String, String, String, String[]) 266 */ getInterfaces()267 public String[] getInterfaces() { 268 int index = header + 6; 269 int n = readUnsignedShort(index); 270 String[] interfaces = new String[n]; 271 if (n > 0) { 272 char[] buf = new char[maxStringLength]; 273 for (int i = 0; i < n; ++i) { 274 index += 2; 275 interfaces[i] = readClass(index, buf); 276 } 277 } 278 return interfaces; 279 } 280 281 /** 282 * Copies the constant pool data into the given {@link ClassWriter}. Should 283 * be called before the {@link #accept(ClassVisitor,int)} method. 284 * 285 * @param classWriter 286 * the {@link ClassWriter} to copy constant pool into. 287 */ copyPool(final ClassWriter classWriter)288 void copyPool(final ClassWriter classWriter) { 289 char[] buf = new char[maxStringLength]; 290 int ll = items.length; 291 Item[] items2 = new Item[ll]; 292 for (int i = 1; i < ll; i++) { 293 int index = items[i]; 294 int tag = b[index - 1]; 295 Item item = new Item(i); 296 int nameType; 297 switch (tag) { 298 case ClassWriter.FIELD: 299 case ClassWriter.METH: 300 case ClassWriter.IMETH: 301 nameType = items[readUnsignedShort(index + 2)]; 302 item.set(tag, readClass(index, buf), readUTF8(nameType, buf), 303 readUTF8(nameType + 2, buf)); 304 break; 305 case ClassWriter.INT: 306 item.set(readInt(index)); 307 break; 308 case ClassWriter.FLOAT: 309 item.set(Float.intBitsToFloat(readInt(index))); 310 break; 311 case ClassWriter.NAME_TYPE: 312 item.set(tag, readUTF8(index, buf), readUTF8(index + 2, buf), 313 null); 314 break; 315 case ClassWriter.LONG: 316 item.set(readLong(index)); 317 ++i; 318 break; 319 case ClassWriter.DOUBLE: 320 item.set(Double.longBitsToDouble(readLong(index))); 321 ++i; 322 break; 323 case ClassWriter.UTF8: { 324 String s = strings[i]; 325 if (s == null) { 326 index = items[i]; 327 s = strings[i] = readUTF(index + 2, 328 readUnsignedShort(index), buf); 329 } 330 item.set(tag, s, null, null); 331 break; 332 } 333 case ClassWriter.HANDLE: { 334 int fieldOrMethodRef = items[readUnsignedShort(index + 1)]; 335 nameType = items[readUnsignedShort(fieldOrMethodRef + 2)]; 336 item.set(ClassWriter.HANDLE_BASE + readByte(index), 337 readClass(fieldOrMethodRef, buf), 338 readUTF8(nameType, buf), readUTF8(nameType + 2, buf)); 339 break; 340 } 341 case ClassWriter.INDY: 342 if (classWriter.bootstrapMethods == null) { 343 copyBootstrapMethods(classWriter, items2, buf); 344 } 345 nameType = items[readUnsignedShort(index + 2)]; 346 item.set(readUTF8(nameType, buf), readUTF8(nameType + 2, buf), 347 readUnsignedShort(index)); 348 break; 349 // case ClassWriter.STR: 350 // case ClassWriter.CLASS: 351 // case ClassWriter.MTYPE 352 default: 353 item.set(tag, readUTF8(index, buf), null, null); 354 break; 355 } 356 357 int index2 = item.hashCode % items2.length; 358 item.next = items2[index2]; 359 items2[index2] = item; 360 } 361 362 int off = items[1] - 1; 363 classWriter.pool.putByteArray(b, off, header - off); 364 classWriter.items = items2; 365 classWriter.threshold = (int) (0.75d * ll); 366 classWriter.index = ll; 367 } 368 369 /** 370 * Copies the bootstrap method data into the given {@link ClassWriter}. 371 * Should be called before the {@link #accept(ClassVisitor,int)} method. 372 * 373 * @param classWriter 374 * the {@link ClassWriter} to copy bootstrap methods into. 375 */ copyBootstrapMethods(final ClassWriter classWriter, final Item[] items, final char[] c)376 private void copyBootstrapMethods(final ClassWriter classWriter, 377 final Item[] items, final char[] c) { 378 // finds the "BootstrapMethods" attribute 379 int u = getAttributes(); 380 boolean found = false; 381 for (int i = readUnsignedShort(u); i > 0; --i) { 382 String attrName = readUTF8(u + 2, c); 383 if ("BootstrapMethods".equals(attrName)) { 384 found = true; 385 break; 386 } 387 u += 6 + readInt(u + 4); 388 } 389 if (!found) { 390 return; 391 } 392 // copies the bootstrap methods in the class writer 393 int boostrapMethodCount = readUnsignedShort(u + 8); 394 for (int j = 0, v = u + 10; j < boostrapMethodCount; j++) { 395 int position = v - u - 10; 396 int hashCode = readConst(readUnsignedShort(v), c).hashCode(); 397 for (int k = readUnsignedShort(v + 2); k > 0; --k) { 398 hashCode ^= readConst(readUnsignedShort(v + 4), c).hashCode(); 399 v += 2; 400 } 401 v += 4; 402 Item item = new Item(j); 403 item.set(position, hashCode & 0x7FFFFFFF); 404 int index = item.hashCode % items.length; 405 item.next = items[index]; 406 items[index] = item; 407 } 408 int attrSize = readInt(u + 4); 409 ByteVector bootstrapMethods = new ByteVector(attrSize + 62); 410 bootstrapMethods.putByteArray(b, u + 10, attrSize - 2); 411 classWriter.bootstrapMethodsCount = boostrapMethodCount; 412 classWriter.bootstrapMethods = bootstrapMethods; 413 } 414 415 /** 416 * Constructs a new {@link ClassReader} object. 417 * 418 * @param is 419 * an input stream from which to read the class. 420 * @throws IOException 421 * if a problem occurs during reading. 422 */ ClassReader(final InputStream is)423 public ClassReader(final InputStream is) throws IOException { 424 this(readClass(is, false)); 425 } 426 427 /** 428 * Constructs a new {@link ClassReader} object. 429 * 430 * @param name 431 * the binary qualified name of the class to be read. 432 * @throws IOException 433 * if an exception occurs during reading. 434 */ ClassReader(final String name)435 public ClassReader(final String name) throws IOException { 436 this(readClass( 437 ClassLoader.getSystemResourceAsStream(name.replace('.', '/') 438 + ".class"), true)); 439 } 440 441 /** 442 * Reads the bytecode of a class. 443 * 444 * @param is 445 * an input stream from which to read the class. 446 * @param close 447 * true to close the input stream after reading. 448 * @return the bytecode read from the given input stream. 449 * @throws IOException 450 * if a problem occurs during reading. 451 */ readClass(final InputStream is, boolean close)452 private static byte[] readClass(final InputStream is, boolean close) 453 throws IOException { 454 if (is == null) { 455 throw new IOException("Class not found"); 456 } 457 try { 458 byte[] b = new byte[is.available()]; 459 int len = 0; 460 while (true) { 461 int n = is.read(b, len, b.length - len); 462 if (n == -1) { 463 if (len < b.length) { 464 byte[] c = new byte[len]; 465 System.arraycopy(b, 0, c, 0, len); 466 b = c; 467 } 468 return b; 469 } 470 len += n; 471 if (len == b.length) { 472 int last = is.read(); 473 if (last < 0) { 474 return b; 475 } 476 byte[] c = new byte[b.length + 1000]; 477 System.arraycopy(b, 0, c, 0, len); 478 c[len++] = (byte) last; 479 b = c; 480 } 481 } 482 } finally { 483 if (close) { 484 is.close(); 485 } 486 } 487 } 488 489 // ------------------------------------------------------------------------ 490 // Public methods 491 // ------------------------------------------------------------------------ 492 493 /** 494 * Makes the given visitor visit the Java class of this {@link ClassReader} 495 * . This class is the one specified in the constructor (see 496 * {@link #ClassReader(byte[]) ClassReader}). 497 * 498 * @param classVisitor 499 * the visitor that must visit this class. 500 * @param flags 501 * option flags that can be used to modify the default behavior 502 * of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES} 503 * , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}. 504 */ accept(final ClassVisitor classVisitor, final int flags)505 public void accept(final ClassVisitor classVisitor, final int flags) { 506 accept(classVisitor, new Attribute[0], flags); 507 } 508 509 /** 510 * Makes the given visitor visit the Java class of this {@link ClassReader}. 511 * This class is the one specified in the constructor (see 512 * {@link #ClassReader(byte[]) ClassReader}). 513 * 514 * @param classVisitor 515 * the visitor that must visit this class. 516 * @param attrs 517 * prototypes of the attributes that must be parsed during the 518 * visit of the class. Any attribute whose type is not equal to 519 * the type of one the prototypes will not be parsed: its byte 520 * array value will be passed unchanged to the ClassWriter. 521 * <i>This may corrupt it if this value contains references to 522 * the constant pool, or has syntactic or semantic links with a 523 * class element that has been transformed by a class adapter 524 * between the reader and the writer</i>. 525 * @param flags 526 * option flags that can be used to modify the default behavior 527 * of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES} 528 * , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}. 529 */ accept(final ClassVisitor classVisitor, final Attribute[] attrs, final int flags)530 public void accept(final ClassVisitor classVisitor, 531 final Attribute[] attrs, final int flags) { 532 int u = header; // current offset in the class file 533 char[] c = new char[maxStringLength]; // buffer used to read strings 534 535 Context context = new Context(); 536 context.attrs = attrs; 537 context.flags = flags; 538 context.buffer = c; 539 540 // reads the class declaration 541 int access = readUnsignedShort(u); 542 String name = readClass(u + 2, c); 543 String superClass = readClass(u + 4, c); 544 String[] interfaces = new String[readUnsignedShort(u + 6)]; 545 u += 8; 546 for (int i = 0; i < interfaces.length; ++i) { 547 interfaces[i] = readClass(u, c); 548 u += 2; 549 } 550 551 // reads the class attributes 552 String signature = null; 553 String sourceFile = null; 554 String sourceDebug = null; 555 String enclosingOwner = null; 556 String enclosingName = null; 557 String enclosingDesc = null; 558 int anns = 0; 559 int ianns = 0; 560 int tanns = 0; 561 int itanns = 0; 562 int innerClasses = 0; 563 Attribute attributes = null; 564 565 u = getAttributes(); 566 for (int i = readUnsignedShort(u); i > 0; --i) { 567 String attrName = readUTF8(u + 2, c); 568 // tests are sorted in decreasing frequency order 569 // (based on frequencies observed on typical classes) 570 if ("SourceFile".equals(attrName)) { 571 sourceFile = readUTF8(u + 8, c); 572 } else if ("InnerClasses".equals(attrName)) { 573 innerClasses = u + 8; 574 } else if ("EnclosingMethod".equals(attrName)) { 575 enclosingOwner = readClass(u + 8, c); 576 int item = readUnsignedShort(u + 10); 577 if (item != 0) { 578 enclosingName = readUTF8(items[item], c); 579 enclosingDesc = readUTF8(items[item] + 2, c); 580 } 581 } else if (SIGNATURES && "Signature".equals(attrName)) { 582 signature = readUTF8(u + 8, c); 583 } else if (ANNOTATIONS 584 && "RuntimeVisibleAnnotations".equals(attrName)) { 585 anns = u + 8; 586 } else if (ANNOTATIONS 587 && "RuntimeVisibleTypeAnnotations".equals(attrName)) { 588 tanns = u + 8; 589 } else if ("Deprecated".equals(attrName)) { 590 access |= Opcodes.ACC_DEPRECATED; 591 } else if ("Synthetic".equals(attrName)) { 592 access |= Opcodes.ACC_SYNTHETIC 593 | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE; 594 } else if ("SourceDebugExtension".equals(attrName)) { 595 int len = readInt(u + 4); 596 sourceDebug = readUTF(u + 8, len, new char[len]); 597 } else if (ANNOTATIONS 598 && "RuntimeInvisibleAnnotations".equals(attrName)) { 599 ianns = u + 8; 600 } else if (ANNOTATIONS 601 && "RuntimeInvisibleTypeAnnotations".equals(attrName)) { 602 itanns = u + 8; 603 } else if ("BootstrapMethods".equals(attrName)) { 604 int[] bootstrapMethods = new int[readUnsignedShort(u + 8)]; 605 for (int j = 0, v = u + 10; j < bootstrapMethods.length; j++) { 606 bootstrapMethods[j] = v; 607 v += 2 + readUnsignedShort(v + 2) << 1; 608 } 609 context.bootstrapMethods = bootstrapMethods; 610 } else { 611 Attribute attr = readAttribute(attrs, attrName, u + 8, 612 readInt(u + 4), c, -1, null); 613 if (attr != null) { 614 attr.next = attributes; 615 attributes = attr; 616 } 617 } 618 u += 6 + readInt(u + 4); 619 } 620 621 // visits the class declaration 622 classVisitor.visit(readInt(items[1] - 7), access, name, signature, 623 superClass, interfaces); 624 625 // visits the source and debug info 626 if ((flags & SKIP_DEBUG) == 0 627 && (sourceFile != null || sourceDebug != null)) { 628 classVisitor.visitSource(sourceFile, sourceDebug); 629 } 630 631 // visits the outer class 632 if (enclosingOwner != null) { 633 classVisitor.visitOuterClass(enclosingOwner, enclosingName, 634 enclosingDesc); 635 } 636 637 // visits the class annotations and type annotations 638 if (ANNOTATIONS && anns != 0) { 639 for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) { 640 v = readAnnotationValues(v + 2, c, true, 641 classVisitor.visitAnnotation(readUTF8(v, c), true)); 642 } 643 } 644 if (ANNOTATIONS && ianns != 0) { 645 for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) { 646 v = readAnnotationValues(v + 2, c, true, 647 classVisitor.visitAnnotation(readUTF8(v, c), false)); 648 } 649 } 650 if (ANNOTATIONS && tanns != 0) { 651 for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) { 652 v = readAnnotationTarget(context, v); 653 v = readAnnotationValues(v + 2, c, true, 654 classVisitor.visitTypeAnnotation(context.typeRef, 655 context.typePath, readUTF8(v, c), true)); 656 } 657 } 658 if (ANNOTATIONS && itanns != 0) { 659 for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) { 660 v = readAnnotationTarget(context, v); 661 v = readAnnotationValues(v + 2, c, true, 662 classVisitor.visitTypeAnnotation(context.typeRef, 663 context.typePath, readUTF8(v, c), false)); 664 } 665 } 666 667 // visits the attributes 668 while (attributes != null) { 669 Attribute attr = attributes.next; 670 attributes.next = null; 671 classVisitor.visitAttribute(attributes); 672 attributes = attr; 673 } 674 675 // visits the inner classes 676 if (innerClasses != 0) { 677 int v = innerClasses + 2; 678 for (int i = readUnsignedShort(innerClasses); i > 0; --i) { 679 classVisitor.visitInnerClass(readClass(v, c), 680 readClass(v + 2, c), readUTF8(v + 4, c), 681 readUnsignedShort(v + 6)); 682 v += 8; 683 } 684 } 685 686 // visits the fields and methods 687 u = header + 10 + 2 * interfaces.length; 688 for (int i = readUnsignedShort(u - 2); i > 0; --i) { 689 u = readField(classVisitor, context, u); 690 } 691 u += 2; 692 for (int i = readUnsignedShort(u - 2); i > 0; --i) { 693 u = readMethod(classVisitor, context, u); 694 } 695 696 // visits the end of the class 697 classVisitor.visitEnd(); 698 } 699 700 /** 701 * Reads a field and makes the given visitor visit it. 702 * 703 * @param classVisitor 704 * the visitor that must visit the field. 705 * @param context 706 * information about the class being parsed. 707 * @param u 708 * the start offset of the field in the class file. 709 * @return the offset of the first byte following the field in the class. 710 */ readField(final ClassVisitor classVisitor, final Context context, int u)711 private int readField(final ClassVisitor classVisitor, 712 final Context context, int u) { 713 // reads the field declaration 714 char[] c = context.buffer; 715 int access = readUnsignedShort(u); 716 String name = readUTF8(u + 2, c); 717 String desc = readUTF8(u + 4, c); 718 u += 6; 719 720 // reads the field attributes 721 String signature = null; 722 int anns = 0; 723 int ianns = 0; 724 int tanns = 0; 725 int itanns = 0; 726 Object value = null; 727 Attribute attributes = null; 728 729 for (int i = readUnsignedShort(u); i > 0; --i) { 730 String attrName = readUTF8(u + 2, c); 731 // tests are sorted in decreasing frequency order 732 // (based on frequencies observed on typical classes) 733 if ("ConstantValue".equals(attrName)) { 734 int item = readUnsignedShort(u + 8); 735 value = item == 0 ? null : readConst(item, c); 736 } else if (SIGNATURES && "Signature".equals(attrName)) { 737 signature = readUTF8(u + 8, c); 738 } else if ("Deprecated".equals(attrName)) { 739 access |= Opcodes.ACC_DEPRECATED; 740 } else if ("Synthetic".equals(attrName)) { 741 access |= Opcodes.ACC_SYNTHETIC 742 | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE; 743 } else if (ANNOTATIONS 744 && "RuntimeVisibleAnnotations".equals(attrName)) { 745 anns = u + 8; 746 } else if (ANNOTATIONS 747 && "RuntimeVisibleTypeAnnotations".equals(attrName)) { 748 tanns = u + 8; 749 } else if (ANNOTATIONS 750 && "RuntimeInvisibleAnnotations".equals(attrName)) { 751 ianns = u + 8; 752 } else if (ANNOTATIONS 753 && "RuntimeInvisibleTypeAnnotations".equals(attrName)) { 754 itanns = u + 8; 755 } else { 756 Attribute attr = readAttribute(context.attrs, attrName, u + 8, 757 readInt(u + 4), c, -1, null); 758 if (attr != null) { 759 attr.next = attributes; 760 attributes = attr; 761 } 762 } 763 u += 6 + readInt(u + 4); 764 } 765 u += 2; 766 767 // visits the field declaration 768 FieldVisitor fv = classVisitor.visitField(access, name, desc, 769 signature, value); 770 if (fv == null) { 771 return u; 772 } 773 774 // visits the field annotations and type annotations 775 if (ANNOTATIONS && anns != 0) { 776 for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) { 777 v = readAnnotationValues(v + 2, c, true, 778 fv.visitAnnotation(readUTF8(v, c), true)); 779 } 780 } 781 if (ANNOTATIONS && ianns != 0) { 782 for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) { 783 v = readAnnotationValues(v + 2, c, true, 784 fv.visitAnnotation(readUTF8(v, c), false)); 785 } 786 } 787 if (ANNOTATIONS && tanns != 0) { 788 for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) { 789 v = readAnnotationTarget(context, v); 790 v = readAnnotationValues(v + 2, c, true, 791 fv.visitTypeAnnotation(context.typeRef, 792 context.typePath, readUTF8(v, c), true)); 793 } 794 } 795 if (ANNOTATIONS && itanns != 0) { 796 for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) { 797 v = readAnnotationTarget(context, v); 798 v = readAnnotationValues(v + 2, c, true, 799 fv.visitTypeAnnotation(context.typeRef, 800 context.typePath, readUTF8(v, c), false)); 801 } 802 } 803 804 // visits the field attributes 805 while (attributes != null) { 806 Attribute attr = attributes.next; 807 attributes.next = null; 808 fv.visitAttribute(attributes); 809 attributes = attr; 810 } 811 812 // visits the end of the field 813 fv.visitEnd(); 814 815 return u; 816 } 817 818 /** 819 * Reads a method and makes the given visitor visit it. 820 * 821 * @param classVisitor 822 * the visitor that must visit the method. 823 * @param context 824 * information about the class being parsed. 825 * @param u 826 * the start offset of the method in the class file. 827 * @return the offset of the first byte following the method in the class. 828 */ readMethod(final ClassVisitor classVisitor, final Context context, int u)829 private int readMethod(final ClassVisitor classVisitor, 830 final Context context, int u) { 831 // reads the method declaration 832 char[] c = context.buffer; 833 context.access = readUnsignedShort(u); 834 context.name = readUTF8(u + 2, c); 835 context.desc = readUTF8(u + 4, c); 836 u += 6; 837 838 // reads the method attributes 839 int code = 0; 840 int exception = 0; 841 String[] exceptions = null; 842 String signature = null; 843 int methodParameters = 0; 844 int anns = 0; 845 int ianns = 0; 846 int tanns = 0; 847 int itanns = 0; 848 int dann = 0; 849 int mpanns = 0; 850 int impanns = 0; 851 int firstAttribute = u; 852 Attribute attributes = null; 853 854 for (int i = readUnsignedShort(u); i > 0; --i) { 855 String attrName = readUTF8(u + 2, c); 856 // tests are sorted in decreasing frequency order 857 // (based on frequencies observed on typical classes) 858 if ("Code".equals(attrName)) { 859 if ((context.flags & SKIP_CODE) == 0) { 860 code = u + 8; 861 } 862 } else if ("Exceptions".equals(attrName)) { 863 exceptions = new String[readUnsignedShort(u + 8)]; 864 exception = u + 10; 865 for (int j = 0; j < exceptions.length; ++j) { 866 exceptions[j] = readClass(exception, c); 867 exception += 2; 868 } 869 } else if (SIGNATURES && "Signature".equals(attrName)) { 870 signature = readUTF8(u + 8, c); 871 } else if ("Deprecated".equals(attrName)) { 872 context.access |= Opcodes.ACC_DEPRECATED; 873 } else if (ANNOTATIONS 874 && "RuntimeVisibleAnnotations".equals(attrName)) { 875 anns = u + 8; 876 } else if (ANNOTATIONS 877 && "RuntimeVisibleTypeAnnotations".equals(attrName)) { 878 tanns = u + 8; 879 } else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) { 880 dann = u + 8; 881 } else if ("Synthetic".equals(attrName)) { 882 context.access |= Opcodes.ACC_SYNTHETIC 883 | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE; 884 } else if (ANNOTATIONS 885 && "RuntimeInvisibleAnnotations".equals(attrName)) { 886 ianns = u + 8; 887 } else if (ANNOTATIONS 888 && "RuntimeInvisibleTypeAnnotations".equals(attrName)) { 889 itanns = u + 8; 890 } else if (ANNOTATIONS 891 && "RuntimeVisibleParameterAnnotations".equals(attrName)) { 892 mpanns = u + 8; 893 } else if (ANNOTATIONS 894 && "RuntimeInvisibleParameterAnnotations".equals(attrName)) { 895 impanns = u + 8; 896 } else if ("MethodParameters".equals(attrName)) { 897 methodParameters = u + 8; 898 } else { 899 Attribute attr = readAttribute(context.attrs, attrName, u + 8, 900 readInt(u + 4), c, -1, null); 901 if (attr != null) { 902 attr.next = attributes; 903 attributes = attr; 904 } 905 } 906 u += 6 + readInt(u + 4); 907 } 908 u += 2; 909 910 // visits the method declaration 911 MethodVisitor mv = classVisitor.visitMethod(context.access, 912 context.name, context.desc, signature, exceptions); 913 if (mv == null) { 914 return u; 915 } 916 917 /* 918 * if the returned MethodVisitor is in fact a MethodWriter, it means 919 * there is no method adapter between the reader and the writer. If, in 920 * addition, the writer's constant pool was copied from this reader 921 * (mw.cw.cr == this), and the signature and exceptions of the method 922 * have not been changed, then it is possible to skip all visit events 923 * and just copy the original code of the method to the writer (the 924 * access, name and descriptor can have been changed, this is not 925 * important since they are not copied as is from the reader). 926 */ 927 if (WRITER && mv instanceof MethodWriter) { 928 MethodWriter mw = (MethodWriter) mv; 929 if (mw.cw.cr == this && signature == mw.signature) { 930 boolean sameExceptions = false; 931 if (exceptions == null) { 932 sameExceptions = mw.exceptionCount == 0; 933 } else if (exceptions.length == mw.exceptionCount) { 934 sameExceptions = true; 935 for (int j = exceptions.length - 1; j >= 0; --j) { 936 exception -= 2; 937 if (mw.exceptions[j] != readUnsignedShort(exception)) { 938 sameExceptions = false; 939 break; 940 } 941 } 942 } 943 if (sameExceptions) { 944 /* 945 * we do not copy directly the code into MethodWriter to 946 * save a byte array copy operation. The real copy will be 947 * done in ClassWriter.toByteArray(). 948 */ 949 mw.classReaderOffset = firstAttribute; 950 mw.classReaderLength = u - firstAttribute; 951 return u; 952 } 953 } 954 } 955 956 // visit the method parameters 957 if (methodParameters != 0) { 958 for (int i = b[methodParameters] & 0xFF, v = methodParameters + 1; i > 0; --i, v = v + 4) { 959 mv.visitParameter(readUTF8(v, c), readUnsignedShort(v + 2)); 960 } 961 } 962 963 // visits the method annotations 964 if (ANNOTATIONS && dann != 0) { 965 AnnotationVisitor dv = mv.visitAnnotationDefault(); 966 readAnnotationValue(dann, c, null, dv); 967 if (dv != null) { 968 dv.visitEnd(); 969 } 970 } 971 if (ANNOTATIONS && anns != 0) { 972 for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) { 973 v = readAnnotationValues(v + 2, c, true, 974 mv.visitAnnotation(readUTF8(v, c), true)); 975 } 976 } 977 if (ANNOTATIONS && ianns != 0) { 978 for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) { 979 v = readAnnotationValues(v + 2, c, true, 980 mv.visitAnnotation(readUTF8(v, c), false)); 981 } 982 } 983 if (ANNOTATIONS && tanns != 0) { 984 for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) { 985 v = readAnnotationTarget(context, v); 986 v = readAnnotationValues(v + 2, c, true, 987 mv.visitTypeAnnotation(context.typeRef, 988 context.typePath, readUTF8(v, c), true)); 989 } 990 } 991 if (ANNOTATIONS && itanns != 0) { 992 for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) { 993 v = readAnnotationTarget(context, v); 994 v = readAnnotationValues(v + 2, c, true, 995 mv.visitTypeAnnotation(context.typeRef, 996 context.typePath, readUTF8(v, c), false)); 997 } 998 } 999 if (ANNOTATIONS && mpanns != 0) { 1000 readParameterAnnotations(mv, context, mpanns, true); 1001 } 1002 if (ANNOTATIONS && impanns != 0) { 1003 readParameterAnnotations(mv, context, impanns, false); 1004 } 1005 1006 // visits the method attributes 1007 while (attributes != null) { 1008 Attribute attr = attributes.next; 1009 attributes.next = null; 1010 mv.visitAttribute(attributes); 1011 attributes = attr; 1012 } 1013 1014 // visits the method code 1015 if (code != 0) { 1016 mv.visitCode(); 1017 readCode(mv, context, code); 1018 } 1019 1020 // visits the end of the method 1021 mv.visitEnd(); 1022 1023 return u; 1024 } 1025 1026 /** 1027 * Reads the bytecode of a method and makes the given visitor visit it. 1028 * 1029 * @param mv 1030 * the visitor that must visit the method's code. 1031 * @param context 1032 * information about the class being parsed. 1033 * @param u 1034 * the start offset of the code attribute in the class file. 1035 */ readCode(final MethodVisitor mv, final Context context, int u)1036 private void readCode(final MethodVisitor mv, final Context context, int u) { 1037 // reads the header 1038 byte[] b = this.b; 1039 char[] c = context.buffer; 1040 int maxStack = readUnsignedShort(u); 1041 int maxLocals = readUnsignedShort(u + 2); 1042 int codeLength = readInt(u + 4); 1043 u += 8; 1044 1045 // reads the bytecode to find the labels 1046 int codeStart = u; 1047 int codeEnd = u + codeLength; 1048 Label[] labels = context.labels = new Label[codeLength + 2]; 1049 readLabel(codeLength + 1, labels); 1050 while (u < codeEnd) { 1051 int offset = u - codeStart; 1052 int opcode = b[u] & 0xFF; 1053 switch (ClassWriter.TYPE[opcode]) { 1054 case ClassWriter.NOARG_INSN: 1055 case ClassWriter.IMPLVAR_INSN: 1056 u += 1; 1057 break; 1058 case ClassWriter.LABEL_INSN: 1059 readLabel(offset + readShort(u + 1), labels); 1060 u += 3; 1061 break; 1062 case ClassWriter.LABELW_INSN: 1063 readLabel(offset + readInt(u + 1), labels); 1064 u += 5; 1065 break; 1066 case ClassWriter.WIDE_INSN: 1067 opcode = b[u + 1] & 0xFF; 1068 if (opcode == Opcodes.IINC) { 1069 u += 6; 1070 } else { 1071 u += 4; 1072 } 1073 break; 1074 case ClassWriter.TABL_INSN: 1075 // skips 0 to 3 padding bytes 1076 u = u + 4 - (offset & 3); 1077 // reads instruction 1078 readLabel(offset + readInt(u), labels); 1079 for (int i = readInt(u + 8) - readInt(u + 4) + 1; i > 0; --i) { 1080 readLabel(offset + readInt(u + 12), labels); 1081 u += 4; 1082 } 1083 u += 12; 1084 break; 1085 case ClassWriter.LOOK_INSN: 1086 // skips 0 to 3 padding bytes 1087 u = u + 4 - (offset & 3); 1088 // reads instruction 1089 readLabel(offset + readInt(u), labels); 1090 for (int i = readInt(u + 4); i > 0; --i) { 1091 readLabel(offset + readInt(u + 12), labels); 1092 u += 8; 1093 } 1094 u += 8; 1095 break; 1096 case ClassWriter.VAR_INSN: 1097 case ClassWriter.SBYTE_INSN: 1098 case ClassWriter.LDC_INSN: 1099 u += 2; 1100 break; 1101 case ClassWriter.SHORT_INSN: 1102 case ClassWriter.LDCW_INSN: 1103 case ClassWriter.FIELDORMETH_INSN: 1104 case ClassWriter.TYPE_INSN: 1105 case ClassWriter.IINC_INSN: 1106 u += 3; 1107 break; 1108 case ClassWriter.ITFMETH_INSN: 1109 case ClassWriter.INDYMETH_INSN: 1110 u += 5; 1111 break; 1112 // case MANA_INSN: 1113 default: 1114 u += 4; 1115 break; 1116 } 1117 } 1118 1119 // reads the try catch entries to find the labels, and also visits them 1120 for (int i = readUnsignedShort(u); i > 0; --i) { 1121 Label start = readLabel(readUnsignedShort(u + 2), labels); 1122 Label end = readLabel(readUnsignedShort(u + 4), labels); 1123 Label handler = readLabel(readUnsignedShort(u + 6), labels); 1124 String type = readUTF8(items[readUnsignedShort(u + 8)], c); 1125 mv.visitTryCatchBlock(start, end, handler, type); 1126 u += 8; 1127 } 1128 u += 2; 1129 1130 // reads the code attributes 1131 int[] tanns = null; // start index of each visible type annotation 1132 int[] itanns = null; // start index of each invisible type annotation 1133 int tann = 0; // current index in tanns array 1134 int itann = 0; // current index in itanns array 1135 int ntoff = -1; // next visible type annotation code offset 1136 int nitoff = -1; // next invisible type annotation code offset 1137 int varTable = 0; 1138 int varTypeTable = 0; 1139 boolean zip = true; 1140 boolean unzip = (context.flags & EXPAND_FRAMES) != 0; 1141 int stackMap = 0; 1142 int stackMapSize = 0; 1143 int frameCount = 0; 1144 Context frame = null; 1145 Attribute attributes = null; 1146 1147 for (int i = readUnsignedShort(u); i > 0; --i) { 1148 String attrName = readUTF8(u + 2, c); 1149 if ("LocalVariableTable".equals(attrName)) { 1150 if ((context.flags & SKIP_DEBUG) == 0) { 1151 varTable = u + 8; 1152 for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) { 1153 int label = readUnsignedShort(v + 10); 1154 if (labels[label] == null) { 1155 readLabel(label, labels).status |= Label.DEBUG; 1156 } 1157 label += readUnsignedShort(v + 12); 1158 if (labels[label] == null) { 1159 readLabel(label, labels).status |= Label.DEBUG; 1160 } 1161 v += 10; 1162 } 1163 } 1164 } else if ("LocalVariableTypeTable".equals(attrName)) { 1165 varTypeTable = u + 8; 1166 } else if ("LineNumberTable".equals(attrName)) { 1167 if ((context.flags & SKIP_DEBUG) == 0) { 1168 for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) { 1169 int label = readUnsignedShort(v + 10); 1170 if (labels[label] == null) { 1171 readLabel(label, labels).status |= Label.DEBUG; 1172 } 1173 Label l = labels[label]; 1174 while (l.line > 0) { 1175 if (l.next == null) { 1176 l.next = new Label(); 1177 } 1178 l = l.next; 1179 } 1180 l.line = readUnsignedShort(v + 12); 1181 v += 4; 1182 } 1183 } 1184 } else if (ANNOTATIONS 1185 && "RuntimeVisibleTypeAnnotations".equals(attrName)) { 1186 tanns = readTypeAnnotations(mv, context, u + 8, true); 1187 ntoff = tanns.length == 0 || readByte(tanns[0]) < 0x43 ? -1 1188 : readUnsignedShort(tanns[0] + 1); 1189 } else if (ANNOTATIONS 1190 && "RuntimeInvisibleTypeAnnotations".equals(attrName)) { 1191 itanns = readTypeAnnotations(mv, context, u + 8, false); 1192 nitoff = itanns.length == 0 || readByte(itanns[0]) < 0x43 ? -1 1193 : readUnsignedShort(itanns[0] + 1); 1194 } else if (FRAMES && "StackMapTable".equals(attrName)) { 1195 if ((context.flags & SKIP_FRAMES) == 0) { 1196 stackMap = u + 10; 1197 stackMapSize = readInt(u + 4); 1198 frameCount = readUnsignedShort(u + 8); 1199 } 1200 /* 1201 * here we do not extract the labels corresponding to the 1202 * attribute content. This would require a full parsing of the 1203 * attribute, which would need to be repeated in the second 1204 * phase (see below). Instead the content of the attribute is 1205 * read one frame at a time (i.e. after a frame has been 1206 * visited, the next frame is read), and the labels it contains 1207 * are also extracted one frame at a time. Thanks to the 1208 * ordering of frames, having only a "one frame lookahead" is 1209 * not a problem, i.e. it is not possible to see an offset 1210 * smaller than the offset of the current insn and for which no 1211 * Label exist. 1212 */ 1213 /* 1214 * This is not true for UNINITIALIZED type offsets. We solve 1215 * this by parsing the stack map table without a full decoding 1216 * (see below). 1217 */ 1218 } else if (FRAMES && "StackMap".equals(attrName)) { 1219 if ((context.flags & SKIP_FRAMES) == 0) { 1220 zip = false; 1221 stackMap = u + 10; 1222 stackMapSize = readInt(u + 4); 1223 frameCount = readUnsignedShort(u + 8); 1224 } 1225 /* 1226 * IMPORTANT! here we assume that the frames are ordered, as in 1227 * the StackMapTable attribute, although this is not guaranteed 1228 * by the attribute format. 1229 */ 1230 } else { 1231 for (int j = 0; j < context.attrs.length; ++j) { 1232 if (context.attrs[j].type.equals(attrName)) { 1233 Attribute attr = context.attrs[j].read(this, u + 8, 1234 readInt(u + 4), c, codeStart - 8, labels); 1235 if (attr != null) { 1236 attr.next = attributes; 1237 attributes = attr; 1238 } 1239 } 1240 } 1241 } 1242 u += 6 + readInt(u + 4); 1243 } 1244 u += 2; 1245 1246 // generates the first (implicit) stack map frame 1247 if (FRAMES && stackMap != 0) { 1248 /* 1249 * for the first explicit frame the offset is not offset_delta + 1 1250 * but only offset_delta; setting the implicit frame offset to -1 1251 * allow the use of the "offset_delta + 1" rule in all cases 1252 */ 1253 frame = context; 1254 frame.offset = -1; 1255 frame.mode = 0; 1256 frame.localCount = 0; 1257 frame.localDiff = 0; 1258 frame.stackCount = 0; 1259 frame.local = new Object[maxLocals]; 1260 frame.stack = new Object[maxStack]; 1261 if (unzip) { 1262 getImplicitFrame(context); 1263 } 1264 /* 1265 * Finds labels for UNINITIALIZED frame types. Instead of decoding 1266 * each element of the stack map table, we look for 3 consecutive 1267 * bytes that "look like" an UNINITIALIZED type (tag 8, offset 1268 * within code bounds, NEW instruction at this offset). We may find 1269 * false positives (i.e. not real UNINITIALIZED types), but this 1270 * should be rare, and the only consequence will be the creation of 1271 * an unneeded label. This is better than creating a label for each 1272 * NEW instruction, and faster than fully decoding the whole stack 1273 * map table. 1274 */ 1275 for (int i = stackMap; i < stackMap + stackMapSize - 2; ++i) { 1276 if (b[i] == 8) { // UNINITIALIZED FRAME TYPE 1277 int v = readUnsignedShort(i + 1); 1278 if (v >= 0 && v < codeLength) { 1279 if ((b[codeStart + v] & 0xFF) == Opcodes.NEW) { 1280 readLabel(v, labels); 1281 } 1282 } 1283 } 1284 } 1285 } 1286 1287 // visits the instructions 1288 u = codeStart; 1289 while (u < codeEnd) { 1290 int offset = u - codeStart; 1291 1292 // visits the label and line number for this offset, if any 1293 Label l = labels[offset]; 1294 if (l != null) { 1295 Label next = l.next; 1296 l.next = null; 1297 mv.visitLabel(l); 1298 if ((context.flags & SKIP_DEBUG) == 0 && l.line > 0) { 1299 mv.visitLineNumber(l.line, l); 1300 while (next != null) { 1301 mv.visitLineNumber(next.line, l); 1302 next = next.next; 1303 } 1304 } 1305 } 1306 1307 // visits the frame for this offset, if any 1308 while (FRAMES && frame != null 1309 && (frame.offset == offset || frame.offset == -1)) { 1310 // if there is a frame for this offset, makes the visitor visit 1311 // it, and reads the next frame if there is one. 1312 if (frame.offset != -1) { 1313 if (!zip || unzip) { 1314 mv.visitFrame(Opcodes.F_NEW, frame.localCount, 1315 frame.local, frame.stackCount, frame.stack); 1316 } else { 1317 mv.visitFrame(frame.mode, frame.localDiff, frame.local, 1318 frame.stackCount, frame.stack); 1319 } 1320 } 1321 if (frameCount > 0) { 1322 stackMap = readFrame(stackMap, zip, unzip, frame); 1323 --frameCount; 1324 } else { 1325 frame = null; 1326 } 1327 } 1328 1329 // visits the instruction at this offset 1330 int opcode = b[u] & 0xFF; 1331 switch (ClassWriter.TYPE[opcode]) { 1332 case ClassWriter.NOARG_INSN: 1333 mv.visitInsn(opcode); 1334 u += 1; 1335 break; 1336 case ClassWriter.IMPLVAR_INSN: 1337 if (opcode > Opcodes.ISTORE) { 1338 opcode -= 59; // ISTORE_0 1339 mv.visitVarInsn(Opcodes.ISTORE + (opcode >> 2), 1340 opcode & 0x3); 1341 } else { 1342 opcode -= 26; // ILOAD_0 1343 mv.visitVarInsn(Opcodes.ILOAD + (opcode >> 2), opcode & 0x3); 1344 } 1345 u += 1; 1346 break; 1347 case ClassWriter.LABEL_INSN: 1348 mv.visitJumpInsn(opcode, labels[offset + readShort(u + 1)]); 1349 u += 3; 1350 break; 1351 case ClassWriter.LABELW_INSN: 1352 mv.visitJumpInsn(opcode - 33, labels[offset + readInt(u + 1)]); 1353 u += 5; 1354 break; 1355 case ClassWriter.WIDE_INSN: 1356 opcode = b[u + 1] & 0xFF; 1357 if (opcode == Opcodes.IINC) { 1358 mv.visitIincInsn(readUnsignedShort(u + 2), readShort(u + 4)); 1359 u += 6; 1360 } else { 1361 mv.visitVarInsn(opcode, readUnsignedShort(u + 2)); 1362 u += 4; 1363 } 1364 break; 1365 case ClassWriter.TABL_INSN: { 1366 // skips 0 to 3 padding bytes 1367 u = u + 4 - (offset & 3); 1368 // reads instruction 1369 int label = offset + readInt(u); 1370 int min = readInt(u + 4); 1371 int max = readInt(u + 8); 1372 Label[] table = new Label[max - min + 1]; 1373 u += 12; 1374 for (int i = 0; i < table.length; ++i) { 1375 table[i] = labels[offset + readInt(u)]; 1376 u += 4; 1377 } 1378 mv.visitTableSwitchInsn(min, max, labels[label], table); 1379 break; 1380 } 1381 case ClassWriter.LOOK_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 len = readInt(u + 4); 1387 int[] keys = new int[len]; 1388 Label[] values = new Label[len]; 1389 u += 8; 1390 for (int i = 0; i < len; ++i) { 1391 keys[i] = readInt(u); 1392 values[i] = labels[offset + readInt(u + 4)]; 1393 u += 8; 1394 } 1395 mv.visitLookupSwitchInsn(labels[label], keys, values); 1396 break; 1397 } 1398 case ClassWriter.VAR_INSN: 1399 mv.visitVarInsn(opcode, b[u + 1] & 0xFF); 1400 u += 2; 1401 break; 1402 case ClassWriter.SBYTE_INSN: 1403 mv.visitIntInsn(opcode, b[u + 1]); 1404 u += 2; 1405 break; 1406 case ClassWriter.SHORT_INSN: 1407 mv.visitIntInsn(opcode, readShort(u + 1)); 1408 u += 3; 1409 break; 1410 case ClassWriter.LDC_INSN: 1411 mv.visitLdcInsn(readConst(b[u + 1] & 0xFF, c)); 1412 u += 2; 1413 break; 1414 case ClassWriter.LDCW_INSN: 1415 mv.visitLdcInsn(readConst(readUnsignedShort(u + 1), c)); 1416 u += 3; 1417 break; 1418 case ClassWriter.FIELDORMETH_INSN: 1419 case ClassWriter.ITFMETH_INSN: { 1420 int cpIndex = items[readUnsignedShort(u + 1)]; 1421 boolean itf = b[cpIndex - 1] == ClassWriter.IMETH; 1422 String iowner = readClass(cpIndex, c); 1423 cpIndex = items[readUnsignedShort(cpIndex + 2)]; 1424 String iname = readUTF8(cpIndex, c); 1425 String idesc = readUTF8(cpIndex + 2, c); 1426 if (opcode < Opcodes.INVOKEVIRTUAL) { 1427 mv.visitFieldInsn(opcode, iowner, iname, idesc); 1428 } else { 1429 mv.visitMethodInsn(opcode, iowner, iname, idesc, itf); 1430 } 1431 if (opcode == Opcodes.INVOKEINTERFACE) { 1432 u += 5; 1433 } else { 1434 u += 3; 1435 } 1436 break; 1437 } 1438 case ClassWriter.INDYMETH_INSN: { 1439 int cpIndex = items[readUnsignedShort(u + 1)]; 1440 int bsmIndex = context.bootstrapMethods[readUnsignedShort(cpIndex)]; 1441 Handle bsm = (Handle) readConst(readUnsignedShort(bsmIndex), c); 1442 int bsmArgCount = readUnsignedShort(bsmIndex + 2); 1443 Object[] bsmArgs = new Object[bsmArgCount]; 1444 bsmIndex += 4; 1445 for (int i = 0; i < bsmArgCount; i++) { 1446 bsmArgs[i] = readConst(readUnsignedShort(bsmIndex), c); 1447 bsmIndex += 2; 1448 } 1449 cpIndex = items[readUnsignedShort(cpIndex + 2)]; 1450 String iname = readUTF8(cpIndex, c); 1451 String idesc = readUTF8(cpIndex + 2, c); 1452 mv.visitInvokeDynamicInsn(iname, idesc, bsm, bsmArgs); 1453 u += 5; 1454 break; 1455 } 1456 case ClassWriter.TYPE_INSN: 1457 mv.visitTypeInsn(opcode, readClass(u + 1, c)); 1458 u += 3; 1459 break; 1460 case ClassWriter.IINC_INSN: 1461 mv.visitIincInsn(b[u + 1] & 0xFF, b[u + 2]); 1462 u += 3; 1463 break; 1464 // case MANA_INSN: 1465 default: 1466 mv.visitMultiANewArrayInsn(readClass(u + 1, c), b[u + 3] & 0xFF); 1467 u += 4; 1468 break; 1469 } 1470 1471 // visit the instruction annotations, if any 1472 while (tanns != null && tann < tanns.length && ntoff <= offset) { 1473 if (ntoff == offset) { 1474 int v = readAnnotationTarget(context, tanns[tann]); 1475 readAnnotationValues(v + 2, c, true, 1476 mv.visitInsnAnnotation(context.typeRef, 1477 context.typePath, readUTF8(v, c), true)); 1478 } 1479 ntoff = ++tann >= tanns.length || readByte(tanns[tann]) < 0x43 ? -1 1480 : readUnsignedShort(tanns[tann] + 1); 1481 } 1482 while (itanns != null && itann < itanns.length && nitoff <= offset) { 1483 if (nitoff == offset) { 1484 int v = readAnnotationTarget(context, itanns[itann]); 1485 readAnnotationValues(v + 2, c, true, 1486 mv.visitInsnAnnotation(context.typeRef, 1487 context.typePath, readUTF8(v, c), false)); 1488 } 1489 nitoff = ++itann >= itanns.length 1490 || readByte(itanns[itann]) < 0x43 ? -1 1491 : readUnsignedShort(itanns[itann] + 1); 1492 } 1493 } 1494 if (labels[codeLength] != null) { 1495 mv.visitLabel(labels[codeLength]); 1496 } 1497 1498 // visits the local variable tables 1499 if ((context.flags & SKIP_DEBUG) == 0 && varTable != 0) { 1500 int[] typeTable = null; 1501 if (varTypeTable != 0) { 1502 u = varTypeTable + 2; 1503 typeTable = new int[readUnsignedShort(varTypeTable) * 3]; 1504 for (int i = typeTable.length; i > 0;) { 1505 typeTable[--i] = u + 6; // signature 1506 typeTable[--i] = readUnsignedShort(u + 8); // index 1507 typeTable[--i] = readUnsignedShort(u); // start 1508 u += 10; 1509 } 1510 } 1511 u = varTable + 2; 1512 for (int i = readUnsignedShort(varTable); i > 0; --i) { 1513 int start = readUnsignedShort(u); 1514 int length = readUnsignedShort(u + 2); 1515 int index = readUnsignedShort(u + 8); 1516 String vsignature = null; 1517 if (typeTable != null) { 1518 for (int j = 0; j < typeTable.length; j += 3) { 1519 if (typeTable[j] == start && typeTable[j + 1] == index) { 1520 vsignature = readUTF8(typeTable[j + 2], c); 1521 break; 1522 } 1523 } 1524 } 1525 mv.visitLocalVariable(readUTF8(u + 4, c), readUTF8(u + 6, c), 1526 vsignature, labels[start], labels[start + length], 1527 index); 1528 u += 10; 1529 } 1530 } 1531 1532 // visits the local variables type annotations 1533 if (tanns != null) { 1534 for (int i = 0; i < tanns.length; ++i) { 1535 if ((readByte(tanns[i]) >> 1) == (0x40 >> 1)) { 1536 int v = readAnnotationTarget(context, tanns[i]); 1537 v = readAnnotationValues(v + 2, c, true, 1538 mv.visitLocalVariableAnnotation(context.typeRef, 1539 context.typePath, context.start, 1540 context.end, context.index, readUTF8(v, c), 1541 true)); 1542 } 1543 } 1544 } 1545 if (itanns != null) { 1546 for (int i = 0; i < itanns.length; ++i) { 1547 if ((readByte(itanns[i]) >> 1) == (0x40 >> 1)) { 1548 int v = readAnnotationTarget(context, itanns[i]); 1549 v = readAnnotationValues(v + 2, c, true, 1550 mv.visitLocalVariableAnnotation(context.typeRef, 1551 context.typePath, context.start, 1552 context.end, context.index, readUTF8(v, c), 1553 false)); 1554 } 1555 } 1556 } 1557 1558 // visits the code attributes 1559 while (attributes != null) { 1560 Attribute attr = attributes.next; 1561 attributes.next = null; 1562 mv.visitAttribute(attributes); 1563 attributes = attr; 1564 } 1565 1566 // visits the max stack and max locals values 1567 mv.visitMaxs(maxStack, maxLocals); 1568 } 1569 1570 /** 1571 * Parses a type annotation table to find the labels, and to visit the try 1572 * catch block annotations. 1573 * 1574 * @param u 1575 * the start offset of a type annotation table. 1576 * @param mv 1577 * the method visitor to be used to visit the try catch block 1578 * annotations. 1579 * @param context 1580 * information about the class being parsed. 1581 * @param visible 1582 * if the type annotation table to parse contains runtime visible 1583 * annotations. 1584 * @return the start offset of each type annotation in the parsed table. 1585 */ readTypeAnnotations(final MethodVisitor mv, final Context context, int u, boolean visible)1586 private int[] readTypeAnnotations(final MethodVisitor mv, 1587 final Context context, int u, boolean visible) { 1588 char[] c = context.buffer; 1589 int[] offsets = new int[readUnsignedShort(u)]; 1590 u += 2; 1591 for (int i = 0; i < offsets.length; ++i) { 1592 offsets[i] = u; 1593 int target = readInt(u); 1594 switch (target >>> 24) { 1595 case 0x00: // CLASS_TYPE_PARAMETER 1596 case 0x01: // METHOD_TYPE_PARAMETER 1597 case 0x16: // METHOD_FORMAL_PARAMETER 1598 u += 2; 1599 break; 1600 case 0x13: // FIELD 1601 case 0x14: // METHOD_RETURN 1602 case 0x15: // METHOD_RECEIVER 1603 u += 1; 1604 break; 1605 case 0x40: // LOCAL_VARIABLE 1606 case 0x41: // RESOURCE_VARIABLE 1607 for (int j = readUnsignedShort(u + 1); j > 0; --j) { 1608 int start = readUnsignedShort(u + 3); 1609 int length = readUnsignedShort(u + 5); 1610 readLabel(start, context.labels); 1611 readLabel(start + length, context.labels); 1612 u += 6; 1613 } 1614 u += 3; 1615 break; 1616 case 0x47: // CAST 1617 case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT 1618 case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT 1619 case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT 1620 case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT 1621 u += 4; 1622 break; 1623 // case 0x10: // CLASS_EXTENDS 1624 // case 0x11: // CLASS_TYPE_PARAMETER_BOUND 1625 // case 0x12: // METHOD_TYPE_PARAMETER_BOUND 1626 // case 0x17: // THROWS 1627 // case 0x42: // EXCEPTION_PARAMETER 1628 // case 0x43: // INSTANCEOF 1629 // case 0x44: // NEW 1630 // case 0x45: // CONSTRUCTOR_REFERENCE 1631 // case 0x46: // METHOD_REFERENCE 1632 default: 1633 u += 3; 1634 break; 1635 } 1636 int pathLength = readByte(u); 1637 if ((target >>> 24) == 0x42) { 1638 TypePath path = pathLength == 0 ? null : new TypePath(b, u); 1639 u += 1 + 2 * pathLength; 1640 u = readAnnotationValues(u + 2, c, true, 1641 mv.visitTryCatchAnnotation(target, path, 1642 readUTF8(u, c), visible)); 1643 } else { 1644 u = readAnnotationValues(u + 3 + 2 * pathLength, c, true, null); 1645 } 1646 } 1647 return offsets; 1648 } 1649 1650 /** 1651 * Parses the header of a type annotation to extract its target_type and 1652 * target_path (the result is stored in the given context), and returns the 1653 * start offset of the rest of the type_annotation structure (i.e. the 1654 * offset to the type_index field, which is followed by 1655 * num_element_value_pairs and then the name,value pairs). 1656 * 1657 * @param context 1658 * information about the class being parsed. This is where the 1659 * extracted target_type and target_path must be stored. 1660 * @param u 1661 * the start offset of a type_annotation structure. 1662 * @return the start offset of the rest of the type_annotation structure. 1663 */ readAnnotationTarget(final Context context, int u)1664 private int readAnnotationTarget(final Context context, int u) { 1665 int target = readInt(u); 1666 switch (target >>> 24) { 1667 case 0x00: // CLASS_TYPE_PARAMETER 1668 case 0x01: // METHOD_TYPE_PARAMETER 1669 case 0x16: // METHOD_FORMAL_PARAMETER 1670 target &= 0xFFFF0000; 1671 u += 2; 1672 break; 1673 case 0x13: // FIELD 1674 case 0x14: // METHOD_RETURN 1675 case 0x15: // METHOD_RECEIVER 1676 target &= 0xFF000000; 1677 u += 1; 1678 break; 1679 case 0x40: // LOCAL_VARIABLE 1680 case 0x41: { // RESOURCE_VARIABLE 1681 target &= 0xFF000000; 1682 int n = readUnsignedShort(u + 1); 1683 context.start = new Label[n]; 1684 context.end = new Label[n]; 1685 context.index = new int[n]; 1686 u += 3; 1687 for (int i = 0; i < n; ++i) { 1688 int start = readUnsignedShort(u); 1689 int length = readUnsignedShort(u + 2); 1690 context.start[i] = readLabel(start, context.labels); 1691 context.end[i] = readLabel(start + length, context.labels); 1692 context.index[i] = readUnsignedShort(u + 4); 1693 u += 6; 1694 } 1695 break; 1696 } 1697 case 0x47: // CAST 1698 case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT 1699 case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT 1700 case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT 1701 case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT 1702 target &= 0xFF0000FF; 1703 u += 4; 1704 break; 1705 // case 0x10: // CLASS_EXTENDS 1706 // case 0x11: // CLASS_TYPE_PARAMETER_BOUND 1707 // case 0x12: // METHOD_TYPE_PARAMETER_BOUND 1708 // case 0x17: // THROWS 1709 // case 0x42: // EXCEPTION_PARAMETER 1710 // case 0x43: // INSTANCEOF 1711 // case 0x44: // NEW 1712 // case 0x45: // CONSTRUCTOR_REFERENCE 1713 // case 0x46: // METHOD_REFERENCE 1714 default: 1715 target &= (target >>> 24) < 0x43 ? 0xFFFFFF00 : 0xFF000000; 1716 u += 3; 1717 break; 1718 } 1719 int pathLength = readByte(u); 1720 context.typeRef = target; 1721 context.typePath = pathLength == 0 ? null : new TypePath(b, u); 1722 return u + 1 + 2 * pathLength; 1723 } 1724 1725 /** 1726 * Reads parameter annotations and makes the given visitor visit them. 1727 * 1728 * @param mv 1729 * the visitor that must visit the annotations. 1730 * @param context 1731 * information about the class being parsed. 1732 * @param v 1733 * start offset in {@link #b b} of the annotations to be read. 1734 * @param visible 1735 * <tt>true</tt> if the annotations to be read are visible at 1736 * runtime. 1737 */ 1738 private void readParameterAnnotations(final MethodVisitor mv, 1739 final Context context, int v, final boolean visible) { 1740 int i; 1741 int n = b[v++] & 0xFF; 1742 // workaround for a bug in javac (javac compiler generates a parameter 1743 // annotation array whose size is equal to the number of parameters in 1744 // the Java source file, while it should generate an array whose size is 1745 // equal to the number of parameters in the method descriptor - which 1746 // includes the synthetic parameters added by the compiler). This work- 1747 // around supposes that the synthetic parameters are the first ones. 1748 int synthetics = Type.getArgumentTypes(context.desc).length - n; 1749 AnnotationVisitor av; 1750 for (i = 0; i < synthetics; ++i) { 1751 // virtual annotation to detect synthetic parameters in MethodWriter 1752 av = mv.visitParameterAnnotation(i, "Ljava/lang/Synthetic;", false); 1753 if (av != null) { 1754 av.visitEnd(); 1755 } 1756 } 1757 char[] c = context.buffer; 1758 for (; i < n + synthetics; ++i) { 1759 int j = readUnsignedShort(v); 1760 v += 2; 1761 for (; j > 0; --j) { 1762 av = mv.visitParameterAnnotation(i, readUTF8(v, c), visible); 1763 v = readAnnotationValues(v + 2, c, true, av); 1764 } 1765 } 1766 } 1767 1768 /** 1769 * Reads the values of an annotation and makes the given visitor visit them. 1770 * 1771 * @param v 1772 * the start offset in {@link #b b} of the values to be read 1773 * (including the unsigned short that gives the number of 1774 * values). 1775 * @param buf 1776 * buffer to be used to call {@link #readUTF8 readUTF8}, 1777 * {@link #readClass(int,char[]) readClass} or {@link #readConst 1778 * readConst}. 1779 * @param named 1780 * if the annotation values are named or not. 1781 * @param av 1782 * the visitor that must visit the values. 1783 * @return the end offset of the annotation values. 1784 */ 1785 private int readAnnotationValues(int v, final char[] buf, 1786 final boolean named, final AnnotationVisitor av) { 1787 int i = readUnsignedShort(v); 1788 v += 2; 1789 if (named) { 1790 for (; i > 0; --i) { 1791 v = readAnnotationValue(v + 2, buf, readUTF8(v, buf), av); 1792 } 1793 } else { 1794 for (; i > 0; --i) { 1795 v = readAnnotationValue(v, buf, null, av); 1796 } 1797 } 1798 if (av != null) { 1799 av.visitEnd(); 1800 } 1801 return v; 1802 } 1803 1804 /** 1805 * Reads a value of an annotation and makes the given visitor visit it. 1806 * 1807 * @param v 1808 * the start offset in {@link #b b} of the value to be read 1809 * (<i>not including the value name constant pool index</i>). 1810 * @param buf 1811 * buffer to be used to call {@link #readUTF8 readUTF8}, 1812 * {@link #readClass(int,char[]) readClass} or {@link #readConst 1813 * readConst}. 1814 * @param name 1815 * the name of the value to be read. 1816 * @param av 1817 * the visitor that must visit the value. 1818 * @return the end offset of the annotation value. 1819 */ readAnnotationValue(int v, final char[] buf, final String name, final AnnotationVisitor av)1820 private int readAnnotationValue(int v, final char[] buf, final String name, 1821 final AnnotationVisitor av) { 1822 int i; 1823 if (av == null) { 1824 switch (b[v] & 0xFF) { 1825 case 'e': // enum_const_value 1826 return v + 5; 1827 case '@': // annotation_value 1828 return readAnnotationValues(v + 3, buf, true, null); 1829 case '[': // array_value 1830 return readAnnotationValues(v + 1, buf, false, null); 1831 default: 1832 return v + 3; 1833 } 1834 } 1835 switch (b[v++] & 0xFF) { 1836 case 'I': // pointer to CONSTANT_Integer 1837 case 'J': // pointer to CONSTANT_Long 1838 case 'F': // pointer to CONSTANT_Float 1839 case 'D': // pointer to CONSTANT_Double 1840 av.visit(name, readConst(readUnsignedShort(v), buf)); 1841 v += 2; 1842 break; 1843 case 'B': // pointer to CONSTANT_Byte 1844 av.visit(name, (byte) readInt(items[readUnsignedShort(v)])); 1845 v += 2; 1846 break; 1847 case 'Z': // pointer to CONSTANT_Boolean 1848 av.visit(name, 1849 readInt(items[readUnsignedShort(v)]) == 0 ? Boolean.FALSE 1850 : Boolean.TRUE); 1851 v += 2; 1852 break; 1853 case 'S': // pointer to CONSTANT_Short 1854 av.visit(name, (short) readInt(items[readUnsignedShort(v)])); 1855 v += 2; 1856 break; 1857 case 'C': // pointer to CONSTANT_Char 1858 av.visit(name, (char) readInt(items[readUnsignedShort(v)])); 1859 v += 2; 1860 break; 1861 case 's': // pointer to CONSTANT_Utf8 1862 av.visit(name, readUTF8(v, buf)); 1863 v += 2; 1864 break; 1865 case 'e': // enum_const_value 1866 av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf)); 1867 v += 4; 1868 break; 1869 case 'c': // class_info 1870 av.visit(name, Type.getType(readUTF8(v, buf))); 1871 v += 2; 1872 break; 1873 case '@': // annotation_value 1874 v = readAnnotationValues(v + 2, buf, true, 1875 av.visitAnnotation(name, readUTF8(v, buf))); 1876 break; 1877 case '[': // array_value 1878 int size = readUnsignedShort(v); 1879 v += 2; 1880 if (size == 0) { 1881 return readAnnotationValues(v - 2, buf, false, 1882 av.visitArray(name)); 1883 } 1884 switch (this.b[v++] & 0xFF) { 1885 case 'B': 1886 byte[] bv = new byte[size]; 1887 for (i = 0; i < size; i++) { 1888 bv[i] = (byte) readInt(items[readUnsignedShort(v)]); 1889 v += 3; 1890 } 1891 av.visit(name, bv); 1892 --v; 1893 break; 1894 case 'Z': 1895 boolean[] zv = new boolean[size]; 1896 for (i = 0; i < size; i++) { 1897 zv[i] = readInt(items[readUnsignedShort(v)]) != 0; 1898 v += 3; 1899 } 1900 av.visit(name, zv); 1901 --v; 1902 break; 1903 case 'S': 1904 short[] sv = new short[size]; 1905 for (i = 0; i < size; i++) { 1906 sv[i] = (short) readInt(items[readUnsignedShort(v)]); 1907 v += 3; 1908 } 1909 av.visit(name, sv); 1910 --v; 1911 break; 1912 case 'C': 1913 char[] cv = new char[size]; 1914 for (i = 0; i < size; i++) { 1915 cv[i] = (char) readInt(items[readUnsignedShort(v)]); 1916 v += 3; 1917 } 1918 av.visit(name, cv); 1919 --v; 1920 break; 1921 case 'I': 1922 int[] iv = new int[size]; 1923 for (i = 0; i < size; i++) { 1924 iv[i] = readInt(items[readUnsignedShort(v)]); 1925 v += 3; 1926 } 1927 av.visit(name, iv); 1928 --v; 1929 break; 1930 case 'J': 1931 long[] lv = new long[size]; 1932 for (i = 0; i < size; i++) { 1933 lv[i] = readLong(items[readUnsignedShort(v)]); 1934 v += 3; 1935 } 1936 av.visit(name, lv); 1937 --v; 1938 break; 1939 case 'F': 1940 float[] fv = new float[size]; 1941 for (i = 0; i < size; i++) { 1942 fv[i] = Float 1943 .intBitsToFloat(readInt(items[readUnsignedShort(v)])); 1944 v += 3; 1945 } 1946 av.visit(name, fv); 1947 --v; 1948 break; 1949 case 'D': 1950 double[] dv = new double[size]; 1951 for (i = 0; i < size; i++) { 1952 dv[i] = Double 1953 .longBitsToDouble(readLong(items[readUnsignedShort(v)])); 1954 v += 3; 1955 } 1956 av.visit(name, dv); 1957 --v; 1958 break; 1959 default: 1960 v = readAnnotationValues(v - 3, buf, false, av.visitArray(name)); 1961 } 1962 } 1963 return v; 1964 } 1965 1966 /** 1967 * Computes the implicit frame of the method currently being parsed (as 1968 * defined in the given {@link Context}) and stores it in the given context. 1969 * 1970 * @param frame 1971 * information about the class being parsed. 1972 */ getImplicitFrame(final Context frame)1973 private void getImplicitFrame(final Context frame) { 1974 String desc = frame.desc; 1975 Object[] locals = frame.local; 1976 int local = 0; 1977 if ((frame.access & Opcodes.ACC_STATIC) == 0) { 1978 if ("<init>".equals(frame.name)) { 1979 locals[local++] = Opcodes.UNINITIALIZED_THIS; 1980 } else { 1981 locals[local++] = readClass(header + 2, frame.buffer); 1982 } 1983 } 1984 int i = 1; 1985 loop: while (true) { 1986 int j = i; 1987 switch (desc.charAt(i++)) { 1988 case 'Z': 1989 case 'C': 1990 case 'B': 1991 case 'S': 1992 case 'I': 1993 locals[local++] = Opcodes.INTEGER; 1994 break; 1995 case 'F': 1996 locals[local++] = Opcodes.FLOAT; 1997 break; 1998 case 'J': 1999 locals[local++] = Opcodes.LONG; 2000 break; 2001 case 'D': 2002 locals[local++] = Opcodes.DOUBLE; 2003 break; 2004 case '[': 2005 while (desc.charAt(i) == '[') { 2006 ++i; 2007 } 2008 if (desc.charAt(i) == 'L') { 2009 ++i; 2010 while (desc.charAt(i) != ';') { 2011 ++i; 2012 } 2013 } 2014 locals[local++] = desc.substring(j, ++i); 2015 break; 2016 case 'L': 2017 while (desc.charAt(i) != ';') { 2018 ++i; 2019 } 2020 locals[local++] = desc.substring(j + 1, i++); 2021 break; 2022 default: 2023 break loop; 2024 } 2025 } 2026 frame.localCount = local; 2027 } 2028 2029 /** 2030 * Reads a stack map frame and stores the result in the given 2031 * {@link Context} object. 2032 * 2033 * @param stackMap 2034 * the start offset of a stack map frame in the class file. 2035 * @param zip 2036 * if the stack map frame at stackMap is compressed or not. 2037 * @param unzip 2038 * if the stack map frame must be uncompressed. 2039 * @param frame 2040 * where the parsed stack map frame must be stored. 2041 * @return the offset of the first byte following the parsed frame. 2042 */ readFrame(int stackMap, boolean zip, boolean unzip, Context frame)2043 private int readFrame(int stackMap, boolean zip, boolean unzip, 2044 Context frame) { 2045 char[] c = frame.buffer; 2046 Label[] labels = frame.labels; 2047 int tag; 2048 int delta; 2049 if (zip) { 2050 tag = b[stackMap++] & 0xFF; 2051 } else { 2052 tag = MethodWriter.FULL_FRAME; 2053 frame.offset = -1; 2054 } 2055 frame.localDiff = 0; 2056 if (tag < MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME) { 2057 delta = tag; 2058 frame.mode = Opcodes.F_SAME; 2059 frame.stackCount = 0; 2060 } else if (tag < MethodWriter.RESERVED) { 2061 delta = tag - MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME; 2062 stackMap = readFrameType(frame.stack, 0, stackMap, c, labels); 2063 frame.mode = Opcodes.F_SAME1; 2064 frame.stackCount = 1; 2065 } else { 2066 delta = readUnsignedShort(stackMap); 2067 stackMap += 2; 2068 if (tag == MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { 2069 stackMap = readFrameType(frame.stack, 0, stackMap, c, labels); 2070 frame.mode = Opcodes.F_SAME1; 2071 frame.stackCount = 1; 2072 } else if (tag >= MethodWriter.CHOP_FRAME 2073 && tag < MethodWriter.SAME_FRAME_EXTENDED) { 2074 frame.mode = Opcodes.F_CHOP; 2075 frame.localDiff = MethodWriter.SAME_FRAME_EXTENDED - tag; 2076 frame.localCount -= frame.localDiff; 2077 frame.stackCount = 0; 2078 } else if (tag == MethodWriter.SAME_FRAME_EXTENDED) { 2079 frame.mode = Opcodes.F_SAME; 2080 frame.stackCount = 0; 2081 } else if (tag < MethodWriter.FULL_FRAME) { 2082 int local = unzip ? frame.localCount : 0; 2083 for (int i = tag - MethodWriter.SAME_FRAME_EXTENDED; i > 0; i--) { 2084 stackMap = readFrameType(frame.local, local++, stackMap, c, 2085 labels); 2086 } 2087 frame.mode = Opcodes.F_APPEND; 2088 frame.localDiff = tag - MethodWriter.SAME_FRAME_EXTENDED; 2089 frame.localCount += frame.localDiff; 2090 frame.stackCount = 0; 2091 } else { // if (tag == FULL_FRAME) { 2092 frame.mode = Opcodes.F_FULL; 2093 int n = readUnsignedShort(stackMap); 2094 stackMap += 2; 2095 frame.localDiff = n; 2096 frame.localCount = n; 2097 for (int local = 0; n > 0; n--) { 2098 stackMap = readFrameType(frame.local, local++, stackMap, c, 2099 labels); 2100 } 2101 n = readUnsignedShort(stackMap); 2102 stackMap += 2; 2103 frame.stackCount = n; 2104 for (int stack = 0; n > 0; n--) { 2105 stackMap = readFrameType(frame.stack, stack++, stackMap, c, 2106 labels); 2107 } 2108 } 2109 } 2110 frame.offset += delta + 1; 2111 readLabel(frame.offset, labels); 2112 return stackMap; 2113 } 2114 2115 /** 2116 * Reads a stack map frame type and stores it at the given index in the 2117 * given array. 2118 * 2119 * @param frame 2120 * the array where the parsed type must be stored. 2121 * @param index 2122 * the index in 'frame' where the parsed type must be stored. 2123 * @param v 2124 * the start offset of the stack map frame type to read. 2125 * @param buf 2126 * a buffer to read strings. 2127 * @param labels 2128 * the labels of the method currently being parsed, indexed by 2129 * their offset. If the parsed type is an Uninitialized type, a 2130 * new label for the corresponding NEW instruction is stored in 2131 * this array if it does not already exist. 2132 * @return the offset of the first byte after the parsed type. 2133 */ readFrameType(final Object[] frame, final int index, int v, final char[] buf, final Label[] labels)2134 private int readFrameType(final Object[] frame, final int index, int v, 2135 final char[] buf, final Label[] labels) { 2136 int type = b[v++] & 0xFF; 2137 switch (type) { 2138 case 0: 2139 frame[index] = Opcodes.TOP; 2140 break; 2141 case 1: 2142 frame[index] = Opcodes.INTEGER; 2143 break; 2144 case 2: 2145 frame[index] = Opcodes.FLOAT; 2146 break; 2147 case 3: 2148 frame[index] = Opcodes.DOUBLE; 2149 break; 2150 case 4: 2151 frame[index] = Opcodes.LONG; 2152 break; 2153 case 5: 2154 frame[index] = Opcodes.NULL; 2155 break; 2156 case 6: 2157 frame[index] = Opcodes.UNINITIALIZED_THIS; 2158 break; 2159 case 7: // Object 2160 frame[index] = readClass(v, buf); 2161 v += 2; 2162 break; 2163 default: // Uninitialized 2164 frame[index] = readLabel(readUnsignedShort(v), labels); 2165 v += 2; 2166 } 2167 return v; 2168 } 2169 2170 /** 2171 * Returns the label corresponding to the given offset. The default 2172 * implementation of this method creates a label for the given offset if it 2173 * has not been already created. 2174 * 2175 * @param offset 2176 * a bytecode offset in a method. 2177 * @param labels 2178 * the already created labels, indexed by their offset. If a 2179 * label already exists for offset this method must not create a 2180 * new one. Otherwise it must store the new label in this array. 2181 * @return a non null Label, which must be equal to labels[offset]. 2182 */ readLabel(int offset, Label[] labels)2183 protected Label readLabel(int offset, Label[] labels) { 2184 if (labels[offset] == null) { 2185 labels[offset] = new Label(); 2186 } 2187 return labels[offset]; 2188 } 2189 2190 /** 2191 * Returns the start index of the attribute_info structure of this class. 2192 * 2193 * @return the start index of the attribute_info structure of this class. 2194 */ getAttributes()2195 private int getAttributes() { 2196 // skips the header 2197 int u = header + 8 + readUnsignedShort(header + 6) * 2; 2198 // skips fields and methods 2199 for (int i = readUnsignedShort(u); i > 0; --i) { 2200 for (int j = readUnsignedShort(u + 8); j > 0; --j) { 2201 u += 6 + readInt(u + 12); 2202 } 2203 u += 8; 2204 } 2205 u += 2; 2206 for (int i = readUnsignedShort(u); i > 0; --i) { 2207 for (int j = readUnsignedShort(u + 8); j > 0; --j) { 2208 u += 6 + readInt(u + 12); 2209 } 2210 u += 8; 2211 } 2212 // the attribute_info structure starts just after the methods 2213 return u + 2; 2214 } 2215 2216 /** 2217 * Reads an attribute in {@link #b b}. 2218 * 2219 * @param attrs 2220 * prototypes of the attributes that must be parsed during the 2221 * visit of the class. Any attribute whose type is not equal to 2222 * the type of one the prototypes is ignored (i.e. an empty 2223 * {@link Attribute} instance is returned). 2224 * @param type 2225 * the type of the attribute. 2226 * @param off 2227 * index of the first byte of the attribute's content in 2228 * {@link #b b}. The 6 attribute header bytes, containing the 2229 * type and the length of the attribute, are not taken into 2230 * account here (they have already been read). 2231 * @param len 2232 * the length of the attribute's content. 2233 * @param buf 2234 * buffer to be used to call {@link #readUTF8 readUTF8}, 2235 * {@link #readClass(int,char[]) readClass} or {@link #readConst 2236 * readConst}. 2237 * @param codeOff 2238 * index of the first byte of code's attribute content in 2239 * {@link #b b}, or -1 if the attribute to be read is not a code 2240 * attribute. The 6 attribute header bytes, containing the type 2241 * and the length of the attribute, are not taken into account 2242 * here. 2243 * @param labels 2244 * the labels of the method's code, or <tt>null</tt> if the 2245 * attribute to be read is not a code attribute. 2246 * @return the attribute that has been read, or <tt>null</tt> to skip this 2247 * attribute. 2248 */ readAttribute(final Attribute[] attrs, final String type, final int off, final int len, final char[] buf, final int codeOff, final Label[] labels)2249 private Attribute readAttribute(final Attribute[] attrs, final String type, 2250 final int off, final int len, final char[] buf, final int codeOff, 2251 final Label[] labels) { 2252 for (int i = 0; i < attrs.length; ++i) { 2253 if (attrs[i].type.equals(type)) { 2254 return attrs[i].read(this, off, len, buf, codeOff, labels); 2255 } 2256 } 2257 return new Attribute(type).read(this, off, len, null, -1, null); 2258 } 2259 2260 // ------------------------------------------------------------------------ 2261 // Utility methods: low level parsing 2262 // ------------------------------------------------------------------------ 2263 2264 /** 2265 * Returns the number of constant pool items in {@link #b b}. 2266 * 2267 * @return the number of constant pool items in {@link #b b}. 2268 */ getItemCount()2269 public int getItemCount() { 2270 return items.length; 2271 } 2272 2273 /** 2274 * Returns the start index of the constant pool item in {@link #b b}, plus 2275 * one. <i>This method is intended for {@link Attribute} sub classes, and is 2276 * normally not needed by class generators or adapters.</i> 2277 * 2278 * @param item 2279 * the index a constant pool item. 2280 * @return the start index of the constant pool item in {@link #b b}, plus 2281 * one. 2282 */ getItem(final int item)2283 public int getItem(final int item) { 2284 return items[item]; 2285 } 2286 2287 /** 2288 * Returns the maximum length of the strings contained in the constant pool 2289 * of the class. 2290 * 2291 * @return the maximum length of the strings contained in the constant pool 2292 * of the class. 2293 */ getMaxStringLength()2294 public int getMaxStringLength() { 2295 return maxStringLength; 2296 } 2297 2298 /** 2299 * Reads a byte value in {@link #b b}. <i>This method is intended for 2300 * {@link Attribute} sub classes, and is normally not needed by class 2301 * generators or adapters.</i> 2302 * 2303 * @param index 2304 * the start index of the value to be read in {@link #b b}. 2305 * @return the read value. 2306 */ readByte(final int index)2307 public int readByte(final int index) { 2308 return b[index] & 0xFF; 2309 } 2310 2311 /** 2312 * Reads an unsigned short value in {@link #b b}. <i>This method is intended 2313 * for {@link Attribute} sub classes, and is normally not needed by class 2314 * generators or adapters.</i> 2315 * 2316 * @param index 2317 * the start index of the value to be read in {@link #b b}. 2318 * @return the read value. 2319 */ readUnsignedShort(final int index)2320 public int readUnsignedShort(final int index) { 2321 byte[] b = this.b; 2322 return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF); 2323 } 2324 2325 /** 2326 * Reads a signed short value in {@link #b b}. <i>This method is intended 2327 * for {@link Attribute} sub classes, and is normally not needed by class 2328 * generators or adapters.</i> 2329 * 2330 * @param index 2331 * the start index of the value to be read in {@link #b b}. 2332 * @return the read value. 2333 */ readShort(final int index)2334 public short readShort(final int index) { 2335 byte[] b = this.b; 2336 return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF)); 2337 } 2338 2339 /** 2340 * Reads a signed int value in {@link #b b}. <i>This method is intended for 2341 * {@link Attribute} sub classes, and is normally not needed by class 2342 * generators or adapters.</i> 2343 * 2344 * @param index 2345 * the start index of the value to be read in {@link #b b}. 2346 * @return the read value. 2347 */ readInt(final int index)2348 public int readInt(final int index) { 2349 byte[] b = this.b; 2350 return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16) 2351 | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF); 2352 } 2353 2354 /** 2355 * Reads a signed long value in {@link #b b}. <i>This method is intended for 2356 * {@link Attribute} sub classes, and is normally not needed by class 2357 * generators or adapters.</i> 2358 * 2359 * @param index 2360 * the start index of the value to be read in {@link #b b}. 2361 * @return the read value. 2362 */ readLong(final int index)2363 public long readLong(final int index) { 2364 long l1 = readInt(index); 2365 long l0 = readInt(index + 4) & 0xFFFFFFFFL; 2366 return (l1 << 32) | l0; 2367 } 2368 2369 /** 2370 * Reads an UTF8 string constant pool item in {@link #b b}. <i>This method 2371 * is intended for {@link Attribute} sub classes, and is normally not needed 2372 * by class generators or adapters.</i> 2373 * 2374 * @param index 2375 * the start index of an unsigned short value in {@link #b b}, 2376 * whose value is the index of an UTF8 constant pool item. 2377 * @param buf 2378 * buffer to be used to read the item. This buffer must be 2379 * sufficiently large. It is not automatically resized. 2380 * @return the String corresponding to the specified UTF8 item. 2381 */ readUTF8(int index, final char[] buf)2382 public String readUTF8(int index, final char[] buf) { 2383 int item = readUnsignedShort(index); 2384 if (index == 0 || item == 0) { 2385 return null; 2386 } 2387 String s = strings[item]; 2388 if (s != null) { 2389 return s; 2390 } 2391 index = items[item]; 2392 return strings[item] = readUTF(index + 2, readUnsignedShort(index), buf); 2393 } 2394 2395 /** 2396 * Reads UTF8 string in {@link #b b}. 2397 * 2398 * @param index 2399 * start offset of the UTF8 string to be read. 2400 * @param utfLen 2401 * length of the UTF8 string to be read. 2402 * @param buf 2403 * buffer to be used to read the string. This buffer must be 2404 * sufficiently large. It is not automatically resized. 2405 * @return the String corresponding to the specified UTF8 string. 2406 */ readUTF(int index, final int utfLen, final char[] buf)2407 private String readUTF(int index, final int utfLen, final char[] buf) { 2408 int endIndex = index + utfLen; 2409 byte[] b = this.b; 2410 int strLen = 0; 2411 int c; 2412 int st = 0; 2413 char cc = 0; 2414 while (index < endIndex) { 2415 c = b[index++]; 2416 switch (st) { 2417 case 0: 2418 c = c & 0xFF; 2419 if (c < 0x80) { // 0xxxxxxx 2420 buf[strLen++] = (char) c; 2421 } else if (c < 0xE0 && c > 0xBF) { // 110x xxxx 10xx xxxx 2422 cc = (char) (c & 0x1F); 2423 st = 1; 2424 } else { // 1110 xxxx 10xx xxxx 10xx xxxx 2425 cc = (char) (c & 0x0F); 2426 st = 2; 2427 } 2428 break; 2429 2430 case 1: // byte 2 of 2-byte char or byte 3 of 3-byte char 2431 buf[strLen++] = (char) ((cc << 6) | (c & 0x3F)); 2432 st = 0; 2433 break; 2434 2435 case 2: // byte 2 of 3-byte char 2436 cc = (char) ((cc << 6) | (c & 0x3F)); 2437 st = 1; 2438 break; 2439 } 2440 } 2441 return new String(buf, 0, strLen); 2442 } 2443 2444 /** 2445 * Reads a class constant pool item in {@link #b b}. <i>This method is 2446 * intended for {@link Attribute} sub classes, and is normally not needed by 2447 * class generators or adapters.</i> 2448 * 2449 * @param index 2450 * the start index of an unsigned short value in {@link #b b}, 2451 * whose value is the index of a class constant pool item. 2452 * @param buf 2453 * buffer to be used to read the item. This buffer must be 2454 * sufficiently large. It is not automatically resized. 2455 * @return the String corresponding to the specified class item. 2456 */ readClass(final int index, final char[] buf)2457 public String readClass(final int index, final char[] buf) { 2458 // computes the start index of the CONSTANT_Class item in b 2459 // and reads the CONSTANT_Utf8 item designated by 2460 // the first two bytes of this CONSTANT_Class item 2461 return readUTF8(items[readUnsignedShort(index)], buf); 2462 } 2463 2464 /** 2465 * Reads a numeric or string constant pool item in {@link #b b}. <i>This 2466 * method is intended for {@link Attribute} sub classes, and is normally not 2467 * needed by class generators or adapters.</i> 2468 * 2469 * @param item 2470 * the index of a constant pool item. 2471 * @param buf 2472 * buffer to be used to read the item. This buffer must be 2473 * sufficiently large. It is not automatically resized. 2474 * @return the {@link Integer}, {@link Float}, {@link Long}, {@link Double}, 2475 * {@link String}, {@link Type} or {@link Handle} corresponding to 2476 * the given constant pool item. 2477 */ readConst(final int item, final char[] buf)2478 public Object readConst(final int item, final char[] buf) { 2479 int index = items[item]; 2480 switch (b[index - 1]) { 2481 case ClassWriter.INT: 2482 return readInt(index); 2483 case ClassWriter.FLOAT: 2484 return Float.intBitsToFloat(readInt(index)); 2485 case ClassWriter.LONG: 2486 return readLong(index); 2487 case ClassWriter.DOUBLE: 2488 return Double.longBitsToDouble(readLong(index)); 2489 case ClassWriter.CLASS: 2490 return Type.getObjectType(readUTF8(index, buf)); 2491 case ClassWriter.STR: 2492 return readUTF8(index, buf); 2493 case ClassWriter.MTYPE: 2494 return Type.getMethodType(readUTF8(index, buf)); 2495 default: // case ClassWriter.HANDLE_BASE + [1..9]: 2496 int tag = readByte(index); 2497 int[] items = this.items; 2498 int cpIndex = items[readUnsignedShort(index + 1)]; 2499 String owner = readClass(cpIndex, buf); 2500 cpIndex = items[readUnsignedShort(cpIndex + 2)]; 2501 String name = readUTF8(cpIndex, buf); 2502 String desc = readUTF8(cpIndex + 2, buf); 2503 return new Handle(tag, owner, name, desc); 2504 } 2505 } 2506 } 2507