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