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