1 /*** 2 * ASM: a very small and fast Java bytecode manipulation framework 3 * Copyright (c) 2000-2007 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.mockito.asm; 31 32 /** 33 * A {@link ClassVisitor} that generates classes in bytecode form. More 34 * precisely this visitor generates a byte array conforming to the Java class 35 * file format. It can be used alone, to generate a Java class "from scratch", 36 * or with one or more {@link ClassReader ClassReader} and adapter class visitor 37 * to generate a modified class from one or more existing Java classes. 38 * 39 * @author Eric Bruneton 40 */ 41 public class ClassWriter implements ClassVisitor { 42 43 /** 44 * Flag to automatically compute the maximum stack size and the maximum 45 * number of local variables of methods. If this flag is set, then the 46 * arguments of the {@link MethodVisitor#visitMaxs visitMaxs} method of the 47 * {@link MethodVisitor} returned by the {@link #visitMethod visitMethod} 48 * method will be ignored, and computed automatically from the signature and 49 * the bytecode of each method. 50 * 51 * @see #ClassWriter(int) 52 */ 53 public static final int COMPUTE_MAXS = 1; 54 55 /** 56 * Flag to automatically compute the stack map frames of methods from 57 * scratch. If this flag is set, then the calls to the 58 * {@link MethodVisitor#visitFrame} method are ignored, and the stack map 59 * frames are recomputed from the methods bytecode. The arguments of the 60 * {@link MethodVisitor#visitMaxs visitMaxs} method are also ignored and 61 * recomputed from the bytecode. In other words, computeFrames implies 62 * computeMaxs. 63 * 64 * @see #ClassWriter(int) 65 */ 66 public static final int COMPUTE_FRAMES = 2; 67 68 /** 69 * The type of instructions without any argument. 70 */ 71 static final int NOARG_INSN = 0; 72 73 /** 74 * The type of instructions with an signed byte argument. 75 */ 76 static final int SBYTE_INSN = 1; 77 78 /** 79 * The type of instructions with an signed short argument. 80 */ 81 static final int SHORT_INSN = 2; 82 83 /** 84 * The type of instructions with a local variable index argument. 85 */ 86 static final int VAR_INSN = 3; 87 88 /** 89 * The type of instructions with an implicit local variable index argument. 90 */ 91 static final int IMPLVAR_INSN = 4; 92 93 /** 94 * The type of instructions with a type descriptor argument. 95 */ 96 static final int TYPE_INSN = 5; 97 98 /** 99 * The type of field and method invocations instructions. 100 */ 101 static final int FIELDORMETH_INSN = 6; 102 103 /** 104 * The type of the INVOKEINTERFACE instruction. 105 */ 106 static final int ITFMETH_INSN = 7; 107 108 /** 109 * The type of instructions with a 2 bytes bytecode offset label. 110 */ 111 static final int LABEL_INSN = 8; 112 113 /** 114 * The type of instructions with a 4 bytes bytecode offset label. 115 */ 116 static final int LABELW_INSN = 9; 117 118 /** 119 * The type of the LDC instruction. 120 */ 121 static final int LDC_INSN = 10; 122 123 /** 124 * The type of the LDC_W and LDC2_W instructions. 125 */ 126 static final int LDCW_INSN = 11; 127 128 /** 129 * The type of the IINC instruction. 130 */ 131 static final int IINC_INSN = 12; 132 133 /** 134 * The type of the TABLESWITCH instruction. 135 */ 136 static final int TABL_INSN = 13; 137 138 /** 139 * The type of the LOOKUPSWITCH instruction. 140 */ 141 static final int LOOK_INSN = 14; 142 143 /** 144 * The type of the MULTIANEWARRAY instruction. 145 */ 146 static final int MANA_INSN = 15; 147 148 /** 149 * The type of the WIDE instruction. 150 */ 151 static final int WIDE_INSN = 16; 152 153 /** 154 * The instruction types of all JVM opcodes. 155 */ 156 static final byte[] TYPE; 157 158 /** 159 * The type of CONSTANT_Class constant pool items. 160 */ 161 static final int CLASS = 7; 162 163 /** 164 * The type of CONSTANT_Fieldref constant pool items. 165 */ 166 static final int FIELD = 9; 167 168 /** 169 * The type of CONSTANT_Methodref constant pool items. 170 */ 171 static final int METH = 10; 172 173 /** 174 * The type of CONSTANT_InterfaceMethodref constant pool items. 175 */ 176 static final int IMETH = 11; 177 178 /** 179 * The type of CONSTANT_String constant pool items. 180 */ 181 static final int STR = 8; 182 183 /** 184 * The type of CONSTANT_Integer constant pool items. 185 */ 186 static final int INT = 3; 187 188 /** 189 * The type of CONSTANT_Float constant pool items. 190 */ 191 static final int FLOAT = 4; 192 193 /** 194 * The type of CONSTANT_Long constant pool items. 195 */ 196 static final int LONG = 5; 197 198 /** 199 * The type of CONSTANT_Double constant pool items. 200 */ 201 static final int DOUBLE = 6; 202 203 /** 204 * The type of CONSTANT_NameAndType constant pool items. 205 */ 206 static final int NAME_TYPE = 12; 207 208 /** 209 * The type of CONSTANT_Utf8 constant pool items. 210 */ 211 static final int UTF8 = 1; 212 213 /** 214 * Normal type Item stored in the ClassWriter {@link ClassWriter#typeTable}, 215 * instead of the constant pool, in order to avoid clashes with normal 216 * constant pool items in the ClassWriter constant pool's hash table. 217 */ 218 static final int TYPE_NORMAL = 13; 219 220 /** 221 * Uninitialized type Item stored in the ClassWriter 222 * {@link ClassWriter#typeTable}, instead of the constant pool, in order to 223 * avoid clashes with normal constant pool items in the ClassWriter constant 224 * pool's hash table. 225 */ 226 static final int TYPE_UNINIT = 14; 227 228 /** 229 * Merged type Item stored in the ClassWriter {@link ClassWriter#typeTable}, 230 * instead of the constant pool, in order to avoid clashes with normal 231 * constant pool items in the ClassWriter constant pool's hash table. 232 */ 233 static final int TYPE_MERGED = 15; 234 235 /** 236 * The class reader from which this class writer was constructed, if any. 237 */ 238 ClassReader cr; 239 240 /** 241 * Minor and major version numbers of the class to be generated. 242 */ 243 int version; 244 245 /** 246 * Index of the next item to be added in the constant pool. 247 */ 248 int index; 249 250 /** 251 * The constant pool of this class. 252 */ 253 final ByteVector pool; 254 255 /** 256 * The constant pool's hash table data. 257 */ 258 Item[] items; 259 260 /** 261 * The threshold of the constant pool's hash table. 262 */ 263 int threshold; 264 265 /** 266 * A reusable key used to look for items in the {@link #items} hash table. 267 */ 268 final Item key; 269 270 /** 271 * A reusable key used to look for items in the {@link #items} hash table. 272 */ 273 final Item key2; 274 275 /** 276 * A reusable key used to look for items in the {@link #items} hash table. 277 */ 278 final Item key3; 279 280 /** 281 * A type table used to temporarily store internal names that will not 282 * necessarily be stored in the constant pool. This type table is used by 283 * the control flow and data flow analysis algorithm used to compute stack 284 * map frames from scratch. This array associates to each index <tt>i</tt> 285 * the Item whose index is <tt>i</tt>. All Item objects stored in this 286 * array are also stored in the {@link #items} hash table. These two arrays 287 * allow to retrieve an Item from its index or, conversely, to get the index 288 * of an Item from its value. Each Item stores an internal name in its 289 * {@link Item#strVal1} field. 290 */ 291 Item[] typeTable; 292 293 /** 294 * Number of elements in the {@link #typeTable} array. 295 */ 296 private short typeCount; 297 298 /** 299 * The access flags of this class. 300 */ 301 private int access; 302 303 /** 304 * The constant pool item that contains the internal name of this class. 305 */ 306 private int name; 307 308 /** 309 * The internal name of this class. 310 */ 311 String thisName; 312 313 /** 314 * The constant pool item that contains the signature of this class. 315 */ 316 private int signature; 317 318 /** 319 * The constant pool item that contains the internal name of the super class 320 * of this class. 321 */ 322 private int superName; 323 324 /** 325 * Number of interfaces implemented or extended by this class or interface. 326 */ 327 private int interfaceCount; 328 329 /** 330 * The interfaces implemented or extended by this class or interface. More 331 * precisely, this array contains the indexes of the constant pool items 332 * that contain the internal names of these interfaces. 333 */ 334 private int[] interfaces; 335 336 /** 337 * The index of the constant pool item that contains the name of the source 338 * file from which this class was compiled. 339 */ 340 private int sourceFile; 341 342 /** 343 * The SourceDebug attribute of this class. 344 */ 345 private ByteVector sourceDebug; 346 347 /** 348 * The constant pool item that contains the name of the enclosing class of 349 * this class. 350 */ 351 private int enclosingMethodOwner; 352 353 /** 354 * The constant pool item that contains the name and descriptor of the 355 * enclosing method of this class. 356 */ 357 private int enclosingMethod; 358 359 /** 360 * The runtime visible annotations of this class. 361 */ 362 private AnnotationWriter anns; 363 364 /** 365 * The runtime invisible annotations of this class. 366 */ 367 private AnnotationWriter ianns; 368 369 /** 370 * The non standard attributes of this class. 371 */ 372 private Attribute attrs; 373 374 /** 375 * The number of entries in the InnerClasses attribute. 376 */ 377 private int innerClassesCount; 378 379 /** 380 * The InnerClasses attribute. 381 */ 382 private ByteVector innerClasses; 383 384 /** 385 * The fields of this class. These fields are stored in a linked list of 386 * {@link FieldWriter} objects, linked to each other by their 387 * {@link FieldWriter#next} field. This field stores the first element of 388 * this list. 389 */ 390 FieldWriter firstField; 391 392 /** 393 * The fields of this class. These fields are stored in a linked list of 394 * {@link FieldWriter} objects, linked to each other by their 395 * {@link FieldWriter#next} field. This field stores the last element of 396 * this list. 397 */ 398 FieldWriter lastField; 399 400 /** 401 * The methods of this class. These methods are stored in a linked list of 402 * {@link MethodWriter} objects, linked to each other by their 403 * {@link MethodWriter#next} field. This field stores the first element of 404 * this list. 405 */ 406 MethodWriter firstMethod; 407 408 /** 409 * The methods of this class. These methods are stored in a linked list of 410 * {@link MethodWriter} objects, linked to each other by their 411 * {@link MethodWriter#next} field. This field stores the last element of 412 * this list. 413 */ 414 MethodWriter lastMethod; 415 416 /** 417 * <tt>true</tt> if the maximum stack size and number of local variables 418 * must be automatically computed. 419 */ 420 private final boolean computeMaxs; 421 422 /** 423 * <tt>true</tt> if the stack map frames must be recomputed from scratch. 424 */ 425 private final boolean computeFrames; 426 427 /** 428 * <tt>true</tt> if the stack map tables of this class are invalid. The 429 * {@link MethodWriter#resizeInstructions} method cannot transform existing 430 * stack map tables, and so produces potentially invalid classes when it is 431 * executed. In this case the class is reread and rewritten with the 432 * {@link #COMPUTE_FRAMES} option (the resizeInstructions method can resize 433 * stack map tables when this option is used). 434 */ 435 boolean invalidFrames; 436 437 // ------------------------------------------------------------------------ 438 // Static initializer 439 // ------------------------------------------------------------------------ 440 441 /** 442 * Computes the instruction types of JVM opcodes. 443 */ 444 static { 445 int i; 446 byte[] b = new byte[220]; 447 String s = "AAAAAAAAAAAAAAAABCKLLDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD" 448 + "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 449 + "AAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAIIIIIIIIIIIIIIIIDNOAA" 450 + "AAAAGGGGGGGHAFBFAAFFAAQPIIJJIIIIIIIIIIIIIIIIII"; 451 for (i = 0; i < b.length; ++i) { 452 b[i] = (byte) (s.charAt(i) - 'A'); 453 } 454 TYPE = b; 455 456 // code to generate the above string 457 // 458 // // SBYTE_INSN instructions 459 // b[Constants.NEWARRAY] = SBYTE_INSN; 460 // b[Constants.BIPUSH] = SBYTE_INSN; 461 // 462 // // SHORT_INSN instructions 463 // b[Constants.SIPUSH] = SHORT_INSN; 464 // 465 // // (IMPL)VAR_INSN instructions 466 // b[Constants.RET] = VAR_INSN; 467 // for (i = Constants.ILOAD; i <= Constants.ALOAD; ++i) { 468 // b[i] = VAR_INSN; 469 // } 470 // for (i = Constants.ISTORE; i <= Constants.ASTORE; ++i) { 471 // b[i] = VAR_INSN; 472 // } 473 // for (i = 26; i <= 45; ++i) { // ILOAD_0 to ALOAD_3 474 // b[i] = IMPLVAR_INSN; 475 // } 476 // for (i = 59; i <= 78; ++i) { // ISTORE_0 to ASTORE_3 477 // b[i] = IMPLVAR_INSN; 478 // } 479 // 480 // // TYPE_INSN instructions 481 // b[Constants.NEW] = TYPE_INSN; 482 // b[Constants.ANEWARRAY] = TYPE_INSN; 483 // b[Constants.CHECKCAST] = TYPE_INSN; 484 // b[Constants.INSTANCEOF] = TYPE_INSN; 485 // 486 // // (Set)FIELDORMETH_INSN instructions 487 // for (i = Constants.GETSTATIC; i <= Constants.INVOKESTATIC; ++i) { 488 // b[i] = FIELDORMETH_INSN; 489 // } 490 // b[Constants.INVOKEINTERFACE] = ITFMETH_INSN; 491 // 492 // // LABEL(W)_INSN instructions 493 // for (i = Constants.IFEQ; i <= Constants.JSR; ++i) { 494 // b[i] = LABEL_INSN; 495 // } 496 // b[Constants.IFNULL] = LABEL_INSN; 497 // b[Constants.IFNONNULL] = LABEL_INSN; 498 // b[200] = LABELW_INSN; // GOTO_W 499 // b[201] = LABELW_INSN; // JSR_W 500 // // temporary opcodes used internally by ASM - see Label and 501 // MethodWriter 502 // for (i = 202; i < 220; ++i) { 503 // b[i] = LABEL_INSN; 504 // } 505 // 506 // // LDC(_W) instructions 507 // b[Constants.LDC] = LDC_INSN; 508 // b[19] = LDCW_INSN; // LDC_W 509 // b[20] = LDCW_INSN; // LDC2_W 510 // 511 // // special instructions 512 // b[Constants.IINC] = IINC_INSN; 513 // b[Constants.TABLESWITCH] = TABL_INSN; 514 // b[Constants.LOOKUPSWITCH] = LOOK_INSN; 515 // b[Constants.MULTIANEWARRAY] = MANA_INSN; 516 // b[196] = WIDE_INSN; // WIDE 517 // 518 // for (i = 0; i < b.length; ++i) { 519 // System.err.print((char)('A' + b[i])); 520 // } 521 // System.err.println(); 522 } 523 524 // ------------------------------------------------------------------------ 525 // Constructor 526 // ------------------------------------------------------------------------ 527 528 /** 529 * Constructs a new {@link ClassWriter} object. 530 * 531 * @param flags option flags that can be used to modify the default behavior 532 * of this class. See {@link #COMPUTE_MAXS}, {@link #COMPUTE_FRAMES}. 533 */ ClassWriter(final int flags)534 public ClassWriter(final int flags) { 535 index = 1; 536 pool = new ByteVector(); 537 items = new Item[256]; 538 threshold = (int) (0.75d * items.length); 539 key = new Item(); 540 key2 = new Item(); 541 key3 = new Item(); 542 this.computeMaxs = (flags & COMPUTE_MAXS) != 0; 543 this.computeFrames = (flags & COMPUTE_FRAMES) != 0; 544 } 545 546 /** 547 * Constructs a new {@link ClassWriter} object and enables optimizations for 548 * "mostly add" bytecode transformations. These optimizations are the 549 * following: 550 * 551 * <ul> <li>The constant pool from the original class is copied as is in 552 * the new class, which saves time. New constant pool entries will be added 553 * at the end if necessary, but unused constant pool entries <i>won't be 554 * removed</i>.</li> <li>Methods that are not transformed are copied as 555 * is in the new class, directly from the original class bytecode (i.e. 556 * without emitting visit events for all the method instructions), which 557 * saves a <i>lot</i> of time. Untransformed methods are detected by the 558 * fact that the {@link ClassReader} receives {@link MethodVisitor} objects 559 * that come from a {@link ClassWriter} (and not from a custom 560 * {@link ClassAdapter} or any other {@link ClassVisitor} instance).</li> 561 * </ul> 562 * 563 * @param classReader the {@link ClassReader} used to read the original 564 * class. It will be used to copy the entire constant pool from the 565 * original class and also to copy other fragments of original 566 * bytecode where applicable. 567 * @param flags option flags that can be used to modify the default behavior 568 * of this class. See {@link #COMPUTE_MAXS}, {@link #COMPUTE_FRAMES}. 569 */ ClassWriter(final ClassReader classReader, final int flags)570 public ClassWriter(final ClassReader classReader, final int flags) { 571 this(flags); 572 classReader.copyPool(this); 573 this.cr = classReader; 574 } 575 576 // ------------------------------------------------------------------------ 577 // Implementation of the ClassVisitor interface 578 // ------------------------------------------------------------------------ 579 visit( final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces)580 public void visit( 581 final int version, 582 final int access, 583 final String name, 584 final String signature, 585 final String superName, 586 final String[] interfaces) 587 { 588 this.version = version; 589 this.access = access; 590 this.name = newClass(name); 591 thisName = name; 592 if (ClassReader.SIGNATURES && signature != null) { 593 this.signature = newUTF8(signature); 594 } 595 this.superName = superName == null ? 0 : newClass(superName); 596 if (interfaces != null && interfaces.length > 0) { 597 interfaceCount = interfaces.length; 598 this.interfaces = new int[interfaceCount]; 599 for (int i = 0; i < interfaceCount; ++i) { 600 this.interfaces[i] = newClass(interfaces[i]); 601 } 602 } 603 } 604 visitSource(final String file, final String debug)605 public void visitSource(final String file, final String debug) { 606 if (file != null) { 607 sourceFile = newUTF8(file); 608 } 609 if (debug != null) { 610 sourceDebug = new ByteVector().putUTF8(debug); 611 } 612 } 613 visitOuterClass( final String owner, final String name, final String desc)614 public void visitOuterClass( 615 final String owner, 616 final String name, 617 final String desc) 618 { 619 enclosingMethodOwner = newClass(owner); 620 if (name != null && desc != null) { 621 enclosingMethod = newNameType(name, desc); 622 } 623 } 624 visitAnnotation( final String desc, final boolean visible)625 public AnnotationVisitor visitAnnotation( 626 final String desc, 627 final boolean visible) 628 { 629 if (!ClassReader.ANNOTATIONS) { 630 return null; 631 } 632 ByteVector bv = new ByteVector(); 633 // write type, and reserve space for values count 634 bv.putShort(newUTF8(desc)).putShort(0); 635 AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv, 2); 636 if (visible) { 637 aw.next = anns; 638 anns = aw; 639 } else { 640 aw.next = ianns; 641 ianns = aw; 642 } 643 return aw; 644 } 645 visitAttribute(final Attribute attr)646 public void visitAttribute(final Attribute attr) { 647 attr.next = attrs; 648 attrs = attr; 649 } 650 visitInnerClass( final String name, final String outerName, final String innerName, final int access)651 public void visitInnerClass( 652 final String name, 653 final String outerName, 654 final String innerName, 655 final int access) 656 { 657 if (innerClasses == null) { 658 innerClasses = new ByteVector(); 659 } 660 ++innerClassesCount; 661 innerClasses.putShort(name == null ? 0 : newClass(name)); 662 innerClasses.putShort(outerName == null ? 0 : newClass(outerName)); 663 innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName)); 664 innerClasses.putShort(access); 665 } 666 visitField( final int access, final String name, final String desc, final String signature, final Object value)667 public FieldVisitor visitField( 668 final int access, 669 final String name, 670 final String desc, 671 final String signature, 672 final Object value) 673 { 674 return new FieldWriter(this, access, name, desc, signature, value); 675 } 676 visitMethod( final int access, final String name, final String desc, final String signature, final String[] exceptions)677 public MethodVisitor visitMethod( 678 final int access, 679 final String name, 680 final String desc, 681 final String signature, 682 final String[] exceptions) 683 { 684 return new MethodWriter(this, 685 access, 686 name, 687 desc, 688 signature, 689 exceptions, 690 computeMaxs, 691 computeFrames); 692 } 693 visitEnd()694 public void visitEnd() { 695 } 696 697 // ------------------------------------------------------------------------ 698 // Other public methods 699 // ------------------------------------------------------------------------ 700 701 /** 702 * Returns the bytecode of the class that was build with this class writer. 703 * 704 * @return the bytecode of the class that was build with this class writer. 705 */ toByteArray()706 public byte[] toByteArray() { 707 // computes the real size of the bytecode of this class 708 int size = 24 + 2 * interfaceCount; 709 int nbFields = 0; 710 FieldWriter fb = firstField; 711 while (fb != null) { 712 ++nbFields; 713 size += fb.getSize(); 714 fb = fb.next; 715 } 716 int nbMethods = 0; 717 MethodWriter mb = firstMethod; 718 while (mb != null) { 719 ++nbMethods; 720 size += mb.getSize(); 721 mb = mb.next; 722 } 723 int attributeCount = 0; 724 if (ClassReader.SIGNATURES && signature != 0) { 725 ++attributeCount; 726 size += 8; 727 newUTF8("Signature"); 728 } 729 if (sourceFile != 0) { 730 ++attributeCount; 731 size += 8; 732 newUTF8("SourceFile"); 733 } 734 if (sourceDebug != null) { 735 ++attributeCount; 736 size += sourceDebug.length + 4; 737 newUTF8("SourceDebugExtension"); 738 } 739 if (enclosingMethodOwner != 0) { 740 ++attributeCount; 741 size += 10; 742 newUTF8("EnclosingMethod"); 743 } 744 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 745 ++attributeCount; 746 size += 6; 747 newUTF8("Deprecated"); 748 } 749 if ((access & Opcodes.ACC_SYNTHETIC) != 0 750 && (version & 0xffff) < Opcodes.V1_5) 751 { 752 ++attributeCount; 753 size += 6; 754 newUTF8("Synthetic"); 755 } 756 if (innerClasses != null) { 757 ++attributeCount; 758 size += 8 + innerClasses.length; 759 newUTF8("InnerClasses"); 760 } 761 if (ClassReader.ANNOTATIONS && anns != null) { 762 ++attributeCount; 763 size += 8 + anns.getSize(); 764 newUTF8("RuntimeVisibleAnnotations"); 765 } 766 if (ClassReader.ANNOTATIONS && ianns != null) { 767 ++attributeCount; 768 size += 8 + ianns.getSize(); 769 newUTF8("RuntimeInvisibleAnnotations"); 770 } 771 if (attrs != null) { 772 attributeCount += attrs.getCount(); 773 size += attrs.getSize(this, null, 0, -1, -1); 774 } 775 size += pool.length; 776 // allocates a byte vector of this size, in order to avoid unnecessary 777 // arraycopy operations in the ByteVector.enlarge() method 778 ByteVector out = new ByteVector(size); 779 out.putInt(0xCAFEBABE).putInt(version); 780 out.putShort(index).putByteArray(pool.data, 0, pool.length); 781 out.putShort(access).putShort(name).putShort(superName); 782 out.putShort(interfaceCount); 783 for (int i = 0; i < interfaceCount; ++i) { 784 out.putShort(interfaces[i]); 785 } 786 out.putShort(nbFields); 787 fb = firstField; 788 while (fb != null) { 789 fb.put(out); 790 fb = fb.next; 791 } 792 out.putShort(nbMethods); 793 mb = firstMethod; 794 while (mb != null) { 795 mb.put(out); 796 mb = mb.next; 797 } 798 out.putShort(attributeCount); 799 if (ClassReader.SIGNATURES && signature != 0) { 800 out.putShort(newUTF8("Signature")).putInt(2).putShort(signature); 801 } 802 if (sourceFile != 0) { 803 out.putShort(newUTF8("SourceFile")).putInt(2).putShort(sourceFile); 804 } 805 if (sourceDebug != null) { 806 int len = sourceDebug.length - 2; 807 out.putShort(newUTF8("SourceDebugExtension")).putInt(len); 808 out.putByteArray(sourceDebug.data, 2, len); 809 } 810 if (enclosingMethodOwner != 0) { 811 out.putShort(newUTF8("EnclosingMethod")).putInt(4); 812 out.putShort(enclosingMethodOwner).putShort(enclosingMethod); 813 } 814 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 815 out.putShort(newUTF8("Deprecated")).putInt(0); 816 } 817 if ((access & Opcodes.ACC_SYNTHETIC) != 0 818 && (version & 0xffff) < Opcodes.V1_5) 819 { 820 out.putShort(newUTF8("Synthetic")).putInt(0); 821 } 822 if (innerClasses != null) { 823 out.putShort(newUTF8("InnerClasses")); 824 out.putInt(innerClasses.length + 2).putShort(innerClassesCount); 825 out.putByteArray(innerClasses.data, 0, innerClasses.length); 826 } 827 if (ClassReader.ANNOTATIONS && anns != null) { 828 out.putShort(newUTF8("RuntimeVisibleAnnotations")); 829 anns.put(out); 830 } 831 if (ClassReader.ANNOTATIONS && ianns != null) { 832 out.putShort(newUTF8("RuntimeInvisibleAnnotations")); 833 ianns.put(out); 834 } 835 if (attrs != null) { 836 attrs.put(this, null, 0, -1, -1, out); 837 } 838 if (invalidFrames) { 839 ClassWriter cw = new ClassWriter(COMPUTE_FRAMES); 840 new ClassReader(out.data).accept(cw, ClassReader.SKIP_FRAMES); 841 return cw.toByteArray(); 842 } 843 return out.data; 844 } 845 846 // ------------------------------------------------------------------------ 847 // Utility methods: constant pool management 848 // ------------------------------------------------------------------------ 849 850 /** 851 * Adds a number or string constant to the constant pool of the class being 852 * build. Does nothing if the constant pool already contains a similar item. 853 * 854 * @param cst the value of the constant to be added to the constant pool. 855 * This parameter must be an {@link Integer}, a {@link Float}, a 856 * {@link Long}, a {@link Double}, a {@link String} or a 857 * {@link Type}. 858 * @return a new or already existing constant item with the given value. 859 */ newConstItem(final Object cst)860 Item newConstItem(final Object cst) { 861 if (cst instanceof Integer) { 862 int val = ((Integer) cst).intValue(); 863 return newInteger(val); 864 } else if (cst instanceof Byte) { 865 int val = ((Byte) cst).intValue(); 866 return newInteger(val); 867 } else if (cst instanceof Character) { 868 int val = ((Character) cst).charValue(); 869 return newInteger(val); 870 } else if (cst instanceof Short) { 871 int val = ((Short) cst).intValue(); 872 return newInteger(val); 873 } else if (cst instanceof Boolean) { 874 int val = ((Boolean) cst).booleanValue() ? 1 : 0; 875 return newInteger(val); 876 } else if (cst instanceof Float) { 877 float val = ((Float) cst).floatValue(); 878 return newFloat(val); 879 } else if (cst instanceof Long) { 880 long val = ((Long) cst).longValue(); 881 return newLong(val); 882 } else if (cst instanceof Double) { 883 double val = ((Double) cst).doubleValue(); 884 return newDouble(val); 885 } else if (cst instanceof String) { 886 return newString((String) cst); 887 } else if (cst instanceof Type) { 888 Type t = (Type) cst; 889 return newClassItem(t.getSort() == Type.OBJECT 890 ? t.getInternalName() 891 : t.getDescriptor()); 892 } else { 893 throw new IllegalArgumentException("value " + cst); 894 } 895 } 896 897 /** 898 * Adds a number or string constant to the constant pool of the class being 899 * build. Does nothing if the constant pool already contains a similar item. 900 * <i>This method is intended for {@link Attribute} sub classes, and is 901 * normally not needed by class generators or adapters.</i> 902 * 903 * @param cst the value of the constant to be added to the constant pool. 904 * This parameter must be an {@link Integer}, a {@link Float}, a 905 * {@link Long}, a {@link Double} or a {@link String}. 906 * @return the index of a new or already existing constant item with the 907 * given value. 908 */ newConst(final Object cst)909 public int newConst(final Object cst) { 910 return newConstItem(cst).index; 911 } 912 913 /** 914 * Adds an UTF8 string to the constant pool of the class being build. Does 915 * nothing if the constant pool already contains a similar item. <i>This 916 * method is intended for {@link Attribute} sub classes, and is normally not 917 * needed by class generators or adapters.</i> 918 * 919 * @param value the String value. 920 * @return the index of a new or already existing UTF8 item. 921 */ newUTF8(final String value)922 public int newUTF8(final String value) { 923 key.set(UTF8, value, null, null); 924 Item result = get(key); 925 if (result == null) { 926 pool.putByte(UTF8).putUTF8(value); 927 result = new Item(index++, key); 928 put(result); 929 } 930 return result.index; 931 } 932 933 /** 934 * Adds a class reference to the constant pool of the class being build. 935 * Does nothing if the constant pool already contains a similar item. 936 * <i>This method is intended for {@link Attribute} sub classes, and is 937 * normally not needed by class generators or adapters.</i> 938 * 939 * @param value the internal name of the class. 940 * @return a new or already existing class reference item. 941 */ newClassItem(final String value)942 Item newClassItem(final String value) { 943 key2.set(CLASS, value, null, null); 944 Item result = get(key2); 945 if (result == null) { 946 pool.put12(CLASS, newUTF8(value)); 947 result = new Item(index++, key2); 948 put(result); 949 } 950 return result; 951 } 952 953 /** 954 * Adds a class reference to the constant pool of the class being build. 955 * Does nothing if the constant pool already contains a similar item. 956 * <i>This method is intended for {@link Attribute} sub classes, and is 957 * normally not needed by class generators or adapters.</i> 958 * 959 * @param value the internal name of the class. 960 * @return the index of a new or already existing class reference item. 961 */ newClass(final String value)962 public int newClass(final String value) { 963 return newClassItem(value).index; 964 } 965 966 /** 967 * Adds a field reference to the constant pool of the class being build. 968 * Does nothing if the constant pool already contains a similar item. 969 * 970 * @param owner the internal name of the field's owner class. 971 * @param name the field's name. 972 * @param desc the field's descriptor. 973 * @return a new or already existing field reference item. 974 */ newFieldItem(final String owner, final String name, final String desc)975 Item newFieldItem(final String owner, final String name, final String desc) 976 { 977 key3.set(FIELD, owner, name, desc); 978 Item result = get(key3); 979 if (result == null) { 980 put122(FIELD, newClass(owner), newNameType(name, desc)); 981 result = new Item(index++, key3); 982 put(result); 983 } 984 return result; 985 } 986 987 /** 988 * Adds a field reference to the constant pool of the class being build. 989 * Does nothing if the constant pool already contains a similar item. 990 * <i>This method is intended for {@link Attribute} sub classes, and is 991 * normally not needed by class generators or adapters.</i> 992 * 993 * @param owner the internal name of the field's owner class. 994 * @param name the field's name. 995 * @param desc the field's descriptor. 996 * @return the index of a new or already existing field reference item. 997 */ newField(final String owner, final String name, final String desc)998 public int newField(final String owner, final String name, final String desc) 999 { 1000 return newFieldItem(owner, name, desc).index; 1001 } 1002 1003 /** 1004 * Adds a method reference to the constant pool of the class being build. 1005 * Does nothing if the constant pool already contains a similar item. 1006 * 1007 * @param owner the internal name of the method's owner class. 1008 * @param name the method's name. 1009 * @param desc the method's descriptor. 1010 * @param itf <tt>true</tt> if <tt>owner</tt> is an interface. 1011 * @return a new or already existing method reference item. 1012 */ newMethodItem( final String owner, final String name, final String desc, final boolean itf)1013 Item newMethodItem( 1014 final String owner, 1015 final String name, 1016 final String desc, 1017 final boolean itf) 1018 { 1019 int type = itf ? IMETH : METH; 1020 key3.set(type, owner, name, desc); 1021 Item result = get(key3); 1022 if (result == null) { 1023 put122(type, newClass(owner), newNameType(name, desc)); 1024 result = new Item(index++, key3); 1025 put(result); 1026 } 1027 return result; 1028 } 1029 1030 /** 1031 * Adds a method reference to the constant pool of the class being build. 1032 * Does nothing if the constant pool already contains a similar item. 1033 * <i>This method is intended for {@link Attribute} sub classes, and is 1034 * normally not needed by class generators or adapters.</i> 1035 * 1036 * @param owner the internal name of the method's owner class. 1037 * @param name the method's name. 1038 * @param desc the method's descriptor. 1039 * @param itf <tt>true</tt> if <tt>owner</tt> is an interface. 1040 * @return the index of a new or already existing method reference item. 1041 */ newMethod( final String owner, final String name, final String desc, final boolean itf)1042 public int newMethod( 1043 final String owner, 1044 final String name, 1045 final String desc, 1046 final boolean itf) 1047 { 1048 return newMethodItem(owner, name, desc, itf).index; 1049 } 1050 1051 /** 1052 * Adds an integer to the constant pool of the class being build. Does 1053 * nothing if the constant pool already contains a similar item. 1054 * 1055 * @param value the int value. 1056 * @return a new or already existing int item. 1057 */ newInteger(final int value)1058 Item newInteger(final int value) { 1059 key.set(value); 1060 Item result = get(key); 1061 if (result == null) { 1062 pool.putByte(INT).putInt(value); 1063 result = new Item(index++, key); 1064 put(result); 1065 } 1066 return result; 1067 } 1068 1069 /** 1070 * Adds a float to the constant pool of the class being build. Does nothing 1071 * if the constant pool already contains a similar item. 1072 * 1073 * @param value the float value. 1074 * @return a new or already existing float item. 1075 */ newFloat(final float value)1076 Item newFloat(final float value) { 1077 key.set(value); 1078 Item result = get(key); 1079 if (result == null) { 1080 pool.putByte(FLOAT).putInt(key.intVal); 1081 result = new Item(index++, key); 1082 put(result); 1083 } 1084 return result; 1085 } 1086 1087 /** 1088 * Adds a long to the constant pool of the class being build. Does nothing 1089 * if the constant pool already contains a similar item. 1090 * 1091 * @param value the long value. 1092 * @return a new or already existing long item. 1093 */ newLong(final long value)1094 Item newLong(final long value) { 1095 key.set(value); 1096 Item result = get(key); 1097 if (result == null) { 1098 pool.putByte(LONG).putLong(value); 1099 result = new Item(index, key); 1100 put(result); 1101 index += 2; 1102 } 1103 return result; 1104 } 1105 1106 /** 1107 * Adds a double to the constant pool of the class being build. Does nothing 1108 * if the constant pool already contains a similar item. 1109 * 1110 * @param value the double value. 1111 * @return a new or already existing double item. 1112 */ newDouble(final double value)1113 Item newDouble(final double value) { 1114 key.set(value); 1115 Item result = get(key); 1116 if (result == null) { 1117 pool.putByte(DOUBLE).putLong(key.longVal); 1118 result = new Item(index, key); 1119 put(result); 1120 index += 2; 1121 } 1122 return result; 1123 } 1124 1125 /** 1126 * Adds a string to the constant pool of the class being build. Does nothing 1127 * if the constant pool already contains a similar item. 1128 * 1129 * @param value the String value. 1130 * @return a new or already existing string item. 1131 */ newString(final String value)1132 private Item newString(final String value) { 1133 key2.set(STR, value, null, null); 1134 Item result = get(key2); 1135 if (result == null) { 1136 pool.put12(STR, newUTF8(value)); 1137 result = new Item(index++, key2); 1138 put(result); 1139 } 1140 return result; 1141 } 1142 1143 /** 1144 * Adds a name and type to the constant pool of the class being build. Does 1145 * nothing if the constant pool already contains a similar item. <i>This 1146 * method is intended for {@link Attribute} sub classes, and is normally not 1147 * needed by class generators or adapters.</i> 1148 * 1149 * @param name a name. 1150 * @param desc a type descriptor. 1151 * @return the index of a new or already existing name and type item. 1152 */ newNameType(final String name, final String desc)1153 public int newNameType(final String name, final String desc) { 1154 key2.set(NAME_TYPE, name, desc, null); 1155 Item result = get(key2); 1156 if (result == null) { 1157 put122(NAME_TYPE, newUTF8(name), newUTF8(desc)); 1158 result = new Item(index++, key2); 1159 put(result); 1160 } 1161 return result.index; 1162 } 1163 1164 /** 1165 * Adds the given internal name to {@link #typeTable} and returns its index. 1166 * Does nothing if the type table already contains this internal name. 1167 * 1168 * @param type the internal name to be added to the type table. 1169 * @return the index of this internal name in the type table. 1170 */ addType(final String type)1171 int addType(final String type) { 1172 key.set(TYPE_NORMAL, type, null, null); 1173 Item result = get(key); 1174 if (result == null) { 1175 result = addType(key); 1176 } 1177 return result.index; 1178 } 1179 1180 /** 1181 * Adds the given "uninitialized" type to {@link #typeTable} and returns its 1182 * index. This method is used for UNINITIALIZED types, made of an internal 1183 * name and a bytecode offset. 1184 * 1185 * @param type the internal name to be added to the type table. 1186 * @param offset the bytecode offset of the NEW instruction that created 1187 * this UNINITIALIZED type value. 1188 * @return the index of this internal name in the type table. 1189 */ addUninitializedType(final String type, final int offset)1190 int addUninitializedType(final String type, final int offset) { 1191 key.type = TYPE_UNINIT; 1192 key.intVal = offset; 1193 key.strVal1 = type; 1194 key.hashCode = 0x7FFFFFFF & (TYPE_UNINIT + type.hashCode() + offset); 1195 Item result = get(key); 1196 if (result == null) { 1197 result = addType(key); 1198 } 1199 return result.index; 1200 } 1201 1202 /** 1203 * Adds the given Item to {@link #typeTable}. 1204 * 1205 * @param item the value to be added to the type table. 1206 * @return the added Item, which a new Item instance with the same value as 1207 * the given Item. 1208 */ addType(final Item item)1209 private Item addType(final Item item) { 1210 ++typeCount; 1211 Item result = new Item(typeCount, key); 1212 put(result); 1213 if (typeTable == null) { 1214 typeTable = new Item[16]; 1215 } 1216 if (typeCount == typeTable.length) { 1217 Item[] newTable = new Item[2 * typeTable.length]; 1218 System.arraycopy(typeTable, 0, newTable, 0, typeTable.length); 1219 typeTable = newTable; 1220 } 1221 typeTable[typeCount] = result; 1222 return result; 1223 } 1224 1225 /** 1226 * Returns the index of the common super type of the two given types. This 1227 * method calls {@link #getCommonSuperClass} and caches the result in the 1228 * {@link #items} hash table to speedup future calls with the same 1229 * parameters. 1230 * 1231 * @param type1 index of an internal name in {@link #typeTable}. 1232 * @param type2 index of an internal name in {@link #typeTable}. 1233 * @return the index of the common super type of the two given types. 1234 */ getMergedType(final int type1, final int type2)1235 int getMergedType(final int type1, final int type2) { 1236 key2.type = TYPE_MERGED; 1237 key2.longVal = type1 | (((long) type2) << 32); 1238 key2.hashCode = 0x7FFFFFFF & (TYPE_MERGED + type1 + type2); 1239 Item result = get(key2); 1240 if (result == null) { 1241 String t = typeTable[type1].strVal1; 1242 String u = typeTable[type2].strVal1; 1243 key2.intVal = addType(getCommonSuperClass(t, u)); 1244 result = new Item((short) 0, key2); 1245 put(result); 1246 } 1247 return result.intVal; 1248 } 1249 1250 /** 1251 * Returns the common super type of the two given types. The default 1252 * implementation of this method <i>loads<i> the two given classes and uses 1253 * the java.lang.Class methods to find the common super class. It can be 1254 * overridden to compute this common super type in other ways, in particular 1255 * without actually loading any class, or to take into account the class 1256 * that is currently being generated by this ClassWriter, which can of 1257 * course not be loaded since it is under construction. 1258 * 1259 * @param type1 the internal name of a class. 1260 * @param type2 the internal name of another class. 1261 * @return the internal name of the common super class of the two given 1262 * classes. 1263 */ getCommonSuperClass(final String type1, final String type2)1264 protected String getCommonSuperClass(final String type1, final String type2) 1265 { 1266 Class c, d; 1267 try { 1268 c = Class.forName(type1.replace('/', '.')); 1269 d = Class.forName(type2.replace('/', '.')); 1270 } catch (Exception e) { 1271 throw new RuntimeException(e.toString()); 1272 } 1273 if (c.isAssignableFrom(d)) { 1274 return type1; 1275 } 1276 if (d.isAssignableFrom(c)) { 1277 return type2; 1278 } 1279 if (c.isInterface() || d.isInterface()) { 1280 return "java/lang/Object"; 1281 } else { 1282 do { 1283 c = c.getSuperclass(); 1284 } while (!c.isAssignableFrom(d)); 1285 return c.getName().replace('.', '/'); 1286 } 1287 } 1288 1289 /** 1290 * Returns the constant pool's hash table item which is equal to the given 1291 * item. 1292 * 1293 * @param key a constant pool item. 1294 * @return the constant pool's hash table item which is equal to the given 1295 * item, or <tt>null</tt> if there is no such item. 1296 */ get(final Item key)1297 private Item get(final Item key) { 1298 Item i = items[key.hashCode % items.length]; 1299 while (i != null && !key.isEqualTo(i)) { 1300 i = i.next; 1301 } 1302 return i; 1303 } 1304 1305 /** 1306 * Puts the given item in the constant pool's hash table. The hash table 1307 * <i>must</i> not already contains this item. 1308 * 1309 * @param i the item to be added to the constant pool's hash table. 1310 */ put(final Item i)1311 private void put(final Item i) { 1312 if (index > threshold) { 1313 int ll = items.length; 1314 int nl = ll * 2 + 1; 1315 Item[] newItems = new Item[nl]; 1316 for (int l = ll - 1; l >= 0; --l) { 1317 Item j = items[l]; 1318 while (j != null) { 1319 int index = j.hashCode % newItems.length; 1320 Item k = j.next; 1321 j.next = newItems[index]; 1322 newItems[index] = j; 1323 j = k; 1324 } 1325 } 1326 items = newItems; 1327 threshold = (int) (nl * 0.75); 1328 } 1329 int index = i.hashCode % items.length; 1330 i.next = items[index]; 1331 items[index] = i; 1332 } 1333 1334 /** 1335 * Puts one byte and two shorts into the constant pool. 1336 * 1337 * @param b a byte. 1338 * @param s1 a short. 1339 * @param s2 another short. 1340 */ put122(final int b, final int s1, final int s2)1341 private void put122(final int b, final int s1, final int s2) { 1342 pool.put12(b, s1).putShort(s2); 1343 } 1344 } 1345