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.max(DEFAULT_BUFFER_SIZE, cs.length + 64); 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 (!string_table.containsKey(key)) { 114 string_table.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 (!class_table.containsKey(key)) { 121 class_table.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 (!n_a_t_table.containsKey(key)) { 135 n_a_t_table.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 (!utf8_table.containsKey(key)) { 141 utf8_table.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 (!cp_table.containsKey(key)) { 180 cp_table.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 if (index + 3 >= size) { 228 final Constant[] cs = constants; 229 size *= 2; 230 constants = new Constant[size]; 231 System.arraycopy(cs, 0, constants, 0, index); 232 } 233 } 234 235 private final Map<String, Index> string_table = new HashMap<>(); 236 237 238 /** 239 * Look for ConstantString in ConstantPool containing String `str'. 240 * 241 * @param str String to search for 242 * @return index on success, -1 otherwise 243 */ 244 public int lookupString( final String str ) { 245 final Index index = string_table.get(str); 246 return (index != null) ? index.index : -1; 247 } 248 249 250 /** 251 * Add a new String constant to the ConstantPool, if it is not already in there. 252 * 253 * @param str String to add 254 * @return index of entry 255 */ 256 public int addString( final String str ) { 257 int ret; 258 if ((ret = lookupString(str)) != -1) { 259 return ret; // Already in CP 260 } 261 final int utf8 = addUtf8(str); 262 adjustSize(); 263 final ConstantString s = new ConstantString(utf8); 264 ret = index; 265 constants[index++] = s; 266 if (!string_table.containsKey(str)) { 267 string_table.put(str, new Index(ret)); 268 } 269 return ret; 270 } 271 272 private final Map<String, Index> class_table = new HashMap<>(); 273 274 275 /** 276 * Look for ConstantClass in ConstantPool named `str'. 277 * 278 * @param str String to search for 279 * @return index on success, -1 otherwise 280 */ 281 public int lookupClass( final String str ) { 282 final Index index = class_table.get(str.replace('.', '/')); 283 return (index != null) ? index.index : -1; 284 } 285 286 287 private int addClass_( final String clazz ) { 288 int ret; 289 if ((ret = lookupClass(clazz)) != -1) { 290 return ret; // Already in CP 291 } 292 adjustSize(); 293 final ConstantClass c = new ConstantClass(addUtf8(clazz)); 294 ret = index; 295 constants[index++] = c; 296 if (!class_table.containsKey(clazz)) { 297 class_table.put(clazz, new Index(ret)); 298 } 299 return ret; 300 } 301 302 303 /** 304 * Add a new Class reference to the ConstantPool, if it is not already in there. 305 * 306 * @param str Class to add 307 * @return index of entry 308 */ 309 public int addClass( final String str ) { 310 return addClass_(str.replace('.', '/')); 311 } 312 313 314 /** 315 * Add a new Class reference to the ConstantPool for a given type. 316 * 317 * @param type Class to add 318 * @return index of entry 319 */ 320 public int addClass( final ObjectType type ) { 321 return addClass(type.getClassName()); 322 } 323 324 325 /** 326 * Add a reference to an array class (e.g. String[][]) as needed by MULTIANEWARRAY 327 * instruction, e.g. to the ConstantPool. 328 * 329 * @param type type of array class 330 * @return index of entry 331 */ 332 public int addArrayClass( final ArrayType type ) { 333 return addClass_(type.getSignature()); 334 } 335 336 337 /** 338 * Look for ConstantInteger in ConstantPool. 339 * 340 * @param n integer number to look for 341 * @return index on success, -1 otherwise 342 */ 343 public int lookupInteger( final int n ) { 344 for (int i = 1; i < index; i++) { 345 if (constants[i] instanceof ConstantInteger) { 346 final ConstantInteger c = (ConstantInteger) constants[i]; 347 if (c.getBytes() == n) { 348 return i; 349 } 350 } 351 } 352 return -1; 353 } 354 355 356 /** 357 * Add a new Integer constant to the ConstantPool, if it is not already in there. 358 * 359 * @param n integer number to add 360 * @return index of entry 361 */ 362 public int addInteger( final int n ) { 363 int ret; 364 if ((ret = lookupInteger(n)) != -1) { 365 return ret; // Already in CP 366 } 367 adjustSize(); 368 ret = index; 369 constants[index++] = new ConstantInteger(n); 370 return ret; 371 } 372 373 374 /** 375 * Look for ConstantFloat in ConstantPool. 376 * 377 * @param n Float number to look for 378 * @return index on success, -1 otherwise 379 */ 380 public int lookupFloat( final float n ) { 381 final int bits = Float.floatToIntBits(n); 382 for (int i = 1; i < index; i++) { 383 if (constants[i] instanceof ConstantFloat) { 384 final ConstantFloat c = (ConstantFloat) constants[i]; 385 if (Float.floatToIntBits(c.getBytes()) == bits) { 386 return i; 387 } 388 } 389 } 390 return -1; 391 } 392 393 394 /** 395 * Add a new Float constant to the ConstantPool, if it is not already in there. 396 * 397 * @param n Float number to add 398 * @return index of entry 399 */ 400 public int addFloat( final float n ) { 401 int ret; 402 if ((ret = lookupFloat(n)) != -1) { 403 return ret; // Already in CP 404 } 405 adjustSize(); 406 ret = index; 407 constants[index++] = new ConstantFloat(n); 408 return ret; 409 } 410 411 private final Map<String, Index> utf8_table = new HashMap<>(); 412 413 414 /** 415 * Look for ConstantUtf8 in ConstantPool. 416 * 417 * @param n Utf8 string to look for 418 * @return index on success, -1 otherwise 419 */ 420 public int lookupUtf8( final String n ) { 421 final Index index = utf8_table.get(n); 422 return (index != null) ? index.index : -1; 423 } 424 425 426 /** 427 * Add a new Utf8 constant to the ConstantPool, if it is not already in there. 428 * 429 * @param n Utf8 string to add 430 * @return index of entry 431 */ 432 public int addUtf8( final String n ) { 433 int ret; 434 if ((ret = lookupUtf8(n)) != -1) { 435 return ret; // Already in CP 436 } 437 adjustSize(); 438 ret = index; 439 constants[index++] = new ConstantUtf8(n); 440 if (!utf8_table.containsKey(n)) { 441 utf8_table.put(n, new Index(ret)); 442 } 443 return ret; 444 } 445 446 447 /** 448 * Look for ConstantLong in ConstantPool. 449 * 450 * @param n Long number to look for 451 * @return index on success, -1 otherwise 452 */ 453 public int lookupLong( final long n ) { 454 for (int i = 1; i < index; i++) { 455 if (constants[i] instanceof ConstantLong) { 456 final ConstantLong c = (ConstantLong) constants[i]; 457 if (c.getBytes() == n) { 458 return i; 459 } 460 } 461 } 462 return -1; 463 } 464 465 466 /** 467 * Add a new long constant to the ConstantPool, if it is not already in there. 468 * 469 * @param n Long number to add 470 * @return index of entry 471 */ 472 public int addLong( final long n ) { 473 int ret; 474 if ((ret = lookupLong(n)) != -1) { 475 return ret; // Already in CP 476 } 477 adjustSize(); 478 ret = index; 479 constants[index] = new ConstantLong(n); 480 index += 2; // Wastes one entry according to spec 481 return ret; 482 } 483 484 485 /** 486 * Look for ConstantDouble in ConstantPool. 487 * 488 * @param n Double number to look for 489 * @return index on success, -1 otherwise 490 */ 491 public int lookupDouble( final double n ) { 492 final long bits = Double.doubleToLongBits(n); 493 for (int i = 1; i < index; i++) { 494 if (constants[i] instanceof ConstantDouble) { 495 final ConstantDouble c = (ConstantDouble) constants[i]; 496 if (Double.doubleToLongBits(c.getBytes()) == bits) { 497 return i; 498 } 499 } 500 } 501 return -1; 502 } 503 504 505 /** 506 * Add a new double constant to the ConstantPool, if it is not already in there. 507 * 508 * @param n Double number to add 509 * @return index of entry 510 */ 511 public int addDouble( final double n ) { 512 int ret; 513 if ((ret = lookupDouble(n)) != -1) { 514 return ret; // Already in CP 515 } 516 adjustSize(); 517 ret = index; 518 constants[index] = new ConstantDouble(n); 519 index += 2; // Wastes one entry according to spec 520 return ret; 521 } 522 523 private final Map<String, Index> n_a_t_table = new HashMap<>(); 524 525 526 /** 527 * Look for ConstantNameAndType in ConstantPool. 528 * 529 * @param name of variable/method 530 * @param signature of variable/method 531 * @return index on success, -1 otherwise 532 */ 533 public int lookupNameAndType( final String name, final String signature ) { 534 final Index _index = n_a_t_table.get(name + NAT_DELIM + signature); 535 return (_index != null) ? _index.index : -1; 536 } 537 538 539 /** 540 * Add a new NameAndType constant to the ConstantPool if it is not already 541 * in there. 542 * 543 * @param name Name string to add 544 * @param signature signature string to add 545 * @return index of entry 546 */ 547 public int addNameAndType( final String name, final String signature ) { 548 int ret; 549 int name_index; 550 int signature_index; 551 if ((ret = lookupNameAndType(name, signature)) != -1) { 552 return ret; // Already in CP 553 } 554 adjustSize(); 555 name_index = addUtf8(name); 556 signature_index = addUtf8(signature); 557 ret = index; 558 constants[index++] = new ConstantNameAndType(name_index, signature_index); 559 final String key = name + NAT_DELIM + signature; 560 if (!n_a_t_table.containsKey(key)) { 561 n_a_t_table.put(key, new Index(ret)); 562 } 563 return ret; 564 } 565 566 private final Map<String, Index> cp_table = new HashMap<>(); 567 568 569 /** 570 * Look for ConstantMethodref in ConstantPool. 571 * 572 * @param class_name Where to find method 573 * @param method_name Guess what 574 * @param signature return and argument types 575 * @return index on success, -1 otherwise 576 */ 577 public int lookupMethodref( final String class_name, final String method_name, final String signature ) { 578 final Index index = cp_table.get(class_name + METHODREF_DELIM + method_name 579 + METHODREF_DELIM + signature); 580 return (index != null) ? index.index : -1; 581 } 582 583 584 public int lookupMethodref( final MethodGen method ) { 585 return lookupMethodref(method.getClassName(), method.getName(), method.getSignature()); 586 } 587 588 589 /** 590 * Add a new Methodref constant to the ConstantPool, if it is not already 591 * in there. 592 * 593 * @param class_name class name string to add 594 * @param method_name method name string to add 595 * @param signature method signature string to add 596 * @return index of entry 597 */ 598 public int addMethodref( final String class_name, final String method_name, final String signature ) { 599 int ret; 600 int class_index; 601 int name_and_type_index; 602 if ((ret = lookupMethodref(class_name, method_name, signature)) != -1) { 603 return ret; // Already in CP 604 } 605 adjustSize(); 606 name_and_type_index = addNameAndType(method_name, signature); 607 class_index = addClass(class_name); 608 ret = index; 609 constants[index++] = new ConstantMethodref(class_index, name_and_type_index); 610 final String key = class_name + METHODREF_DELIM + method_name + METHODREF_DELIM + signature; 611 if (!cp_table.containsKey(key)) { 612 cp_table.put(key, new Index(ret)); 613 } 614 return ret; 615 } 616 617 618 public int addMethodref( final MethodGen method ) { 619 return addMethodref(method.getClassName(), method.getName(), method.getSignature()); 620 } 621 622 623 /** 624 * Look for ConstantInterfaceMethodref in ConstantPool. 625 * 626 * @param class_name Where to find method 627 * @param method_name Guess what 628 * @param signature return and argument types 629 * @return index on success, -1 otherwise 630 */ 631 public int lookupInterfaceMethodref( final String class_name, final String method_name, final String signature ) { 632 final Index index = cp_table.get(class_name + IMETHODREF_DELIM + method_name 633 + IMETHODREF_DELIM + signature); 634 return (index != null) ? index.index : -1; 635 } 636 637 638 public int lookupInterfaceMethodref( final MethodGen method ) { 639 return lookupInterfaceMethodref(method.getClassName(), method.getName(), method 640 .getSignature()); 641 } 642 643 644 /** 645 * Add a new InterfaceMethodref constant to the ConstantPool, if it is not already 646 * in there. 647 * 648 * @param class_name class name string to add 649 * @param method_name method name string to add 650 * @param signature signature string to add 651 * @return index of entry 652 */ 653 public int addInterfaceMethodref( final String class_name, final String method_name, final String signature ) { 654 int ret; 655 int class_index; 656 int name_and_type_index; 657 if ((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1) { 658 return ret; // Already in CP 659 } 660 adjustSize(); 661 class_index = addClass(class_name); 662 name_and_type_index = addNameAndType(method_name, signature); 663 ret = index; 664 constants[index++] = new ConstantInterfaceMethodref(class_index, name_and_type_index); 665 final String key = class_name + IMETHODREF_DELIM + method_name + IMETHODREF_DELIM + signature; 666 if (!cp_table.containsKey(key)) { 667 cp_table.put(key, new Index(ret)); 668 } 669 return ret; 670 } 671 672 673 public int addInterfaceMethodref( final MethodGen method ) { 674 return addInterfaceMethodref(method.getClassName(), method.getName(), method.getSignature()); 675 } 676 677 678 /** 679 * Look for ConstantFieldref in ConstantPool. 680 * 681 * @param class_name Where to find method 682 * @param field_name Guess what 683 * @param signature return and argument types 684 * @return index on success, -1 otherwise 685 */ 686 public int lookupFieldref( final String class_name, final String field_name, final String signature ) { 687 final Index index = cp_table.get(class_name + FIELDREF_DELIM + field_name 688 + FIELDREF_DELIM + signature); 689 return (index != null) ? index.index : -1; 690 } 691 692 693 /** 694 * Add a new Fieldref constant to the ConstantPool, if it is not already 695 * in there. 696 * 697 * @param class_name class name string to add 698 * @param field_name field name string to add 699 * @param signature signature string to add 700 * @return index of entry 701 */ 702 public int addFieldref( final String class_name, final String field_name, final String signature ) { 703 int ret; 704 int class_index; 705 int name_and_type_index; 706 if ((ret = lookupFieldref(class_name, field_name, signature)) != -1) { 707 return ret; // Already in CP 708 } 709 adjustSize(); 710 class_index = addClass(class_name); 711 name_and_type_index = addNameAndType(field_name, signature); 712 ret = index; 713 constants[index++] = new ConstantFieldref(class_index, name_and_type_index); 714 final String key = class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature; 715 if (!cp_table.containsKey(key)) { 716 cp_table.put(key, new Index(ret)); 717 } 718 return ret; 719 } 720 721 722 /** 723 * @param i index in constant pool 724 * @return constant pool entry at index i 725 */ 726 public Constant getConstant( final int i ) { 727 return constants[i]; 728 } 729 730 731 /** 732 * Use with care! 733 * 734 * @param i index in constant pool 735 * @param c new constant pool entry at index i 736 */ 737 public void setConstant( final int i, final Constant c ) { 738 constants[i] = c; 739 } 740 741 742 /** 743 * @return intermediate constant pool 744 */ 745 public ConstantPool getConstantPool() { 746 return new ConstantPool(constants); 747 } 748 749 750 /** 751 * @return current size of constant pool 752 */ 753 public int getSize() { 754 return index; 755 } 756 757 758 /** 759 * @return constant pool with proper length 760 */ 761 public ConstantPool getFinalConstantPool() { 762 final Constant[] cs = new Constant[index]; 763 System.arraycopy(constants, 0, cs, 0, index); 764 return new ConstantPool(cs); 765 } 766 767 768 /** 769 * @return String representation. 770 */ 771 @Override 772 public String toString() { 773 final StringBuilder buf = new StringBuilder(); 774 for (int i = 1; i < index; i++) { 775 buf.append(i).append(")").append(constants[i]).append("\n"); 776 } 777 return buf.toString(); 778 } 779 780 781 /** Import constant from another ConstantPool and return new index. 782 */ 783 public int addConstant( final Constant c, final ConstantPoolGen cp ) { 784 final Constant[] constants = cp.getConstantPool().getConstantPool(); 785 switch (c.getTag()) { 786 case Const.CONSTANT_String: { 787 final ConstantString s = (ConstantString) c; 788 final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; 789 return addString(u8.getBytes()); 790 } 791 case Const.CONSTANT_Class: { 792 final ConstantClass s = (ConstantClass) c; 793 final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; 794 return addClass(u8.getBytes()); 795 } 796 case Const.CONSTANT_NameAndType: { 797 final ConstantNameAndType n = (ConstantNameAndType) c; 798 final ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; 799 final ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; 800 return addNameAndType(u8.getBytes(), u8_2.getBytes()); 801 } 802 case Const.CONSTANT_Utf8: 803 return addUtf8(((ConstantUtf8) c).getBytes()); 804 case Const.CONSTANT_Double: 805 return addDouble(((ConstantDouble) c).getBytes()); 806 case Const.CONSTANT_Float: 807 return addFloat(((ConstantFloat) c).getBytes()); 808 case Const.CONSTANT_Long: 809 return addLong(((ConstantLong) c).getBytes()); 810 case Const.CONSTANT_Integer: 811 return addInteger(((ConstantInteger) c).getBytes()); 812 case Const.CONSTANT_InterfaceMethodref: 813 case Const.CONSTANT_Methodref: 814 case Const.CONSTANT_Fieldref: { 815 final ConstantCP m = (ConstantCP) c; 816 final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; 817 final ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()]; 818 ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; 819 final String class_name = u8.getBytes().replace('/', '.'); 820 u8 = (ConstantUtf8) constants[n.getNameIndex()]; 821 final String name = u8.getBytes(); 822 u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; 823 final String signature = u8.getBytes(); 824 switch (c.getTag()) { 825 case Const.CONSTANT_InterfaceMethodref: 826 return addInterfaceMethodref(class_name, name, signature); 827 case Const.CONSTANT_Methodref: 828 return addMethodref(class_name, name, signature); 829 case Const.CONSTANT_Fieldref: 830 return addFieldref(class_name, name, signature); 831 default: // Never reached 832 throw new RuntimeException("Unknown constant type " + c); 833 } 834 } 835 default: // Never reached 836 throw new RuntimeException("Unknown constant type " + c); 837 } 838 } 839}