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