| CLConstantPool.java |
1 // Copyright 2012- Bill Campbell, Swami Iyer and Bahar Akbal-Delibas
2
3 package jminusminus;
4
5 import java.io.IOException;
6 import java.util.ArrayList;
7
8 /**
9 * Representation of a class' constant pool.
10 */
11 class CLConstantPool {
12 // Index of the next item into the constant pool.
13 private int cpIndex;
14
15 // List of constant pool items.
16 private ArrayList<CLCPInfo> cpItems;
17
18 /**
19 * Constructs an empty constant pool.
20 */
21 public CLConstantPool() {
22 cpIndex = 1;
23 cpItems = new ArrayList<CLCPInfo>();
24 }
25
26 /**
27 * Returns the size of the constant pool.
28 *
29 * @return the size of the constant pool.
30 */
31 public int size() {
32 return cpItems.size();
33 }
34
35 /**
36 * Returns the index of the specified item in the constant pool or -1.
37 *
38 * @param cpInfo item to find.
39 * @return the index of the specified item in the constant pool or -1.
40 */
41 public int find(CLCPInfo cpInfo) {
42 int index = cpItems.indexOf(cpInfo);
43 return (index != -1) ? cpItems.get(index).cpIndex : index;
44 }
45
46 /**
47 * Returns the constant pool item at the specified index or null.
48 *
49 * @param i constant pool index.
50 * @return the constant pool item at the specified index or null.
51 */
52 public CLCPInfo cpItem(int i) {
53 if (((i - 1) < 0) || ((i - 1) >= cpItems.size())) {
54 return null;
55 }
56 return cpItems.get(i - 1);
57 }
58
59 /**
60 * Adds the specified (non-null) item to the constant pool and returns its index.
61 *
62 * @param cpInfo the item to add.
63 * @return constant pool index of the item.
64 */
65 public int addCPItem(CLCPInfo cpInfo) {
66 cpInfo.cpIndex = cpIndex++;
67 cpItems.add(cpInfo);
68
69 // long and double, with their lower and higher words, are treated by JVM as two items in
70 // the constant pool. We have a single representation for each, so we add a null as
71 // a placeholder in the second slot.
72 if ((cpInfo instanceof CLConstantLongInfo) || (cpInfo instanceof CLConstantDoubleInfo)) {
73 cpIndex++;
74 cpItems.add(null);
75 }
76 return cpInfo.cpIndex;
77 }
78
79 /**
80 * Writes the contents of the constant pool to the specified output stream.
81 *
82 * @param out output stream.
83 * @throws IOException if an error occurs while writing.
84 */
85 public void write(CLOutputStream out) throws IOException {
86 for (CLCPInfo cpInfo : cpItems) {
87 if (cpInfo != null) {
88 cpInfo.write(out);
89 }
90 }
91 }
92
93 /**
94 * Returns the constant pool index of a singleton instance of CLConstantClassInfo.
95 *
96 * @param className class or interface name in internal form.
97 * @return constant pool index.
98 */
99 public int constantClassInfo(String className) {
100 CLCPInfo c = new CLConstantClassInfo(constantUtf8Info(className));
101 return findOrAdd(c);
102 }
103
104 /**
105 * Returns the constant pool index of a singleton instance of CLConstantFieldRefInfo.
106 *
107 * @param className class or interface name in internal form.
108 * @param name name of the field.
109 * @param type descriptor of the field.
110 * @return constant pool index.
111 */
112 public int constantFieldRefInfo(String className, String name, String type) {
113 CLCPInfo c = new CLConstantFieldRefInfo(constantClassInfo(className),
114 constantNameAndTypeInfo(name, type));
115 return findOrAdd(c);
116 }
117
118 /**
119 * Returns the constant pool index of a singleton instance of CLConstantMethodRefInfo.
120 *
121 * @param className class or interface name in internal form.
122 * @param name name of the method.
123 * @param type descriptor of the method.
124 * @return constant pool index.
125 */
126 public int constantMethodRefInfo(String className, String name, String type) {
127 CLCPInfo c = new CLConstantMethodRefInfo(constantClassInfo(className),
128 constantNameAndTypeInfo(name, type));
129 return findOrAdd(c);
130 }
131
132 /**
133 * Returns the constant pool index of a singleton instance of CLConstantInterfaceMethodRefInfo.
134 *
135 * @param className class or interface name in internal form.
136 * @param name name of the method.
137 * @param type descriptor of the method.
138 * @return constant pool index.
139 */
140 public int constantInterfaceMethodRefInfo(String className, String name, String type) {
141 CLCPInfo c = new CLConstantInterfaceMethodRefInfo(
142 constantClassInfo(className), constantNameAndTypeInfo(name, type));
143 return findOrAdd(c);
144 }
145
146 /**
147 * Returns the constant pool index of a singleton instance of CLConstantStringInfo.
148 *
149 * @param s the constant string value.
150 * @return constant pool index.
151 */
152 public int constantStringInfo(String s) {
153 CLCPInfo c = new CLConstantStringInfo(constantUtf8Info(s));
154 return findOrAdd(c);
155 }
156
157 /**
158 * Returns the constant pool index of a singleton instance of CLConstantIntegerInfo.
159 *
160 * @param i the constant int value.
161 * @return constant pool index.
162 */
163 public int constantIntegerInfo(int i) {
164 CLCPInfo c = new CLConstantIntegerInfo(i);
165 return findOrAdd(c);
166 }
167
168 /**
169 * Returns the constant pool index of a singleton instance of CLConstantFloatInfo.
170 *
171 * @param f the constant floating-point value.
172 * @return constant pool index.
173 */
174 public int constantFloatInfo(float f) {
175 CLCPInfo c = new CLConstantFloatInfo(f);
176 return findOrAdd(c);
177 }
178
179 /**
180 * Returns the constant pool index of a singleton instance of CLConstantLongInfo.
181 *
182 * @param l the constant long value.
183 * @return constant pool index.
184 */
185 public int constantLongInfo(long l) {
186 CLCPInfo c = new CLConstantLongInfo(l);
187 return findOrAdd(c);
188 }
189
190 /**
191 * Returns the constant pool index of a singleton instance of CLConstantDoubleInfo.
192 *
193 * @param d the constant double value.
194 * @return constant pool index.
195 */
196 public int constantDoubleInfo(double d) {
197 CLCPInfo c = new CLConstantDoubleInfo(d);
198 return findOrAdd(c);
199 }
200
201 /**
202 * Returns the constant pool index of a singleton instance of CLConstantNameAndTypeInfo.
203 *
204 * @param name field or method name.
205 * @param type field or method type descriptor.
206 * @return constant pool index.
207 */
208 public int constantNameAndTypeInfo(String name, String type) {
209 CLCPInfo c = new CLConstantNameAndTypeInfo(constantUtf8Info(name), constantUtf8Info(type));
210 return findOrAdd(c);
211 }
212
213 /**
214 * Returns the constant pool index of a singleton instance of CLConstantUtf8Info.
215 *
216 * @param s the constant string value.
217 * @return constant pool index.
218 */
219 public int constantUtf8Info(String s) {
220 CLCPInfo c = new CLConstantUtf8Info(s.getBytes());
221 return findOrAdd(c);
222 }
223
224 // Returns the index of the specified item in the constant pool. If the item does not exist,
225 // adds the item to the pool and return its (new) index.
226 private int findOrAdd(CLCPInfo cpInfo) {
227 int index = find(cpInfo);
228 if (index == -1) {
229 index = addCPItem(cpInfo);
230 }
231 return index;
232 }
233 }
234