You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ConstantPoolGen.java 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803
  1. package org.aspectj.apache.bcel.generic;
  2. /* ====================================================================
  3. * The Apache Software License, Version 1.1
  4. *
  5. * Copyright (c) 2001 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Apache" and "Apache Software Foundation" and
  28. * "Apache BCEL" must not be used to endorse or promote products
  29. * derived from this software without prior written permission. For
  30. * written permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * "Apache BCEL", nor may "Apache" appear in their name, without
  34. * prior written permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation. For more
  52. * information on the Apache Software Foundation, please see
  53. * <http://www.apache.org/>.
  54. */
  55. import java.util.HashMap;
  56. import org.aspectj.apache.bcel.Constants;
  57. import org.aspectj.apache.bcel.classfile.Constant;
  58. import org.aspectj.apache.bcel.classfile.ConstantCP;
  59. import org.aspectj.apache.bcel.classfile.ConstantClass;
  60. import org.aspectj.apache.bcel.classfile.ConstantDouble;
  61. import org.aspectj.apache.bcel.classfile.ConstantFieldref;
  62. import org.aspectj.apache.bcel.classfile.ConstantFloat;
  63. import org.aspectj.apache.bcel.classfile.ConstantInteger;
  64. import org.aspectj.apache.bcel.classfile.ConstantInterfaceMethodref;
  65. import org.aspectj.apache.bcel.classfile.ConstantLong;
  66. import org.aspectj.apache.bcel.classfile.ConstantMethodref;
  67. import org.aspectj.apache.bcel.classfile.ConstantNameAndType;
  68. import org.aspectj.apache.bcel.classfile.ConstantPool;
  69. import org.aspectj.apache.bcel.classfile.ConstantString;
  70. import org.aspectj.apache.bcel.classfile.ConstantUtf8;
  71. /**
  72. * This class is used to build up a constant pool. The user adds
  73. * constants via `addXXX' methods, `addString', `addClass',
  74. * etc.. These methods return an index into the constant
  75. * pool. Finally, `getFinalConstantPool()' returns the constant pool
  76. * built up. Intermediate versions of the constant pool can be
  77. * obtained with `getConstantPool()'. A constant pool has capacity for
  78. * Constants.MAX_SHORT entries. Note that the first (0) is used by the
  79. * JVM and that Double and Long constants need two slots.
  80. *
  81. * @version $Id: ConstantPoolGen.java,v 1.3.8.1 2007/02/09 10:45:09 aclement Exp $
  82. * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  83. * @see Constant
  84. */
  85. public class ConstantPoolGen implements java.io.Serializable {
  86. protected int size = 1024; // Inital size, sufficient in most cases
  87. protected Constant[] constants = new Constant[size];
  88. protected int index = 1; // First entry (0) used by JVM
  89. private static final String METHODREF_DELIM = ":";
  90. private static final String IMETHODREF_DELIM = "#";
  91. private static final String FIELDREF_DELIM = "&";
  92. private static final String NAT_DELIM = "%";
  93. private static class Index implements java.io.Serializable {
  94. int index;
  95. Index(int i) { index = i; }
  96. }
  97. /**
  98. * Initialize with given array of constants.
  99. *
  100. * @param c array of given constants, new ones will be appended
  101. */
  102. public ConstantPoolGen(Constant[] cs) {
  103. if(cs.length > size) {
  104. size = cs.length;
  105. constants = new Constant[size];
  106. }
  107. System.arraycopy(cs, 0, constants, 0, cs.length);
  108. if(cs.length > 0)
  109. index = cs.length;
  110. for(int i=1; i < index; i++) {
  111. Constant c = constants[i];
  112. if(c instanceof ConstantString) {
  113. ConstantString s = (ConstantString)c;
  114. ConstantUtf8 u8 = (ConstantUtf8)constants[s.getStringIndex()];
  115. string_table.put(u8.getBytes(), new Index(i));
  116. } else if(c instanceof ConstantClass) {
  117. ConstantClass s = (ConstantClass)c;
  118. ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()];
  119. class_table.put(u8.getBytes(), new Index(i));
  120. } else if(c instanceof ConstantNameAndType) {
  121. ConstantNameAndType n = (ConstantNameAndType)c;
  122. ConstantUtf8 u8 = (ConstantUtf8)constants[n.getNameIndex()];
  123. ConstantUtf8 u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()];
  124. n_a_t_table.put(u8.getBytes() + NAT_DELIM + u8_2.getBytes(), new Index(i));
  125. } else if(c instanceof ConstantUtf8) {
  126. ConstantUtf8 u = (ConstantUtf8)c;
  127. utf8_table.put(u.getBytes(), new Index(i));
  128. } else if(c instanceof ConstantCP) {
  129. ConstantCP m = (ConstantCP)c;
  130. ConstantClass clazz = (ConstantClass)constants[m.getClassIndex()];
  131. ConstantNameAndType n = (ConstantNameAndType)constants[m.getNameAndTypeIndex()];
  132. ConstantUtf8 u8 = (ConstantUtf8)constants[clazz.getNameIndex()];
  133. String class_name = u8.getBytes().replace('/', '.');
  134. u8 = (ConstantUtf8)constants[n.getNameIndex()];
  135. String method_name = u8.getBytes();
  136. u8 = (ConstantUtf8)constants[n.getSignatureIndex()];
  137. String signature = u8.getBytes();
  138. String delim = METHODREF_DELIM;
  139. if(c instanceof ConstantInterfaceMethodref)
  140. delim = IMETHODREF_DELIM;
  141. else if(c instanceof ConstantFieldref)
  142. delim = FIELDREF_DELIM;
  143. StringBuffer key = new StringBuffer(class_name);
  144. key.append(delim).append(method_name).append(delim).append(signature);
  145. cp_table.put(key.toString(), new Index(i));
  146. }
  147. }
  148. }
  149. /**
  150. * Initialize with given constant pool.
  151. */
  152. public ConstantPoolGen(ConstantPool cp) {
  153. this(cp.getConstantPool());
  154. }
  155. /**
  156. * Create empty constant pool.
  157. */
  158. public ConstantPoolGen() {}
  159. /** Resize internal array of constants.
  160. */
  161. protected void adjustSize() {
  162. if(index + 3 >= size) {
  163. Constant[] cs = constants;
  164. size *= 2;
  165. constants = new Constant[size];
  166. System.arraycopy(cs, 0, constants, 0, index);
  167. }
  168. }
  169. private HashMap string_table = new HashMap();
  170. /**
  171. * Look for ConstantString in ConstantPool containing String `str'.
  172. *
  173. * @param str String to search for
  174. * @return index on success, -1 otherwise
  175. */
  176. public int lookupString(String str) {
  177. Index index = (Index)string_table.get(str);
  178. return (index != null)? index.index : -1;
  179. }
  180. /**
  181. * Add a new String constant to the ConstantPool, if it is not already in there.
  182. *
  183. * @param str String to add
  184. * @return index of entry
  185. */
  186. public int addString(String str) {
  187. int ret;
  188. if((ret = lookupString(str)) != -1)
  189. return ret; // Already in CP
  190. int utf8 = addUtf8(str);
  191. adjustSize();
  192. ConstantString s = new ConstantString(utf8);
  193. ret = index;
  194. constants[index++] = s;
  195. string_table.put(str, new Index(ret));
  196. return ret;
  197. }
  198. private HashMap class_table = new HashMap();
  199. /**
  200. * Look for ConstantClass in ConstantPool named `str'.
  201. *
  202. * @param str String to search for
  203. * @return index on success, -1 otherwise
  204. */
  205. public int lookupClass(String str) {
  206. Index index = (Index)class_table.get(str.replace('.', '/'));
  207. return (index != null)? index.index : -1;
  208. }
  209. private int addClass_(String clazz) {
  210. int ret;
  211. if((ret = lookupClass(clazz)) != -1)
  212. return ret; // Already in CP
  213. adjustSize();
  214. ConstantClass c = new ConstantClass(addUtf8(clazz));
  215. ret = index;
  216. constants[index++] = c;
  217. class_table.put(clazz, new Index(ret));
  218. return ret;
  219. }
  220. /**
  221. * Add a new Class reference to the ConstantPool, if it is not already in there.
  222. *
  223. * @param str Class to add
  224. * @return index of entry
  225. */
  226. public int addClass(String str) {
  227. return addClass_(str.replace('.', '/'));
  228. }
  229. /**
  230. * Add a new Class reference to the ConstantPool for a given type.
  231. *
  232. * @param str Class to add
  233. * @return index of entry
  234. */
  235. public int addClass(ObjectType type) {
  236. //BCELBUG:? Should this we getClassName() - perhaps it should be getSignature() ?!?
  237. return addClass(type.getClassName());
  238. // return addClass(type.getSignature());
  239. }
  240. /**
  241. * Add a reference to an array class (e.g. String[][]) as needed by MULTIANEWARRAY
  242. * instruction, e.g. to the ConstantPool.
  243. *
  244. * @param type type of array class
  245. * @return index of entry
  246. */
  247. public int addArrayClass(ArrayType type) {
  248. return addClass_(type.getSignature());
  249. }
  250. /**
  251. * Look for ConstantInteger in ConstantPool.
  252. *
  253. * @param n integer number to look for
  254. * @return index on success, -1 otherwise
  255. */
  256. public int lookupInteger(int n) {
  257. for(int i=1; i < index; i++) {
  258. if(constants[i] instanceof ConstantInteger) {
  259. ConstantInteger c = (ConstantInteger)constants[i];
  260. if(c.getBytes() == n)
  261. return i;
  262. }
  263. }
  264. return -1;
  265. }
  266. /**
  267. * Add a new Integer constant to the ConstantPool, if it is not already in there.
  268. *
  269. * @param n integer number to add
  270. * @return index of entry
  271. */
  272. public int addInteger(int n) {
  273. int ret;
  274. if((ret = lookupInteger(n)) != -1)
  275. return ret; // Already in CP
  276. adjustSize();
  277. ret = index;
  278. constants[index++] = new ConstantInteger(n);
  279. return ret;
  280. }
  281. /**
  282. * Look for ConstantFloat in ConstantPool.
  283. *
  284. * @param n Float number to look for
  285. * @return index on success, -1 otherwise
  286. */
  287. public int lookupFloat(float n) {
  288. int bits = Float.floatToIntBits(n);
  289. for(int i=1; i < index; i++) {
  290. if(constants[i] instanceof ConstantFloat) {
  291. ConstantFloat c = (ConstantFloat)constants[i];
  292. if(Float.floatToIntBits(c.getBytes()) == bits)
  293. return i;
  294. }
  295. }
  296. return -1;
  297. }
  298. /**
  299. * Add a new Float constant to the ConstantPool, if it is not already in there.
  300. *
  301. * @param n Float number to add
  302. * @return index of entry
  303. */
  304. public int addFloat(float n) {
  305. int ret;
  306. if((ret = lookupFloat(n)) != -1)
  307. return ret; // Already in CP
  308. adjustSize();
  309. ret = index;
  310. constants[index++] = new ConstantFloat(n);
  311. return ret;
  312. }
  313. private HashMap utf8_table = new HashMap();
  314. /**
  315. * Look for ConstantUtf8 in ConstantPool.
  316. *
  317. * @param n Utf8 string to look for
  318. * @return index on success, -1 otherwise
  319. */
  320. public int lookupUtf8(String n) {
  321. Index index = (Index)utf8_table.get(n);
  322. return (index != null)? index.index : -1;
  323. }
  324. /**
  325. * Add a new Utf8 constant to the ConstantPool, if it is not already in there.
  326. *
  327. * @param n Utf8 string to add
  328. * @return index of entry
  329. */
  330. public int addUtf8(String n) {
  331. int ret;
  332. if((ret = lookupUtf8(n)) != -1)
  333. return ret; // Already in CP
  334. adjustSize();
  335. ret = index;
  336. constants[index++] = new ConstantUtf8(n);
  337. utf8_table.put(n, new Index(ret));
  338. return ret;
  339. }
  340. /**
  341. * Look for ConstantLong in ConstantPool.
  342. *
  343. * @param n Long number to look for
  344. * @return index on success, -1 otherwise
  345. */
  346. public int lookupLong(long n) {
  347. for(int i=1; i < index; i++) {
  348. if(constants[i] instanceof ConstantLong) {
  349. ConstantLong c = (ConstantLong)constants[i];
  350. if(c.getBytes() == n)
  351. return i;
  352. }
  353. }
  354. return -1;
  355. }
  356. /**
  357. * Add a new long constant to the ConstantPool, if it is not already in there.
  358. *
  359. * @param n Long number to add
  360. * @return index of entry
  361. */
  362. public int addLong(long n) {
  363. int ret;
  364. if((ret = lookupLong(n)) != -1)
  365. return ret; // Already in CP
  366. adjustSize();
  367. ret = index;
  368. constants[index] = new ConstantLong(n);
  369. index += 2; // Wastes one entry according to spec
  370. return ret;
  371. }
  372. /**
  373. * Look for ConstantDouble in ConstantPool.
  374. *
  375. * @param n Double number to look for
  376. * @return index on success, -1 otherwise
  377. */
  378. public int lookupDouble(double n) {
  379. long bits = Double.doubleToLongBits(n);
  380. for(int i=1; i < index; i++) {
  381. if(constants[i] instanceof ConstantDouble) {
  382. ConstantDouble c = (ConstantDouble)constants[i];
  383. if(Double.doubleToLongBits(c.getBytes()) == bits)
  384. return i;
  385. }
  386. }
  387. return -1;
  388. }
  389. /**
  390. * Add a new double constant to the ConstantPool, if it is not already in there.
  391. *
  392. * @param n Double number to add
  393. * @return index of entry
  394. */
  395. public int addDouble(double n) {
  396. int ret;
  397. if((ret = lookupDouble(n)) != -1)
  398. return ret; // Already in CP
  399. adjustSize();
  400. ret = index;
  401. constants[index] = new ConstantDouble(n);
  402. index += 2; // Wastes one entry according to spec
  403. return ret;
  404. }
  405. private HashMap n_a_t_table = new HashMap();
  406. /**
  407. * Look for ConstantNameAndType in ConstantPool.
  408. *
  409. * @param name of variable/method
  410. * @param signature of variable/method
  411. * @return index on success, -1 otherwise
  412. */
  413. public int lookupNameAndType(String name, String signature) {
  414. Index index = (Index)n_a_t_table.get(name + NAT_DELIM + signature);
  415. return (index != null)? index.index : -1;
  416. }
  417. /**
  418. * Add a new NameAndType constant to the ConstantPool if it is not already
  419. * in there.
  420. *
  421. * @param n NameAndType string to add
  422. * @return index of entry
  423. */
  424. public int addNameAndType(String name, String signature) {
  425. int ret;
  426. int name_index, signature_index;
  427. if((ret = lookupNameAndType(name, signature)) != -1)
  428. return ret; // Already in CP
  429. adjustSize();
  430. name_index = addUtf8(name);
  431. signature_index = addUtf8(signature);
  432. ret = index;
  433. constants[index++] = new ConstantNameAndType(name_index, signature_index);
  434. n_a_t_table.put(name + NAT_DELIM + signature, new Index(ret));
  435. return ret;
  436. }
  437. private HashMap cp_table = new HashMap();
  438. /**
  439. * Look for ConstantMethodref in ConstantPool.
  440. *
  441. * @param class_name Where to find method
  442. * @param method_name Guess what
  443. * @param signature return and argument types
  444. * @return index on success, -1 otherwise
  445. */
  446. public int lookupMethodref(String class_name, String method_name, String signature) {
  447. Index index = (Index)cp_table.get(class_name + METHODREF_DELIM + method_name +
  448. METHODREF_DELIM + signature);
  449. return (index != null)? index.index : -1;
  450. }
  451. public int lookupMethodref(MethodGen method) {
  452. return lookupMethodref(method.getClassName(), method.getName(),
  453. method.getSignature());
  454. }
  455. /**
  456. * Add a new Methodref constant to the ConstantPool, if it is not already
  457. * in there.
  458. *
  459. * @param n Methodref string to add
  460. * @return index of entry
  461. */
  462. public int addMethodref(String class_name, String method_name, String signature) {
  463. int ret, class_index, name_and_type_index;
  464. if((ret = lookupMethodref(class_name, method_name, signature)) != -1)
  465. return ret; // Already in CP
  466. adjustSize();
  467. name_and_type_index = addNameAndType(method_name, signature);
  468. class_index = addClass(class_name);
  469. ret = index;
  470. constants[index++] = new ConstantMethodref(class_index, name_and_type_index);
  471. cp_table.put(class_name + METHODREF_DELIM + method_name +
  472. METHODREF_DELIM + signature, new Index(ret));
  473. return ret;
  474. }
  475. public int addMethodref(MethodGen method) {
  476. return addMethodref(method.getClassName(), method.getName(),
  477. method.getSignature());
  478. }
  479. /**
  480. * Look for ConstantInterfaceMethodref in ConstantPool.
  481. *
  482. * @param class_name Where to find method
  483. * @param method_name Guess what
  484. * @param signature return and argument types
  485. * @return index on success, -1 otherwise
  486. */
  487. public int lookupInterfaceMethodref(String class_name, String method_name, String signature) {
  488. Index index = (Index)cp_table.get(class_name + IMETHODREF_DELIM + method_name +
  489. IMETHODREF_DELIM + signature);
  490. return (index != null)? index.index : -1;
  491. }
  492. public int lookupInterfaceMethodref(MethodGen method) {
  493. return lookupInterfaceMethodref(method.getClassName(), method.getName(),
  494. method.getSignature());
  495. }
  496. /**
  497. * Add a new InterfaceMethodref constant to the ConstantPool, if it is not already
  498. * in there.
  499. *
  500. * @param n InterfaceMethodref string to add
  501. * @return index of entry
  502. */
  503. public int addInterfaceMethodref(String class_name, String method_name, String signature) {
  504. int ret, class_index, name_and_type_index;
  505. if((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1)
  506. return ret; // Already in CP
  507. adjustSize();
  508. class_index = addClass(class_name);
  509. name_and_type_index = addNameAndType(method_name, signature);
  510. ret = index;
  511. constants[index++] = new ConstantInterfaceMethodref(class_index, name_and_type_index);
  512. cp_table.put(class_name + IMETHODREF_DELIM + method_name +
  513. IMETHODREF_DELIM + signature, new Index(ret));
  514. return ret;
  515. }
  516. public int addInterfaceMethodref(MethodGen method) {
  517. return addInterfaceMethodref(method.getClassName(), method.getName(),
  518. method.getSignature());
  519. }
  520. /**
  521. * Look for ConstantFieldref in ConstantPool.
  522. *
  523. * @param class_name Where to find method
  524. * @param field_name Guess what
  525. * @param signature return and argument types
  526. * @return index on success, -1 otherwise
  527. */
  528. public int lookupFieldref(String class_name, String field_name, String signature) {
  529. Index index = (Index)cp_table.get(class_name + FIELDREF_DELIM + field_name +
  530. FIELDREF_DELIM + signature);
  531. return (index != null)? index.index : -1;
  532. }
  533. /**
  534. * Add a new Fieldref constant to the ConstantPool, if it is not already
  535. * in there.
  536. *
  537. * @param n Fieldref string to add
  538. * @return index of entry
  539. */
  540. public int addFieldref(String class_name, String field_name, String signature) {
  541. int ret;
  542. int class_index, name_and_type_index;
  543. if((ret = lookupFieldref(class_name, field_name, signature)) != -1)
  544. return ret; // Already in CP
  545. adjustSize();
  546. class_index = addClass(class_name);
  547. name_and_type_index = addNameAndType(field_name, signature);
  548. ret = index;
  549. constants[index++] = new ConstantFieldref(class_index, name_and_type_index);
  550. cp_table.put(class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature, new Index(ret));
  551. return ret;
  552. }
  553. /**
  554. * @param i index in constant pool
  555. * @return constant pool entry at index i
  556. */
  557. public Constant getConstant(int i) { return constants[i]; }
  558. /**
  559. * Use with care!
  560. *
  561. * @param i index in constant pool
  562. * @param c new constant pool entry at index i
  563. */
  564. public void setConstant(int i, Constant c) { constants[i] = c; }
  565. /**
  566. * @return intermediate constant pool
  567. */
  568. public ConstantPool getConstantPool() {
  569. return new ConstantPool(constants);
  570. }
  571. /**
  572. * @return current size of constant pool
  573. */
  574. public int getSize() {
  575. return index;
  576. }
  577. /**
  578. * @return constant pool with proper length
  579. */
  580. public ConstantPool getFinalConstantPool() {
  581. Constant[] cs = new Constant[index];
  582. System.arraycopy(constants, 0, cs, 0, index);
  583. return new ConstantPool(cs);
  584. }
  585. /**
  586. * @return String representation.
  587. */
  588. public String toString() {
  589. StringBuffer buf = new StringBuffer();
  590. for(int i=1; i < index; i++)
  591. buf.append(i + ")" + constants[i] + "\n");
  592. return buf.toString();
  593. }
  594. /** Import constant from another ConstantPool and return new index.
  595. */
  596. public int addConstant(Constant c, ConstantPoolGen cp) {
  597. Constant[] constants = cp.getConstantPool().getConstantPool();
  598. switch(c.getTag()) {
  599. case Constants.CONSTANT_String: {
  600. ConstantString s = (ConstantString)c;
  601. ConstantUtf8 u8 = (ConstantUtf8)constants[s.getStringIndex()];
  602. return addString(u8.getBytes());
  603. }
  604. case Constants.CONSTANT_Class: {
  605. ConstantClass s = (ConstantClass)c;
  606. ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()];
  607. return addClass(u8.getBytes());
  608. }
  609. case Constants.CONSTANT_NameAndType: {
  610. ConstantNameAndType n = (ConstantNameAndType)c;
  611. ConstantUtf8 u8 = (ConstantUtf8)constants[n.getNameIndex()];
  612. ConstantUtf8 u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()];
  613. return addNameAndType(u8.getBytes(), u8_2.getBytes());
  614. }
  615. case Constants.CONSTANT_Utf8:
  616. return addUtf8(((ConstantUtf8)c).getBytes());
  617. case Constants.CONSTANT_Double:
  618. return addDouble(((ConstantDouble)c).getBytes());
  619. case Constants.CONSTANT_Float:
  620. return addFloat(((ConstantFloat)c).getBytes());
  621. case Constants.CONSTANT_Long:
  622. return addLong(((ConstantLong)c).getBytes());
  623. case Constants.CONSTANT_Integer:
  624. return addInteger(((ConstantInteger)c).getBytes());
  625. case Constants.CONSTANT_InterfaceMethodref: case Constants.CONSTANT_Methodref:
  626. case Constants.CONSTANT_Fieldref: {
  627. ConstantCP m = (ConstantCP)c;
  628. ConstantClass clazz = (ConstantClass)constants[m.getClassIndex()];
  629. ConstantNameAndType n = (ConstantNameAndType)constants[m.getNameAndTypeIndex()];
  630. ConstantUtf8 u8 = (ConstantUtf8)constants[clazz.getNameIndex()];
  631. String class_name = u8.getBytes().replace('/', '.');
  632. u8 = (ConstantUtf8)constants[n.getNameIndex()];
  633. String name = u8.getBytes();
  634. u8 = (ConstantUtf8)constants[n.getSignatureIndex()];
  635. String signature = u8.getBytes();
  636. switch(c.getTag()) {
  637. case Constants.CONSTANT_InterfaceMethodref:
  638. return addInterfaceMethodref(class_name, name, signature);
  639. case Constants.CONSTANT_Methodref:
  640. return addMethodref(class_name, name, signature);
  641. case Constants.CONSTANT_Fieldref:
  642. return addFieldref(class_name, name, signature);
  643. default: // Never reached
  644. throw new RuntimeException("Unknown constant type " + c);
  645. }
  646. }
  647. default: // Never reached
  648. throw new RuntimeException("Unknown constant type " + c);
  649. }
  650. }
  651. }