View Javadoc

1   /*
2    * Copyright 2005 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at 
7    * 
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software 
11   * distributed under the License is distributed on an "AS IS" BASIS, 
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
13   * See the License for the specific language governing permissions and 
14   * limitations under the License.
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      //@olsen: added method
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              //@olsen: check index range to select opc_ldc vs. opc_ldc_w
39              int opcode = (value.getIndex() <= 0xFF ? opc_ldc : opc_ldc_w);
40              return Insn.create(opcode, value);
41          case CONSTANTLong :
42          case CONSTANTDouble :
43              //@olsen: require opc_ldc2_w (there's no short form: opc_ldc2)
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      //@olsen: added method
55      public static Insn stringConstant(String s, ConstantPool pool) {
56          //@olsen: need to carefully select opc_ldc/opc_ldc_w/opc_ldc2_w
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          //@olsen: removed redundant 'else's
66          //@olsen: added use of opc_iconst_m1
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          //@olsen: added use of opc_sipush
84          if (i >= -32768 && i < 32768)
85              return Insn.create(opc_sipush, i);
86          //@olsen: need to carefully select opc_ldc/opc_ldc_w/opc_ldc2_w
87          //return Insn.create(opc_ldc, pool.addInteger(i));
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          //@olsen: removed redundant 'else's
97          if (l == 0)
98              return Insn.create(opc_lconst_0);
99          if (l == 1)
100             return Insn.create(opc_lconst_1);
101         //@olsen: need to carefully select opc_ldc/opc_ldc_w/opc_ldc2_w
102         //return Insn.create(opc_ldc2_w, pool.addLong(l));
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         //@olsen: removed redundant 'else's
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         //@olsen: need to carefully select opc_ldc/opc_ldc_w/opc_ldc2_w
119         //return Insn.create(opc_ldc, pool.addFloat(f));
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         //@olsen: removed redundant 'else's
129         if (d == 0)
130             return Insn.create(opc_dconst_0);
131         if (d == 1)
132             return Insn.create(opc_dconst_1);
133         //@olsen: need to carefully select opc_ldc/opc_ldc_w/opc_ldc2_w
134         //return Insn.create(opc_ldc2_w, pool.addDouble(d));
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             //@olsen: added these cases:
305         case T_BOOLEAN:
306         case T_CHAR:
307         case T_BYTE:
308         case T_SHORT:
309             //@olsen: end added cases
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             //@olsen: added these cases:
332         case T_BOOLEAN:
333         case T_CHAR:
334         case T_BYTE:
335         case T_SHORT:
336             //@olsen: end added cases
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 }