001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 */ 018package org.apache.bcel.generic; 019 020import java.util.HashMap; 021import java.util.Map; 022 023import org.apache.bcel.Const; 024import org.apache.bcel.classfile.Constant; 025import org.apache.bcel.classfile.ConstantCP; 026import org.apache.bcel.classfile.ConstantClass; 027import org.apache.bcel.classfile.ConstantDouble; 028import org.apache.bcel.classfile.ConstantFieldref; 029import org.apache.bcel.classfile.ConstantFloat; 030import org.apache.bcel.classfile.ConstantInteger; 031import org.apache.bcel.classfile.ConstantInterfaceMethodref; 032import org.apache.bcel.classfile.ConstantInvokeDynamic; 033import org.apache.bcel.classfile.ConstantLong; 034import org.apache.bcel.classfile.ConstantMethodref; 035import org.apache.bcel.classfile.ConstantNameAndType; 036import org.apache.bcel.classfile.ConstantPool; 037import org.apache.bcel.classfile.ConstantString; 038import org.apache.bcel.classfile.ConstantUtf8; 039 040/** 041 * This class is used to build up a constant pool. The user adds 042 * constants via `addXXX' methods, `addString', `addClass', 043 * etc.. These methods return an index into the constant 044 * pool. Finally, `getFinalConstantPool()' returns the constant pool 045 * built up. Intermediate versions of the constant pool can be 046 * obtained with `getConstantPool()'. A constant pool has capacity for 047 * Constants.MAX_SHORT entries. Note that the first (0) is used by the 048 * JVM and that Double and Long constants need two slots. 049 * 050 * @see Constant 051 */ 052public class ConstantPoolGen { 053 054 private static final int DEFAULT_BUFFER_SIZE = 256; 055 056 /** 057 * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter 058 */ 059 @Deprecated 060 protected int size; 061 062 /** 063 * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter 064 */ 065 @Deprecated 066 protected Constant[] constants; 067 068 /** 069 * @deprecated (since 6.0) will be made private; do not access directly, use getSize() 070 */ 071 @Deprecated 072 protected int index = 1; // First entry (0) used by JVM 073 074 private static final String METHODREF_DELIM = ":"; 075 private static final String IMETHODREF_DELIM = "#"; 076 private static final String FIELDREF_DELIM = "&"; 077 private static final String NAT_DELIM = "%"; // Name and Type 078 079 private static class Index { 080 081 final int index; 082 083 084 Index(final int i) { 085 index = i; 086 } 087 } 088 089 090 /** 091 * Initialize with given array of constants. 092 * 093 * @param cs array of given constants, new ones will be appended 094 */ 095 public ConstantPoolGen(final Constant[] cs) { 096 final StringBuilder sb = new StringBuilder(DEFAULT_BUFFER_SIZE); 097 098 size = Math.min(Math.max(DEFAULT_BUFFER_SIZE, cs.length + 64), Const.MAX_CP_ENTRIES + 1); 099 constants = new Constant[size]; 100 101 System.arraycopy(cs, 0, constants, 0, cs.length); 102 if (cs.length > 0) { 103 index = cs.length; 104 } 105 106 107 for (int i = 1; i < index; i++) { 108 final Constant c = constants[i]; 109 if (c instanceof ConstantString) { 110 final ConstantString s = (ConstantString) c; 111 final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; 112 final String key = u8.getBytes(); 113 if (!stringTable.containsKey(key)) { 114 stringTable.put(key, new Index(i)); 115 } 116 } else if (c instanceof ConstantClass) { 117 final ConstantClass s = (ConstantClass) c; 118 final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; 119 final String key = u8.getBytes(); 120 if (!classTable.containsKey(key)) { 121 classTable.put(key, new Index(i)); 122 } 123 } else if (c instanceof ConstantNameAndType) { 124 final ConstantNameAndType n = (ConstantNameAndType) c; 125 final ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; 126 final ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; 127 128 sb.append(u8.getBytes()); 129 sb.append(NAT_DELIM); 130 sb.append(u8_2.getBytes()); 131 final String key = sb.toString(); 132 sb.delete(0, sb.length()); 133 134 if (!natTable.containsKey(key)) { 135 natTable.put(key, new Index(i)); 136 } 137 } else if (c instanceof ConstantUtf8) { 138 final ConstantUtf8 u = (ConstantUtf8) c; 139 final String key = u.getBytes(); 140 if (!utf8Table.containsKey(key)) { 141 utf8Table.put(key, new Index(i)); 142 } 143 } else if (c instanceof ConstantCP) { 144 final ConstantCP m = (ConstantCP) c; 145 String class_name; 146 ConstantUtf8 u8; 147 148 if (c instanceof ConstantInvokeDynamic) { 149 class_name = Integer.toString(((ConstantInvokeDynamic) m).getBootstrapMethodAttrIndex()); 150 // since name can't begin with digit, can use 151 // METHODREF_DELIM with out fear of duplicates. 152 } else { 153 final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; 154 u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; 155 class_name = u8.getBytes().replace('/', '.'); 156 } 157 158 final ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()]; 159 u8 = (ConstantUtf8) constants[n.getNameIndex()]; 160 final String method_name = u8.getBytes(); 161 u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; 162 final String signature = u8.getBytes(); 163 164 String delim = METHODREF_DELIM; 165 if (c instanceof ConstantInterfaceMethodref) { 166 delim = IMETHODREF_DELIM; 167 } else if (c instanceof ConstantFieldref) { 168 delim = FIELDREF_DELIM; 169 } 170 171 sb.append(class_name); 172 sb.append(delim); 173 sb.append(method_name); 174 sb.append(delim); 175 sb.append(signature); 176 final String key = sb.toString(); 177 sb.delete(0, sb.length()); 178 179 if (!cpTable.containsKey(key)) { 180 cpTable.put(key, new Index(i)); 181 } 182 } else if (c == null) { // entries may be null 183 // nothing to do 184 } else if (c instanceof ConstantInteger) { 185 // nothing to do 186 } else if (c instanceof ConstantLong) { 187 // nothing to do 188 } else if (c instanceof ConstantFloat) { 189 // nothing to do 190 } else if (c instanceof ConstantDouble) { 191 // nothing to do 192 } else if (c instanceof org.apache.bcel.classfile.ConstantMethodType) { 193 // TODO should this be handled somehow? 194 } else if (c instanceof org.apache.bcel.classfile.ConstantMethodHandle) { 195 // TODO should this be handled somehow? 196 } else if (c instanceof org.apache.bcel.classfile.ConstantModule) { 197 // TODO should this be handled somehow? 198 } else if (c instanceof org.apache.bcel.classfile.ConstantPackage) { 199 // TODO should this be handled somehow? 200 } else { 201 assert false : "Unexpected constant type: " + c.getClass().getName(); 202 } 203 } 204 } 205 206 207 /** 208 * Initialize with given constant pool. 209 */ 210 public ConstantPoolGen(final ConstantPool cp) { 211 this(cp.getConstantPool()); 212 } 213 214 215 /** 216 * Create empty constant pool. 217 */ 218 public ConstantPoolGen() { 219 size = DEFAULT_BUFFER_SIZE; 220 constants = new Constant[size]; 221 } 222 223 224 /** Resize internal array of constants. 225 */ 226 protected void adjustSize() { 227 // 3 extra spaces are needed as some entries may take 3 slots 228 if (index + 3 >= Const.MAX_CP_ENTRIES + 1) { 229 throw new IllegalStateException("The number of constants " + (index + 3) 230 + " is over the size of the constant pool: " 231 + Const.MAX_CP_ENTRIES); 232 } 233 234 if (index + 3 >= size) { 235 final Constant[] cs = constants; 236 size *= 2; 237 // the constant array shall not exceed the size of the constant pool 238 size = Math.min(size, Const.MAX_CP_ENTRIES + 1); 239 constants = new Constant[size]; 240 System.arraycopy(cs, 0, constants, 0, index); 241 } 242 } 243 244 private final Map<String, Index> stringTable = new HashMap<>(); 245 246 247 /** 248 * Look for ConstantString in ConstantPool containing String `str'. 249 * 250 * @param str String to search for 251 * @return index on success, -1 otherwise 252 */ 253 public int lookupString( final String str ) { 254 final Index index = stringTable.get(str); 255 return (index != null) ? index.index : -1; 256 } 257 258 259 /** 260 * Add a new String constant to the ConstantPool, if it is not already in there. 261 * 262 * @param str String to add 263 * @return index of entry 264 */ 265 public int addString( final String str ) { 266 int ret; 267 if ((ret = lookupString(str)) != -1) { 268 return ret; // Already in CP 269 } 270 final int utf8 = addUtf8(str); 271 adjustSize(); 272 final ConstantString s = new ConstantString(utf8); 273 ret = index; 274 constants[index++] = s; 275 if (!stringTable.containsKey(str)) { 276 stringTable.put(str, new Index(ret)); 277 } 278 return ret; 279 } 280 281 private final Map<String, Index> classTable = new HashMap<>(); 282 283 284 /** 285 * Look for ConstantClass in ConstantPool named `str'. 286 * 287 * @param str String to search for 288 * @return index on success, -1 otherwise 289 */ 290 public int lookupClass( final String str ) { 291 final Index index = classTable.get(str.replace('.', '/')); 292 return (index != null) ? index.index : -1; 293 } 294 295 296 private int addClass_( final String clazz ) { 297 int ret; 298 if ((ret = lookupClass(clazz)) != -1) { 299 return ret; // Already in CP 300 } 301 adjustSize(); 302 final ConstantClass c = new ConstantClass(addUtf8(clazz)); 303 ret = index; 304 constants[index++] = c; 305 if (!classTable.containsKey(clazz)) { 306 classTable.put(clazz, new Index(ret)); 307 } 308 return ret; 309 } 310 311 312 /** 313 * Add a new Class reference to the ConstantPool, if it is not already in there. 314 * 315 * @param str Class to add 316 * @return index of entry 317 */ 318 public int addClass( final String str ) { 319 return addClass_(str.replace('.', '/')); 320 } 321 322 323 /** 324 * Add a new Class reference to the ConstantPool for a given type. 325 * 326 * @param type Class to add 327 * @return index of entry 328 */ 329 public int addClass( final ObjectType type ) { 330 return addClass(type.getClassName()); 331 } 332 333 334 /** 335 * Add a reference to an array class (e.g. String[][]) as needed by MULTIANEWARRAY 336 * instruction, e.g. to the ConstantPool. 337 * 338 * @param type type of array class 339 * @return index of entry 340 */ 341 public int addArrayClass( final ArrayType type ) { 342 return addClass_(type.getSignature()); 343 } 344 345 346 /** 347 * Look for ConstantInteger in ConstantPool. 348 * 349 * @param n integer number to look for 350 * @return index on success, -1 otherwise 351 */ 352 public int lookupInteger( final int n ) { 353 for (int i = 1; i < index; i++) { 354 if (constants[i] instanceof ConstantInteger) { 355 final ConstantInteger c = (ConstantInteger) constants[i]; 356 if (c.getBytes() == n) { 357 return i; 358 } 359 } 360 } 361 return -1; 362 } 363 364 365 /** 366 * Add a new Integer constant to the ConstantPool, if it is not already in there. 367 * 368 * @param n integer number to add 369 * @return index of entry 370 */ 371 public int addInteger( final int n ) { 372 int ret; 373 if ((ret = lookupInteger(n)) != -1) { 374 return ret; // Already in CP 375 } 376 adjustSize(); 377 ret = index; 378 constants[index++] = new ConstantInteger(n); 379 return ret; 380 } 381 382 383 /** 384 * Look for ConstantFloat in ConstantPool. 385 * 386 * @param n Float number to look for 387 * @return index on success, -1 otherwise 388 */ 389 public int lookupFloat( final float n ) { 390 final int bits = Float.floatToIntBits(n); 391 for (int i = 1; i < index; i++) { 392 if (constants[i] instanceof ConstantFloat) { 393 final ConstantFloat c = (ConstantFloat) constants[i]; 394 if (Float.floatToIntBits(c.getBytes()) == bits) { 395 return i; 396 } 397 } 398 } 399 return -1; 400 } 401 402 403 /** 404 * Add a new Float constant to the ConstantPool, if it is not already in there. 405 * 406 * @param n Float number to add 407 * @return index of entry 408 */ 409 public int addFloat( final float n ) { 410 int ret; 411 if ((ret = lookupFloat(n)) != -1) { 412 return ret; // Already in CP 413 } 414 adjustSize(); 415 ret = index; 416 constants[index++] = new ConstantFloat(n); 417 return ret; 418 } 419 420 private final Map<String, Index> utf8Table = new HashMap<>(); 421 422 423 /** 424 * Look for ConstantUtf8 in ConstantPool. 425 * 426 * @param n Utf8 string to look for 427 * @return index on success, -1 otherwise 428 */ 429 public int lookupUtf8( final String n ) { 430 final Index index = utf8Table.get(n); 431 return (index != null) ? index.index : -1; 432 } 433 434 435 /** 436 * Add a new Utf8 constant to the ConstantPool, if it is not already in there. 437 * 438 * @param n Utf8 string to add 439 * @return index of entry 440 */ 441 public int addUtf8( final String n ) { 442 int ret; 443 if ((ret = lookupUtf8(n)) != -1) { 444 return ret; // Already in CP 445 } 446 adjustSize(); 447 ret = index; 448 constants[index++] = new ConstantUtf8(n); 449 if (!utf8Table.containsKey(n)) { 450 utf8Table.put(n, new Index(ret)); 451 } 452 return ret; 453 } 454 455 456 /** 457 * Look for ConstantLong in ConstantPool. 458 * 459 * @param n Long number to look for 460 * @return index on success, -1 otherwise 461 */ 462 public int lookupLong( final long n ) { 463 for (int i = 1; i < index; i++) { 464 if (constants[i] instanceof ConstantLong) { 465 final ConstantLong c = (ConstantLong) constants[i]; 466 if (c.getBytes() == n) { 467 return i; 468 } 469 } 470 } 471 return -1; 472 } 473 474 475 /** 476 * Add a new long constant to the ConstantPool, if it is not already in there. 477 * 478 * @param n Long number to add 479 * @return index of entry 480 */ 481 public int addLong( final long n ) { 482 int ret; 483 if ((ret = lookupLong(n)) != -1) { 484 return ret; // Already in CP 485 } 486 adjustSize(); 487 ret = index; 488 constants[index] = new ConstantLong(n); 489 index += 2; // Wastes one entry according to spec 490 return ret; 491 } 492 493 494 /** 495 * Look for ConstantDouble in ConstantPool. 496 * 497 * @param n Double number to look for 498 * @return index on success, -1 otherwise 499 */ 500 public int lookupDouble( final double n ) { 501 final long bits = Double.doubleToLongBits(n); 502 for (int i = 1; i < index; i++) { 503 if (constants[i] instanceof ConstantDouble) { 504 final ConstantDouble c = (ConstantDouble) constants[i]; 505 if (Double.doubleToLongBits(c.getBytes()) == bits) { 506 return i; 507 } 508 } 509 } 510 return -1; 511 } 512 513 514 /** 515 * Add a new double constant to the ConstantPool, if it is not already in there. 516 * 517 * @param n Double number to add 518 * @return index of entry 519 */ 520 public int addDouble( final double n ) { 521 int ret; 522 if ((ret = lookupDouble(n)) != -1) { 523 return ret; // Already in CP 524 } 525 adjustSize(); 526 ret = index; 527 constants[index] = new ConstantDouble(n); 528 index += 2; // Wastes one entry according to spec 529 return ret; 530 } 531 532 private final Map<String, Index> natTable = new HashMap<>(); 533 534 535 /** 536 * Look for ConstantNameAndType in ConstantPool. 537 * 538 * @param name of variable/method 539 * @param signature of variable/method 540 * @return index on success, -1 otherwise 541 */ 542 public int lookupNameAndType( final String name, final String signature ) { 543 final Index _index = natTable.get(name + NAT_DELIM + signature); 544 return (_index != null) ? _index.index : -1; 545 } 546 547 548 /** 549 * Add a new NameAndType constant to the ConstantPool if it is not already 550 * in there. 551 * 552 * @param name Name string to add 553 * @param signature signature string to add 554 * @return index of entry 555 */ 556 public int addNameAndType( final String name, final String signature ) { 557 int ret; 558 int name_index; 559 int signature_index; 560 if ((ret = lookupNameAndType(name, signature)) != -1) { 561 return ret; // Already in CP 562 } 563 adjustSize(); 564 name_index = addUtf8(name); 565 signature_index = addUtf8(signature); 566 ret = index; 567 constants[index++] = new ConstantNameAndType(name_index, signature_index); 568 final String key = name + NAT_DELIM + signature; 569 if (!natTable.containsKey(key)) { 570 natTable.put(key, new Index(ret)); 571 } 572 return ret; 573 } 574 575 private final Map<String, Index> cpTable = new HashMap<>(); 576 577 578 /** 579 * Look for ConstantMethodref in ConstantPool. 580 * 581 * @param class_name Where to find method 582 * @param method_name Guess what 583 * @param signature return and argument types 584 * @return index on success, -1 otherwise 585 */ 586 public int lookupMethodref( final String class_name, final String method_name, final String signature ) { 587 final Index index = cpTable.get(class_name + METHODREF_DELIM + method_name 588 + METHODREF_DELIM + signature); 589 return (index != null) ? index.index : -1; 590 } 591 592 593 public int lookupMethodref( final MethodGen method ) { 594 return lookupMethodref(method.getClassName(), method.getName(), method.getSignature()); 595 } 596 597 598 /** 599 * Add a new Methodref constant to the ConstantPool, if it is not already 600 * in there. 601 * 602 * @param class_name class name string to add 603 * @param method_name method name string to add 604 * @param signature method signature string to add 605 * @return index of entry 606 */ 607 public int addMethodref( final String class_name, final String method_name, final String signature ) { 608 int ret; 609 int class_index; 610 int name_and_type_index; 611 if ((ret = lookupMethodref(class_name, method_name, signature)) != -1) { 612 return ret; // Already in CP 613 } 614 adjustSize(); 615 name_and_type_index = addNameAndType(method_name, signature); 616 class_index = addClass(class_name); 617 ret = index; 618 constants[index++] = new ConstantMethodref(class_index, name_and_type_index); 619 final String key = class_name + METHODREF_DELIM + method_name + METHODREF_DELIM + signature; 620 if (!cpTable.containsKey(key)) { 621 cpTable.put(key, new Index(ret)); 622 } 623 return ret; 624 } 625 626 627 public int addMethodref( final MethodGen method ) { 628 return addMethodref(method.getClassName(), method.getName(), method.getSignature()); 629 } 630 631 632 /** 633 * Look for ConstantInterfaceMethodref in ConstantPool. 634 * 635 * @param class_name Where to find method 636 * @param method_name Guess what 637 * @param signature return and argument types 638 * @return index on success, -1 otherwise 639 */ 640 public int lookupInterfaceMethodref( final String class_name, final String method_name, final String signature ) { 641 final Index index = cpTable.get(class_name + IMETHODREF_DELIM + method_name 642 + IMETHODREF_DELIM + signature); 643 return (index != null) ? index.index : -1; 644 } 645 646 647 public int lookupInterfaceMethodref( final MethodGen method ) { 648 return lookupInterfaceMethodref(method.getClassName(), method.getName(), method 649 .getSignature()); 650 } 651 652 653 /** 654 * Add a new InterfaceMethodref constant to the ConstantPool, if it is not already 655 * in there. 656 * 657 * @param class_name class name string to add 658 * @param method_name method name string to add 659 * @param signature signature string to add 660 * @return index of entry 661 */ 662 public int addInterfaceMethodref( final String class_name, final String method_name, final String signature ) { 663 int ret; 664 int class_index; 665 int name_and_type_index; 666 if ((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1) { 667 return ret; // Already in CP 668 } 669 adjustSize(); 670 class_index = addClass(class_name); 671 name_and_type_index = addNameAndType(method_name, signature); 672 ret = index; 673 constants[index++] = new ConstantInterfaceMethodref(class_index, name_and_type_index); 674 final String key = class_name + IMETHODREF_DELIM + method_name + IMETHODREF_DELIM + signature; 675 if (!cpTable.containsKey(key)) { 676 cpTable.put(key, new Index(ret)); 677 } 678 return ret; 679 } 680 681 682 public int addInterfaceMethodref( final MethodGen method ) { 683 return addInterfaceMethodref(method.getClassName(), method.getName(), method.getSignature()); 684 } 685 686 687 /** 688 * Look for ConstantFieldref in ConstantPool. 689 * 690 * @param class_name Where to find method 691 * @param field_name Guess what 692 * @param signature return and argument types 693 * @return index on success, -1 otherwise 694 */ 695 public int lookupFieldref( final String class_name, final String field_name, final String signature ) { 696 final Index index = cpTable.get(class_name + FIELDREF_DELIM + field_name 697 + FIELDREF_DELIM + signature); 698 return (index != null) ? index.index : -1; 699 } 700 701 702 /** 703 * Add a new Fieldref constant to the ConstantPool, if it is not already 704 * in there. 705 * 706 * @param class_name class name string to add 707 * @param field_name field name string to add 708 * @param signature signature string to add 709 * @return index of entry 710 */ 711 public int addFieldref( final String class_name, final String field_name, final String signature ) { 712 int ret; 713 int class_index; 714 int name_and_type_index; 715 if ((ret = lookupFieldref(class_name, field_name, signature)) != -1) { 716 return ret; // Already in CP 717 } 718 adjustSize(); 719 class_index = addClass(class_name); 720 name_and_type_index = addNameAndType(field_name, signature); 721 ret = index; 722 constants[index++] = new ConstantFieldref(class_index, name_and_type_index); 723 final String key = class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature; 724 if (!cpTable.containsKey(key)) { 725 cpTable.put(key, new Index(ret)); 726 } 727 return ret; 728 } 729 730 731 /** 732 * @param i index in constant pool 733 * @return constant pool entry at index i 734 */ 735 public Constant getConstant( final int i ) { 736 return constants[i]; 737 } 738 739 740 /** 741 * Use with care! 742 * 743 * @param i index in constant pool 744 * @param c new constant pool entry at index i 745 */ 746 public void setConstant( final int i, final Constant c ) { 747 constants[i] = c; 748 } 749 750 751 /** 752 * @return intermediate constant pool 753 */ 754 public ConstantPool getConstantPool() { 755 return new ConstantPool(constants); 756 } 757 758 759 /** 760 * @return current size of constant pool 761 */ 762 public int getSize() { 763 return index; 764 } 765 766 767 /** 768 * @return constant pool with proper length 769 */ 770 public ConstantPool getFinalConstantPool() { 771 final Constant[] cs = new Constant[index]; 772 System.arraycopy(constants, 0, cs, 0, index); 773 return new ConstantPool(cs); 774 } 775 776 777 /** 778 * @return String representation. 779 */ 780 @Override 781 public String toString() { 782 final StringBuilder buf = new StringBuilder(); 783 for (int i = 1; i < index; i++) { 784 buf.append(i).append(")").append(constants[i]).append("\n"); 785 } 786 return buf.toString(); 787 } 788 789 790 /** Import constant from another ConstantPool and return new index. 791 */ 792 public int addConstant( final Constant c, final ConstantPoolGen cp ) { 793 final Constant[] constants = cp.getConstantPool().getConstantPool(); 794 switch (c.getTag()) { 795 case Const.CONSTANT_String: { 796 final ConstantString s = (ConstantString) c; 797 final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; 798 return addString(u8.getBytes()); 799 } 800 case Const.CONSTANT_Class: { 801 final ConstantClass s = (ConstantClass) c; 802 final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; 803 return addClass(u8.getBytes()); 804 } 805 case Const.CONSTANT_NameAndType: { 806 final ConstantNameAndType n = (ConstantNameAndType) c; 807 final ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; 808 final ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; 809 return addNameAndType(u8.getBytes(), u8_2.getBytes()); 810 } 811 case Const.CONSTANT_Utf8: 812 return addUtf8(((ConstantUtf8) c).getBytes()); 813 case Const.CONSTANT_Double: 814 return addDouble(((ConstantDouble) c).getBytes()); 815 case Const.CONSTANT_Float: 816 return addFloat(((ConstantFloat) c).getBytes()); 817 case Const.CONSTANT_Long: 818 return addLong(((ConstantLong) c).getBytes()); 819 case Const.CONSTANT_Integer: 820 return addInteger(((ConstantInteger) c).getBytes()); 821 case Const.CONSTANT_InterfaceMethodref: 822 case Const.CONSTANT_Methodref: 823 case Const.CONSTANT_Fieldref: { 824 final ConstantCP m = (ConstantCP) c; 825 final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; 826 final ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()]; 827 ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; 828 final String class_name = u8.getBytes().replace('/', '.'); 829 u8 = (ConstantUtf8) constants[n.getNameIndex()]; 830 final String name = u8.getBytes(); 831 u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; 832 final String signature = u8.getBytes(); 833 switch (c.getTag()) { 834 case Const.CONSTANT_InterfaceMethodref: 835 return addInterfaceMethodref(class_name, name, signature); 836 case Const.CONSTANT_Methodref: 837 return addMethodref(class_name, name, signature); 838 case Const.CONSTANT_Fieldref: 839 return addFieldref(class_name, name, signature); 840 default: // Never reached 841 throw new IllegalArgumentException("Unknown constant type " + c); 842 } 843 } 844 default: // Never reached 845 throw new IllegalArgumentException("Unknown constant type " + c); 846 } 847 } 848}