1 /*** 2 * ASM: a very small and fast Java bytecode manipulation framework 3 * Copyright (c) 2000-2011 INRIA, France Telecom 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of the copyright holders nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 package com.sleepycat.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 extends 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 * Pseudo access flag to distinguish between the synthetic attribute and 70 * the synthetic access flag. 71 */ 72 static final int ACC_SYNTHETIC_ATTRIBUTE = 0x40000; 73 74 /** 75 * The type of instructions without any argument. 76 */ 77 static final int NOARG_INSN = 0; 78 79 /** 80 * The type of instructions with an signed byte argument. 81 */ 82 static final int SBYTE_INSN = 1; 83 84 /** 85 * The type of instructions with an signed short argument. 86 */ 87 static final int SHORT_INSN = 2; 88 89 /** 90 * The type of instructions with a local variable index argument. 91 */ 92 static final int VAR_INSN = 3; 93 94 /** 95 * The type of instructions with an implicit local variable index argument. 96 */ 97 static final int IMPLVAR_INSN = 4; 98 99 /** 100 * The type of instructions with a type descriptor argument. 101 */ 102 static final int TYPE_INSN = 5; 103 104 /** 105 * The type of field and method invocations instructions. 106 */ 107 static final int FIELDORMETH_INSN = 6; 108 109 /** 110 * The type of the INVOKEINTERFACE/INVOKEDYNAMIC instruction. 111 */ 112 static final int ITFMETH_INSN = 7; 113 114 /** 115 * The type of the INVOKEDYNAMIC instruction. 116 */ 117 static final int INDYMETH_INSN = 8; 118 119 /** 120 * The type of instructions with a 2 bytes bytecode offset label. 121 */ 122 static final int LABEL_INSN = 9; 123 124 /** 125 * The type of instructions with a 4 bytes bytecode offset label. 126 */ 127 static final int LABELW_INSN = 10; 128 129 /** 130 * The type of the LDC instruction. 131 */ 132 static final int LDC_INSN = 11; 133 134 /** 135 * The type of the LDC_W and LDC2_W instructions. 136 */ 137 static final int LDCW_INSN = 12; 138 139 /** 140 * The type of the IINC instruction. 141 */ 142 static final int IINC_INSN = 13; 143 144 /** 145 * The type of the TABLESWITCH instruction. 146 */ 147 static final int TABL_INSN = 14; 148 149 /** 150 * The type of the LOOKUPSWITCH instruction. 151 */ 152 static final int LOOK_INSN = 15; 153 154 /** 155 * The type of the MULTIANEWARRAY instruction. 156 */ 157 static final int MANA_INSN = 16; 158 159 /** 160 * The type of the WIDE instruction. 161 */ 162 static final int WIDE_INSN = 17; 163 164 /** 165 * The instruction types of all JVM opcodes. 166 */ 167 static final byte[] TYPE; 168 169 /** 170 * The type of CONSTANT_Class constant pool items. 171 */ 172 static final int CLASS = 7; 173 174 /** 175 * The type of CONSTANT_Fieldref constant pool items. 176 */ 177 static final int FIELD = 9; 178 179 /** 180 * The type of CONSTANT_Methodref constant pool items. 181 */ 182 static final int METH = 10; 183 184 /** 185 * The type of CONSTANT_InterfaceMethodref constant pool items. 186 */ 187 static final int IMETH = 11; 188 189 /** 190 * The type of CONSTANT_String constant pool items. 191 */ 192 static final int STR = 8; 193 194 /** 195 * The type of CONSTANT_Integer constant pool items. 196 */ 197 static final int INT = 3; 198 199 /** 200 * The type of CONSTANT_Float constant pool items. 201 */ 202 static final int FLOAT = 4; 203 204 /** 205 * The type of CONSTANT_Long constant pool items. 206 */ 207 static final int LONG = 5; 208 209 /** 210 * The type of CONSTANT_Double constant pool items. 211 */ 212 static final int DOUBLE = 6; 213 214 /** 215 * The type of CONSTANT_NameAndType constant pool items. 216 */ 217 static final int NAME_TYPE = 12; 218 219 /** 220 * The type of CONSTANT_Utf8 constant pool items. 221 */ 222 static final int UTF8 = 1; 223 224 /** 225 * The type of CONSTANT_MethodType constant pool items. 226 */ 227 static final int MTYPE = 16; 228 229 /** 230 * The type of CONSTANT_MethodHandle constant pool items. 231 */ 232 static final int HANDLE = 15; 233 234 /** 235 * The type of CONSTANT_InvokeDynamic constant pool items. 236 */ 237 static final int INDY = 18; 238 239 /** 240 * The base value for all CONSTANT_MethodHandle constant pool items. 241 * Internally, ASM store the 9 variations of CONSTANT_MethodHandle into 242 * 9 different items. 243 */ 244 static final int HANDLE_BASE = 20; 245 246 /** 247 * Normal type Item stored in the ClassWriter {@link ClassWriter#typeTable}, 248 * instead of the constant pool, in order to avoid clashes with normal 249 * constant pool items in the ClassWriter constant pool's hash table. 250 */ 251 static final int TYPE_NORMAL = 30; 252 253 /** 254 * Uninitialized type Item stored in the ClassWriter 255 * {@link ClassWriter#typeTable}, instead of the constant pool, in order to 256 * avoid clashes with normal constant pool items in the ClassWriter constant 257 * pool's hash table. 258 */ 259 static final int TYPE_UNINIT = 31; 260 261 /** 262 * Merged type Item stored in the ClassWriter {@link ClassWriter#typeTable}, 263 * instead of the constant pool, in order to avoid clashes with normal 264 * constant pool items in the ClassWriter constant pool's hash table. 265 */ 266 static final int TYPE_MERGED = 32; 267 268 /** 269 * The type of BootstrapMethods items. These items are stored in a 270 * special class attribute named BootstrapMethods and 271 * not in the constant pool. 272 */ 273 static final int BSM = 33; 274 275 /** 276 * The class reader from which this class writer was constructed, if any. 277 */ 278 ClassReader cr; 279 280 /** 281 * Minor and major version numbers of the class to be generated. 282 */ 283 int version; 284 285 /** 286 * Index of the next item to be added in the constant pool. 287 */ 288 int index; 289 290 /** 291 * The constant pool of this class. 292 */ 293 final ByteVector pool; 294 295 /** 296 * The constant pool's hash table data. 297 */ 298 Item[] items; 299 300 /** 301 * The threshold of the constant pool's hash table. 302 */ 303 int threshold; 304 305 /** 306 * A reusable key used to look for items in the {@link #items} hash table. 307 */ 308 final Item key; 309 310 /** 311 * A reusable key used to look for items in the {@link #items} hash table. 312 */ 313 final Item key2; 314 315 /** 316 * A reusable key used to look for items in the {@link #items} hash table. 317 */ 318 final Item key3; 319 320 /** 321 * A reusable key used to look for items in the {@link #items} hash table. 322 */ 323 final Item key4; 324 325 /** 326 * A type table used to temporarily store internal names that will not 327 * necessarily be stored in the constant pool. This type table is used by 328 * the control flow and data flow analysis algorithm used to compute stack 329 * map frames from scratch. This array associates to each index <tt>i</tt> 330 * the Item whose index is <tt>i</tt>. All Item objects stored in this 331 * array are also stored in the {@link #items} hash table. These two arrays 332 * allow to retrieve an Item from its index or, conversely, to get the index 333 * of an Item from its value. Each Item stores an internal name in its 334 * {@link Item#strVal1} field. 335 */ 336 Item[] typeTable; 337 338 /** 339 * Number of elements in the {@link #typeTable} array. 340 */ 341 private short typeCount; 342 343 /** 344 * The access flags of this class. 345 */ 346 private int access; 347 348 /** 349 * The constant pool item that contains the internal name of this class. 350 */ 351 private int name; 352 353 /** 354 * The internal name of this class. 355 */ 356 String thisName; 357 358 /** 359 * The constant pool item that contains the signature of this class. 360 */ 361 private int signature; 362 363 /** 364 * The constant pool item that contains the internal name of the super class 365 * of this class. 366 */ 367 private int superName; 368 369 /** 370 * Number of interfaces implemented or extended by this class or interface. 371 */ 372 private int interfaceCount; 373 374 /** 375 * The interfaces implemented or extended by this class or interface. More 376 * precisely, this array contains the indexes of the constant pool items 377 * that contain the internal names of these interfaces. 378 */ 379 private int[] interfaces; 380 381 /** 382 * The index of the constant pool item that contains the name of the source 383 * file from which this class was compiled. 384 */ 385 private int sourceFile; 386 387 /** 388 * The SourceDebug attribute of this class. 389 */ 390 private ByteVector sourceDebug; 391 392 /** 393 * The constant pool item that contains the name of the enclosing class of 394 * this class. 395 */ 396 private int enclosingMethodOwner; 397 398 /** 399 * The constant pool item that contains the name and descriptor of the 400 * enclosing method of this class. 401 */ 402 private int enclosingMethod; 403 404 /** 405 * The runtime visible annotations of this class. 406 */ 407 private AnnotationWriter anns; 408 409 /** 410 * The runtime invisible annotations of this class. 411 */ 412 private AnnotationWriter ianns; 413 414 /** 415 * The non standard attributes of this class. 416 */ 417 private Attribute attrs; 418 419 /** 420 * The number of entries in the InnerClasses attribute. 421 */ 422 private int innerClassesCount; 423 424 /** 425 * The InnerClasses attribute. 426 */ 427 private ByteVector innerClasses; 428 429 /** 430 * The number of entries in the BootstrapMethods attribute. 431 */ 432 int bootstrapMethodsCount; 433 434 /** 435 * The BootstrapMethods attribute. 436 */ 437 ByteVector bootstrapMethods; 438 439 /** 440 * The fields of this class. These fields are stored in a linked list of 441 * {@link FieldWriter} objects, linked to each other by their 442 * {@link FieldWriter#fv} field. This field stores the first element of 443 * this list. 444 */ 445 FieldWriter firstField; 446 447 /** 448 * The fields of this class. These fields are stored in a linked list of 449 * {@link FieldWriter} objects, linked to each other by their 450 * {@link FieldWriter#fv} field. This field stores the last element of 451 * this list. 452 */ 453 FieldWriter lastField; 454 455 /** 456 * The methods of this class. These methods are stored in a linked list of 457 * {@link MethodWriter} objects, linked to each other by their 458 * {@link MethodWriter#mv} field. This field stores the first element of 459 * this list. 460 */ 461 MethodWriter firstMethod; 462 463 /** 464 * The methods of this class. These methods are stored in a linked list of 465 * {@link MethodWriter} objects, linked to each other by their 466 * {@link MethodWriter#mv} field. This field stores the last element of 467 * this list. 468 */ 469 MethodWriter lastMethod; 470 471 /** 472 * <tt>true</tt> if the maximum stack size and number of local variables 473 * must be automatically computed. 474 */ 475 private final boolean computeMaxs; 476 477 /** 478 * <tt>true</tt> if the stack map frames must be recomputed from scratch. 479 */ 480 private final boolean computeFrames; 481 482 /** 483 * <tt>true</tt> if the stack map tables of this class are invalid. The 484 * {@link MethodWriter#resizeInstructions} method cannot transform existing 485 * stack map tables, and so produces potentially invalid classes when it is 486 * executed. In this case the class is reread and rewritten with the 487 * {@link #COMPUTE_FRAMES} option (the resizeInstructions method can resize 488 * stack map tables when this option is used). 489 */ 490 boolean invalidFrames; 491 492 // ------------------------------------------------------------------------ 493 // Static initializer 494 // ------------------------------------------------------------------------ 495 496 /** 497 * Computes the instruction types of JVM opcodes. 498 */ 499 static { 500 int i; 501 byte[] b = new byte[220]; 502 String s = "AAAAAAAAAAAAAAAABCLMMDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD" 503 + "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 504 + "AAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJJJDOPAA" 505 + "AAAAGGGGGGGHIFBFAAFFAARQJJKKJJJJJJJJJJJJJJJJJJ"; 506 for (i = 0; i < b.length; ++i) { 507 b[i] = (byte) (s.charAt(i) - 'A'); 508 } 509 TYPE = b; 510 511 // code to generate the above string 512 // 513 // // SBYTE_INSN instructions 514 // b[Constants.NEWARRAY] = SBYTE_INSN; 515 // b[Constants.BIPUSH] = SBYTE_INSN; 516 // 517 // // SHORT_INSN instructions 518 // b[Constants.SIPUSH] = SHORT_INSN; 519 // 520 // // (IMPL)VAR_INSN instructions 521 // b[Constants.RET] = VAR_INSN; 522 // for (i = Constants.ILOAD; i <= Constants.ALOAD; ++i) { 523 // b[i] = VAR_INSN; 524 // } 525 // for (i = Constants.ISTORE; i <= Constants.ASTORE; ++i) { 526 // b[i] = VAR_INSN; 527 // } 528 // for (i = 26; i <= 45; ++i) { // ILOAD_0 to ALOAD_3 529 // b[i] = IMPLVAR_INSN; 530 // } 531 // for (i = 59; i <= 78; ++i) { // ISTORE_0 to ASTORE_3 532 // b[i] = IMPLVAR_INSN; 533 // } 534 // 535 // // TYPE_INSN instructions 536 // b[Constants.NEW] = TYPE_INSN; 537 // b[Constants.ANEWARRAY] = TYPE_INSN; 538 // b[Constants.CHECKCAST] = TYPE_INSN; 539 // b[Constants.INSTANCEOF] = TYPE_INSN; 540 // 541 // // (Set)FIELDORMETH_INSN instructions 542 // for (i = Constants.GETSTATIC; i <= Constants.INVOKESTATIC; ++i) { 543 // b[i] = FIELDORMETH_INSN; 544 // } 545 // b[Constants.INVOKEINTERFACE] = ITFMETH_INSN; 546 // b[Constants.INVOKEDYNAMIC] = INDYMETH_INSN; 547 // 548 // // LABEL(W)_INSN instructions 549 // for (i = Constants.IFEQ; i <= Constants.JSR; ++i) { 550 // b[i] = LABEL_INSN; 551 // } 552 // b[Constants.IFNULL] = LABEL_INSN; 553 // b[Constants.IFNONNULL] = LABEL_INSN; 554 // b[200] = LABELW_INSN; // GOTO_W 555 // b[201] = LABELW_INSN; // JSR_W 556 // // temporary opcodes used internally by ASM - see Label and 557 // MethodWriter 558 // for (i = 202; i < 220; ++i) { 559 // b[i] = LABEL_INSN; 560 // } 561 // 562 // // LDC(_W) instructions 563 // b[Constants.LDC] = LDC_INSN; 564 // b[19] = LDCW_INSN; // LDC_W 565 // b[20] = LDCW_INSN; // LDC2_W 566 // 567 // // special instructions 568 // b[Constants.IINC] = IINC_INSN; 569 // b[Constants.TABLESWITCH] = TABL_INSN; 570 // b[Constants.LOOKUPSWITCH] = LOOK_INSN; 571 // b[Constants.MULTIANEWARRAY] = MANA_INSN; 572 // b[196] = WIDE_INSN; // WIDE 573 // 574 // for (i = 0; i < b.length; ++i) { 575 // System.err.print((char)('A' + b[i])); 576 // } 577 // System.err.println(); 578 } 579 580 // ------------------------------------------------------------------------ 581 // Constructor 582 // ------------------------------------------------------------------------ 583 584 /** 585 * Constructs a new {@link ClassWriter} object. 586 * 587 * @param flags option flags that can be used to modify the default behavior 588 * of this class. See {@link #COMPUTE_MAXS}, {@link #COMPUTE_FRAMES}. 589 */ ClassWriter(final int flags)590 public ClassWriter(final int flags) { 591 super(Opcodes.ASM4); 592 index = 1; 593 pool = new ByteVector(); 594 items = new Item[256]; 595 threshold = (int) (0.75d * items.length); 596 key = new Item(); 597 key2 = new Item(); 598 key3 = new Item(); 599 key4 = new Item(); 600 this.computeMaxs = (flags & COMPUTE_MAXS) != 0; 601 this.computeFrames = (flags & COMPUTE_FRAMES) != 0; 602 } 603 604 /** 605 * Constructs a new {@link ClassWriter} object and enables optimizations for 606 * "mostly add" bytecode transformations. These optimizations are the 607 * following: 608 * 609 * <ul> <li>The constant pool from the original class is copied as is in the 610 * new class, which saves time. New constant pool entries will be added at 611 * the end if necessary, but unused constant pool entries <i>won't be 612 * removed</i>.</li> <li>Methods that are not transformed are copied as is 613 * in the new class, directly from the original class bytecode (i.e. without 614 * emitting visit events for all the method instructions), which saves a 615 * <i>lot</i> of time. Untransformed methods are detected by the fact that 616 * the {@link ClassReader} receives {@link MethodVisitor} objects that come 617 * from a {@link ClassWriter} (and not from any other {@link ClassVisitor} 618 * instance).</li> </ul> 619 * 620 * @param classReader the {@link ClassReader} used to read the original 621 * class. It will be used to copy the entire constant pool from the 622 * original class and also to copy other fragments of original 623 * bytecode where applicable. 624 * @param flags option flags that can be used to modify the default behavior 625 * of this class. <i>These option flags do not affect methods that 626 * are copied as is in the new class. This means that the maximum 627 * stack size nor the stack frames will be computed for these 628 * methods</i>. See {@link #COMPUTE_MAXS}, {@link #COMPUTE_FRAMES}. 629 */ ClassWriter(final ClassReader classReader, final int flags)630 public ClassWriter(final ClassReader classReader, final int flags) { 631 this(flags); 632 classReader.copyPool(this); 633 this.cr = classReader; 634 } 635 636 // ------------------------------------------------------------------------ 637 // Implementation of the ClassVisitor abstract class 638 // ------------------------------------------------------------------------ 639 640 @Override visit( final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces)641 public final void visit( 642 final int version, 643 final int access, 644 final String name, 645 final String signature, 646 final String superName, 647 final String[] interfaces) 648 { 649 this.version = version; 650 this.access = access; 651 this.name = newClass(name); 652 thisName = name; 653 if (ClassReader.SIGNATURES && signature != null) { 654 this.signature = newUTF8(signature); 655 } 656 this.superName = superName == null ? 0 : newClass(superName); 657 if (interfaces != null && interfaces.length > 0) { 658 interfaceCount = interfaces.length; 659 this.interfaces = new int[interfaceCount]; 660 for (int i = 0; i < interfaceCount; ++i) { 661 this.interfaces[i] = newClass(interfaces[i]); 662 } 663 } 664 } 665 666 @Override visitSource(final String file, final String debug)667 public final void visitSource(final String file, final String debug) { 668 if (file != null) { 669 sourceFile = newUTF8(file); 670 } 671 if (debug != null) { 672 sourceDebug = new ByteVector().putUTF8(debug); 673 } 674 } 675 676 @Override visitOuterClass( final String owner, final String name, final String desc)677 public final void visitOuterClass( 678 final String owner, 679 final String name, 680 final String desc) 681 { 682 enclosingMethodOwner = newClass(owner); 683 if (name != null && desc != null) { 684 enclosingMethod = newNameType(name, desc); 685 } 686 } 687 688 @Override visitAnnotation( final String desc, final boolean visible)689 public final AnnotationVisitor visitAnnotation( 690 final String desc, 691 final boolean visible) 692 { 693 if (!ClassReader.ANNOTATIONS) { 694 return null; 695 } 696 ByteVector bv = new ByteVector(); 697 // write type, and reserve space for values count 698 bv.putShort(newUTF8(desc)).putShort(0); 699 AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv, 2); 700 if (visible) { 701 aw.next = anns; 702 anns = aw; 703 } else { 704 aw.next = ianns; 705 ianns = aw; 706 } 707 return aw; 708 } 709 710 @Override visitAttribute(final Attribute attr)711 public final void visitAttribute(final Attribute attr) { 712 attr.next = attrs; 713 attrs = attr; 714 } 715 716 @Override visitInnerClass( final String name, final String outerName, final String innerName, final int access)717 public final void visitInnerClass( 718 final String name, 719 final String outerName, 720 final String innerName, 721 final int access) 722 { 723 if (innerClasses == null) { 724 innerClasses = new ByteVector(); 725 } 726 ++innerClassesCount; 727 innerClasses.putShort(name == null ? 0 : newClass(name)); 728 innerClasses.putShort(outerName == null ? 0 : newClass(outerName)); 729 innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName)); 730 innerClasses.putShort(access); 731 } 732 733 @Override visitField( final int access, final String name, final String desc, final String signature, final Object value)734 public final FieldVisitor visitField( 735 final int access, 736 final String name, 737 final String desc, 738 final String signature, 739 final Object value) 740 { 741 return new FieldWriter(this, access, name, desc, signature, value); 742 } 743 744 @Override visitMethod( final int access, final String name, final String desc, final String signature, final String[] exceptions)745 public final MethodVisitor visitMethod( 746 final int access, 747 final String name, 748 final String desc, 749 final String signature, 750 final String[] exceptions) 751 { 752 return new MethodWriter(this, 753 access, 754 name, 755 desc, 756 signature, 757 exceptions, 758 computeMaxs, 759 computeFrames); 760 } 761 762 @Override visitEnd()763 public final void visitEnd() { 764 } 765 766 // ------------------------------------------------------------------------ 767 // Other public methods 768 // ------------------------------------------------------------------------ 769 770 /** 771 * Returns the bytecode of the class that was build with this class writer. 772 * 773 * @return the bytecode of the class that was build with this class writer. 774 */ toByteArray()775 public byte[] toByteArray() { 776 if (index > Short.MAX_VALUE) { 777 throw new RuntimeException("Class file too large!"); 778 } 779 // computes the real size of the bytecode of this class 780 int size = 24 + 2 * interfaceCount; 781 int nbFields = 0; 782 FieldWriter fb = firstField; 783 while (fb != null) { 784 ++nbFields; 785 size += fb.getSize(); 786 fb = (FieldWriter) fb.fv; 787 } 788 int nbMethods = 0; 789 MethodWriter mb = firstMethod; 790 while (mb != null) { 791 ++nbMethods; 792 size += mb.getSize(); 793 mb = (MethodWriter) mb.mv; 794 } 795 int attributeCount = 0; 796 if (bootstrapMethods != null) { // we put it as first argument in order 797 // to improve a bit ClassReader.copyBootstrapMethods 798 ++attributeCount; 799 size += 8 + bootstrapMethods.length; 800 newUTF8("BootstrapMethods"); 801 } 802 if (ClassReader.SIGNATURES && signature != 0) { 803 ++attributeCount; 804 size += 8; 805 newUTF8("Signature"); 806 } 807 if (sourceFile != 0) { 808 ++attributeCount; 809 size += 8; 810 newUTF8("SourceFile"); 811 } 812 if (sourceDebug != null) { 813 ++attributeCount; 814 size += sourceDebug.length + 4; 815 newUTF8("SourceDebugExtension"); 816 } 817 if (enclosingMethodOwner != 0) { 818 ++attributeCount; 819 size += 10; 820 newUTF8("EnclosingMethod"); 821 } 822 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 823 ++attributeCount; 824 size += 6; 825 newUTF8("Deprecated"); 826 } 827 if ((access & Opcodes.ACC_SYNTHETIC) != 0 828 && ((version & 0xFFFF) < Opcodes.V1_5 || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0)) 829 { 830 ++attributeCount; 831 size += 6; 832 newUTF8("Synthetic"); 833 } 834 if (innerClasses != null) { 835 ++attributeCount; 836 size += 8 + innerClasses.length; 837 newUTF8("InnerClasses"); 838 } 839 if (ClassReader.ANNOTATIONS && anns != null) { 840 ++attributeCount; 841 size += 8 + anns.getSize(); 842 newUTF8("RuntimeVisibleAnnotations"); 843 } 844 if (ClassReader.ANNOTATIONS && ianns != null) { 845 ++attributeCount; 846 size += 8 + ianns.getSize(); 847 newUTF8("RuntimeInvisibleAnnotations"); 848 } 849 if (attrs != null) { 850 attributeCount += attrs.getCount(); 851 size += attrs.getSize(this, null, 0, -1, -1); 852 } 853 size += pool.length; 854 // allocates a byte vector of this size, in order to avoid unnecessary 855 // arraycopy operations in the ByteVector.enlarge() method 856 ByteVector out = new ByteVector(size); 857 out.putInt(0xCAFEBABE).putInt(version); 858 out.putShort(index).putByteArray(pool.data, 0, pool.length); 859 int mask = Opcodes.ACC_DEPRECATED 860 | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE 861 | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / (ClassWriter.ACC_SYNTHETIC_ATTRIBUTE / Opcodes.ACC_SYNTHETIC)); 862 out.putShort(access & ~mask).putShort(name).putShort(superName); 863 out.putShort(interfaceCount); 864 for (int i = 0; i < interfaceCount; ++i) { 865 out.putShort(interfaces[i]); 866 } 867 out.putShort(nbFields); 868 fb = firstField; 869 while (fb != null) { 870 fb.put(out); 871 fb = (FieldWriter) fb.fv; 872 } 873 out.putShort(nbMethods); 874 mb = firstMethod; 875 while (mb != null) { 876 mb.put(out); 877 mb = (MethodWriter) mb.mv; 878 } 879 out.putShort(attributeCount); 880 if (bootstrapMethods != null) { // should be the first class attribute ? 881 out.putShort(newUTF8("BootstrapMethods")); 882 out.putInt(bootstrapMethods.length + 2).putShort(bootstrapMethodsCount); 883 out.putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length); 884 } 885 if (ClassReader.SIGNATURES && signature != 0) { 886 out.putShort(newUTF8("Signature")).putInt(2).putShort(signature); 887 } 888 if (sourceFile != 0) { 889 out.putShort(newUTF8("SourceFile")).putInt(2).putShort(sourceFile); 890 } 891 if (sourceDebug != null) { 892 int len = sourceDebug.length - 2; 893 out.putShort(newUTF8("SourceDebugExtension")).putInt(len); 894 out.putByteArray(sourceDebug.data, 2, len); 895 } 896 if (enclosingMethodOwner != 0) { 897 out.putShort(newUTF8("EnclosingMethod")).putInt(4); 898 out.putShort(enclosingMethodOwner).putShort(enclosingMethod); 899 } 900 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 901 out.putShort(newUTF8("Deprecated")).putInt(0); 902 } 903 if ((access & Opcodes.ACC_SYNTHETIC) != 0 904 && ((version & 0xFFFF) < Opcodes.V1_5 || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0)) 905 { 906 out.putShort(newUTF8("Synthetic")).putInt(0); 907 } 908 if (innerClasses != null) { 909 out.putShort(newUTF8("InnerClasses")); 910 out.putInt(innerClasses.length + 2).putShort(innerClassesCount); 911 out.putByteArray(innerClasses.data, 0, innerClasses.length); 912 } 913 if (ClassReader.ANNOTATIONS && anns != null) { 914 out.putShort(newUTF8("RuntimeVisibleAnnotations")); 915 anns.put(out); 916 } 917 if (ClassReader.ANNOTATIONS && ianns != null) { 918 out.putShort(newUTF8("RuntimeInvisibleAnnotations")); 919 ianns.put(out); 920 } 921 if (attrs != null) { 922 attrs.put(this, null, 0, -1, -1, out); 923 } 924 if (invalidFrames) { 925 ClassWriter cw = new ClassWriter(COMPUTE_FRAMES); 926 new ClassReader(out.data).accept(cw, ClassReader.SKIP_FRAMES); 927 return cw.toByteArray(); 928 } 929 return out.data; 930 } 931 932 // ------------------------------------------------------------------------ 933 // Utility methods: constant pool management 934 // ------------------------------------------------------------------------ 935 936 /** 937 * Adds a number or string constant to the constant pool of the class being 938 * build. Does nothing if the constant pool already contains a similar item. 939 * 940 * @param cst the value of the constant to be added to the constant pool. 941 * This parameter must be an {@link Integer}, a {@link Float}, a 942 * {@link Long}, a {@link Double}, a {@link String} or a 943 * {@link Type}. 944 * @return a new or already existing constant item with the given value. 945 */ newConstItem(final Object cst)946 Item newConstItem(final Object cst) { 947 if (cst instanceof Integer) { 948 int val = ((Integer) cst).intValue(); 949 return newInteger(val); 950 } else if (cst instanceof Byte) { 951 int val = ((Byte) cst).intValue(); 952 return newInteger(val); 953 } else if (cst instanceof Character) { 954 int val = ((Character) cst).charValue(); 955 return newInteger(val); 956 } else if (cst instanceof Short) { 957 int val = ((Short) cst).intValue(); 958 return newInteger(val); 959 } else if (cst instanceof Boolean) { 960 int val = ((Boolean) cst).booleanValue() ? 1 : 0; 961 return newInteger(val); 962 } else if (cst instanceof Float) { 963 float val = ((Float) cst).floatValue(); 964 return newFloat(val); 965 } else if (cst instanceof Long) { 966 long val = ((Long) cst).longValue(); 967 return newLong(val); 968 } else if (cst instanceof Double) { 969 double val = ((Double) cst).doubleValue(); 970 return newDouble(val); 971 } else if (cst instanceof String) { 972 return newString((String) cst); 973 } else if (cst instanceof Type) { 974 Type t = (Type) cst; 975 int s = t.getSort(); 976 if (s == Type.ARRAY) { 977 return newClassItem(t.getDescriptor()); 978 } else if (s == Type.OBJECT) { 979 return newClassItem(t.getInternalName()); 980 } else { // s == Type.METHOD 981 return newMethodTypeItem(t.getDescriptor()); 982 } 983 } else if (cst instanceof Handle) { 984 Handle h = (Handle) cst; 985 return newHandleItem(h.tag, h.owner, h.name, h.desc); 986 } else { 987 throw new IllegalArgumentException("value " + cst); 988 } 989 } 990 991 /** 992 * Adds a number or string constant to the constant pool of the class being 993 * build. Does nothing if the constant pool already contains a similar item. 994 * <i>This method is intended for {@link Attribute} sub classes, and is 995 * normally not needed by class generators or adapters.</i> 996 * 997 * @param cst the value of the constant to be added to the constant pool. 998 * This parameter must be an {@link Integer}, a {@link Float}, a 999 * {@link Long}, a {@link Double} or a {@link String}. 1000 * @return the index of a new or already existing constant item with the 1001 * given value. 1002 */ newConst(final Object cst)1003 public int newConst(final Object cst) { 1004 return newConstItem(cst).index; 1005 } 1006 1007 /** 1008 * Adds an UTF8 string to the constant pool of the class being build. Does 1009 * nothing if the constant pool already contains a similar item. <i>This 1010 * method is intended for {@link Attribute} sub classes, and is normally not 1011 * needed by class generators or adapters.</i> 1012 * 1013 * @param value the String value. 1014 * @return the index of a new or already existing UTF8 item. 1015 */ newUTF8(final String value)1016 public int newUTF8(final String value) { 1017 key.set(UTF8, value, null, null); 1018 Item result = get(key); 1019 if (result == null) { 1020 pool.putByte(UTF8).putUTF8(value); 1021 result = new Item(index++, key); 1022 put(result); 1023 } 1024 return result.index; 1025 } 1026 1027 /** 1028 * Adds a class reference to the constant pool of the class being build. 1029 * Does nothing if the constant pool already contains a similar item. 1030 * <i>This method is intended for {@link Attribute} sub classes, and is 1031 * normally not needed by class generators or adapters.</i> 1032 * 1033 * @param value the internal name of the class. 1034 * @return a new or already existing class reference item. 1035 */ newClassItem(final String value)1036 Item newClassItem(final String value) { 1037 key2.set(CLASS, value, null, null); 1038 Item result = get(key2); 1039 if (result == null) { 1040 pool.put12(CLASS, newUTF8(value)); 1041 result = new Item(index++, key2); 1042 put(result); 1043 } 1044 return result; 1045 } 1046 1047 /** 1048 * Adds a class reference to the constant pool of the class being build. 1049 * Does nothing if the constant pool already contains a similar item. 1050 * <i>This method is intended for {@link Attribute} sub classes, and is 1051 * normally not needed by class generators or adapters.</i> 1052 * 1053 * @param value the internal name of the class. 1054 * @return the index of a new or already existing class reference item. 1055 */ newClass(final String value)1056 public int newClass(final String value) { 1057 return newClassItem(value).index; 1058 } 1059 1060 /** 1061 * Adds a method type reference to the constant pool of the class being 1062 * build. Does nothing if the constant pool already contains a similar item. 1063 * <i>This method is intended for {@link Attribute} sub classes, and is 1064 * normally not needed by class generators or adapters.</i> 1065 * 1066 * @param methodDesc method descriptor of the method type. 1067 * @return a new or already existing method type reference item. 1068 */ newMethodTypeItem(final String methodDesc)1069 Item newMethodTypeItem(final String methodDesc) { 1070 key2.set(MTYPE, methodDesc, null, null); 1071 Item result = get(key2); 1072 if (result == null) { 1073 pool.put12(MTYPE, newUTF8(methodDesc)); 1074 result = new Item(index++, key2); 1075 put(result); 1076 } 1077 return result; 1078 } 1079 1080 /** 1081 * Adds a method type reference to the constant pool of the class being 1082 * build. Does nothing if the constant pool already contains a similar item. 1083 * <i>This method is intended for {@link Attribute} sub classes, and is 1084 * normally not needed by class generators or adapters.</i> 1085 * 1086 * @param methodDesc method descriptor of the method type. 1087 * @return the index of a new or already existing method type reference 1088 * item. 1089 */ newMethodType(final String methodDesc)1090 public int newMethodType(final String methodDesc) { 1091 return newMethodTypeItem(methodDesc).index; 1092 } 1093 1094 /** 1095 * Adds a handle to the constant pool of the class being build. Does nothing 1096 * if the constant pool already contains a similar item. <i>This method is 1097 * intended for {@link Attribute} sub classes, and is normally not needed by 1098 * class generators or adapters.</i> 1099 * 1100 * @param tag the kind of this handle. Must be {@link Opcodes#H_GETFIELD}, 1101 * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, 1102 * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, 1103 * {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, 1104 * {@link Opcodes#H_NEWINVOKESPECIAL} or 1105 * {@link Opcodes#H_INVOKEINTERFACE}. 1106 * @param owner the internal name of the field or method owner class. 1107 * @param name the name of the field or method. 1108 * @param desc the descriptor of the field or method. 1109 * @return a new or an already existing method type reference item. 1110 */ newHandleItem( final int tag, final String owner, final String name, final String desc)1111 Item newHandleItem( 1112 final int tag, 1113 final String owner, 1114 final String name, 1115 final String desc) 1116 { 1117 key4.set(HANDLE_BASE + tag, owner, name, desc); 1118 Item result = get(key4); 1119 if (result == null) { 1120 if (tag <= Opcodes.H_PUTSTATIC) { 1121 put112(HANDLE, tag, newField(owner, name, desc)); 1122 } else { 1123 put112(HANDLE, tag, newMethod(owner, 1124 name, 1125 desc, 1126 tag == Opcodes.H_INVOKEINTERFACE)); 1127 } 1128 result = new Item(index++, key4); 1129 put(result); 1130 } 1131 return result; 1132 } 1133 1134 /** 1135 * Adds a handle to the constant pool of the class being 1136 * build. Does nothing if the constant pool already contains a similar item. 1137 * <i>This method is intended for {@link Attribute} sub classes, and is 1138 * normally not needed by class generators or adapters.</i> 1139 * 1140 * @param tag the kind of this handle. Must be {@link Opcodes#H_GETFIELD}, 1141 * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, 1142 * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, 1143 * {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, 1144 * {@link Opcodes#H_NEWINVOKESPECIAL} or 1145 * {@link Opcodes#H_INVOKEINTERFACE}. 1146 * @param owner the internal name of the field or method owner class. 1147 * @param name the name of the field or method. 1148 * @param desc the descriptor of the field or method. 1149 * @return the index of a new or already existing method type reference 1150 * item. 1151 */ newHandle( final int tag, final String owner, final String name, final String desc)1152 public int newHandle( 1153 final int tag, 1154 final String owner, 1155 final String name, 1156 final String desc) 1157 { 1158 return newHandleItem(tag, owner, name, desc).index; 1159 } 1160 1161 /** 1162 * Adds an invokedynamic reference to the constant pool of the class being 1163 * build. Does nothing if the constant pool already contains a similar item. 1164 * <i>This method is intended for {@link Attribute} sub classes, and is 1165 * normally not needed by class generators or adapters.</i> 1166 * 1167 * @param name name of the invoked method. 1168 * @param desc descriptor of the invoke method. 1169 * @param bsm the bootstrap method. 1170 * @param bsmArgs the bootstrap method constant arguments. 1171 * 1172 * @return a new or an already existing invokedynamic type reference item. 1173 */ newInvokeDynamicItem( final String name, final String desc, final Handle bsm, final Object... bsmArgs)1174 Item newInvokeDynamicItem( 1175 final String name, 1176 final String desc, 1177 final Handle bsm, 1178 final Object... bsmArgs) 1179 { 1180 // cache for performance 1181 ByteVector bootstrapMethods = this.bootstrapMethods; 1182 if (bootstrapMethods == null) { 1183 bootstrapMethods = this.bootstrapMethods = new ByteVector(); 1184 } 1185 1186 int position = bootstrapMethods.length; // record current position 1187 1188 int hashCode = bsm.hashCode(); 1189 bootstrapMethods.putShort(newHandle(bsm.tag, 1190 bsm.owner, 1191 bsm.name, 1192 bsm.desc)); 1193 1194 int argsLength = bsmArgs.length; 1195 bootstrapMethods.putShort(argsLength); 1196 1197 for (int i = 0; i < argsLength; i++) { 1198 Object bsmArg = bsmArgs[i]; 1199 hashCode ^= bsmArg.hashCode(); 1200 bootstrapMethods.putShort(newConst(bsmArg)); 1201 } 1202 1203 byte[] data = bootstrapMethods.data; 1204 int length = (1 + 1 + argsLength) << 1; // (bsm + argCount + arguments) 1205 hashCode &= 0x7FFFFFFF; 1206 Item result = items[hashCode % items.length]; 1207 loop: while (result != null) { 1208 if (result.type != BSM || result.hashCode != hashCode) { 1209 result = result.next; 1210 continue; 1211 } 1212 1213 // because the data encode the size of the argument 1214 // we don't need to test if these size are equals 1215 int resultPosition = result.intVal; 1216 for (int p = 0; p < length; p++) { 1217 if (data[position + p] != data[resultPosition + p]) { 1218 result = result.next; 1219 continue loop; 1220 } 1221 } 1222 break; 1223 } 1224 1225 int bootstrapMethodIndex; 1226 if (result != null) { 1227 bootstrapMethodIndex = result.index; 1228 bootstrapMethods.length = position; // revert to old position 1229 } else { 1230 bootstrapMethodIndex = bootstrapMethodsCount++; 1231 result = new Item(bootstrapMethodIndex); 1232 result.set(position, hashCode); 1233 put(result); 1234 } 1235 1236 // now, create the InvokeDynamic constant 1237 key3.set(name, desc, bootstrapMethodIndex); 1238 result = get(key3); 1239 if (result == null) { 1240 put122(INDY, bootstrapMethodIndex, newNameType(name, desc)); 1241 result = new Item(index++, key3); 1242 put(result); 1243 } 1244 return result; 1245 } 1246 1247 /** 1248 * Adds an invokedynamic reference to the constant pool of the class being 1249 * build. Does nothing if the constant pool already contains a similar item. 1250 * <i>This method is intended for {@link Attribute} sub classes, and is 1251 * normally not needed by class generators or adapters.</i> 1252 * 1253 * @param name name of the invoked method. 1254 * @param desc descriptor of the invoke method. 1255 * @param bsm the bootstrap method. 1256 * @param bsmArgs the bootstrap method constant arguments. 1257 * 1258 * @return the index of a new or already existing invokedynamic 1259 * reference item. 1260 */ newInvokeDynamic( final String name, final String desc, final Handle bsm, final Object... bsmArgs)1261 public int newInvokeDynamic( 1262 final String name, 1263 final String desc, 1264 final Handle bsm, 1265 final Object... bsmArgs) 1266 { 1267 return newInvokeDynamicItem(name, desc, bsm, bsmArgs).index; 1268 } 1269 1270 /** 1271 * Adds a field reference to the constant pool of the class being build. 1272 * Does nothing if the constant pool already contains a similar item. 1273 * 1274 * @param owner the internal name of the field's owner class. 1275 * @param name the field's name. 1276 * @param desc the field's descriptor. 1277 * @return a new or already existing field reference item. 1278 */ newFieldItem(final String owner, final String name, final String desc)1279 Item newFieldItem(final String owner, final String name, final String desc) 1280 { 1281 key3.set(FIELD, owner, name, desc); 1282 Item result = get(key3); 1283 if (result == null) { 1284 put122(FIELD, newClass(owner), newNameType(name, desc)); 1285 result = new Item(index++, key3); 1286 put(result); 1287 } 1288 return result; 1289 } 1290 1291 /** 1292 * Adds a field reference to the constant pool of the class being build. 1293 * Does nothing if the constant pool already contains a similar item. 1294 * <i>This method is intended for {@link Attribute} sub classes, and is 1295 * normally not needed by class generators or adapters.</i> 1296 * 1297 * @param owner the internal name of the field's owner class. 1298 * @param name the field's name. 1299 * @param desc the field's descriptor. 1300 * @return the index of a new or already existing field reference item. 1301 */ newField(final String owner, final String name, final String desc)1302 public int newField(final String owner, final String name, final String desc) 1303 { 1304 return newFieldItem(owner, name, desc).index; 1305 } 1306 1307 /** 1308 * Adds a method reference to the constant pool of the class being build. 1309 * Does nothing if the constant pool already contains a similar item. 1310 * 1311 * @param owner the internal name of the method's owner class. 1312 * @param name the method's name. 1313 * @param desc the method's descriptor. 1314 * @param itf <tt>true</tt> if <tt>owner</tt> is an interface. 1315 * @return a new or already existing method reference item. 1316 */ newMethodItem( final String owner, final String name, final String desc, final boolean itf)1317 Item newMethodItem( 1318 final String owner, 1319 final String name, 1320 final String desc, 1321 final boolean itf) 1322 { 1323 int type = itf ? IMETH : METH; 1324 key3.set(type, owner, name, desc); 1325 Item result = get(key3); 1326 if (result == null) { 1327 put122(type, newClass(owner), newNameType(name, desc)); 1328 result = new Item(index++, key3); 1329 put(result); 1330 } 1331 return result; 1332 } 1333 1334 /** 1335 * Adds a method reference to the constant pool of the class being build. 1336 * Does nothing if the constant pool already contains a similar item. 1337 * <i>This method is intended for {@link Attribute} sub classes, and is 1338 * normally not needed by class generators or adapters.</i> 1339 * 1340 * @param owner the internal name of the method's owner class. 1341 * @param name the method's name. 1342 * @param desc the method's descriptor. 1343 * @param itf <tt>true</tt> if <tt>owner</tt> is an interface. 1344 * @return the index of a new or already existing method reference item. 1345 */ newMethod( final String owner, final String name, final String desc, final boolean itf)1346 public int newMethod( 1347 final String owner, 1348 final String name, 1349 final String desc, 1350 final boolean itf) 1351 { 1352 return newMethodItem(owner, name, desc, itf).index; 1353 } 1354 1355 /** 1356 * Adds an integer to the constant pool of the class being build. Does 1357 * nothing if the constant pool already contains a similar item. 1358 * 1359 * @param value the int value. 1360 * @return a new or already existing int item. 1361 */ newInteger(final int value)1362 Item newInteger(final int value) { 1363 key.set(value); 1364 Item result = get(key); 1365 if (result == null) { 1366 pool.putByte(INT).putInt(value); 1367 result = new Item(index++, key); 1368 put(result); 1369 } 1370 return result; 1371 } 1372 1373 /** 1374 * Adds a float to the constant pool of the class being build. Does nothing 1375 * if the constant pool already contains a similar item. 1376 * 1377 * @param value the float value. 1378 * @return a new or already existing float item. 1379 */ newFloat(final float value)1380 Item newFloat(final float value) { 1381 key.set(value); 1382 Item result = get(key); 1383 if (result == null) { 1384 pool.putByte(FLOAT).putInt(key.intVal); 1385 result = new Item(index++, key); 1386 put(result); 1387 } 1388 return result; 1389 } 1390 1391 /** 1392 * Adds a long to the constant pool of the class being build. Does nothing 1393 * if the constant pool already contains a similar item. 1394 * 1395 * @param value the long value. 1396 * @return a new or already existing long item. 1397 */ newLong(final long value)1398 Item newLong(final long value) { 1399 key.set(value); 1400 Item result = get(key); 1401 if (result == null) { 1402 pool.putByte(LONG).putLong(value); 1403 result = new Item(index, key); 1404 index += 2; 1405 put(result); 1406 } 1407 return result; 1408 } 1409 1410 /** 1411 * Adds a double to the constant pool of the class being build. Does nothing 1412 * if the constant pool already contains a similar item. 1413 * 1414 * @param value the double value. 1415 * @return a new or already existing double item. 1416 */ newDouble(final double value)1417 Item newDouble(final double value) { 1418 key.set(value); 1419 Item result = get(key); 1420 if (result == null) { 1421 pool.putByte(DOUBLE).putLong(key.longVal); 1422 result = new Item(index, key); 1423 index += 2; 1424 put(result); 1425 } 1426 return result; 1427 } 1428 1429 /** 1430 * Adds a string to the constant pool of the class being build. Does nothing 1431 * if the constant pool already contains a similar item. 1432 * 1433 * @param value the String value. 1434 * @return a new or already existing string item. 1435 */ newString(final String value)1436 private Item newString(final String value) { 1437 key2.set(STR, value, null, null); 1438 Item result = get(key2); 1439 if (result == null) { 1440 pool.put12(STR, newUTF8(value)); 1441 result = new Item(index++, key2); 1442 put(result); 1443 } 1444 return result; 1445 } 1446 1447 /** 1448 * Adds a name and type to the constant pool of the class being build. Does 1449 * nothing if the constant pool already contains a similar item. <i>This 1450 * method is intended for {@link Attribute} sub classes, and is normally not 1451 * needed by class generators or adapters.</i> 1452 * 1453 * @param name a name. 1454 * @param desc a type descriptor. 1455 * @return the index of a new or already existing name and type item. 1456 */ newNameType(final String name, final String desc)1457 public int newNameType(final String name, final String desc) { 1458 return newNameTypeItem(name, desc).index; 1459 } 1460 1461 /** 1462 * Adds a name and type to the constant pool of the class being build. Does 1463 * nothing if the constant pool already contains a similar item. 1464 * 1465 * @param name a name. 1466 * @param desc a type descriptor. 1467 * @return a new or already existing name and type item. 1468 */ newNameTypeItem(final String name, final String desc)1469 Item newNameTypeItem(final String name, final String desc) { 1470 key2.set(NAME_TYPE, name, desc, null); 1471 Item result = get(key2); 1472 if (result == null) { 1473 put122(NAME_TYPE, newUTF8(name), newUTF8(desc)); 1474 result = new Item(index++, key2); 1475 put(result); 1476 } 1477 return result; 1478 } 1479 1480 /** 1481 * Adds the given internal name to {@link #typeTable} and returns its index. 1482 * Does nothing if the type table already contains this internal name. 1483 * 1484 * @param type the internal name to be added to the type table. 1485 * @return the index of this internal name in the type table. 1486 */ addType(final String type)1487 int addType(final String type) { 1488 key.set(TYPE_NORMAL, type, null, null); 1489 Item result = get(key); 1490 if (result == null) { 1491 result = addType(key); 1492 } 1493 return result.index; 1494 } 1495 1496 /** 1497 * Adds the given "uninitialized" type to {@link #typeTable} and returns its 1498 * index. This method is used for UNINITIALIZED types, made of an internal 1499 * name and a bytecode offset. 1500 * 1501 * @param type the internal name to be added to the type table. 1502 * @param offset the bytecode offset of the NEW instruction that created 1503 * this UNINITIALIZED type value. 1504 * @return the index of this internal name in the type table. 1505 */ addUninitializedType(final String type, final int offset)1506 int addUninitializedType(final String type, final int offset) { 1507 key.type = TYPE_UNINIT; 1508 key.intVal = offset; 1509 key.strVal1 = type; 1510 key.hashCode = 0x7FFFFFFF & (TYPE_UNINIT + type.hashCode() + offset); 1511 Item result = get(key); 1512 if (result == null) { 1513 result = addType(key); 1514 } 1515 return result.index; 1516 } 1517 1518 /** 1519 * Adds the given Item to {@link #typeTable}. 1520 * 1521 * @param item the value to be added to the type table. 1522 * @return the added Item, which a new Item instance with the same value as 1523 * the given Item. 1524 */ addType(final Item item)1525 private Item addType(final Item item) { 1526 ++typeCount; 1527 Item result = new Item(typeCount, key); 1528 put(result); 1529 if (typeTable == null) { 1530 typeTable = new Item[16]; 1531 } 1532 if (typeCount == typeTable.length) { 1533 Item[] newTable = new Item[2 * typeTable.length]; 1534 System.arraycopy(typeTable, 0, newTable, 0, typeTable.length); 1535 typeTable = newTable; 1536 } 1537 typeTable[typeCount] = result; 1538 return result; 1539 } 1540 1541 /** 1542 * Returns the index of the common super type of the two given types. This 1543 * method calls {@link #getCommonSuperClass} and caches the result in the 1544 * {@link #items} hash table to speedup future calls with the same 1545 * parameters. 1546 * 1547 * @param type1 index of an internal name in {@link #typeTable}. 1548 * @param type2 index of an internal name in {@link #typeTable}. 1549 * @return the index of the common super type of the two given types. 1550 */ getMergedType(final int type1, final int type2)1551 int getMergedType(final int type1, final int type2) { 1552 key2.type = TYPE_MERGED; 1553 key2.longVal = type1 | (((long) type2) << 32); 1554 key2.hashCode = 0x7FFFFFFF & (TYPE_MERGED + type1 + type2); 1555 Item result = get(key2); 1556 if (result == null) { 1557 String t = typeTable[type1].strVal1; 1558 String u = typeTable[type2].strVal1; 1559 key2.intVal = addType(getCommonSuperClass(t, u)); 1560 result = new Item((short) 0, key2); 1561 put(result); 1562 } 1563 return result.intVal; 1564 } 1565 1566 /** 1567 * Returns the common super type of the two given types. The default 1568 * implementation of this method <i>loads<i> the two given classes and uses 1569 * the java.lang.Class methods to find the common super class. It can be 1570 * overridden to compute this common super type in other ways, in particular 1571 * without actually loading any class, or to take into account the class 1572 * that is currently being generated by this ClassWriter, which can of 1573 * course not be loaded since it is under construction. 1574 * 1575 * @param type1 the internal name of a class. 1576 * @param type2 the internal name of another class. 1577 * @return the internal name of the common super class of the two given 1578 * classes. 1579 */ getCommonSuperClass(final String type1, final String type2)1580 protected String getCommonSuperClass(final String type1, final String type2) 1581 { 1582 Class<?> c, d; 1583 ClassLoader classLoader = getClass().getClassLoader(); 1584 try { 1585 c = Class.forName(type1.replace('/', '.'), false, classLoader); 1586 d = Class.forName(type2.replace('/', '.'), false, classLoader); 1587 } catch (Exception e) { 1588 throw new RuntimeException(e.toString()); 1589 } 1590 if (c.isAssignableFrom(d)) { 1591 return type1; 1592 } 1593 if (d.isAssignableFrom(c)) { 1594 return type2; 1595 } 1596 if (c.isInterface() || d.isInterface()) { 1597 return "java/lang/Object"; 1598 } else { 1599 do { 1600 c = c.getSuperclass(); 1601 } while (!c.isAssignableFrom(d)); 1602 return c.getName().replace('.', '/'); 1603 } 1604 } 1605 1606 /** 1607 * Returns the constant pool's hash table item which is equal to the given 1608 * item. 1609 * 1610 * @param key a constant pool item. 1611 * @return the constant pool's hash table item which is equal to the given 1612 * item, or <tt>null</tt> if there is no such item. 1613 */ get(final Item key)1614 private Item get(final Item key) { 1615 Item i = items[key.hashCode % items.length]; 1616 while (i != null && (i.type != key.type || !key.isEqualTo(i))) { 1617 i = i.next; 1618 } 1619 return i; 1620 } 1621 1622 /** 1623 * Puts the given item in the constant pool's hash table. The hash table 1624 * <i>must</i> not already contains this item. 1625 * 1626 * @param i the item to be added to the constant pool's hash table. 1627 */ put(final Item i)1628 private void put(final Item i) { 1629 if (index + typeCount > threshold) { 1630 int ll = items.length; 1631 int nl = ll * 2 + 1; 1632 Item[] newItems = new Item[nl]; 1633 for (int l = ll - 1; l >= 0; --l) { 1634 Item j = items[l]; 1635 while (j != null) { 1636 int index = j.hashCode % newItems.length; 1637 Item k = j.next; 1638 j.next = newItems[index]; 1639 newItems[index] = j; 1640 j = k; 1641 } 1642 } 1643 items = newItems; 1644 threshold = (int) (nl * 0.75); 1645 } 1646 int index = i.hashCode % items.length; 1647 i.next = items[index]; 1648 items[index] = i; 1649 } 1650 1651 /** 1652 * Puts one byte and two shorts into the constant pool. 1653 * 1654 * @param b a byte. 1655 * @param s1 a short. 1656 * @param s2 another short. 1657 */ put122(final int b, final int s1, final int s2)1658 private void put122(final int b, final int s1, final int s2) { 1659 pool.put12(b, s1).putShort(s2); 1660 } 1661 1662 /** 1663 * Puts two bytes and one short into the constant pool. 1664 * 1665 * @param b1 a byte. 1666 * @param b2 another byte. 1667 * @param s a short. 1668 */ put112(final int b1, final int b2, final int s)1669 private void put112(final int b1, final int b2, final int s) { 1670 pool.put11(b1, b2).putShort(s); 1671 } 1672 } 1673