/jEdit/tags/jedit-4-3-pre10/bsh/org/objectweb/asm/ClassWriter.java

# · Java · 950 lines · 398 code · 148 blank · 404 comment · 91 complexity · b20f4f64ccad6eebf427633d6256d644 MD5 · raw file

  1. /***
  2. * ASM: a very small and fast Java bytecode manipulation framework
  3. * Copyright (C) 2000 INRIA, France Telecom
  4. * Copyright (C) 2002 France Telecom
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. *
  20. * Contact: Eric.Bruneton@rd.francetelecom.com
  21. *
  22. * Author: Eric Bruneton
  23. */
  24. package bsh.org.objectweb.asm;
  25. /**
  26. * A {@link ClassVisitor ClassVisitor} that generates Java class files. More
  27. * precisely this visitor generates a byte array conforming to the Java class
  28. * file format. It can be used alone, to generate a Java class "from scratch",
  29. * or with one or more {@link ClassReader ClassReader} and adapter class
  30. * visitor to generate a modified class from one or more existing Java classes.
  31. */
  32. public class ClassWriter implements ClassVisitor {
  33. /**
  34. * The type of CONSTANT_Class constant pool items.
  35. */
  36. final static int CLASS = 7;
  37. /**
  38. * The type of CONSTANT_Fieldref constant pool items.
  39. */
  40. final static int FIELD = 9;
  41. /**
  42. * The type of CONSTANT_Methodref constant pool items.
  43. */
  44. final static int METH = 10;
  45. /**
  46. * The type of CONSTANT_InterfaceMethodref constant pool items.
  47. */
  48. final static int IMETH = 11;
  49. /**
  50. * The type of CONSTANT_String constant pool items.
  51. */
  52. final static int STR = 8;
  53. /**
  54. * The type of CONSTANT_Integer constant pool items.
  55. */
  56. final static int INT = 3;
  57. /**
  58. * The type of CONSTANT_Float constant pool items.
  59. */
  60. final static int FLOAT = 4;
  61. /**
  62. * The type of CONSTANT_Long constant pool items.
  63. */
  64. final static int LONG = 5;
  65. /**
  66. * The type of CONSTANT_Double constant pool items.
  67. */
  68. final static int DOUBLE = 6;
  69. /**
  70. * The type of CONSTANT_NameAndType constant pool items.
  71. */
  72. final static int NAME_TYPE = 12;
  73. /**
  74. * The type of CONSTANT_Utf8 constant pool items.
  75. */
  76. final static int UTF8 = 1;
  77. /**
  78. * Index of the next item to be added in the constant pool.
  79. */
  80. private short index;
  81. /**
  82. * The constant pool of this class.
  83. */
  84. private ByteVector pool;
  85. /**
  86. * The constant pool's hash table data.
  87. */
  88. private Item[] table;
  89. /**
  90. * The threshold of the constant pool's hash table.
  91. */
  92. private int threshold;
  93. /**
  94. * The access flags of this class.
  95. */
  96. private int access;
  97. /**
  98. * The constant pool item that contains the internal name of this class.
  99. */
  100. private int name;
  101. /**
  102. * The constant pool item that contains the internal name of the super class
  103. * of this class.
  104. */
  105. private int superName;
  106. /**
  107. * Number of interfaces implemented or extended by this class or interface.
  108. */
  109. private int interfaceCount;
  110. /**
  111. * The interfaces implemented or extended by this class or interface. More
  112. * precisely, this array contains the indexes of the constant pool items
  113. * that contain the internal names of these interfaces.
  114. */
  115. private int[] interfaces;
  116. /**
  117. * The constant pool item that contains the name of the source file from
  118. * which this class was compiled.
  119. */
  120. private Item sourceFile;
  121. /**
  122. * Number of fields of this class.
  123. */
  124. private int fieldCount;
  125. /**
  126. * The fields of this class.
  127. */
  128. private ByteVector fields;
  129. /**
  130. * <tt>true</tt> if the maximum stack size and number of local variables must
  131. * be automatically computed.
  132. */
  133. private boolean computeMaxs;
  134. /**
  135. * The methods of this class. These methods are stored in a linked list of
  136. * {@link CodeWriter CodeWriter} objects, linked to each other by their {@link
  137. * CodeWriter#next} field. This field stores the first element of this list.
  138. */
  139. CodeWriter firstMethod;
  140. /**
  141. * The methods of this class. These methods are stored in a linked list of
  142. * {@link CodeWriter CodeWriter} objects, linked to each other by their {@link
  143. * CodeWriter#next} field. This field stores the last element of this list.
  144. */
  145. CodeWriter lastMethod;
  146. /**
  147. * The number of entries in the InnerClasses attribute.
  148. */
  149. private int innerClassesCount;
  150. /**
  151. * The InnerClasses attribute.
  152. */
  153. private ByteVector innerClasses;
  154. /**
  155. * A reusable key used to look for items in the hash {@link #table table}.
  156. */
  157. Item key;
  158. /**
  159. * A reusable key used to look for items in the hash {@link #table table}.
  160. */
  161. Item key2;
  162. /**
  163. * A reusable key used to look for items in the hash {@link #table table}.
  164. */
  165. Item key3;
  166. /**
  167. * The type of instructions without any label.
  168. */
  169. final static int NOARG_INSN = 0;
  170. /**
  171. * The type of instructions with an signed byte label.
  172. */
  173. final static int SBYTE_INSN = 1;
  174. /**
  175. * The type of instructions with an signed short label.
  176. */
  177. final static int SHORT_INSN = 2;
  178. /**
  179. * The type of instructions with a local variable index label.
  180. */
  181. final static int VAR_INSN = 3;
  182. /**
  183. * The type of instructions with an implicit local variable index label.
  184. */
  185. final static int IMPLVAR_INSN = 4;
  186. /**
  187. * The type of instructions with a type descriptor argument.
  188. */
  189. final static int TYPE_INSN = 5;
  190. /**
  191. * The type of field and method invocations instructions.
  192. */
  193. final static int FIELDORMETH_INSN = 6;
  194. /**
  195. * The type of the INVOKEINTERFACE instruction.
  196. */
  197. final static int ITFMETH_INSN = 7;
  198. /**
  199. * The type of instructions with a 2 bytes bytecode offset label.
  200. */
  201. final static int LABEL_INSN = 8;
  202. /**
  203. * The type of instructions with a 4 bytes bytecode offset label.
  204. */
  205. final static int LABELW_INSN = 9;
  206. /**
  207. * The type of the LDC instruction.
  208. */
  209. final static int LDC_INSN = 10;
  210. /**
  211. * The type of the LDC_W and LDC2_W instructions.
  212. */
  213. final static int LDCW_INSN = 11;
  214. /**
  215. * The type of the IINC instruction.
  216. */
  217. final static int IINC_INSN = 12;
  218. /**
  219. * The type of the TABLESWITCH instruction.
  220. */
  221. final static int TABL_INSN = 13;
  222. /**
  223. * The type of the LOOKUPSWITCH instruction.
  224. */
  225. final static int LOOK_INSN = 14;
  226. /**
  227. * The type of the MULTIANEWARRAY instruction.
  228. */
  229. final static int MANA_INSN = 15;
  230. /**
  231. * The type of the WIDE instruction.
  232. */
  233. final static int WIDE_INSN = 16;
  234. /**
  235. * The instruction types of all JVM opcodes.
  236. */
  237. static byte[] TYPE;
  238. // --------------------------------------------------------------------------
  239. // Static initializer
  240. // --------------------------------------------------------------------------
  241. /**
  242. * Computes the instruction types of JVM opcodes.
  243. */
  244. static {
  245. int i;
  246. byte[] b = new byte[220];
  247. String s =
  248. "AAAAAAAAAAAAAAAABCKLLDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADDDDDEEEEEEEEE" +
  249. "EEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAA" +
  250. "AAAAAAAAAAAAAAAAAIIIIIIIIIIIIIIIIDNOAAAAAAGGGGGGGHAFBFAAFFAAQPIIJJII" +
  251. "IIIIIIIIIIIIIIII";
  252. for (i = 0; i < b.length; ++i) {
  253. b[i] = (byte)(s.charAt(i) - 'A');
  254. }
  255. TYPE = b;
  256. /* code to generate the above string
  257. // SBYTE_INSN instructions
  258. b[Constants.NEWARRAY] = SBYTE_INSN;
  259. b[Constants.BIPUSH] = SBYTE_INSN;
  260. // SHORT_INSN instructions
  261. b[Constants.SIPUSH] = SHORT_INSN;
  262. // (IMPL)VAR_INSN instructions
  263. b[Constants.RET] = VAR_INSN;
  264. for (i = Constants.ILOAD; i <= Constants.ALOAD; ++i) {
  265. b[i] = VAR_INSN;
  266. }
  267. for (i = Constants.ISTORE; i <= Constants.ASTORE; ++i) {
  268. b[i] = VAR_INSN;
  269. }
  270. for (i = 26; i <= 45; ++i) { // ILOAD_0 to ALOAD_3
  271. b[i] = IMPLVAR_INSN;
  272. }
  273. for (i = 59; i <= 78; ++i) { // ISTORE_0 to ASTORE_3
  274. b[i] = IMPLVAR_INSN;
  275. }
  276. // TYPE_INSN instructions
  277. b[Constants.NEW] = TYPE_INSN;
  278. b[Constants.ANEWARRAY] = TYPE_INSN;
  279. b[Constants.CHECKCAST] = TYPE_INSN;
  280. b[Constants.INSTANCEOF] = TYPE_INSN;
  281. // (Set)FIELDORMETH_INSN instructions
  282. for (i = Constants.GETSTATIC; i <= Constants.INVOKESTATIC; ++i) {
  283. b[i] = FIELDORMETH_INSN;
  284. }
  285. b[Constants.INVOKEINTERFACE] = ITFMETH_INSN;
  286. // LABEL(W)_INSN instructions
  287. for (i = Constants.IFEQ; i <= Constants.JSR; ++i) {
  288. b[i] = LABEL_INSN;
  289. }
  290. b[Constants.IFNULL] = LABEL_INSN;
  291. b[Constants.IFNONNULL] = LABEL_INSN;
  292. b[200] = LABELW_INSN; // GOTO_W
  293. b[201] = LABELW_INSN; // JSR_W
  294. // temporary opcodes used internally by ASM - see Label and CodeWriter
  295. for (i = 202; i < 220; ++i) {
  296. b[i] = LABEL_INSN;
  297. }
  298. // LDC(_W) instructions
  299. b[Constants.LDC] = LDC_INSN;
  300. b[19] = LDCW_INSN; // LDC_W
  301. b[20] = LDCW_INSN; // LDC2_W
  302. // special instructions
  303. b[Constants.IINC] = IINC_INSN;
  304. b[Constants.TABLESWITCH] = TABL_INSN;
  305. b[Constants.LOOKUPSWITCH] = LOOK_INSN;
  306. b[Constants.MULTIANEWARRAY] = MANA_INSN;
  307. b[196] = WIDE_INSN; // WIDE
  308. for (i = 0; i < b.length; ++i) {
  309. System.err.print((char)('A' + b[i]));
  310. }
  311. System.err.println();
  312. */
  313. }
  314. // --------------------------------------------------------------------------
  315. // Constructor
  316. // --------------------------------------------------------------------------
  317. /**
  318. * Constructs a new {@link ClassWriter ClassWriter} object.
  319. *
  320. * @param computeMaxs <tt>true</tt> if the maximum stack size and the maximum
  321. * number of local variables must be automatically computed. If this flag
  322. * is <tt>true</tt>, then the arguments of the {@link
  323. * CodeVisitor#visitMaxs visitMaxs} method of the {@link CodeVisitor
  324. * CodeVisitor} returned by the {@link #visitMethod visitMethod} method
  325. * will be ignored, and computed automatically from the signature and
  326. * the bytecode of each method.
  327. */
  328. public ClassWriter (final boolean computeMaxs) {
  329. index = 1;
  330. pool = new ByteVector();
  331. table = new Item[64];
  332. threshold = (int)(0.75d*table.length);
  333. key = new Item();
  334. key2 = new Item();
  335. key3 = new Item();
  336. this.computeMaxs = computeMaxs;
  337. }
  338. // --------------------------------------------------------------------------
  339. // Implementation of the ClassVisitor interface
  340. // --------------------------------------------------------------------------
  341. public void visit (
  342. final int access,
  343. final String name,
  344. final String superName,
  345. final String[] interfaces,
  346. final String sourceFile)
  347. {
  348. this.access = access;
  349. this.name = newClass(name).index;
  350. this.superName = superName == null ? 0 : newClass(superName).index;
  351. if (interfaces != null && interfaces.length > 0) {
  352. interfaceCount = interfaces.length;
  353. this.interfaces = new int[interfaceCount];
  354. for (int i = 0; i < interfaceCount; ++i) {
  355. this.interfaces[i] = newClass(interfaces[i]).index;
  356. }
  357. }
  358. if (sourceFile != null) {
  359. newUTF8("SourceFile");
  360. this.sourceFile = newUTF8(sourceFile);
  361. }
  362. if ((access & Constants.ACC_DEPRECATED) != 0) {
  363. newUTF8("Deprecated");
  364. }
  365. }
  366. public void visitInnerClass (
  367. final String name,
  368. final String outerName,
  369. final String innerName,
  370. final int access)
  371. {
  372. if (innerClasses == null) {
  373. newUTF8("InnerClasses");
  374. innerClasses = new ByteVector();
  375. }
  376. ++innerClassesCount;
  377. innerClasses.put2(name == null ? 0 : newClass(name).index);
  378. innerClasses.put2(outerName == null ? 0 : newClass(outerName).index);
  379. innerClasses.put2(innerName == null ? 0 : newUTF8(innerName).index);
  380. innerClasses.put2(access);
  381. }
  382. public void visitField (
  383. final int access,
  384. final String name,
  385. final String desc,
  386. final Object value)
  387. {
  388. ++fieldCount;
  389. if (fields == null) {
  390. fields = new ByteVector();
  391. }
  392. fields.put2(access).put2(newUTF8(name).index).put2(newUTF8(desc).index);
  393. int attributeCount = 0;
  394. if (value != null) {
  395. ++attributeCount;
  396. }
  397. if ((access & Constants.ACC_SYNTHETIC) != 0) {
  398. ++attributeCount;
  399. }
  400. if ((access & Constants.ACC_DEPRECATED) != 0) {
  401. ++attributeCount;
  402. }
  403. fields.put2(attributeCount);
  404. if (value != null) {
  405. fields.put2(newUTF8("ConstantValue").index);
  406. fields.put4(2).put2(newCst(value).index);
  407. }
  408. if ((access & Constants.ACC_SYNTHETIC) != 0) {
  409. fields.put2(newUTF8("Synthetic").index).put4(0);
  410. }
  411. if ((access & Constants.ACC_DEPRECATED) != 0) {
  412. fields.put2(newUTF8("Deprecated").index).put4(0);
  413. }
  414. }
  415. public CodeVisitor visitMethod (
  416. final int access,
  417. final String name,
  418. final String desc,
  419. final String[] exceptions)
  420. {
  421. CodeWriter cw = new CodeWriter(this, computeMaxs);
  422. cw.init(access, name, desc, exceptions);
  423. return cw;
  424. }
  425. public void visitEnd () {
  426. }
  427. // --------------------------------------------------------------------------
  428. // Other public methods
  429. // --------------------------------------------------------------------------
  430. /**
  431. * Returns the bytecode of the class that was build with this class writer.
  432. *
  433. * @return the bytecode of the class that was build with this class writer.
  434. */
  435. public byte[] toByteArray () {
  436. // computes the real size of the bytecode of this class
  437. int size = 24 + 2*interfaceCount;
  438. if (fields != null) {
  439. size += fields.length;
  440. }
  441. int nbMethods = 0;
  442. CodeWriter cb = firstMethod;
  443. while (cb != null) {
  444. ++nbMethods;
  445. size += cb.getSize();
  446. cb = cb.next;
  447. }
  448. size += pool.length;
  449. int attributeCount = 0;
  450. if (sourceFile != null) {
  451. ++attributeCount;
  452. size += 8;
  453. }
  454. if ((access & Constants.ACC_DEPRECATED) != 0) {
  455. ++attributeCount;
  456. size += 6;
  457. }
  458. if (innerClasses != null) {
  459. ++attributeCount;
  460. size += 8 + innerClasses.length;
  461. }
  462. // allocates a byte vector of this size, in order to avoid unnecessary
  463. // arraycopy operations in the ByteVector.enlarge() method
  464. ByteVector out = new ByteVector(size);
  465. out.put4(0xCAFEBABE).put2(3).put2(45);
  466. out.put2(index).putByteArray(pool.data, 0, pool.length);
  467. out.put2(access).put2(name).put2(superName);
  468. out.put2(interfaceCount);
  469. for (int i = 0; i < interfaceCount; ++i) {
  470. out.put2(interfaces[i]);
  471. }
  472. out.put2(fieldCount);
  473. if (fields != null) {
  474. out.putByteArray(fields.data, 0, fields.length);
  475. }
  476. out.put2(nbMethods);
  477. cb = firstMethod;
  478. while (cb != null) {
  479. cb.put(out);
  480. cb = cb.next;
  481. }
  482. out.put2(attributeCount);
  483. if (sourceFile != null) {
  484. out.put2(newUTF8("SourceFile").index).put4(2).put2(sourceFile.index);
  485. }
  486. if ((access & Constants.ACC_DEPRECATED) != 0) {
  487. out.put2(newUTF8("Deprecated").index).put4(0);
  488. }
  489. if (innerClasses != null) {
  490. out.put2(newUTF8("InnerClasses").index);
  491. out.put4(innerClasses.length + 2).put2(innerClassesCount);
  492. out.putByteArray(innerClasses.data, 0, innerClasses.length);
  493. }
  494. return out.data;
  495. }
  496. // --------------------------------------------------------------------------
  497. // Utility methods: constant pool management
  498. // --------------------------------------------------------------------------
  499. /**
  500. * Adds a number or string constant to the constant pool of the class being
  501. * build. Does nothing if the constant pool already contains a similar item.
  502. *
  503. * @param cst the value of the constant to be added to the constant pool. This
  504. * parameter must be an {@link java.lang.Integer Integer}, a {@link
  505. * java.lang.Float Float}, a {@link java.lang.Long Long}, a {@link
  506. java.lang.Double Double} or a {@link String String}.
  507. * @return a new or already existing constant item with the given value.
  508. */
  509. Item newCst (final Object cst) {
  510. if (cst instanceof Integer) {
  511. int val = ((Integer)cst).intValue();
  512. return newInteger(val);
  513. } else if (cst instanceof Float) {
  514. float val = ((Float)cst).floatValue();
  515. return newFloat(val);
  516. } else if (cst instanceof Long) {
  517. long val = ((Long)cst).longValue();
  518. return newLong(val);
  519. } else if (cst instanceof Double) {
  520. double val = ((Double)cst).doubleValue();
  521. return newDouble(val);
  522. } else if (cst instanceof String) {
  523. return newString((String)cst);
  524. } else {
  525. throw new IllegalArgumentException("value " + cst);
  526. }
  527. }
  528. /**
  529. * Adds an UTF string to the constant pool of the class being build. Does
  530. * nothing if the constant pool already contains a similar item.
  531. *
  532. * @param value the String value.
  533. * @return a new or already existing UTF8 item.
  534. */
  535. Item newUTF8 (final String value) {
  536. key.set(UTF8, value, null, null);
  537. Item result = get(key);
  538. if (result == null) {
  539. pool.put1(UTF8).putUTF(value);
  540. result = new Item(index++, key);
  541. put(result);
  542. }
  543. return result;
  544. }
  545. /**
  546. * Adds a class reference to the constant pool of the class being build. Does
  547. * nothing if the constant pool already contains a similar item.
  548. *
  549. * @param value the internal name of the class.
  550. * @return a new or already existing class reference item.
  551. */
  552. Item newClass (final String value) {
  553. key2.set(CLASS, value, null, null);
  554. Item result = get(key2);
  555. if (result == null) {
  556. pool.put12(CLASS, newUTF8(value).index);
  557. result = new Item(index++, key2);
  558. put(result);
  559. }
  560. return result;
  561. }
  562. /**
  563. * Adds a field reference to the constant pool of the class being build. Does
  564. * nothing if the constant pool already contains a similar item.
  565. *
  566. * @param owner the internal name of the field's owner class.
  567. * @param name the field's name.
  568. * @param desc the field's descriptor.
  569. * @return a new or already existing field reference item.
  570. */
  571. Item newField (
  572. final String owner,
  573. final String name,
  574. final String desc)
  575. {
  576. key3.set(FIELD, owner, name, desc);
  577. Item result = get(key3);
  578. if (result == null) {
  579. put122(FIELD, newClass(owner).index, newNameType(name, desc).index);
  580. result = new Item(index++, key3);
  581. put(result);
  582. }
  583. return result;
  584. }
  585. /**
  586. * Adds a method reference to the constant pool of the class being build. Does
  587. * nothing if the constant pool already contains a similar item.
  588. *
  589. * @param owner the internal name of the method's owner class.
  590. * @param name the method's name.
  591. * @param desc the method's descriptor.
  592. * @return a new or already existing method reference item.
  593. */
  594. Item newMethod (
  595. final String owner,
  596. final String name,
  597. final String desc)
  598. {
  599. key3.set(METH, owner, name, desc);
  600. Item result = get(key3);
  601. if (result == null) {
  602. put122(METH, newClass(owner).index, newNameType(name, desc).index);
  603. result = new Item(index++, key3);
  604. put(result);
  605. }
  606. return result;
  607. }
  608. /**
  609. * Adds an interface method reference to the constant pool of the class being
  610. * build. Does nothing if the constant pool already contains a similar item.
  611. *
  612. * @param ownerItf the internal name of the method's owner interface.
  613. * @param name the method's name.
  614. * @param desc the method's descriptor.
  615. * @return a new or already existing interface method reference item.
  616. */
  617. Item newItfMethod (
  618. final String ownerItf,
  619. final String name,
  620. final String desc)
  621. {
  622. key3.set(IMETH, ownerItf, name, desc);
  623. Item result = get(key3);
  624. if (result == null) {
  625. put122(IMETH, newClass(ownerItf).index, newNameType(name, desc).index);
  626. result = new Item(index++, key3);
  627. put(result);
  628. }
  629. return result;
  630. }
  631. /**
  632. * Adds an integer to the constant pool of the class being build. Does nothing
  633. * if the constant pool already contains a similar item.
  634. *
  635. * @param value the int value.
  636. * @return a new or already existing int item.
  637. */
  638. private Item newInteger (final int value) {
  639. key.set(value);
  640. Item result = get(key);
  641. if (result == null) {
  642. pool.put1(INT).put4(value);
  643. result = new Item(index++, key);
  644. put(result);
  645. }
  646. return result;
  647. }
  648. /**
  649. * Adds a float to the constant pool of the class being build. Does nothing if
  650. * the constant pool already contains a similar item.
  651. *
  652. * @param value the float value.
  653. * @return a new or already existing float item.
  654. */
  655. private Item newFloat (final float value) {
  656. key.set(value);
  657. Item result = get(key);
  658. if (result == null) {
  659. pool.put1(FLOAT).put4(Float.floatToIntBits(value));
  660. result = new Item(index++, key);
  661. put(result);
  662. }
  663. return result;
  664. }
  665. /**
  666. * Adds a long to the constant pool of the class being build. Does nothing if
  667. * the constant pool already contains a similar item.
  668. *
  669. * @param value the long value.
  670. * @return a new or already existing long item.
  671. */
  672. private Item newLong (final long value) {
  673. key.set(value);
  674. Item result = get(key);
  675. if (result == null) {
  676. pool.put1(LONG).put8(value);
  677. result = new Item(index, key);
  678. put(result);
  679. index += 2;
  680. }
  681. return result;
  682. }
  683. /**
  684. * Adds a double to the constant pool of the class being build. Does nothing
  685. * if the constant pool already contains a similar item.
  686. *
  687. * @param value the double value.
  688. * @return a new or already existing double item.
  689. */
  690. private Item newDouble (final double value) {
  691. key.set(value);
  692. Item result = get(key);
  693. if (result == null) {
  694. pool.put1(DOUBLE).put8(Double.doubleToLongBits(value));
  695. result = new Item(index, key);
  696. put(result);
  697. index += 2;
  698. }
  699. return result;
  700. }
  701. /**
  702. * Adds a string to the constant pool of the class being build. Does nothing
  703. * if the constant pool already contains a similar item.
  704. *
  705. * @param value the String value.
  706. * @return a new or already existing string item.
  707. */
  708. private Item newString (final String value) {
  709. key2.set(STR, value, null, null);
  710. Item result = get(key2);
  711. if (result == null) {
  712. pool.put12(STR, newUTF8(value).index);
  713. result = new Item(index++, key2);
  714. put(result);
  715. }
  716. return result;
  717. }
  718. /**
  719. * Adds a name and type to the constant pool of the class being build. Does
  720. * nothing if the constant pool already contains a similar item.
  721. *
  722. * @param name a name.
  723. * @param desc a type descriptor.
  724. * @return a new or already existing name and type item.
  725. */
  726. private Item newNameType (final String name, final String desc) {
  727. key2.set(NAME_TYPE, name, desc, null);
  728. Item result = get(key2);
  729. if (result == null) {
  730. put122(NAME_TYPE, newUTF8(name).index, newUTF8(desc).index);
  731. result = new Item(index++, key2);
  732. put(result);
  733. }
  734. return result;
  735. }
  736. /**
  737. * Returns the constant pool's hash table item which is equal to the given
  738. * item.
  739. *
  740. * @param key a constant pool item.
  741. * @return the constant pool's hash table item which is equal to the given
  742. * item, or <tt>null</tt> if there is no such item.
  743. */
  744. private Item get (final Item key) {
  745. Item tab[] = table;
  746. int hashCode = key.hashCode;
  747. int index = (hashCode & 0x7FFFFFFF) % tab.length;
  748. for (Item i = tab[index]; i != null; i = i.next) {
  749. if (i.hashCode == hashCode && key.isEqualTo(i)) {
  750. return i;
  751. }
  752. }
  753. return null;
  754. }
  755. /**
  756. * Puts the given item in the constant pool's hash table. The hash table
  757. * <i>must</i> not already contains this item.
  758. *
  759. * @param i the item to be added to the constant pool's hash table.
  760. */
  761. private void put (final Item i) {
  762. if (index > threshold) {
  763. int oldCapacity = table.length;
  764. Item oldMap[] = table;
  765. int newCapacity = oldCapacity * 2 + 1;
  766. Item newMap[] = new Item[newCapacity];
  767. threshold = (int)(newCapacity * 0.75);
  768. table = newMap;
  769. for (int j = oldCapacity; j-- > 0; ) {
  770. for (Item old = oldMap[j]; old != null; ) {
  771. Item e = old;
  772. old = old.next;
  773. int index = (e.hashCode & 0x7FFFFFFF) % newCapacity;
  774. e.next = newMap[index];
  775. newMap[index] = e;
  776. }
  777. }
  778. }
  779. int index = (i.hashCode & 0x7FFFFFFF) % table.length;
  780. i.next = table[index];
  781. table[index] = i;
  782. }
  783. /**
  784. * Puts one byte and two shorts into the constant pool.
  785. *
  786. * @param b a byte.
  787. * @param s1 a short.
  788. * @param s2 another short.
  789. */
  790. private void put122 (final int b, final int s1, final int s2) {
  791. pool.put12(b, s1).put2(s2);
  792. }
  793. }