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