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 */ 30package com.sleepycat.asm; 31 32/** 33 * A {@link ClassVisitor} that generates classes in bytecode form. More 34 * precisely this visitor generates a byte array conforming to the Java class 35 * file format. It can be used alone, to generate a Java class "from scratch", 36 * or with one or more {@link ClassReader ClassReader} and adapter class visitor 37 * to generate a modified class from one or more existing Java classes. 38 * 39 * @author Eric Bruneton 40 */ 41public 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 byte[] TYPE; 132 133 /** 134 * The type of CONSTANT_Class constant pool items. 135 */ 136 final static int CLASS = 7; 137 138 /** 139 * The type of CONSTANT_Fieldref constant pool items. 140 */ 141 final static int FIELD = 9; 142 143 /** 144 * The type of CONSTANT_Methodref constant pool items. 145 */ 146 final static int METH = 10; 147 148 /** 149 * The type of CONSTANT_InterfaceMethodref constant pool items. 150 */ 151 final static int IMETH = 11; 152 153 /** 154 * The type of CONSTANT_String constant pool items. 155 */ 156 final static int STR = 8; 157 158 /** 159 * The type of CONSTANT_Integer constant pool items. 160 */ 161 final static int INT = 3; 162 163 /** 164 * The type of CONSTANT_Float constant pool items. 165 */ 166 final static int FLOAT = 4; 167 168 /** 169 * The type of CONSTANT_Long constant pool items. 170 */ 171 final static int LONG = 5; 172 173 /** 174 * The type of CONSTANT_Double constant pool items. 175 */ 176 final static int DOUBLE = 6; 177 178 /** 179 * The type of CONSTANT_NameAndType constant pool items. 180 */ 181 final static int NAME_TYPE = 12; 182 183 /** 184 * The type of CONSTANT_Utf8 constant pool items. 185 */ 186 final static int UTF8 = 1; 187 188 /** 189 * The class reader from which this class writer was constructed, if any. 190 */ 191 ClassReader cr; 192 193 /** 194 * Minor and major version numbers of the class to be generated. 195 */ 196 int version; 197 198 /** 199 * Index of the next item to be added in the constant pool. 200 */ 201 int index; 202 203 /** 204 * The constant pool of this class. 205 */ 206 ByteVector pool; 207 208 /** 209 * The constant pool's hash table data. 210 */ 211 Item[] items; 212 213 /** 214 * The threshold of the constant pool's hash table. 215 */ 216 int threshold; 217 218 /** 219 * A reusable key used to look for items in the hash {@link #items items}. 220 */ 221 Item key; 222 223 /** 224 * A reusable key used to look for items in the hash {@link #items items}. 225 */ 226 Item key2; 227 228 /** 229 * A reusable key used to look for items in the hash {@link #items items}. 230 */ 231 Item key3; 232 233 /** 234 * The access flags of this class. 235 */ 236 private int access; 237 238 /** 239 * The constant pool item that contains the internal name of this class. 240 */ 241 private int name; 242 243 /** 244 * The constant pool item that contains the signature of this class. 245 */ 246 private int signature; 247 248 /** 249 * The constant pool item that contains the internal name of the super class 250 * of this class. 251 */ 252 private int superName; 253 254 /** 255 * Number of interfaces implemented or extended by this class or interface. 256 */ 257 private int interfaceCount; 258 259 /** 260 * The interfaces implemented or extended by this class or interface. More 261 * precisely, this array contains the indexes of the constant pool items 262 * that contain the internal names of these interfaces. 263 */ 264 private int[] interfaces; 265 266 /** 267 * The index of the constant pool item that contains the name of the source 268 * file from which this class was compiled. 269 */ 270 private int sourceFile; 271 272 /** 273 * The SourceDebug attribute of this class. 274 */ 275 private ByteVector sourceDebug; 276 277 /** 278 * The constant pool item that contains the name of the enclosing class of 279 * this class. 280 */ 281 private int enclosingMethodOwner; 282 283 /** 284 * The constant pool item that contains the name and descriptor of the 285 * enclosing method of this class. 286 */ 287 private int enclosingMethod; 288 289 /** 290 * The runtime visible annotations of this class. 291 */ 292 private AnnotationWriter anns; 293 294 /** 295 * The runtime invisible annotations of this class. 296 */ 297 private AnnotationWriter ianns; 298 299 /** 300 * The non standard attributes of this class. 301 */ 302 private Attribute attrs; 303 304 /** 305 * The number of entries in the InnerClasses attribute. 306 */ 307 private int innerClassesCount; 308 309 /** 310 * The InnerClasses attribute. 311 */ 312 private ByteVector innerClasses; 313 314 /** 315 * The fields of this class. These fields are stored in a linked list of 316 * {@link FieldWriter} objects, linked to each other by their 317 * {@link FieldWriter#next} field. This field stores the first element of 318 * this list. 319 */ 320 FieldWriter firstField; 321 322 /** 323 * The fields of this class. These fields are stored in a linked list of 324 * {@link FieldWriter} objects, linked to each other by their 325 * {@link FieldWriter#next} field. This field stores the last element of 326 * this list. 327 */ 328 FieldWriter lastField; 329 330 /** 331 * The methods of this class. These methods are stored in a linked list of 332 * {@link MethodWriter} objects, linked to each other by their 333 * {@link MethodWriter#next} field. This field stores the first element of 334 * this list. 335 */ 336 MethodWriter firstMethod; 337 338 /** 339 * The methods of this class. These methods are stored in a linked list of 340 * {@link MethodWriter} objects, linked to each other by their 341 * {@link MethodWriter#next} field. This field stores the last element of 342 * this list. 343 */ 344 MethodWriter lastMethod; 345 346 /** 347 * <tt>true</tt> if the maximum stack size and number of local variables 348 * must be automatically computed. 349 */ 350 private boolean computeMaxs; 351 352 // ------------------------------------------------------------------------ 353 // Static initializer 354 // ------------------------------------------------------------------------ 355 356 /** 357 * Computes the instruction types of JVM opcodes. 358 */ 359 static { 360 int i; 361 byte[] b = new byte[220]; 362 String s = "AAAAAAAAAAAAAAAABCKLLDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD" 363 + "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 364 + "AAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAIIIIIIIIIIIIIIIIDNOAA" 365 + "AAAAGGGGGGGHAFBFAAFFAAQPIIJJIIIIIIIIIIIIIIIIII"; 366 for (i = 0; i < b.length; ++i) { 367 b[i] = (byte) (s.charAt(i) - 'A'); 368 } 369 TYPE = b; 370 371 // code to generate the above string 372 // 373 // // SBYTE_INSN instructions 374 // b[Constants.NEWARRAY] = SBYTE_INSN; 375 // b[Constants.BIPUSH] = SBYTE_INSN; 376 // 377 // // SHORT_INSN instructions 378 // b[Constants.SIPUSH] = SHORT_INSN; 379 // 380 // // (IMPL)VAR_INSN instructions 381 // b[Constants.RET] = VAR_INSN; 382 // for (i = Constants.ILOAD; i <= Constants.ALOAD; ++i) { 383 // b[i] = VAR_INSN; 384 // } 385 // for (i = Constants.ISTORE; i <= Constants.ASTORE; ++i) { 386 // b[i] = VAR_INSN; 387 // } 388 // for (i = 26; i <= 45; ++i) { // ILOAD_0 to ALOAD_3 389 // b[i] = IMPLVAR_INSN; 390 // } 391 // for (i = 59; i <= 78; ++i) { // ISTORE_0 to ASTORE_3 392 // b[i] = IMPLVAR_INSN; 393 // } 394 // 395 // // TYPE_INSN instructions 396 // b[Constants.NEW] = TYPE_INSN; 397 // b[Constants.ANEWARRAY] = TYPE_INSN; 398 // b[Constants.CHECKCAST] = TYPE_INSN; 399 // b[Constants.INSTANCEOF] = TYPE_INSN; 400 // 401 // // (Set)FIELDORMETH_INSN instructions 402 // for (i = Constants.GETSTATIC; i <= Constants.INVOKESTATIC; ++i) { 403 // b[i] = FIELDORMETH_INSN; 404 // } 405 // b[Constants.INVOKEINTERFACE] = ITFMETH_INSN; 406 // 407 // // LABEL(W)_INSN instructions 408 // for (i = Constants.IFEQ; i <= Constants.JSR; ++i) { 409 // b[i] = LABEL_INSN; 410 // } 411 // b[Constants.IFNULL] = LABEL_INSN; 412 // b[Constants.IFNONNULL] = LABEL_INSN; 413 // b[200] = LABELW_INSN; // GOTO_W 414 // b[201] = LABELW_INSN; // JSR_W 415 // // temporary opcodes used internally by ASM - see Label and 416 // MethodWriter 417 // for (i = 202; i < 220; ++i) { 418 // b[i] = LABEL_INSN; 419 // } 420 // 421 // // LDC(_W) instructions 422 // b[Constants.LDC] = LDC_INSN; 423 // b[19] = LDCW_INSN; // LDC_W 424 // b[20] = LDCW_INSN; // LDC2_W 425 // 426 // // special instructions 427 // b[Constants.IINC] = IINC_INSN; 428 // b[Constants.TABLESWITCH] = TABL_INSN; 429 // b[Constants.LOOKUPSWITCH] = LOOK_INSN; 430 // b[Constants.MULTIANEWARRAY] = MANA_INSN; 431 // b[196] = WIDE_INSN; // WIDE 432 // 433 // for (i = 0; i < b.length; ++i) { 434 // System.err.print((char)('A' + b[i])); 435 // } 436 // System.err.println(); 437 } 438 439 // ------------------------------------------------------------------------ 440 // Constructor 441 // ------------------------------------------------------------------------ 442 443 /** 444 * Constructs a new {@link ClassWriter ClassWriter} object. 445 * 446 * @param computeMaxs <tt>true</tt> if the maximum stack size and the 447 * maximum number of local variables must be automatically computed. 448 * If this flag is <tt>true</tt>, then the arguments of the 449 * {@link MethodVisitor#visitMaxs visitMaxs} method of the 450 * {@link MethodVisitor} returned by the 451 * {@link #visitMethod visitMethod} method will be ignored, and 452 * computed automatically from the signature and the bytecode of each 453 * method. 454 */ 455 public ClassWriter(final boolean computeMaxs) { 456 this(computeMaxs, false); 457 } 458 459 /** 460 * Constructs a new {@link ClassWriter} object. 461 * 462 * @param computeMaxs <tt>true</tt> if the maximum stack size and the 463 * maximum number of local variables must be automatically computed. 464 * If this flag is <tt>true</tt>, then the arguments of the 465 * {@link MethodVisitor#visitMaxs visitMaxs} method of the 466 * {@link MethodVisitor} returned by the 467 * {@link #visitMethod visitMethod} method will be ignored, and 468 * computed automatically from the signature and the bytecode of each 469 * method. 470 * @param skipUnknownAttributes <b>Deprecated</b>. The value of this 471 * parameter is ignored. 472 */ 473 public ClassWriter( 474 final boolean computeMaxs, 475 final boolean skipUnknownAttributes) 476 { 477 index = 1; 478 pool = new ByteVector(); 479 items = new Item[256]; 480 threshold = (int) (0.75d * items.length); 481 key = new Item(); 482 key2 = new Item(); 483 key3 = new Item(); 484 this.computeMaxs = computeMaxs; 485 } 486 487 /** 488 * Constructs a new {@link ClassWriter} object and enables optimizations for 489 * "mostly add" bytecode transformations. These optimizations are the 490 * following: 491 * 492 * <ul> <li>The constant pool from the original class is copied as is in 493 * the new class, which saves time. New constant pool entries will be added 494 * at the end if necessary, but unused constant pool entries <i>won't be 495 * removed</i>.</li> <li>Methods that are not transformed are copied as 496 * is in the new class, directly from the original class bytecode (i.e. 497 * without emitting visit events for all the method instructions), which 498 * saves a <i>lot</i> of time. Untransformed methods are detected by the 499 * fact that the {@link ClassReader} receives {@link MethodVisitor} objects 500 * that come from a {@link ClassWriter} (and not from a custom 501 * {@link ClassAdapter} or any other {@link ClassVisitor} instance).</li> 502 * </ul> 503 * 504 * @param classReader the {@link ClassReader} used to read the original 505 * class. It will be used to copy the entire constant pool from the 506 * original class and also to copy other fragments of original 507 * bytecode where applicable. 508 * @param computeMaxs <tt>true</tt> if the maximum stack size and the 509 * maximum number of local variables must be automatically computed. 510 * If this flag is <tt>true</tt>, then the arguments of the 511 * {@link MethodVisitor#visitMaxs visitMaxs} method of the 512 * {@link MethodVisitor} returned by the 513 * {@link #visitMethod visitMethod} method will be ignored, and 514 * computed automatically from the signature and the bytecode of each 515 * method. 516 */ 517 public ClassWriter( 518 final ClassReader classReader, 519 final boolean computeMaxs) 520 { 521 this(computeMaxs, false); 522 classReader.copyPool(this); 523 this.cr = classReader; 524 } 525 526 // ------------------------------------------------------------------------ 527 // Implementation of the ClassVisitor interface 528 // ------------------------------------------------------------------------ 529 530 public void visit( 531 final int version, 532 final int access, 533 final String name, 534 final String signature, 535 final String superName, 536 final String[] interfaces) 537 { 538 this.version = version; 539 this.access = access; 540 this.name = newClass(name); 541 if (signature != null) { 542 this.signature = newUTF8(signature); 543 } 544 this.superName = superName == null ? 0 : newClass(superName); 545 if (interfaces != null && interfaces.length > 0) { 546 interfaceCount = interfaces.length; 547 this.interfaces = new int[interfaceCount]; 548 for (int i = 0; i < interfaceCount; ++i) { 549 this.interfaces[i] = newClass(interfaces[i]); 550 } 551 } 552 } 553 554 public void visitSource(final String file, final String debug) { 555 if (file != null) { 556 sourceFile = newUTF8(file); 557 } 558 if (debug != null) { 559 sourceDebug = new ByteVector().putUTF8(debug); 560 } 561 } 562 563 public void visitOuterClass( 564 final String owner, 565 final String name, 566 final String desc) 567 { 568 enclosingMethodOwner = newClass(owner); 569 if (name != null && desc != null) { 570 enclosingMethod = newNameType(name, desc); 571 } 572 } 573 574 public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 575 ByteVector bv = new ByteVector(); 576 // write type, and reserve space for values count 577 bv.putShort(newUTF8(desc)).putShort(0); 578 AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv, 2); 579 if (visible) { 580 aw.next = anns; 581 anns = aw; 582 } else { 583 aw.next = ianns; 584 ianns = aw; 585 } 586 return aw; 587 } 588 589 public void visitAttribute(final Attribute attr) { 590 attr.next = attrs; 591 attrs = attr; 592 } 593 594 public void visitInnerClass( 595 final String name, 596 final String outerName, 597 final String innerName, 598 final int access) 599 { 600 if (innerClasses == null) { 601 innerClasses = new ByteVector(); 602 } 603 ++innerClassesCount; 604 innerClasses.putShort(name == null ? 0 : newClass(name)); 605 innerClasses.putShort(outerName == null ? 0 : newClass(outerName)); 606 innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName)); 607 innerClasses.putShort(access); 608 } 609 610 public FieldVisitor visitField( 611 final int access, 612 final String name, 613 final String desc, 614 final String signature, 615 final Object value) 616 { 617 return new FieldWriter(this, access, name, desc, signature, value); 618 } 619 620 public MethodVisitor visitMethod( 621 final int access, 622 final String name, 623 final String desc, 624 final String signature, 625 final String[] exceptions) 626 { 627 return new MethodWriter(this, 628 access, 629 name, 630 desc, 631 signature, 632 exceptions, 633 computeMaxs); 634 } 635 636 public void visitEnd() { 637 } 638 639 // ------------------------------------------------------------------------ 640 // Other public methods 641 // ------------------------------------------------------------------------ 642 643 /** 644 * Returns the bytecode of the class that was build with this class writer. 645 * 646 * @return the bytecode of the class that was build with this class writer. 647 */ 648 public byte[] toByteArray() { 649 // computes the real size of the bytecode of this class 650 int size = 24 + 2 * interfaceCount; 651 int nbFields = 0; 652 FieldWriter fb = firstField; 653 while (fb != null) { 654 ++nbFields; 655 size += fb.getSize(); 656 fb = fb.next; 657 } 658 int nbMethods = 0; 659 MethodWriter mb = firstMethod; 660 while (mb != null) { 661 ++nbMethods; 662 size += mb.getSize(); 663 mb = mb.next; 664 } 665 int attributeCount = 0; 666 if (signature != 0) { 667 ++attributeCount; 668 size += 8; 669 newUTF8("Signature"); 670 } 671 if (sourceFile != 0) { 672 ++attributeCount; 673 size += 8; 674 newUTF8("SourceFile"); 675 } 676 if (sourceDebug != null) { 677 ++attributeCount; 678 size += sourceDebug.length + 4; 679 newUTF8("SourceDebugExtension"); 680 } 681 if (enclosingMethodOwner != 0) { 682 ++attributeCount; 683 size += 10; 684 newUTF8("EnclosingMethod"); 685 } 686 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 687 ++attributeCount; 688 size += 6; 689 newUTF8("Deprecated"); 690 } 691 if ((access & Opcodes.ACC_SYNTHETIC) != 0 692 && (version & 0xffff) < Opcodes.V1_5) 693 { 694 ++attributeCount; 695 size += 6; 696 newUTF8("Synthetic"); 697 } 698 if (version == Opcodes.V1_4) { 699 if ((access & Opcodes.ACC_ANNOTATION) != 0) { 700 ++attributeCount; 701 size += 6; 702 newUTF8("Annotation"); 703 } 704 if ((access & Opcodes.ACC_ENUM) != 0) { 705 ++attributeCount; 706 size += 6; 707 newUTF8("Enum"); 708 } 709 } 710 if (innerClasses != null) { 711 ++attributeCount; 712 size += 8 + innerClasses.length; 713 newUTF8("InnerClasses"); 714 } 715 if (anns != null) { 716 ++attributeCount; 717 size += 8 + anns.getSize(); 718 newUTF8("RuntimeVisibleAnnotations"); 719 } 720 if (ianns != null) { 721 ++attributeCount; 722 size += 8 + ianns.getSize(); 723 newUTF8("RuntimeInvisibleAnnotations"); 724 } 725 if (attrs != null) { 726 attributeCount += attrs.getCount(); 727 size += attrs.getSize(this, null, 0, -1, -1); 728 } 729 size += pool.length; 730 // allocates a byte vector of this size, in order to avoid unnecessary 731 // arraycopy operations in the ByteVector.enlarge() method 732 ByteVector out = new ByteVector(size); 733 out.putInt(0xCAFEBABE).putInt(version); 734 out.putShort(index).putByteArray(pool.data, 0, pool.length); 735 out.putShort(access).putShort(name).putShort(superName); 736 out.putShort(interfaceCount); 737 for (int i = 0; i < interfaceCount; ++i) { 738 out.putShort(interfaces[i]); 739 } 740 out.putShort(nbFields); 741 fb = firstField; 742 while (fb != null) { 743 fb.put(out); 744 fb = fb.next; 745 } 746 out.putShort(nbMethods); 747 mb = firstMethod; 748 while (mb != null) { 749 mb.put(out); 750 mb = mb.next; 751 } 752 out.putShort(attributeCount); 753 if (signature != 0) { 754 out.putShort(newUTF8("Signature")).putInt(2).putShort(signature); 755 } 756 if (sourceFile != 0) { 757 out.putShort(newUTF8("SourceFile")).putInt(2).putShort(sourceFile); 758 } 759 if (sourceDebug != null) { 760 int len = sourceDebug.length - 2; 761 out.putShort(newUTF8("SourceDebugExtension")).putInt(len); 762 out.putByteArray(sourceDebug.data, 2, len); 763 } 764 if (enclosingMethodOwner != 0) { 765 out.putShort(newUTF8("EnclosingMethod")).putInt(4); 766 out.putShort(enclosingMethodOwner).putShort(enclosingMethod); 767 } 768 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 769 out.putShort(newUTF8("Deprecated")).putInt(0); 770 } 771 if ((access & Opcodes.ACC_SYNTHETIC) != 0 772 && (version & 0xffff) < Opcodes.V1_5) 773 { 774 out.putShort(newUTF8("Synthetic")).putInt(0); 775 } 776 if (version == Opcodes.V1_4) { 777 if ((access & Opcodes.ACC_ANNOTATION) != 0) { 778 out.putShort(newUTF8("Annotation")).putInt(0); 779 } 780 if ((access & Opcodes.ACC_ENUM) != 0) { 781 out.putShort(newUTF8("Enum")).putInt(0); 782 } 783 } 784 if (innerClasses != null) { 785 out.putShort(newUTF8("InnerClasses")); 786 out.putInt(innerClasses.length + 2).putShort(innerClassesCount); 787 out.putByteArray(innerClasses.data, 0, innerClasses.length); 788 } 789 if (anns != null) { 790 out.putShort(newUTF8("RuntimeVisibleAnnotations")); 791 anns.put(out); 792 } 793 if (ianns != null) { 794 out.putShort(newUTF8("RuntimeInvisibleAnnotations")); 795 ianns.put(out); 796 } 797 if (attrs != null) { 798 attrs.put(this, null, 0, -1, -1, out); 799 } 800 return out.data; 801 } 802 803 // ------------------------------------------------------------------------ 804 // Utility methods: constant pool management 805 // ------------------------------------------------------------------------ 806 807 /** 808 * Adds a number or string constant to the constant pool of the class being 809 * build. Does nothing if the constant pool already contains a similar item. 810 * 811 * @param cst the value of the constant to be added to the constant pool. 812 * This parameter must be an {@link Integer}, a {@link Float}, a 813 * {@link Long}, a {@link Double}, a {@link String} or a 814 * {@link Type}. 815 * @return a new or already existing constant item with the given value. 816 */ 817 Item newConstItem(final Object cst) { 818 if (cst instanceof Integer) { 819 int val = ((Integer) cst).intValue(); 820 return newInteger(val); 821 } else if (cst instanceof Byte) { 822 int val = ((Byte) cst).intValue(); 823 return newInteger(val); 824 } else if (cst instanceof Character) { 825 int val = ((Character) cst).charValue(); 826 return newInteger(val); 827 } else if (cst instanceof Short) { 828 int val = ((Short) cst).intValue(); 829 return newInteger(val); 830 } else if (cst instanceof Boolean) { 831 int val = ((Boolean) cst).booleanValue() ? 1 : 0; 832 return newInteger(val); 833 } else if (cst instanceof Float) { 834 float val = ((Float) cst).floatValue(); 835 return newFloat(val); 836 } else if (cst instanceof Long) { 837 long val = ((Long) cst).longValue(); 838 return newLong(val); 839 } else if (cst instanceof Double) { 840 double val = ((Double) cst).doubleValue(); 841 return newDouble(val); 842 } else if (cst instanceof String) { 843 return newString((String) cst); 844 } else if (cst instanceof Type) { 845 Type t = (Type) cst; 846 return newClassItem(t.getSort() == Type.OBJECT 847 ? t.getInternalName() 848 : t.getDescriptor()); 849 } else { 850 throw new IllegalArgumentException("value " + cst); 851 } 852 } 853 854 /** 855 * Adds a number or string constant to the constant pool of the class being 856 * build. Does nothing if the constant pool already contains a similar item. 857 * <i>This method is intended for {@link Attribute} sub classes, and is 858 * normally not needed by class generators or adapters.</i> 859 * 860 * @param cst the value of the constant to be added to the constant pool. 861 * This parameter must be an {@link Integer}, a {@link Float}, a 862 * {@link Long}, a {@link Double} or a {@link String}. 863 * @return the index of a new or already existing constant item with the 864 * given value. 865 */ 866 public int newConst(final Object cst) { 867 return newConstItem(cst).index; 868 } 869 870 /** 871 * Adds an UTF8 string to the constant pool of the class being build. Does 872 * nothing if the constant pool already contains a similar item. <i>This 873 * method is intended for {@link Attribute} sub classes, and is normally not 874 * needed by class generators or adapters.</i> 875 * 876 * @param value the String value. 877 * @return the index of a new or already existing UTF8 item. 878 */ 879 public int newUTF8(final String value) { 880 key.set(UTF8, value, null, null); 881 Item result = get(key); 882 if (result == null) { 883 pool.putByte(UTF8).putUTF8(value); 884 result = new Item(index++, key); 885 put(result); 886 } 887 return result.index; 888 } 889 890 /** 891 * Adds a class reference to the constant pool of the class being build. 892 * Does nothing if the constant pool already contains a similar item. 893 * <i>This method is intended for {@link Attribute} sub classes, and is 894 * normally not needed by class generators or adapters.</i> 895 * 896 * @param value the internal name of the class. 897 * @return the index of a new or already existing class reference item. 898 */ 899 public int newClass(final String value) { 900 return newClassItem(value).index; 901 } 902 903 /** 904 * Adds a class reference to the constant pool of the class being build. 905 * Does nothing if the constant pool already contains a similar item. 906 * <i>This method is intended for {@link Attribute} sub classes, and is 907 * normally not needed by class generators or adapters.</i> 908 * 909 * @param value the internal name of the class. 910 * @return a new or already existing class reference item. 911 */ 912 private Item newClassItem(final String value) { 913 key2.set(CLASS, value, null, null); 914 Item result = get(key2); 915 if (result == null) { 916 pool.put12(CLASS, newUTF8(value)); 917 result = new Item(index++, key2); 918 put(result); 919 } 920 return result; 921 } 922 923 /** 924 * Adds a field reference to the constant pool of the class being build. 925 * Does nothing if the constant pool already contains a similar item. 926 * <i>This method is intended for {@link Attribute} sub classes, and is 927 * normally not needed by class generators or adapters.</i> 928 * 929 * @param owner the internal name of the field's owner class. 930 * @param name the field's name. 931 * @param desc the field's descriptor. 932 * @return the index of a new or already existing field reference item. 933 */ 934 public int newField(final String owner, final String name, final String desc) 935 { 936 key3.set(FIELD, owner, name, desc); 937 Item result = get(key3); 938 if (result == null) { 939 put122(FIELD, newClass(owner), newNameType(name, desc)); 940 result = new Item(index++, key3); 941 put(result); 942 } 943 return result.index; 944 } 945 946 /** 947 * Adds a method reference to the constant pool of the class being build. 948 * Does nothing if the constant pool already contains a similar item. 949 * 950 * @param owner the internal name of the method's owner class. 951 * @param name the method's name. 952 * @param desc the method's descriptor. 953 * @param itf <tt>true</tt> if <tt>owner</tt> is an interface. 954 * @return a new or already existing method reference item. 955 */ 956 Item newMethodItem( 957 final String owner, 958 final String name, 959 final String desc, 960 final boolean itf) 961 { 962 int type = itf ? IMETH : METH; 963 key3.set(type, owner, name, desc); 964 Item result = get(key3); 965 if (result == null) { 966 put122(type, newClass(owner), newNameType(name, desc)); 967 result = new Item(index++, key3); 968 put(result); 969 } 970 return result; 971 } 972 973 /** 974 * Adds a method reference to the constant pool of the class being build. 975 * Does nothing if the constant pool already contains a similar item. 976 * <i>This method is intended for {@link Attribute} sub classes, and is 977 * normally not needed by class generators or adapters.</i> 978 * 979 * @param owner the internal name of the method's owner class. 980 * @param name the method's name. 981 * @param desc the method's descriptor. 982 * @param itf <tt>true</tt> if <tt>owner</tt> is an interface. 983 * @return the index of a new or already existing method reference item. 984 */ 985 public int newMethod( 986 final String owner, 987 final String name, 988 final String desc, 989 final boolean itf) 990 { 991 return newMethodItem(owner, name, desc, itf).index; 992 } 993 994 /** 995 * Adds an integer to the constant pool of the class being build. Does 996 * nothing if the constant pool already contains a similar item. 997 * 998 * @param value the int value. 999 * @return a new or already existing int item. 1000 */ 1001 Item newInteger(final int value) { 1002 key.set(value); 1003 Item result = get(key); 1004 if (result == null) { 1005 pool.putByte(INT).putInt(value); 1006 result = new Item(index++, key); 1007 put(result); 1008 } 1009 return result; 1010 } 1011 1012 /** 1013 * Adds a float to the constant pool of the class being build. Does nothing 1014 * if the constant pool already contains a similar item. 1015 * 1016 * @param value the float value. 1017 * @return a new or already existing float item. 1018 */ 1019 Item newFloat(final float value) { 1020 key.set(value); 1021 Item result = get(key); 1022 if (result == null) { 1023 pool.putByte(FLOAT).putInt(Float.floatToIntBits(value)); 1024 result = new Item(index++, key); 1025 put(result); 1026 } 1027 return result; 1028 } 1029 1030 /** 1031 * Adds a long to the constant pool of the class being build. Does nothing 1032 * if the constant pool already contains a similar item. 1033 * 1034 * @param value the long value. 1035 * @return a new or already existing long item. 1036 */ 1037 Item newLong(final long value) { 1038 key.set(value); 1039 Item result = get(key); 1040 if (result == null) { 1041 pool.putByte(LONG).putLong(value); 1042 result = new Item(index, key); 1043 put(result); 1044 index += 2; 1045 } 1046 return result; 1047 } 1048 1049 /** 1050 * Adds a double to the constant pool of the class being build. Does nothing 1051 * if the constant pool already contains a similar item. 1052 * 1053 * @param value the double value. 1054 * @return a new or already existing double item. 1055 */ 1056 Item newDouble(final double value) { 1057 key.set(value); 1058 Item result = get(key); 1059 if (result == null) { 1060 pool.putByte(DOUBLE).putLong(Double.doubleToLongBits(value)); 1061 result = new Item(index, key); 1062 put(result); 1063 index += 2; 1064 } 1065 return result; 1066 } 1067 1068 /** 1069 * Adds a string to the constant pool of the class being build. Does nothing 1070 * if the constant pool already contains a similar item. 1071 * 1072 * @param value the String value. 1073 * @return a new or already existing string item. 1074 */ 1075 private Item newString(final String value) { 1076 key2.set(STR, value, null, null); 1077 Item result = get(key2); 1078 if (result == null) { 1079 pool.put12(STR, newUTF8(value)); 1080 result = new Item(index++, key2); 1081 put(result); 1082 } 1083 return result; 1084 } 1085 1086 /** 1087 * Adds a name and type to the constant pool of the class being build. Does 1088 * nothing if the constant pool already contains a similar item. <i>This 1089 * method is intended for {@link Attribute} sub classes, and is normally not 1090 * needed by class generators or adapters.</i> 1091 * 1092 * @param name a name. 1093 * @param desc a type descriptor. 1094 * @return the index of a new or already existing name and type item. 1095 */ 1096 public int newNameType(final String name, final String desc) { 1097 key2.set(NAME_TYPE, name, desc, null); 1098 Item result = get(key2); 1099 if (result == null) { 1100 put122(NAME_TYPE, newUTF8(name), newUTF8(desc)); 1101 result = new Item(index++, key2); 1102 put(result); 1103 } 1104 return result.index; 1105 } 1106 1107 /** 1108 * Returns the constant pool's hash table item which is equal to the given 1109 * item. 1110 * 1111 * @param key a constant pool item. 1112 * @return the constant pool's hash table item which is equal to the given 1113 * item, or <tt>null</tt> if there is no such item. 1114 */ 1115 private Item get(final Item key) { 1116 Item i = items[key.hashCode % items.length]; 1117 while (i != null && !key.isEqualTo(i)) { 1118 i = i.next; 1119 } 1120 return i; 1121 } 1122 1123 /** 1124 * Puts the given item in the constant pool's hash table. The hash table 1125 * <i>must</i> not already contains this item. 1126 * 1127 * @param i the item to be added to the constant pool's hash table. 1128 */ 1129 private void put(final Item i) { 1130 if (index > threshold) { 1131 int ll = items.length; 1132 int nl = ll * 2 + 1; 1133 Item[] newItems = new Item[nl]; 1134 for (int l = ll - 1; l >= 0; --l) { 1135 Item j = items[l]; 1136 while (j != null) { 1137 int index = j.hashCode % newItems.length; 1138 Item k = j.next; 1139 j.next = newItems[index]; 1140 newItems[index] = j; 1141 j = k; 1142 } 1143 } 1144 items = newItems; 1145 threshold = (int) (nl * 0.75); 1146 } 1147 int index = i.hashCode % items.length; 1148 i.next = items[index]; 1149 items[index] = i; 1150 } 1151 1152 /** 1153 * Puts one byte and two shorts into the constant pool. 1154 * 1155 * @param b a byte. 1156 * @param s1 a short. 1157 * @param s2 another short. 1158 */ 1159 private void put122(final int b, final int s1, final int s2) { 1160 pool.put12(b, s1).putShort(s2); 1161 } 1162} 1163