View Javadoc

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