1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.jdo.impl.enhancer.classfile;
20
21 /***
22 * InsnUtils provides a set of static methods which serve to
23 * select vm instructions during code annotation.
24 */
25 public
26 class InsnUtils implements VMConstants {
27
28 /***
29 * Return the best instruction for loading a value from the constant
30 * pool onto the stack - hopefully use short form
31 */
32
33 public static Insn constantValue(ConstValue value) {
34 int tag = value.tag();
35 switch (tag) {
36 case CONSTANTInteger :
37 case CONSTANTFloat :
38 case CONSTANTString :
39
40 int opcode = (value.getIndex() <= 0xFF ? opc_ldc : opc_ldc_w);
41 return Insn.create(opcode, value);
42 case CONSTANTLong :
43 case CONSTANTDouble :
44
45 return Insn.create(opc_ldc2_w, value);
46 default:
47 throw new InsnError("bad constant tag");
48 }
49 }
50
51 /***
52 * Return the best instruction for loading the specified String
53 * constant onto the stack - hopefully use short form
54 */
55
56 public static Insn stringConstant(String s, ConstantPool pool) {
57
58 return constantValue(pool.addString(s));
59 }
60
61 /***
62 * Return the best instruction for loading the specified integer
63 * constant onto the stack - hopefully use short form
64 */
65 public static Insn integerConstant(int i, ConstantPool pool) {
66
67
68 if (i == -1)
69 return Insn.create(opc_iconst_m1);
70 if (i == 0)
71 return Insn.create(opc_iconst_0);
72 if (i == 1)
73 return Insn.create(opc_iconst_1);
74 if (i == 2)
75 return Insn.create(opc_iconst_2);
76 if (i == 3)
77 return Insn.create(opc_iconst_3);
78 if (i == 4)
79 return Insn.create(opc_iconst_4);
80 if (i == 5)
81 return Insn.create(opc_iconst_5);
82 if (i >= -128 && i < 128)
83 return Insn.create(opc_bipush, i);
84
85 if (i >= -32768 && i < 32768)
86 return Insn.create(opc_sipush, i);
87
88
89 return constantValue(pool.addInteger(i));
90 }
91
92 /***
93 * Return the best instruction for loading the specified long constant onto
94 * the stack.
95 */
96 public static Insn longConstant(long l, ConstantPool pool) {
97
98 if (l == 0)
99 return Insn.create(opc_lconst_0);
100 if (l == 1)
101 return Insn.create(opc_lconst_1);
102
103
104 return constantValue(pool.addLong(l));
105 }
106
107 /***
108 * Return the best instruction for loading the specified float constant onto
109 * the stack.
110 */
111 public static Insn floatConstant(float f, ConstantPool pool) {
112
113 if (f == 0)
114 return Insn.create(opc_fconst_0);
115 if (f == 1)
116 return Insn.create(opc_fconst_1);
117 if (f == 2)
118 return Insn.create(opc_fconst_2);
119
120
121 return constantValue(pool.addFloat(f));
122 }
123
124 /***
125 * Return the best instruction for loading the specified double constant onto
126 * the stack.
127 */
128 public static Insn doubleConstant(double d, ConstantPool pool) {
129
130 if (d == 0)
131 return Insn.create(opc_dconst_0);
132 if (d == 1)
133 return Insn.create(opc_dconst_1);
134
135
136 return constantValue(pool.addDouble(d));
137 }
138
139 /***
140 * Return the best instruction for storing a reference to a local
141 * variable slot
142 */
143 public static Insn aStore(int i, ConstantPool pool) {
144 if (i == 0)
145 return Insn.create(opc_astore_0);
146 else if (i == 1)
147 return Insn.create(opc_astore_1);
148 else if (i == 2)
149 return Insn.create(opc_astore_2);
150 else if (i == 3)
151 return Insn.create(opc_astore_3);
152 return Insn.create(opc_astore, i);
153 }
154
155 /***
156 * Return the best instruction for storing an int to a local
157 * variable slot
158 */
159 public static Insn iStore(int i, ConstantPool pool) {
160 if (i == 0)
161 return Insn.create(opc_istore_0);
162 else if (i == 1)
163 return Insn.create(opc_istore_1);
164 else if (i == 2)
165 return Insn.create(opc_istore_2);
166 else if (i == 3)
167 return Insn.create(opc_istore_3);
168 return Insn.create(opc_istore, i);
169 }
170
171 /***
172 * Return the best instruction for storing a float to a local
173 * variable slot
174 */
175 public static Insn fStore(int i, ConstantPool pool) {
176 if (i == 0)
177 return Insn.create(opc_fstore_0);
178 else if (i == 1)
179 return Insn.create(opc_fstore_1);
180 else if (i == 2)
181 return Insn.create(opc_fstore_2);
182 else if (i == 3)
183 return Insn.create(opc_fstore_3);
184 return Insn.create(opc_fstore, i);
185 }
186
187 /***
188 * Return the best instruction for storing a long to a local
189 * variable slot
190 */
191 public static Insn lStore(int i, ConstantPool pool) {
192 if (i == 0)
193 return Insn.create(opc_lstore_0);
194 else if (i == 1)
195 return Insn.create(opc_lstore_1);
196 else if (i == 2)
197 return Insn.create(opc_lstore_2);
198 else if (i == 3)
199 return Insn.create(opc_lstore_3);
200 return Insn.create(opc_lstore, i);
201 }
202
203 /***
204 * Return the best instruction for storing a double to a local
205 * variable slot
206 */
207 public static Insn dStore(int i, ConstantPool pool) {
208 if (i == 0)
209 return Insn.create(opc_dstore_0);
210 else if (i == 1)
211 return Insn.create(opc_dstore_1);
212 else if (i == 2)
213 return Insn.create(opc_dstore_2);
214 else if (i == 3)
215 return Insn.create(opc_dstore_3);
216 return Insn.create(opc_dstore, i);
217 }
218
219 /***
220 * Return the best instruction for loading a reference from a local
221 * variable slot
222 */
223 public static Insn aLoad(int i, ConstantPool pool) {
224 if (i == 0)
225 return Insn.create(opc_aload_0);
226 else if (i == 1)
227 return Insn.create(opc_aload_1);
228 else if (i == 2)
229 return Insn.create(opc_aload_2);
230 else if (i == 3)
231 return Insn.create(opc_aload_3);
232 return Insn.create(opc_aload, i);
233 }
234
235 /***
236 * Return the best instruction for loading an int from a local
237 * variable slot
238 */
239 public static Insn iLoad(int i, ConstantPool pool) {
240 if (i == 0)
241 return Insn.create(opc_iload_0);
242 else if (i == 1)
243 return Insn.create(opc_iload_1);
244 else if (i == 2)
245 return Insn.create(opc_iload_2);
246 else if (i == 3)
247 return Insn.create(opc_iload_3);
248 return Insn.create(opc_iload, i);
249 }
250
251 /***
252 * Return the best instruction for loading a float from a local
253 * variable slot
254 */
255 public static Insn fLoad(int i, ConstantPool pool) {
256 if (i == 0)
257 return Insn.create(opc_fload_0);
258 else if (i == 1)
259 return Insn.create(opc_fload_1);
260 else if (i == 2)
261 return Insn.create(opc_fload_2);
262 else if (i == 3)
263 return Insn.create(opc_fload_3);
264 return Insn.create(opc_fload, i);
265 }
266
267 /***
268 * Return the best instruction for loading a long from a local
269 * variable slot
270 */
271 public static Insn lLoad(int i, ConstantPool pool) {
272 if (i == 0)
273 return Insn.create(opc_lload_0);
274 else if (i == 1)
275 return Insn.create(opc_lload_1);
276 else if (i == 2)
277 return Insn.create(opc_lload_2);
278 else if (i == 3)
279 return Insn.create(opc_lload_3);
280 return Insn.create(opc_lload, i);
281 }
282
283 /***
284 * Return the best instruction for loading a double from a local
285 * variable slot
286 */
287 public static Insn dLoad(int i, ConstantPool pool) {
288 if (i == 0)
289 return Insn.create(opc_dload_0);
290 else if (i == 1)
291 return Insn.create(opc_dload_1);
292 else if (i == 2)
293 return Insn.create(opc_dload_2);
294 else if (i == 3)
295 return Insn.create(opc_dload_3);
296 return Insn.create(opc_dload, i);
297 }
298
299 /***
300 * Return the best instruction for loading a value from a local
301 * variable slot
302 */
303 public static Insn load(int tp, int i, ConstantPool pool) {
304 switch(tp) {
305
306 case T_BOOLEAN:
307 case T_CHAR:
308 case T_BYTE:
309 case T_SHORT:
310
311 case T_INT:
312 return iLoad(i, pool);
313 case T_FLOAT:
314 return fLoad(i, pool);
315 case T_DOUBLE:
316 return dLoad(i, pool);
317 case T_LONG:
318 return lLoad(i, pool);
319 case TC_OBJECT:
320 return aLoad(i, pool);
321 default:
322 throw new InsnError("bad load type");
323 }
324 }
325
326 /***
327 * Return the best instruction for storing a value to a local
328 * variable slot
329 */
330 public static Insn store(int tp, int i, ConstantPool pool) {
331 switch(tp) {
332
333 case T_BOOLEAN:
334 case T_CHAR:
335 case T_BYTE:
336 case T_SHORT:
337
338 case T_INT:
339 return iStore(i, pool);
340 case T_FLOAT:
341 return fStore(i, pool);
342 case T_DOUBLE:
343 return dStore(i, pool);
344 case T_LONG:
345 return lStore(i, pool);
346 case TC_OBJECT:
347 return aStore(i, pool);
348 default:
349 throw new InsnError("bad store type");
350 }
351 }
352 }