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 */ 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 */ 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 */ 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 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 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 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 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 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 687 public void visitAttribute(final Attribute attr) { 688 attr.next = attrs; 689 attrs = attr; 690 } 691 692 @Override 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 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 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 1503 private void put122(final int b, final int s1, final int s2) { 1504 pool.put12(b, s1).putShort(s2); 1505 } 1506 } 1507