1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 */ 4 /* 5 * Licensed to the Apache Software Foundation (ASF) under one or more 6 * contributor license agreements. See the NOTICE file distributed with 7 * this work for additional information regarding copyright ownership. 8 * The ASF licenses this file to You under the Apache License, Version 2.0 9 * (the "License"); you may not use this file except in compliance with 10 * the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 package com.sun.org.apache.bcel.internal.generic; 21 22 import java.util.HashMap; 23 import java.util.Map; 24 25 import com.sun.org.apache.bcel.internal.Const; 26 import com.sun.org.apache.bcel.internal.classfile.Constant; 27 import com.sun.org.apache.bcel.internal.classfile.ConstantCP; 28 import com.sun.org.apache.bcel.internal.classfile.ConstantClass; 29 import com.sun.org.apache.bcel.internal.classfile.ConstantDouble; 30 import com.sun.org.apache.bcel.internal.classfile.ConstantFieldref; 31 import com.sun.org.apache.bcel.internal.classfile.ConstantFloat; 32 import com.sun.org.apache.bcel.internal.classfile.ConstantInteger; 33 import com.sun.org.apache.bcel.internal.classfile.ConstantInterfaceMethodref; 34 import com.sun.org.apache.bcel.internal.classfile.ConstantInvokeDynamic; 35 import com.sun.org.apache.bcel.internal.classfile.ConstantLong; 36 import com.sun.org.apache.bcel.internal.classfile.ConstantMethodref; 37 import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType; 38 import com.sun.org.apache.bcel.internal.classfile.ConstantPool; 39 import com.sun.org.apache.bcel.internal.classfile.ConstantString; 40 import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; 41 42 /** 43 * This class is used to build up a constant pool. The user adds constants via 44 * `addXXX' methods, `addString', `addClass', etc.. These methods return an 45 * index into the constant pool. Finally, `getFinalConstantPool()' returns the 46 * constant pool built up. Intermediate versions of the constant pool can be 47 * obtained with `getConstantPool()'. A constant pool has capacity for 48 * Constants.MAX_SHORT entries. Note that the first (0) is used by the JVM and 49 * that Double and Long constants need two slots. 50 * 51 * @version $Id: ConstantPoolGen.java 1749603 2016-06-21 20:50:19Z ggregory $ 52 * @see Constant 53 */ 54 public class ConstantPoolGen { 55 56 private static final int DEFAULT_BUFFER_SIZE = 256; 57 private int size; 58 private Constant[] constants; 59 private int index = 1; // First entry (0) used by JVM 60 61 private static final String METHODREF_DELIM = ":"; 62 private static final String IMETHODREF_DELIM = "#"; 63 private static final String FIELDREF_DELIM = "&"; 64 private static final String NAT_DELIM = "%"; // Name and Type 65 66 private static class Index { 67 68 final int index; 69 70 Index(final int i) { 71 index = i; 72 } 73 } 74 75 /** 76 * Initialize with given array of constants. 77 * 78 * @param cs array of given constants, new ones will be appended 79 */ 80 public ConstantPoolGen(final Constant[] cs) { 81 final StringBuilder sb = new StringBuilder(DEFAULT_BUFFER_SIZE); 82 83 size = Math.max(DEFAULT_BUFFER_SIZE, cs.length + 64); 84 constants = new Constant[size]; 85 86 System.arraycopy(cs, 0, constants, 0, cs.length); 87 if (cs.length > 0) { 88 index = cs.length; 89 } 90 91 for (int i = 1; i < index; i++) { 92 final Constant c = constants[i]; 93 if (c instanceof ConstantString) { 94 final ConstantString s = (ConstantString) c; 95 final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; 96 final String key = u8.getBytes(); 97 if (!string_table.containsKey(key)) { 98 string_table.put(key, new Index(i)); 99 } 100 } else if (c instanceof ConstantClass) { 101 final ConstantClass s = (ConstantClass) c; 102 final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; 103 final String key = u8.getBytes(); 104 if (!class_table.containsKey(key)) { 105 class_table.put(key, new Index(i)); 106 } 107 } else if (c instanceof ConstantNameAndType) { 108 final ConstantNameAndType n = (ConstantNameAndType) c; 109 final ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; 110 final ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; 111 112 sb.append(u8.getBytes()); 113 sb.append(NAT_DELIM); 114 sb.append(u8_2.getBytes()); 115 final String key = sb.toString(); 116 sb.delete(0, sb.length()); 117 118 if (!n_a_t_table.containsKey(key)) { 119 n_a_t_table.put(key, new Index(i)); 120 } 121 } else if (c instanceof ConstantUtf8) { 122 final ConstantUtf8 u = (ConstantUtf8) c; 123 final String key = u.getBytes(); 124 if (!utf8_table.containsKey(key)) { 125 utf8_table.put(key, new Index(i)); 126 } 127 } else if (c instanceof ConstantCP) { 128 final ConstantCP m = (ConstantCP) c; 129 String class_name; 130 ConstantUtf8 u8; 131 132 if (c instanceof ConstantInvokeDynamic) { 133 class_name = Integer.toString(((ConstantInvokeDynamic) m).getBootstrapMethodAttrIndex()); 134 // since name can't begin with digit, can use 135 // METHODREF_DELIM with out fear of duplicates. 136 } else { 137 final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; 138 u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; 139 class_name = u8.getBytes().replace('/', '.'); 140 } 141 142 final ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()]; 143 u8 = (ConstantUtf8) constants[n.getNameIndex()]; 144 final String method_name = u8.getBytes(); 145 u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; 146 final String signature = u8.getBytes(); 147 148 String delim = METHODREF_DELIM; 149 if (c instanceof ConstantInterfaceMethodref) { 150 delim = IMETHODREF_DELIM; 151 } else if (c instanceof ConstantFieldref) { 152 delim = FIELDREF_DELIM; 153 } 154 155 sb.append(class_name); 156 sb.append(delim); 157 sb.append(method_name); 158 sb.append(delim); 159 sb.append(signature); 160 final String key = sb.toString(); 161 sb.delete(0, sb.length()); 162 163 if (!cp_table.containsKey(key)) { 164 cp_table.put(key, new Index(i)); 165 } 166 } else if (c == null) { // entries may be null 167 // nothing to do 168 } else if (c instanceof ConstantInteger) { 169 // nothing to do 170 } else if (c instanceof ConstantLong) { 171 // nothing to do 172 } else if (c instanceof ConstantFloat) { 173 // nothing to do 174 } else if (c instanceof ConstantDouble) { 175 // nothing to do 176 } else if (c instanceof com.sun.org.apache.bcel.internal.classfile.ConstantMethodType) { 177 // TODO should this be handled somehow? 178 } else if (c instanceof com.sun.org.apache.bcel.internal.classfile.ConstantMethodHandle) { 179 // TODO should this be handled somehow? 180 } else { 181 assert false : "Unexpected constant type: " + c.getClass().getName(); 182 } 183 } 184 } 185 186 /** 187 * Initialize with given constant pool. 188 */ 189 public ConstantPoolGen(final ConstantPool cp) { 190 this(cp.getConstantPool()); 191 } 192 193 /** 194 * Create empty constant pool. 195 */ 196 public ConstantPoolGen() { 197 size = DEFAULT_BUFFER_SIZE; 198 constants = new Constant[size]; 199 } 200 201 /** 202 * Resize internal array of constants. 203 */ 204 protected void adjustSize() { 205 if (index + 3 >= size) { 206 final Constant[] cs = constants; 207 size *= 2; 208 constants = new Constant[size]; 209 System.arraycopy(cs, 0, constants, 0, index); 210 } 211 } 212 213 private final Map<String, Index> string_table = new HashMap<>(); 214 215 /** 216 * Look for ConstantString in ConstantPool containing String `str'. 217 * 218 * @param str String to search for 219 * @return index on success, -1 otherwise 220 */ 221 public int lookupString(final String str) { 222 final Index index = string_table.get(str); 223 return (index != null) ? index.index : -1; 224 } 225 226 /** 227 * Add a new String constant to the ConstantPool, if it is not already in 228 * there. 229 * 230 * @param str String to add 231 * @return index of entry 232 */ 233 public int addString(final String str) { 234 int ret; 235 if ((ret = lookupString(str)) != -1) { 236 return ret; // Already in CP 237 } 238 final int utf8 = addUtf8(str); 239 adjustSize(); 240 final ConstantString s = new ConstantString(utf8); 241 ret = index; 242 constants[index++] = s; 243 if (!string_table.containsKey(str)) { 244 string_table.put(str, new Index(ret)); 245 } 246 return ret; 247 } 248 249 private final Map<String, Index> class_table = new HashMap<>(); 250 251 /** 252 * Look for ConstantClass in ConstantPool named `str'. 253 * 254 * @param str String to search for 255 * @return index on success, -1 otherwise 256 */ 257 public int lookupClass(final String str) { 258 final Index index = class_table.get(str.replace('.', '/')); 259 return (index != null) ? index.index : -1; 260 } 261 262 private int addClass_(final String clazz) { 263 int ret; 264 if ((ret = lookupClass(clazz)) != -1) { 265 return ret; // Already in CP 266 } 267 adjustSize(); 268 final ConstantClass c = new ConstantClass(addUtf8(clazz)); 269 ret = index; 270 constants[index++] = c; 271 if (!class_table.containsKey(clazz)) { 272 class_table.put(clazz, new Index(ret)); 273 } 274 return ret; 275 } 276 277 /** 278 * Add a new Class reference to the ConstantPool, if it is not already in 279 * there. 280 * 281 * @param str Class to add 282 * @return index of entry 283 */ 284 public int addClass(final String str) { 285 return addClass_(str.replace('.', '/')); 286 } 287 288 /** 289 * Add a new Class reference to the ConstantPool for a given type. 290 * 291 * @param type Class to add 292 * @return index of entry 293 */ 294 public int addClass(final ObjectType type) { 295 return addClass(type.getClassName()); 296 } 297 298 /** 299 * Add a reference to an array class (e.g. String[][]) as needed by 300 * MULTIANEWARRAY instruction, e.g. to the ConstantPool. 301 * 302 * @param type type of array class 303 * @return index of entry 304 */ 305 public int addArrayClass(final ArrayType type) { 306 return addClass_(type.getSignature()); 307 } 308 309 /** 310 * Look for ConstantInteger in ConstantPool. 311 * 312 * @param n integer number to look for 313 * @return index on success, -1 otherwise 314 */ 315 public int lookupInteger(final int n) { 316 for (int i = 1; i < index; i++) { 317 if (constants[i] instanceof ConstantInteger) { 318 final ConstantInteger c = (ConstantInteger) constants[i]; 319 if (c.getBytes() == n) { 320 return i; 321 } 322 } 323 } 324 return -1; 325 } 326 327 /** 328 * Add a new Integer constant to the ConstantPool, if it is not already in 329 * there. 330 * 331 * @param n integer number to add 332 * @return index of entry 333 */ 334 public int addInteger(final int n) { 335 int ret; 336 if ((ret = lookupInteger(n)) != -1) { 337 return ret; // Already in CP 338 } 339 adjustSize(); 340 ret = index; 341 constants[index++] = new ConstantInteger(n); 342 return ret; 343 } 344 345 /** 346 * Look for ConstantFloat in ConstantPool. 347 * 348 * @param n Float number to look for 349 * @return index on success, -1 otherwise 350 */ 351 public int lookupFloat(final float n) { 352 final int bits = Float.floatToIntBits(n); 353 for (int i = 1; i < index; i++) { 354 if (constants[i] instanceof ConstantFloat) { 355 final ConstantFloat c = (ConstantFloat) constants[i]; 356 if (Float.floatToIntBits(c.getBytes()) == bits) { 357 return i; 358 } 359 } 360 } 361 return -1; 362 } 363 364 /** 365 * Add a new Float constant to the ConstantPool, if it is not already in 366 * there. 367 * 368 * @param n Float number to add 369 * @return index of entry 370 */ 371 public int addFloat(final float n) { 372 int ret; 373 if ((ret = lookupFloat(n)) != -1) { 374 return ret; // Already in CP 375 } 376 adjustSize(); 377 ret = index; 378 constants[index++] = new ConstantFloat(n); 379 return ret; 380 } 381 382 private final Map<String, Index> utf8_table = new HashMap<>(); 383 384 /** 385 * Look for ConstantUtf8 in ConstantPool. 386 * 387 * @param n Utf8 string to look for 388 * @return index on success, -1 otherwise 389 */ 390 public int lookupUtf8(final String n) { 391 final Index index = utf8_table.get(n); 392 return (index != null) ? index.index : -1; 393 } 394 395 /** 396 * Add a new Utf8 constant to the ConstantPool, if it is not already in 397 * there. 398 * 399 * @param n Utf8 string to add 400 * @return index of entry 401 */ 402 public int addUtf8(final String n) { 403 int ret; 404 if ((ret = lookupUtf8(n)) != -1) { 405 return ret; // Already in CP 406 } 407 adjustSize(); 408 ret = index; 409 constants[index++] = new ConstantUtf8(n); 410 if (!utf8_table.containsKey(n)) { 411 utf8_table.put(n, new Index(ret)); 412 } 413 return ret; 414 } 415 416 /** 417 * Look for ConstantLong in ConstantPool. 418 * 419 * @param n Long number to look for 420 * @return index on success, -1 otherwise 421 */ 422 public int lookupLong(final long n) { 423 for (int i = 1; i < index; i++) { 424 if (constants[i] instanceof ConstantLong) { 425 final ConstantLong c = (ConstantLong) constants[i]; 426 if (c.getBytes() == n) { 427 return i; 428 } 429 } 430 } 431 return -1; 432 } 433 434 /** 435 * Add a new long constant to the ConstantPool, if it is not already in 436 * there. 437 * 438 * @param n Long number to add 439 * @return index of entry 440 */ 441 public int addLong(final long n) { 442 int ret; 443 if ((ret = lookupLong(n)) != -1) { 444 return ret; // Already in CP 445 } 446 adjustSize(); 447 ret = index; 448 constants[index] = new ConstantLong(n); 449 index += 2; // Wastes one entry according to spec 450 return ret; 451 } 452 453 /** 454 * Look for ConstantDouble in ConstantPool. 455 * 456 * @param n Double number to look for 457 * @return index on success, -1 otherwise 458 */ 459 public int lookupDouble(final double n) { 460 final long bits = Double.doubleToLongBits(n); 461 for (int i = 1; i < index; i++) { 462 if (constants[i] instanceof ConstantDouble) { 463 final ConstantDouble c = (ConstantDouble) constants[i]; 464 if (Double.doubleToLongBits(c.getBytes()) == bits) { 465 return i; 466 } 467 } 468 } 469 return -1; 470 } 471 472 /** 473 * Add a new double constant to the ConstantPool, if it is not already in 474 * there. 475 * 476 * @param n Double number to add 477 * @return index of entry 478 */ 479 public int addDouble(final double n) { 480 int ret; 481 if ((ret = lookupDouble(n)) != -1) { 482 return ret; // Already in CP 483 } 484 adjustSize(); 485 ret = index; 486 constants[index] = new ConstantDouble(n); 487 index += 2; // Wastes one entry according to spec 488 return ret; 489 } 490 491 private final Map<String, Index> n_a_t_table = new HashMap<>(); 492 493 /** 494 * Look for ConstantNameAndType in ConstantPool. 495 * 496 * @param name of variable/method 497 * @param signature of variable/method 498 * @return index on success, -1 otherwise 499 */ 500 public int lookupNameAndType(final String name, final String signature) { 501 final Index _index = n_a_t_table.get(name + NAT_DELIM + signature); 502 return (_index != null) ? _index.index : -1; 503 } 504 505 /** 506 * Add a new NameAndType constant to the ConstantPool if it is not already 507 * in there. 508 * 509 * @param name Name string to add 510 * @param signature signature string to add 511 * @return index of entry 512 */ 513 public int addNameAndType(final String name, final String signature) { 514 int ret; 515 int name_index; 516 int signature_index; 517 if ((ret = lookupNameAndType(name, signature)) != -1) { 518 return ret; // Already in CP 519 } 520 adjustSize(); 521 name_index = addUtf8(name); 522 signature_index = addUtf8(signature); 523 ret = index; 524 constants[index++] = new ConstantNameAndType(name_index, signature_index); 525 final String key = name + NAT_DELIM + signature; 526 if (!n_a_t_table.containsKey(key)) { 527 n_a_t_table.put(key, new Index(ret)); 528 } 529 return ret; 530 } 531 532 private final Map<String, Index> cp_table = new HashMap<>(); 533 534 /** 535 * Look for ConstantMethodref in ConstantPool. 536 * 537 * @param class_name Where to find method 538 * @param method_name Guess what 539 * @param signature return and argument types 540 * @return index on success, -1 otherwise 541 */ 542 public int lookupMethodref(final String class_name, final String method_name, final String signature) { 543 final Index index = cp_table.get(class_name + METHODREF_DELIM + method_name 544 + METHODREF_DELIM + signature); 545 return (index != null) ? index.index : -1; 546 } 547 548 public int lookupMethodref(final MethodGen method) { 549 return lookupMethodref(method.getClassName(), method.getName(), method.getSignature()); 550 } 551 552 /** 553 * Add a new Methodref constant to the ConstantPool, if it is not already in 554 * there. 555 * 556 * @param class_name class name string to add 557 * @param method_name method name string to add 558 * @param signature method signature string to add 559 * @return index of entry 560 */ 561 public int addMethodref(final String class_name, final String method_name, final String signature) { 562 int ret; 563 int class_index; 564 int name_and_type_index; 565 if ((ret = lookupMethodref(class_name, method_name, signature)) != -1) { 566 return ret; // Already in CP 567 } 568 adjustSize(); 569 name_and_type_index = addNameAndType(method_name, signature); 570 class_index = addClass(class_name); 571 ret = index; 572 constants[index++] = new ConstantMethodref(class_index, name_and_type_index); 573 final String key = class_name + METHODREF_DELIM + method_name + METHODREF_DELIM + signature; 574 if (!cp_table.containsKey(key)) { 575 cp_table.put(key, new Index(ret)); 576 } 577 return ret; 578 } 579 580 public int addMethodref(final MethodGen method) { 581 return addMethodref(method.getClassName(), method.getName(), method.getSignature()); 582 } 583 584 /** 585 * Look for ConstantInterfaceMethodref in ConstantPool. 586 * 587 * @param class_name Where to find method 588 * @param method_name Guess what 589 * @param signature return and argument types 590 * @return index on success, -1 otherwise 591 */ 592 public int lookupInterfaceMethodref(final String class_name, final String method_name, final String signature) { 593 final Index index = cp_table.get(class_name + IMETHODREF_DELIM + method_name 594 + IMETHODREF_DELIM + signature); 595 return (index != null) ? index.index : -1; 596 } 597 598 public int lookupInterfaceMethodref(final MethodGen method) { 599 return lookupInterfaceMethodref(method.getClassName(), method.getName(), method 600 .getSignature()); 601 } 602 603 /** 604 * Add a new InterfaceMethodref constant to the ConstantPool, if it is not 605 * already in there. 606 * 607 * @param class_name class name string to add 608 * @param method_name method name string to add 609 * @param signature signature string to add 610 * @return index of entry 611 */ 612 public int addInterfaceMethodref(final String class_name, final String method_name, final String signature) { 613 int ret; 614 int class_index; 615 int name_and_type_index; 616 if ((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1) { 617 return ret; // Already in CP 618 } 619 adjustSize(); 620 class_index = addClass(class_name); 621 name_and_type_index = addNameAndType(method_name, signature); 622 ret = index; 623 constants[index++] = new ConstantInterfaceMethodref(class_index, name_and_type_index); 624 final String key = class_name + IMETHODREF_DELIM + method_name + IMETHODREF_DELIM + signature; 625 if (!cp_table.containsKey(key)) { 626 cp_table.put(key, new Index(ret)); 627 } 628 return ret; 629 } 630 631 public int addInterfaceMethodref(final MethodGen method) { 632 return addInterfaceMethodref(method.getClassName(), method.getName(), method.getSignature()); 633 } 634 635 /** 636 * Look for ConstantFieldref in ConstantPool. 637 * 638 * @param class_name Where to find method 639 * @param field_name Guess what 640 * @param signature return and argument types 641 * @return index on success, -1 otherwise 642 */ 643 public int lookupFieldref(final String class_name, final String field_name, final String signature) { 644 final Index index = cp_table.get(class_name + FIELDREF_DELIM + field_name 645 + FIELDREF_DELIM + signature); 646 return (index != null) ? index.index : -1; 647 } 648 649 /** 650 * Add a new Fieldref constant to the ConstantPool, if it is not already in 651 * there. 652 * 653 * @param class_name class name string to add 654 * @param field_name field name string to add 655 * @param signature signature string to add 656 * @return index of entry 657 */ 658 public int addFieldref(final String class_name, final String field_name, final String signature) { 659 int ret; 660 int class_index; 661 int name_and_type_index; 662 if ((ret = lookupFieldref(class_name, field_name, signature)) != -1) { 663 return ret; // Already in CP 664 } 665 adjustSize(); 666 class_index = addClass(class_name); 667 name_and_type_index = addNameAndType(field_name, signature); 668 ret = index; 669 constants[index++] = new ConstantFieldref(class_index, name_and_type_index); 670 final String key = class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature; 671 if (!cp_table.containsKey(key)) { 672 cp_table.put(key, new Index(ret)); 673 } 674 return ret; 675 } 676 677 /** 678 * @param i index in constant pool 679 * @return constant pool entry at index i 680 */ 681 public Constant getConstant(final int i) { 682 return constants[i]; 683 } 684 685 /** 686 * Use with care! 687 * 688 * @param i index in constant pool 689 * @param c new constant pool entry at index i 690 */ 691 public void setConstant(final int i, final Constant c) { 692 constants[i] = c; 693 } 694 695 /** 696 * @return intermediate constant pool 697 */ 698 public ConstantPool getConstantPool() { 699 return new ConstantPool(constants); 700 } 701 702 /** 703 * @return current size of constant pool 704 */ 705 public int getSize() { 706 return index; 707 } 708 709 /** 710 * @return constant pool with proper length 711 */ 712 public ConstantPool getFinalConstantPool() { 713 final Constant[] cs = new Constant[index]; 714 System.arraycopy(constants, 0, cs, 0, index); 715 return new ConstantPool(cs); 716 } 717 718 /** 719 * @return String representation. 720 */ 721 @Override 722 public String toString() { 723 final StringBuilder buf = new StringBuilder(); 724 for (int i = 1; i < index; i++) { 725 buf.append(i).append(")").append(constants[i]).append("\n"); 726 } 727 return buf.toString(); 728 } 729 730 /** 731 * Import constant from another ConstantPool and return new index. 732 */ 733 public int addConstant(final Constant c, final ConstantPoolGen cp) { 734 final Constant[] constants = cp.getConstantPool().getConstantPool(); 735 switch (c.getTag()) { 736 case Const.CONSTANT_String: { 737 final ConstantString s = (ConstantString) c; 738 final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; 739 return addString(u8.getBytes()); 740 } 741 case Const.CONSTANT_Class: { 742 final ConstantClass s = (ConstantClass) c; 743 final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; 744 return addClass(u8.getBytes()); 745 } 746 case Const.CONSTANT_NameAndType: { 747 final ConstantNameAndType n = (ConstantNameAndType) c; 748 final ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; 749 final ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; 750 return addNameAndType(u8.getBytes(), u8_2.getBytes()); 751 } 752 case Const.CONSTANT_Utf8: 753 return addUtf8(((ConstantUtf8) c).getBytes()); 754 case Const.CONSTANT_Double: 755 return addDouble(((ConstantDouble) c).getBytes()); 756 case Const.CONSTANT_Float: 757 return addFloat(((ConstantFloat) c).getBytes()); 758 case Const.CONSTANT_Long: 759 return addLong(((ConstantLong) c).getBytes()); 760 case Const.CONSTANT_Integer: 761 return addInteger(((ConstantInteger) c).getBytes()); 762 case Const.CONSTANT_InterfaceMethodref: 763 case Const.CONSTANT_Methodref: 764 case Const.CONSTANT_Fieldref: { 765 final ConstantCP m = (ConstantCP) c; 766 final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; 767 final ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()]; 768 ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; 769 final String class_name = u8.getBytes().replace('/', '.'); 770 u8 = (ConstantUtf8) constants[n.getNameIndex()]; 771 final String name = u8.getBytes(); 772 u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; 773 final String signature = u8.getBytes(); 774 switch (c.getTag()) { 775 case Const.CONSTANT_InterfaceMethodref: 776 return addInterfaceMethodref(class_name, name, signature); 777 case Const.CONSTANT_Methodref: 778 return addMethodref(class_name, name, signature); 779 case Const.CONSTANT_Fieldref: 780 return addFieldref(class_name, name, signature); 781 default: // Never reached 782 throw new RuntimeException("Unknown constant type " + c); 783 } 784 } 785 default: // Never reached 786 throw new RuntimeException("Unknown constant type " + c); 787 } 788 } 789 }