1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 /* 26 * This file is available under and governed by the GNU General Public 27 * License version 2 only, as published by the Free Software Foundation. 28 * However, the following notice accompanied the original version of this 29 * file: 30 * 31 * ASM: a very small and fast Java bytecode manipulation framework 32 * Copyright (c) 2000-2011 INRIA, France Telecom 33 * All rights reserved. 34 * 35 * Redistribution and use in source and binary forms, with or without 36 * modification, are permitted provided that the following conditions 37 * are met: 38 * 1. Redistributions of source code must retain the above copyright 39 * notice, this list of conditions and the following disclaimer. 40 * 2. Redistributions in binary form must reproduce the above copyright 41 * notice, this list of conditions and the following disclaimer in the 42 * documentation and/or other materials provided with the distribution. 43 * 3. Neither the name of the copyright holders nor the names of its 44 * contributors may be used to endorse or promote products derived from 45 * this software without specific prior written permission. 46 * 47 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 48 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 50 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 51 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 52 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 53 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 54 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 55 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 56 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 57 * THE POSSIBILITY OF SUCH DAMAGE. 58 */ 59 package jdk.internal.org.objectweb.asm; 60 61 import java.io.IOException; 62 import java.io.InputStream; 63 64 /** 65 * A Java class parser to make a {@link ClassVisitor} visit an existing class. 66 * This class parses a byte array conforming to the Java class file format and 67 * calls the appropriate visit methods of a given class visitor for each field, 68 * method and bytecode instruction encountered. 69 * 70 * @author Eric Bruneton 71 * @author Eugene Kuleshov 72 */ 73 public class ClassReader { 74 75 /** 76 * True to enable signatures support. 77 */ 78 static final boolean SIGNATURES = true; 79 80 /** 81 * True to enable annotations support. 82 */ 83 static final boolean ANNOTATIONS = true; 84 85 /** 86 * True to enable stack map frames support. 87 */ 88 static final boolean FRAMES = true; 89 90 /** 91 * True to enable bytecode writing support. 92 */ 93 static final boolean WRITER = true; 94 95 /** 96 * True to enable JSR_W and GOTO_W support. 97 */ 98 static final boolean RESIZE = true; 99 100 /** 101 * Flag to skip method code. If this class is set <code>CODE</code> 102 * attribute won't be visited. This can be used, for example, to retrieve 103 * annotations for methods and method parameters. 104 */ 105 public static final int SKIP_CODE = 1; 106 107 /** 108 * Flag to skip the debug information in the class. If this flag is set the 109 * debug information of the class is not visited, i.e. the 110 * {@link MethodVisitor#visitLocalVariable visitLocalVariable} and 111 * {@link MethodVisitor#visitLineNumber visitLineNumber} methods will not be 112 * called. 113 */ 114 public static final int SKIP_DEBUG = 2; 115 116 /** 117 * Flag to skip the stack map frames in the class. If this flag is set the 118 * stack map frames of the class is not visited, i.e. the 119 * {@link MethodVisitor#visitFrame visitFrame} method will not be called. 120 * This flag is useful when the {@link ClassWriter#COMPUTE_FRAMES} option is 121 * used: it avoids visiting frames that will be ignored and recomputed from 122 * scratch in the class writer. 123 */ 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; 219 break; 220 case ClassWriter.LONG: 221 case ClassWriter.DOUBLE: 222 size = 9; 223 ++i; 224 break; 225 case ClassWriter.UTF8: 226 size = 3 + readUnsignedShort(index + 1); 227 if (size > max) { 228 max = size; 229 } 230 break; 231 case ClassWriter.HANDLE: 232 size = 4; 233 break; 234 // case ClassWriter.CLASS: 235 // case ClassWriter.STR: 236 // case ClassWriter.MTYPE 237 default: 238 size = 3; 239 break; 240 } 241 index += size; 242 } 243 maxStringLength = max; 244 // the class header information starts just after the constant pool 245 header = index; 246 } 247 248 /** 249 * Returns the class's access flags (see {@link Opcodes}). This value may 250 * not reflect Deprecated and Synthetic flags when bytecode is before 1.5 251 * and those flags are represented by attributes. 252 * 253 * @return the class access flags 254 * 255 * @see ClassVisitor#visit(int, int, String, String, String, String[]) 256 */ 257 public int getAccess() { 258 return readUnsignedShort(header); 259 } 260 261 /** 262 * Returns the internal name of the class (see 263 * {@link Type#getInternalName() getInternalName}). 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 Label l = labels[label]; 1203 while (l.line > 0) { 1204 if (l.next == null) { 1205 l.next = new Label(); 1206 } 1207 l = l.next; 1208 } 1209 l.line = readUnsignedShort(v + 12); 1210 v += 4; 1211 } 1212 } 1213 } else if (ANNOTATIONS 1214 && "RuntimeVisibleTypeAnnotations".equals(attrName)) { 1215 tanns = readTypeAnnotations(mv, context, u + 8, true); 1216 ntoff = tanns.length == 0 || readByte(tanns[0]) < 0x43 ? -1 1217 : readUnsignedShort(tanns[0] + 1); 1218 } else if (ANNOTATIONS 1219 && "RuntimeInvisibleTypeAnnotations".equals(attrName)) { 1220 itanns = readTypeAnnotations(mv, context, u + 8, false); 1221 nitoff = itanns.length == 0 || readByte(itanns[0]) < 0x43 ? -1 1222 : readUnsignedShort(itanns[0] + 1); 1223 } else if (FRAMES && "StackMapTable".equals(attrName)) { 1224 if ((context.flags & SKIP_FRAMES) == 0) { 1225 stackMap = u + 10; 1226 stackMapSize = readInt(u + 4); 1227 frameCount = readUnsignedShort(u + 8); 1228 } 1229 /* 1230 * here we do not extract the labels corresponding to the 1231 * attribute content. This would require a full parsing of the 1232 * attribute, which would need to be repeated in the second 1233 * phase (see below). Instead the content of the attribute is 1234 * read one frame at a time (i.e. after a frame has been 1235 * visited, the next frame is read), and the labels it contains 1236 * are also extracted one frame at a time. Thanks to the 1237 * ordering of frames, having only a "one frame lookahead" is 1238 * not a problem, i.e. it is not possible to see an offset 1239 * smaller than the offset of the current insn and for which no 1240 * Label exist. 1241 */ 1242 /* 1243 * This is not true for UNINITIALIZED type offsets. We solve 1244 * this by parsing the stack map table without a full decoding 1245 * (see below). 1246 */ 1247 } else if (FRAMES && "StackMap".equals(attrName)) { 1248 if ((context.flags & SKIP_FRAMES) == 0) { 1249 zip = false; 1250 stackMap = u + 10; 1251 stackMapSize = readInt(u + 4); 1252 frameCount = readUnsignedShort(u + 8); 1253 } 1254 /* 1255 * IMPORTANT! here we assume that the frames are ordered, as in 1256 * the StackMapTable attribute, although this is not guaranteed 1257 * by the attribute format. 1258 */ 1259 } else { 1260 for (int j = 0; j < context.attrs.length; ++j) { 1261 if (context.attrs[j].type.equals(attrName)) { 1262 Attribute attr = context.attrs[j].read(this, u + 8, 1263 readInt(u + 4), c, codeStart - 8, labels); 1264 if (attr != null) { 1265 attr.next = attributes; 1266 attributes = attr; 1267 } 1268 } 1269 } 1270 } 1271 u += 6 + readInt(u + 4); 1272 } 1273 u += 2; 1274 1275 // generates the first (implicit) stack map frame 1276 if (FRAMES && stackMap != 0) { 1277 /* 1278 * for the first explicit frame the offset is not offset_delta + 1 1279 * but only offset_delta; setting the implicit frame offset to -1 1280 * allow the use of the "offset_delta + 1" rule in all cases 1281 */ 1282 frame = context; 1283 frame.offset = -1; 1284 frame.mode = 0; 1285 frame.localCount = 0; 1286 frame.localDiff = 0; 1287 frame.stackCount = 0; 1288 frame.local = new Object[maxLocals]; 1289 frame.stack = new Object[maxStack]; 1290 if (unzip) { 1291 getImplicitFrame(context); 1292 } 1293 /* 1294 * Finds labels for UNINITIALIZED frame types. Instead of decoding 1295 * each element of the stack map table, we look for 3 consecutive 1296 * bytes that "look like" an UNINITIALIZED type (tag 8, offset 1297 * within code bounds, NEW instruction at this offset). We may find 1298 * false positives (i.e. not real UNINITIALIZED types), but this 1299 * should be rare, and the only consequence will be the creation of 1300 * an unneeded label. This is better than creating a label for each 1301 * NEW instruction, and faster than fully decoding the whole stack 1302 * map table. 1303 */ 1304 for (int i = stackMap; i < stackMap + stackMapSize - 2; ++i) { 1305 if (b[i] == 8) { // UNINITIALIZED FRAME TYPE 1306 int v = readUnsignedShort(i + 1); 1307 if (v >= 0 && v < codeLength) { 1308 if ((b[codeStart + v] & 0xFF) == Opcodes.NEW) { 1309 readLabel(v, labels); 1310 } 1311 } 1312 } 1313 } 1314 } 1315 1316 // visits the instructions 1317 u = codeStart; 1318 while (u < codeEnd) { 1319 int offset = u - codeStart; 1320 1321 // visits the label and line number for this offset, if any 1322 Label l = labels[offset]; 1323 if (l != null) { 1324 Label next = l.next; 1325 l.next = null; 1326 mv.visitLabel(l); 1327 if ((context.flags & SKIP_DEBUG) == 0 && l.line > 0) { 1328 mv.visitLineNumber(l.line, l); 1329 while (next != null) { 1330 mv.visitLineNumber(next.line, l); 1331 next = next.next; 1332 } 1333 } 1334 } 1335 1336 // visits the frame for this offset, if any 1337 while (FRAMES && frame != null 1338 && (frame.offset == offset || frame.offset == -1)) { 1339 // if there is a frame for this offset, makes the visitor visit 1340 // it, and reads the next frame if there is one. 1341 if (frame.offset != -1) { 1342 if (!zip || unzip) { 1343 mv.visitFrame(Opcodes.F_NEW, frame.localCount, 1344 frame.local, frame.stackCount, frame.stack); 1345 } else { 1346 mv.visitFrame(frame.mode, frame.localDiff, frame.local, 1347 frame.stackCount, frame.stack); 1348 } 1349 } 1350 if (frameCount > 0) { 1351 stackMap = readFrame(stackMap, zip, unzip, frame); 1352 --frameCount; 1353 } else { 1354 frame = null; 1355 } 1356 } 1357 1358 // visits the instruction at this offset 1359 int opcode = b[u] & 0xFF; 1360 switch (ClassWriter.TYPE[opcode]) { 1361 case ClassWriter.NOARG_INSN: 1362 mv.visitInsn(opcode); 1363 u += 1; 1364 break; 1365 case ClassWriter.IMPLVAR_INSN: 1366 if (opcode > Opcodes.ISTORE) { 1367 opcode -= 59; // ISTORE_0 1368 mv.visitVarInsn(Opcodes.ISTORE + (opcode >> 2), 1369 opcode & 0x3); 1370 } else { 1371 opcode -= 26; // ILOAD_0 1372 mv.visitVarInsn(Opcodes.ILOAD + (opcode >> 2), opcode & 0x3); 1373 } 1374 u += 1; 1375 break; 1376 case ClassWriter.LABEL_INSN: 1377 mv.visitJumpInsn(opcode, labels[offset + readShort(u + 1)]); 1378 u += 3; 1379 break; 1380 case ClassWriter.LABELW_INSN: 1381 mv.visitJumpInsn(opcode - 33, labels[offset + readInt(u + 1)]); 1382 u += 5; 1383 break; 1384 case ClassWriter.WIDE_INSN: 1385 opcode = b[u + 1] & 0xFF; 1386 if (opcode == Opcodes.IINC) { 1387 mv.visitIincInsn(readUnsignedShort(u + 2), readShort(u + 4)); 1388 u += 6; 1389 } else { 1390 mv.visitVarInsn(opcode, readUnsignedShort(u + 2)); 1391 u += 4; 1392 } 1393 break; 1394 case ClassWriter.TABL_INSN: { 1395 // skips 0 to 3 padding bytes 1396 u = u + 4 - (offset & 3); 1397 // reads instruction 1398 int label = offset + readInt(u); 1399 int min = readInt(u + 4); 1400 int max = readInt(u + 8); 1401 Label[] table = new Label[max - min + 1]; 1402 u += 12; 1403 for (int i = 0; i < table.length; ++i) { 1404 table[i] = labels[offset + readInt(u)]; 1405 u += 4; 1406 } 1407 mv.visitTableSwitchInsn(min, max, labels[label], table); 1408 break; 1409 } 1410 case ClassWriter.LOOK_INSN: { 1411 // skips 0 to 3 padding bytes 1412 u = u + 4 - (offset & 3); 1413 // reads instruction 1414 int label = offset + readInt(u); 1415 int len = readInt(u + 4); 1416 int[] keys = new int[len]; 1417 Label[] values = new Label[len]; 1418 u += 8; 1419 for (int i = 0; i < len; ++i) { 1420 keys[i] = readInt(u); 1421 values[i] = labels[offset + readInt(u + 4)]; 1422 u += 8; 1423 } 1424 mv.visitLookupSwitchInsn(labels[label], keys, values); 1425 break; 1426 } 1427 case ClassWriter.VAR_INSN: 1428 mv.visitVarInsn(opcode, b[u + 1] & 0xFF); 1429 u += 2; 1430 break; 1431 case ClassWriter.SBYTE_INSN: 1432 mv.visitIntInsn(opcode, b[u + 1]); 1433 u += 2; 1434 break; 1435 case ClassWriter.SHORT_INSN: 1436 mv.visitIntInsn(opcode, readShort(u + 1)); 1437 u += 3; 1438 break; 1439 case ClassWriter.LDC_INSN: 1440 mv.visitLdcInsn(readConst(b[u + 1] & 0xFF, c)); 1441 u += 2; 1442 break; 1443 case ClassWriter.LDCW_INSN: 1444 mv.visitLdcInsn(readConst(readUnsignedShort(u + 1), c)); 1445 u += 3; 1446 break; 1447 case ClassWriter.FIELDORMETH_INSN: 1448 case ClassWriter.ITFMETH_INSN: { 1449 int cpIndex = items[readUnsignedShort(u + 1)]; 1450 boolean itf = b[cpIndex - 1] == ClassWriter.IMETH; 1451 String iowner = readClass(cpIndex, c); 1452 cpIndex = items[readUnsignedShort(cpIndex + 2)]; 1453 String iname = readUTF8(cpIndex, c); 1454 String idesc = readUTF8(cpIndex + 2, c); 1455 if (opcode < Opcodes.INVOKEVIRTUAL) { 1456 mv.visitFieldInsn(opcode, iowner, iname, idesc); 1457 } else { 1458 mv.visitMethodInsn(opcode, iowner, iname, idesc, itf); 1459 } 1460 if (opcode == Opcodes.INVOKEINTERFACE) { 1461 u += 5; 1462 } else { 1463 u += 3; 1464 } 1465 break; 1466 } 1467 case ClassWriter.INDYMETH_INSN: { 1468 int cpIndex = items[readUnsignedShort(u + 1)]; 1469 int bsmIndex = context.bootstrapMethods[readUnsignedShort(cpIndex)]; 1470 Handle bsm = (Handle) readConst(readUnsignedShort(bsmIndex), c); 1471 int bsmArgCount = readUnsignedShort(bsmIndex + 2); 1472 Object[] bsmArgs = new Object[bsmArgCount]; 1473 bsmIndex += 4; 1474 for (int i = 0; i < bsmArgCount; i++) { 1475 bsmArgs[i] = readConst(readUnsignedShort(bsmIndex), c); 1476 bsmIndex += 2; 1477 } 1478 cpIndex = items[readUnsignedShort(cpIndex + 2)]; 1479 String iname = readUTF8(cpIndex, c); 1480 String idesc = readUTF8(cpIndex + 2, c); 1481 mv.visitInvokeDynamicInsn(iname, idesc, bsm, bsmArgs); 1482 u += 5; 1483 break; 1484 } 1485 case ClassWriter.TYPE_INSN: 1486 mv.visitTypeInsn(opcode, readClass(u + 1, c)); 1487 u += 3; 1488 break; 1489 case ClassWriter.IINC_INSN: 1490 mv.visitIincInsn(b[u + 1] & 0xFF, b[u + 2]); 1491 u += 3; 1492 break; 1493 // case MANA_INSN: 1494 default: 1495 mv.visitMultiANewArrayInsn(readClass(u + 1, c), b[u + 3] & 0xFF); 1496 u += 4; 1497 break; 1498 } 1499 1500 // visit the instruction annotations, if any 1501 while (tanns != null && tann < tanns.length && ntoff <= offset) { 1502 if (ntoff == offset) { 1503 int v = readAnnotationTarget(context, tanns[tann]); 1504 readAnnotationValues(v + 2, c, true, 1505 mv.visitInsnAnnotation(context.typeRef, 1506 context.typePath, readUTF8(v, c), true)); 1507 } 1508 ntoff = ++tann >= tanns.length || readByte(tanns[tann]) < 0x43 ? -1 1509 : readUnsignedShort(tanns[tann] + 1); 1510 } 1511 while (itanns != null && itann < itanns.length && nitoff <= offset) { 1512 if (nitoff == offset) { 1513 int v = readAnnotationTarget(context, itanns[itann]); 1514 readAnnotationValues(v + 2, c, true, 1515 mv.visitInsnAnnotation(context.typeRef, 1516 context.typePath, readUTF8(v, c), false)); 1517 } 1518 nitoff = ++itann >= itanns.length 1519 || readByte(itanns[itann]) < 0x43 ? -1 1520 : readUnsignedShort(itanns[itann] + 1); 1521 } 1522 } 1523 if (labels[codeLength] != null) { 1524 mv.visitLabel(labels[codeLength]); 1525 } 1526 1527 // visits the local variable tables 1528 if ((context.flags & SKIP_DEBUG) == 0 && varTable != 0) { 1529 int[] typeTable = null; 1530 if (varTypeTable != 0) { 1531 u = varTypeTable + 2; 1532 typeTable = new int[readUnsignedShort(varTypeTable) * 3]; 1533 for (int i = typeTable.length; i > 0;) { 1534 typeTable[--i] = u + 6; // signature 1535 typeTable[--i] = readUnsignedShort(u + 8); // index 1536 typeTable[--i] = readUnsignedShort(u); // start 1537 u += 10; 1538 } 1539 } 1540 u = varTable + 2; 1541 for (int i = readUnsignedShort(varTable); i > 0; --i) { 1542 int start = readUnsignedShort(u); 1543 int length = readUnsignedShort(u + 2); 1544 int index = readUnsignedShort(u + 8); 1545 String vsignature = null; 1546 if (typeTable != null) { 1547 for (int j = 0; j < typeTable.length; j += 3) { 1548 if (typeTable[j] == start && typeTable[j + 1] == index) { 1549 vsignature = readUTF8(typeTable[j + 2], c); 1550 break; 1551 } 1552 } 1553 } 1554 mv.visitLocalVariable(readUTF8(u + 4, c), readUTF8(u + 6, c), 1555 vsignature, labels[start], labels[start + length], 1556 index); 1557 u += 10; 1558 } 1559 } 1560 1561 // visits the local variables type annotations 1562 if (tanns != null) { 1563 for (int i = 0; i < tanns.length; ++i) { 1564 if ((readByte(tanns[i]) >> 1) == (0x40 >> 1)) { 1565 int v = readAnnotationTarget(context, tanns[i]); 1566 v = readAnnotationValues(v + 2, c, true, 1567 mv.visitLocalVariableAnnotation(context.typeRef, 1568 context.typePath, context.start, 1569 context.end, context.index, readUTF8(v, c), 1570 true)); 1571 } 1572 } 1573 } 1574 if (itanns != null) { 1575 for (int i = 0; i < itanns.length; ++i) { 1576 if ((readByte(itanns[i]) >> 1) == (0x40 >> 1)) { 1577 int v = readAnnotationTarget(context, itanns[i]); 1578 v = readAnnotationValues(v + 2, c, true, 1579 mv.visitLocalVariableAnnotation(context.typeRef, 1580 context.typePath, context.start, 1581 context.end, context.index, readUTF8(v, c), 1582 false)); 1583 } 1584 } 1585 } 1586 1587 // visits the code attributes 1588 while (attributes != null) { 1589 Attribute attr = attributes.next; 1590 attributes.next = null; 1591 mv.visitAttribute(attributes); 1592 attributes = attr; 1593 } 1594 1595 // visits the max stack and max locals values 1596 mv.visitMaxs(maxStack, maxLocals); 1597 } 1598 1599 /** 1600 * Parses a type annotation table to find the labels, and to visit the try 1601 * catch block annotations. 1602 * 1603 * @param u 1604 * the start offset of a type annotation table. 1605 * @param mv 1606 * the method visitor to be used to visit the try catch block 1607 * annotations. 1608 * @param context 1609 * information about the class being parsed. 1610 * @param visible 1611 * if the type annotation table to parse contains runtime visible 1612 * annotations. 1613 * @return the start offset of each type annotation in the parsed table. 1614 */ 1615 private int[] readTypeAnnotations(final MethodVisitor mv, 1616 final Context context, int u, boolean visible) { 1617 char[] c = context.buffer; 1618 int[] offsets = new int[readUnsignedShort(u)]; 1619 u += 2; 1620 for (int i = 0; i < offsets.length; ++i) { 1621 offsets[i] = u; 1622 int target = readInt(u); 1623 switch (target >>> 24) { 1624 case 0x00: // CLASS_TYPE_PARAMETER 1625 case 0x01: // METHOD_TYPE_PARAMETER 1626 case 0x16: // METHOD_FORMAL_PARAMETER 1627 u += 2; 1628 break; 1629 case 0x13: // FIELD 1630 case 0x14: // METHOD_RETURN 1631 case 0x15: // METHOD_RECEIVER 1632 u += 1; 1633 break; 1634 case 0x40: // LOCAL_VARIABLE 1635 case 0x41: // RESOURCE_VARIABLE 1636 for (int j = readUnsignedShort(u + 1); j > 0; --j) { 1637 int start = readUnsignedShort(u + 3); 1638 int length = readUnsignedShort(u + 5); 1639 readLabel(start, context.labels); 1640 readLabel(start + length, context.labels); 1641 u += 6; 1642 } 1643 u += 3; 1644 break; 1645 case 0x47: // CAST 1646 case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT 1647 case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT 1648 case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT 1649 case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT 1650 u += 4; 1651 break; 1652 // case 0x10: // CLASS_EXTENDS 1653 // case 0x11: // CLASS_TYPE_PARAMETER_BOUND 1654 // case 0x12: // METHOD_TYPE_PARAMETER_BOUND 1655 // case 0x17: // THROWS 1656 // case 0x42: // EXCEPTION_PARAMETER 1657 // case 0x43: // INSTANCEOF 1658 // case 0x44: // NEW 1659 // case 0x45: // CONSTRUCTOR_REFERENCE 1660 // case 0x46: // METHOD_REFERENCE 1661 default: 1662 u += 3; 1663 break; 1664 } 1665 int pathLength = readByte(u); 1666 if ((target >>> 24) == 0x42) { 1667 TypePath path = pathLength == 0 ? null : new TypePath(b, u); 1668 u += 1 + 2 * pathLength; 1669 u = readAnnotationValues(u + 2, c, true, 1670 mv.visitTryCatchAnnotation(target, path, 1671 readUTF8(u, c), visible)); 1672 } else { 1673 u = readAnnotationValues(u + 3 + 2 * pathLength, c, true, null); 1674 } 1675 } 1676 return offsets; 1677 } 1678 1679 /** 1680 * Parses the header of a type annotation to extract its target_type and 1681 * target_path (the result is stored in the given context), and returns the 1682 * start offset of the rest of the type_annotation structure (i.e. the 1683 * offset to the type_index field, which is followed by 1684 * num_element_value_pairs and then the name,value pairs). 1685 * 1686 * @param context 1687 * information about the class being parsed. This is where the 1688 * extracted target_type and target_path must be stored. 1689 * @param u 1690 * the start offset of a type_annotation structure. 1691 * @return the start offset of the rest of the type_annotation structure. 1692 */ 1693 private int readAnnotationTarget(final Context context, int u) { 1694 int target = readInt(u); 1695 switch (target >>> 24) { 1696 case 0x00: // CLASS_TYPE_PARAMETER 1697 case 0x01: // METHOD_TYPE_PARAMETER 1698 case 0x16: // METHOD_FORMAL_PARAMETER 1699 target &= 0xFFFF0000; 1700 u += 2; 1701 break; 1702 case 0x13: // FIELD 1703 case 0x14: // METHOD_RETURN 1704 case 0x15: // METHOD_RECEIVER 1705 target &= 0xFF000000; 1706 u += 1; 1707 break; 1708 case 0x40: // LOCAL_VARIABLE 1709 case 0x41: { // RESOURCE_VARIABLE 1710 target &= 0xFF000000; 1711 int n = readUnsignedShort(u + 1); 1712 context.start = new Label[n]; 1713 context.end = new Label[n]; 1714 context.index = new int[n]; 1715 u += 3; 1716 for (int i = 0; i < n; ++i) { 1717 int start = readUnsignedShort(u); 1718 int length = readUnsignedShort(u + 2); 1719 context.start[i] = readLabel(start, context.labels); 1720 context.end[i] = readLabel(start + length, context.labels); 1721 context.index[i] = readUnsignedShort(u + 4); 1722 u += 6; 1723 } 1724 break; 1725 } 1726 case 0x47: // CAST 1727 case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT 1728 case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT 1729 case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT 1730 case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT 1731 target &= 0xFF0000FF; 1732 u += 4; 1733 break; 1734 // case 0x10: // CLASS_EXTENDS 1735 // case 0x11: // CLASS_TYPE_PARAMETER_BOUND 1736 // case 0x12: // METHOD_TYPE_PARAMETER_BOUND 1737 // case 0x17: // THROWS 1738 // case 0x42: // EXCEPTION_PARAMETER 1739 // case 0x43: // INSTANCEOF 1740 // case 0x44: // NEW 1741 // case 0x45: // CONSTRUCTOR_REFERENCE 1742 // case 0x46: // METHOD_REFERENCE 1743 default: 1744 target &= (target >>> 24) < 0x43 ? 0xFFFFFF00 : 0xFF000000; 1745 u += 3; 1746 break; 1747 } 1748 int pathLength = readByte(u); 1749 context.typeRef = target; 1750 context.typePath = pathLength == 0 ? null : new TypePath(b, u); 1751 return u + 1 + 2 * pathLength; 1752 } 1753 1754 /** 1755 * Reads parameter annotations and makes the given visitor visit them. 1756 * 1757 * @param mv 1758 * the visitor that must visit the annotations. 1759 * @param context 1760 * information about the class being parsed. 1761 * @param v 1762 * start offset in {@link #b b} of the annotations to be read. 1763 * @param visible 1764 * <tt>true</tt> if the annotations to be read are visible at 1765 * runtime. 1766 */ 1767 private void readParameterAnnotations(final MethodVisitor mv, 1768 final Context context, int v, final boolean visible) { 1769 int i; 1770 int n = b[v++] & 0xFF; 1771 // workaround for a bug in javac (javac compiler generates a parameter 1772 // annotation array whose size is equal to the number of parameters in 1773 // the Java source file, while it should generate an array whose size is 1774 // equal to the number of parameters in the method descriptor - which 1775 // includes the synthetic parameters added by the compiler). This work- 1776 // around supposes that the synthetic parameters are the first ones. 1777 int synthetics = Type.getArgumentTypes(context.desc).length - n; 1778 AnnotationVisitor av; 1779 for (i = 0; i < synthetics; ++i) { 1780 // virtual annotation to detect synthetic parameters in MethodWriter 1781 av = mv.visitParameterAnnotation(i, "Ljava/lang/Synthetic;", false); 1782 if (av != null) { 1783 av.visitEnd(); 1784 } 1785 } 1786 char[] c = context.buffer; 1787 for (; i < n + synthetics; ++i) { 1788 int j = readUnsignedShort(v); 1789 v += 2; 1790 for (; j > 0; --j) { 1791 av = mv.visitParameterAnnotation(i, readUTF8(v, c), visible); 1792 v = readAnnotationValues(v + 2, c, true, av); 1793 } 1794 } 1795 } 1796 1797 /** 1798 * Reads the values of an annotation and makes the given visitor visit them. 1799 * 1800 * @param v 1801 * the start offset in {@link #b b} of the values to be read 1802 * (including the unsigned short that gives the number of 1803 * values). 1804 * @param buf 1805 * buffer to be used to call {@link #readUTF8 readUTF8}, 1806 * {@link #readClass(int,char[]) readClass} or {@link #readConst 1807 * readConst}. 1808 * @param named 1809 * if the annotation values are named or not. 1810 * @param av 1811 * the visitor that must visit the values. 1812 * @return the end offset of the annotation values. 1813 */ 1814 private int readAnnotationValues(int v, final char[] buf, 1815 final boolean named, final AnnotationVisitor av) { 1816 int i = readUnsignedShort(v); 1817 v += 2; 1818 if (named) { 1819 for (; i > 0; --i) { 1820 v = readAnnotationValue(v + 2, buf, readUTF8(v, buf), av); 1821 } 1822 } else { 1823 for (; i > 0; --i) { 1824 v = readAnnotationValue(v, buf, null, av); 1825 } 1826 } 1827 if (av != null) { 1828 av.visitEnd(); 1829 } 1830 return v; 1831 } 1832 1833 /** 1834 * Reads a value of an annotation and makes the given visitor visit it. 1835 * 1836 * @param v 1837 * the start offset in {@link #b b} of the value to be read 1838 * (<i>not including the value name constant pool index</i>). 1839 * @param buf 1840 * buffer to be used to call {@link #readUTF8 readUTF8}, 1841 * {@link #readClass(int,char[]) readClass} or {@link #readConst 1842 * readConst}. 1843 * @param name 1844 * the name of the value to be read. 1845 * @param av 1846 * the visitor that must visit the value. 1847 * @return the end offset of the annotation value. 1848 */ 1849 private int readAnnotationValue(int v, final char[] buf, final String name, 1850 final AnnotationVisitor av) { 1851 int i; 1852 if (av == null) { 1853 switch (b[v] & 0xFF) { 1854 case 'e': // enum_const_value 1855 return v + 5; 1856 case '@': // annotation_value 1857 return readAnnotationValues(v + 3, buf, true, null); 1858 case '[': // array_value 1859 return readAnnotationValues(v + 1, buf, false, null); 1860 default: 1861 return v + 3; 1862 } 1863 } 1864 switch (b[v++] & 0xFF) { 1865 case 'I': // pointer to CONSTANT_Integer 1866 case 'J': // pointer to CONSTANT_Long 1867 case 'F': // pointer to CONSTANT_Float 1868 case 'D': // pointer to CONSTANT_Double 1869 av.visit(name, readConst(readUnsignedShort(v), buf)); 1870 v += 2; 1871 break; 1872 case 'B': // pointer to CONSTANT_Byte 1873 av.visit(name, (byte) readInt(items[readUnsignedShort(v)])); 1874 v += 2; 1875 break; 1876 case 'Z': // pointer to CONSTANT_Boolean 1877 av.visit(name, 1878 readInt(items[readUnsignedShort(v)]) == 0 ? Boolean.FALSE 1879 : Boolean.TRUE); 1880 v += 2; 1881 break; 1882 case 'S': // pointer to CONSTANT_Short 1883 av.visit(name, (short) readInt(items[readUnsignedShort(v)])); 1884 v += 2; 1885 break; 1886 case 'C': // pointer to CONSTANT_Char 1887 av.visit(name, (char) readInt(items[readUnsignedShort(v)])); 1888 v += 2; 1889 break; 1890 case 's': // pointer to CONSTANT_Utf8 1891 av.visit(name, readUTF8(v, buf)); 1892 v += 2; 1893 break; 1894 case 'e': // enum_const_value 1895 av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf)); 1896 v += 4; 1897 break; 1898 case 'c': // class_info 1899 av.visit(name, Type.getType(readUTF8(v, buf))); 1900 v += 2; 1901 break; 1902 case '@': // annotation_value 1903 v = readAnnotationValues(v + 2, buf, true, 1904 av.visitAnnotation(name, readUTF8(v, buf))); 1905 break; 1906 case '[': // array_value 1907 int size = readUnsignedShort(v); 1908 v += 2; 1909 if (size == 0) { 1910 return readAnnotationValues(v - 2, buf, false, 1911 av.visitArray(name)); 1912 } 1913 switch (this.b[v++] & 0xFF) { 1914 case 'B': 1915 byte[] bv = new byte[size]; 1916 for (i = 0; i < size; i++) { 1917 bv[i] = (byte) readInt(items[readUnsignedShort(v)]); 1918 v += 3; 1919 } 1920 av.visit(name, bv); 1921 --v; 1922 break; 1923 case 'Z': 1924 boolean[] zv = new boolean[size]; 1925 for (i = 0; i < size; i++) { 1926 zv[i] = readInt(items[readUnsignedShort(v)]) != 0; 1927 v += 3; 1928 } 1929 av.visit(name, zv); 1930 --v; 1931 break; 1932 case 'S': 1933 short[] sv = new short[size]; 1934 for (i = 0; i < size; i++) { 1935 sv[i] = (short) readInt(items[readUnsignedShort(v)]); 1936 v += 3; 1937 } 1938 av.visit(name, sv); 1939 --v; 1940 break; 1941 case 'C': 1942 char[] cv = new char[size]; 1943 for (i = 0; i < size; i++) { 1944 cv[i] = (char) readInt(items[readUnsignedShort(v)]); 1945 v += 3; 1946 } 1947 av.visit(name, cv); 1948 --v; 1949 break; 1950 case 'I': 1951 int[] iv = new int[size]; 1952 for (i = 0; i < size; i++) { 1953 iv[i] = readInt(items[readUnsignedShort(v)]); 1954 v += 3; 1955 } 1956 av.visit(name, iv); 1957 --v; 1958 break; 1959 case 'J': 1960 long[] lv = new long[size]; 1961 for (i = 0; i < size; i++) { 1962 lv[i] = readLong(items[readUnsignedShort(v)]); 1963 v += 3; 1964 } 1965 av.visit(name, lv); 1966 --v; 1967 break; 1968 case 'F': 1969 float[] fv = new float[size]; 1970 for (i = 0; i < size; i++) { 1971 fv[i] = Float 1972 .intBitsToFloat(readInt(items[readUnsignedShort(v)])); 1973 v += 3; 1974 } 1975 av.visit(name, fv); 1976 --v; 1977 break; 1978 case 'D': 1979 double[] dv = new double[size]; 1980 for (i = 0; i < size; i++) { 1981 dv[i] = Double 1982 .longBitsToDouble(readLong(items[readUnsignedShort(v)])); 1983 v += 3; 1984 } 1985 av.visit(name, dv); 1986 --v; 1987 break; 1988 default: 1989 v = readAnnotationValues(v - 3, buf, false, av.visitArray(name)); 1990 } 1991 } 1992 return v; 1993 } 1994 1995 /** 1996 * Computes the implicit frame of the method currently being parsed (as 1997 * defined in the given {@link Context}) and stores it in the given context. 1998 * 1999 * @param frame 2000 * information about the class being parsed. 2001 */ 2002 private void getImplicitFrame(final Context frame) { 2003 String desc = frame.desc; 2004 Object[] locals = frame.local; 2005 int local = 0; 2006 if ((frame.access & Opcodes.ACC_STATIC) == 0) { 2007 if ("<init>".equals(frame.name)) { 2008 locals[local++] = Opcodes.UNINITIALIZED_THIS; 2009 } else { 2010 locals[local++] = readClass(header + 2, frame.buffer); 2011 } 2012 } 2013 int i = 1; 2014 loop: while (true) { 2015 int j = i; 2016 switch (desc.charAt(i++)) { 2017 case 'Z': 2018 case 'C': 2019 case 'B': 2020 case 'S': 2021 case 'I': 2022 locals[local++] = Opcodes.INTEGER; 2023 break; 2024 case 'F': 2025 locals[local++] = Opcodes.FLOAT; 2026 break; 2027 case 'J': 2028 locals[local++] = Opcodes.LONG; 2029 break; 2030 case 'D': 2031 locals[local++] = Opcodes.DOUBLE; 2032 break; 2033 case '[': 2034 while (desc.charAt(i) == '[') { 2035 ++i; 2036 } 2037 if (desc.charAt(i) == 'L') { 2038 ++i; 2039 while (desc.charAt(i) != ';') { 2040 ++i; 2041 } 2042 } 2043 locals[local++] = desc.substring(j, ++i); 2044 break; 2045 case 'L': 2046 while (desc.charAt(i) != ';') { 2047 ++i; 2048 } 2049 locals[local++] = desc.substring(j + 1, i++); 2050 break; 2051 default: 2052 break loop; 2053 } 2054 } 2055 frame.localCount = local; 2056 } 2057 2058 /** 2059 * Reads a stack map frame and stores the result in the given 2060 * {@link Context} object. 2061 * 2062 * @param stackMap 2063 * the start offset of a stack map frame in the class file. 2064 * @param zip 2065 * if the stack map frame at stackMap is compressed or not. 2066 * @param unzip 2067 * if the stack map frame must be uncompressed. 2068 * @param frame 2069 * where the parsed stack map frame must be stored. 2070 * @return the offset of the first byte following the parsed frame. 2071 */ 2072 private int readFrame(int stackMap, boolean zip, boolean unzip, 2073 Context frame) { 2074 char[] c = frame.buffer; 2075 Label[] labels = frame.labels; 2076 int tag; 2077 int delta; 2078 if (zip) { 2079 tag = b[stackMap++] & 0xFF; 2080 } else { 2081 tag = MethodWriter.FULL_FRAME; 2082 frame.offset = -1; 2083 } 2084 frame.localDiff = 0; 2085 if (tag < MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME) { 2086 delta = tag; 2087 frame.mode = Opcodes.F_SAME; 2088 frame.stackCount = 0; 2089 } else if (tag < MethodWriter.RESERVED) { 2090 delta = tag - MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME; 2091 stackMap = readFrameType(frame.stack, 0, stackMap, c, labels); 2092 frame.mode = Opcodes.F_SAME1; 2093 frame.stackCount = 1; 2094 } else { 2095 delta = readUnsignedShort(stackMap); 2096 stackMap += 2; 2097 if (tag == MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { 2098 stackMap = readFrameType(frame.stack, 0, stackMap, c, labels); 2099 frame.mode = Opcodes.F_SAME1; 2100 frame.stackCount = 1; 2101 } else if (tag >= MethodWriter.CHOP_FRAME 2102 && tag < MethodWriter.SAME_FRAME_EXTENDED) { 2103 frame.mode = Opcodes.F_CHOP; 2104 frame.localDiff = MethodWriter.SAME_FRAME_EXTENDED - tag; 2105 frame.localCount -= frame.localDiff; 2106 frame.stackCount = 0; 2107 } else if (tag == MethodWriter.SAME_FRAME_EXTENDED) { 2108 frame.mode = Opcodes.F_SAME; 2109 frame.stackCount = 0; 2110 } else if (tag < MethodWriter.FULL_FRAME) { 2111 int local = unzip ? frame.localCount : 0; 2112 for (int i = tag - MethodWriter.SAME_FRAME_EXTENDED; i > 0; i--) { 2113 stackMap = readFrameType(frame.local, local++, stackMap, c, 2114 labels); 2115 } 2116 frame.mode = Opcodes.F_APPEND; 2117 frame.localDiff = tag - MethodWriter.SAME_FRAME_EXTENDED; 2118 frame.localCount += frame.localDiff; 2119 frame.stackCount = 0; 2120 } else { // if (tag == FULL_FRAME) { 2121 frame.mode = Opcodes.F_FULL; 2122 int n = readUnsignedShort(stackMap); 2123 stackMap += 2; 2124 frame.localDiff = n; 2125 frame.localCount = n; 2126 for (int local = 0; n > 0; n--) { 2127 stackMap = readFrameType(frame.local, local++, stackMap, c, 2128 labels); 2129 } 2130 n = readUnsignedShort(stackMap); 2131 stackMap += 2; 2132 frame.stackCount = n; 2133 for (int stack = 0; n > 0; n--) { 2134 stackMap = readFrameType(frame.stack, stack++, stackMap, c, 2135 labels); 2136 } 2137 } 2138 } 2139 frame.offset += delta + 1; 2140 readLabel(frame.offset, labels); 2141 return stackMap; 2142 } 2143 2144 /** 2145 * Reads a stack map frame type and stores it at the given index in the 2146 * given array. 2147 * 2148 * @param frame 2149 * the array where the parsed type must be stored. 2150 * @param index 2151 * the index in 'frame' where the parsed type must be stored. 2152 * @param v 2153 * the start offset of the stack map frame type to read. 2154 * @param buf 2155 * a buffer to read strings. 2156 * @param labels 2157 * the labels of the method currently being parsed, indexed by 2158 * their offset. If the parsed type is an Uninitialized type, a 2159 * new label for the corresponding NEW instruction is stored in 2160 * this array if it does not already exist. 2161 * @return the offset of the first byte after the parsed type. 2162 */ 2163 private int readFrameType(final Object[] frame, final int index, int v, 2164 final char[] buf, final Label[] labels) { 2165 int type = b[v++] & 0xFF; 2166 switch (type) { 2167 case 0: 2168 frame[index] = Opcodes.TOP; 2169 break; 2170 case 1: 2171 frame[index] = Opcodes.INTEGER; 2172 break; 2173 case 2: 2174 frame[index] = Opcodes.FLOAT; 2175 break; 2176 case 3: 2177 frame[index] = Opcodes.DOUBLE; 2178 break; 2179 case 4: 2180 frame[index] = Opcodes.LONG; 2181 break; 2182 case 5: 2183 frame[index] = Opcodes.NULL; 2184 break; 2185 case 6: 2186 frame[index] = Opcodes.UNINITIALIZED_THIS; 2187 break; 2188 case 7: // Object 2189 frame[index] = readClass(v, buf); 2190 v += 2; 2191 break; 2192 default: // Uninitialized 2193 frame[index] = readLabel(readUnsignedShort(v), labels); 2194 v += 2; 2195 } 2196 return v; 2197 } 2198 2199 /** 2200 * Returns the label corresponding to the given offset. The default 2201 * implementation of this method creates a label for the given offset if it 2202 * has not been already created. 2203 * 2204 * @param offset 2205 * a bytecode offset in a method. 2206 * @param labels 2207 * the already created labels, indexed by their offset. If a 2208 * label already exists for offset this method must not create a 2209 * new one. Otherwise it must store the new label in this array. 2210 * @return a non null Label, which must be equal to labels[offset]. 2211 */ 2212 protected Label readLabel(int offset, Label[] labels) { 2213 if (labels[offset] == null) { 2214 labels[offset] = new Label(); 2215 } 2216 return labels[offset]; 2217 } 2218 2219 /** 2220 * Returns the start index of the attribute_info structure of this class. 2221 * 2222 * @return the start index of the attribute_info structure of this class. 2223 */ 2224 private int getAttributes() { 2225 // skips the header 2226 int u = header + 8 + readUnsignedShort(header + 6) * 2; 2227 // skips fields and methods 2228 for (int i = readUnsignedShort(u); i > 0; --i) { 2229 for (int j = readUnsignedShort(u + 8); j > 0; --j) { 2230 u += 6 + readInt(u + 12); 2231 } 2232 u += 8; 2233 } 2234 u += 2; 2235 for (int i = readUnsignedShort(u); i > 0; --i) { 2236 for (int j = readUnsignedShort(u + 8); j > 0; --j) { 2237 u += 6 + readInt(u + 12); 2238 } 2239 u += 8; 2240 } 2241 // the attribute_info structure starts just after the methods 2242 return u + 2; 2243 } 2244 2245 /** 2246 * Reads an attribute in {@link #b b}. 2247 * 2248 * @param attrs 2249 * prototypes of the attributes that must be parsed during the 2250 * visit of the class. Any attribute whose type is not equal to 2251 * the type of one the prototypes is ignored (i.e. an empty 2252 * {@link Attribute} instance is returned). 2253 * @param type 2254 * the type of the attribute. 2255 * @param off 2256 * index of the first byte of the attribute's content in 2257 * {@link #b b}. The 6 attribute header bytes, containing the 2258 * type and the length of the attribute, are not taken into 2259 * account here (they have already been read). 2260 * @param len 2261 * the length of the attribute's content. 2262 * @param buf 2263 * buffer to be used to call {@link #readUTF8 readUTF8}, 2264 * {@link #readClass(int,char[]) readClass} or {@link #readConst 2265 * readConst}. 2266 * @param codeOff 2267 * index of the first byte of code's attribute content in 2268 * {@link #b b}, or -1 if the attribute to be read is not a code 2269 * attribute. The 6 attribute header bytes, containing the type 2270 * and the length of the attribute, are not taken into account 2271 * here. 2272 * @param labels 2273 * the labels of the method's code, or <tt>null</tt> if the 2274 * attribute to be read is not a code attribute. 2275 * @return the attribute that has been read, or <tt>null</tt> to skip this 2276 * attribute. 2277 */ 2278 private Attribute readAttribute(final Attribute[] attrs, final String type, 2279 final int off, final int len, final char[] buf, final int codeOff, 2280 final Label[] labels) { 2281 for (int i = 0; i < attrs.length; ++i) { 2282 if (attrs[i].type.equals(type)) { 2283 return attrs[i].read(this, off, len, buf, codeOff, labels); 2284 } 2285 } 2286 return new Attribute(type).read(this, off, len, null, -1, null); 2287 } 2288 2289 // ------------------------------------------------------------------------ 2290 // Utility methods: low level parsing 2291 // ------------------------------------------------------------------------ 2292 2293 /** 2294 * Returns the number of constant pool items in {@link #b b}. 2295 * 2296 * @return the number of constant pool items in {@link #b b}. 2297 */ 2298 public int getItemCount() { 2299 return items.length; 2300 } 2301 2302 /** 2303 * Returns the start index of the constant pool item in {@link #b b}, plus 2304 * one. <i>This method is intended for {@link Attribute} sub classes, and is 2305 * normally not needed by class generators or adapters.</i> 2306 * 2307 * @param item 2308 * the index a constant pool item. 2309 * @return the start index of the constant pool item in {@link #b b}, plus 2310 * one. 2311 */ 2312 public int getItem(final int item) { 2313 return items[item]; 2314 } 2315 2316 /** 2317 * Returns the maximum length of the strings contained in the constant pool 2318 * of the class. 2319 * 2320 * @return the maximum length of the strings contained in the constant pool 2321 * of the class. 2322 */ 2323 public int getMaxStringLength() { 2324 return maxStringLength; 2325 } 2326 2327 /** 2328 * Reads a byte value in {@link #b b}. <i>This method is intended for 2329 * {@link Attribute} sub classes, and is normally not needed by class 2330 * generators or adapters.</i> 2331 * 2332 * @param index 2333 * the start index of the value to be read in {@link #b b}. 2334 * @return the read value. 2335 */ 2336 public int readByte(final int index) { 2337 return b[index] & 0xFF; 2338 } 2339 2340 /** 2341 * Reads an unsigned short value in {@link #b b}. <i>This method is intended 2342 * for {@link Attribute} sub classes, and is normally not needed by class 2343 * generators or adapters.</i> 2344 * 2345 * @param index 2346 * the start index of the value to be read in {@link #b b}. 2347 * @return the read value. 2348 */ 2349 public int readUnsignedShort(final int index) { 2350 byte[] b = this.b; 2351 return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF); 2352 } 2353 2354 /** 2355 * Reads a signed short value in {@link #b b}. <i>This method is intended 2356 * for {@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 */ 2363 public short readShort(final int index) { 2364 byte[] b = this.b; 2365 return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF)); 2366 } 2367 2368 /** 2369 * Reads a signed int value in {@link #b b}. <i>This method is intended for 2370 * {@link Attribute} sub classes, and is normally not needed by class 2371 * generators or adapters.</i> 2372 * 2373 * @param index 2374 * the start index of the value to be read in {@link #b b}. 2375 * @return the read value. 2376 */ 2377 public int readInt(final int index) { 2378 byte[] b = this.b; 2379 return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16) 2380 | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF); 2381 } 2382 2383 /** 2384 * Reads a signed long value in {@link #b b}. <i>This method is intended for 2385 * {@link Attribute} sub classes, and is normally not needed by class 2386 * generators or adapters.</i> 2387 * 2388 * @param index 2389 * the start index of the value to be read in {@link #b b}. 2390 * @return the read value. 2391 */ 2392 public long readLong(final int index) { 2393 long l1 = readInt(index); 2394 long l0 = readInt(index + 4) & 0xFFFFFFFFL; 2395 return (l1 << 32) | l0; 2396 } 2397 2398 /** 2399 * Reads an UTF8 string constant pool item in {@link #b b}. <i>This method 2400 * is intended for {@link Attribute} sub classes, and is normally not needed 2401 * by class generators or adapters.</i> 2402 * 2403 * @param index 2404 * the start index of an unsigned short value in {@link #b b}, 2405 * whose value is the index of an UTF8 constant pool item. 2406 * @param buf 2407 * buffer to be used to read the item. This buffer must be 2408 * sufficiently large. It is not automatically resized. 2409 * @return the String corresponding to the specified UTF8 item. 2410 */ 2411 public String readUTF8(int index, final char[] buf) { 2412 int item = readUnsignedShort(index); 2413 if (index == 0 || item == 0) { 2414 return null; 2415 } 2416 String s = strings[item]; 2417 if (s != null) { 2418 return s; 2419 } 2420 index = items[item]; 2421 return strings[item] = readUTF(index + 2, readUnsignedShort(index), buf); 2422 } 2423 2424 /** 2425 * Reads UTF8 string in {@link #b b}. 2426 * 2427 * @param index 2428 * start offset of the UTF8 string to be read. 2429 * @param utfLen 2430 * length of the UTF8 string to be read. 2431 * @param buf 2432 * buffer to be used to read the string. This buffer must be 2433 * sufficiently large. It is not automatically resized. 2434 * @return the String corresponding to the specified UTF8 string. 2435 */ 2436 private String readUTF(int index, final int utfLen, final char[] buf) { 2437 int endIndex = index + utfLen; 2438 byte[] b = this.b; 2439 int strLen = 0; 2440 int c; 2441 int st = 0; 2442 char cc = 0; 2443 while (index < endIndex) { 2444 c = b[index++]; 2445 switch (st) { 2446 case 0: 2447 c = c & 0xFF; 2448 if (c < 0x80) { // 0xxxxxxx 2449 buf[strLen++] = (char) c; 2450 } else if (c < 0xE0 && c > 0xBF) { // 110x xxxx 10xx xxxx 2451 cc = (char) (c & 0x1F); 2452 st = 1; 2453 } else { // 1110 xxxx 10xx xxxx 10xx xxxx 2454 cc = (char) (c & 0x0F); 2455 st = 2; 2456 } 2457 break; 2458 2459 case 1: // byte 2 of 2-byte char or byte 3 of 3-byte char 2460 buf[strLen++] = (char) ((cc << 6) | (c & 0x3F)); 2461 st = 0; 2462 break; 2463 2464 case 2: // byte 2 of 3-byte char 2465 cc = (char) ((cc << 6) | (c & 0x3F)); 2466 st = 1; 2467 break; 2468 } 2469 } 2470 return new String(buf, 0, strLen); 2471 } 2472 2473 /** 2474 * Reads a class constant pool item in {@link #b b}. <i>This method is 2475 * intended for {@link Attribute} sub classes, and is normally not needed by 2476 * class generators or adapters.</i> 2477 * 2478 * @param index 2479 * the start index of an unsigned short value in {@link #b b}, 2480 * whose value is the index of a class constant pool item. 2481 * @param buf 2482 * buffer to be used to read the item. This buffer must be 2483 * sufficiently large. It is not automatically resized. 2484 * @return the String corresponding to the specified class item. 2485 */ 2486 public String readClass(final int index, final char[] buf) { 2487 // computes the start index of the CONSTANT_Class item in b 2488 // and reads the CONSTANT_Utf8 item designated by 2489 // the first two bytes of this CONSTANT_Class item 2490 return readUTF8(items[readUnsignedShort(index)], buf); 2491 } 2492 2493 /** 2494 * Reads a numeric or string constant pool item in {@link #b b}. <i>This 2495 * method is intended for {@link Attribute} sub classes, and is normally not 2496 * needed by class generators or adapters.</i> 2497 * 2498 * @param item 2499 * the index of a constant pool item. 2500 * @param buf 2501 * buffer to be used to read the item. This buffer must be 2502 * sufficiently large. It is not automatically resized. 2503 * @return the {@link Integer}, {@link Float}, {@link Long}, {@link Double}, 2504 * {@link String}, {@link Type} or {@link Handle} corresponding to 2505 * the given constant pool item. 2506 */ 2507 public Object readConst(final int item, final char[] buf) { 2508 int index = items[item]; 2509 switch (b[index - 1]) { 2510 case ClassWriter.INT: 2511 return readInt(index); 2512 case ClassWriter.FLOAT: 2513 return Float.intBitsToFloat(readInt(index)); 2514 case ClassWriter.LONG: 2515 return readLong(index); 2516 case ClassWriter.DOUBLE: 2517 return Double.longBitsToDouble(readLong(index)); 2518 case ClassWriter.CLASS: 2519 return Type.getObjectType(readUTF8(index, buf)); 2520 case ClassWriter.STR: 2521 return readUTF8(index, buf); 2522 case ClassWriter.MTYPE: 2523 return Type.getMethodType(readUTF8(index, buf)); 2524 default: // case ClassWriter.HANDLE_BASE + [1..9]: 2525 int tag = readByte(index); 2526 int[] items = this.items; 2527 int cpIndex = items[readUnsignedShort(index + 1)]; 2528 boolean itf = b[cpIndex - 1] == ClassWriter.IMETH; 2529 String owner = readClass(cpIndex, buf); 2530 cpIndex = items[readUnsignedShort(cpIndex + 2)]; 2531 String name = readUTF8(cpIndex, buf); 2532 String desc = readUTF8(cpIndex + 2, buf); 2533 return new Handle(tag, owner, name, desc, itf); 2534 } 2535 } 2536 }