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