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