View Javadoc

1   /*
2    * Copyright  2000-2004 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  package org.apache.bcel.generic;
18  
19  import org.apache.bcel.Constants;
20  
21  /*** 
22   * Wrapper class for push operations, which are implemented either as BIPUSH,
23   * LDC or xCONST_n instructions.
24   *
25   * @version $Id: PUSH.java 386056 2006-03-15 11:31:56Z tcurdt $
26   * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
27   */
28  public final class PUSH implements CompoundInstruction, VariableLengthInstruction,
29          InstructionConstants {
30  
31      private Instruction instruction;
32  
33  
34      /***
35       * This constructor also applies for values of type short, char, byte 
36       *
37       * @param cp Constant pool
38       * @param value to be pushed 
39       */
40      public PUSH(ConstantPoolGen cp, int value) {
41          if ((value >= -1) && (value <= 5)) {
42              instruction = INSTRUCTIONS[Constants.ICONST_0 + value];
43          } else if ((value >= -128) && (value <= 127)) {
44              instruction = new BIPUSH((byte) value);
45          } else if ((value >= -32768) && (value <= 32767)) {
46              instruction = new SIPUSH((short) value);
47          } else {
48              instruction = new LDC(cp.addInteger(value));
49          }
50      }
51  
52  
53      /***
54       * @param cp Constant pool
55       * @param value to be pushed 
56       */
57      public PUSH(ConstantPoolGen cp, boolean value) {
58          instruction = INSTRUCTIONS[Constants.ICONST_0 + (value ? 1 : 0)];
59      }
60  
61  
62      /***
63       * @param cp Constant pool
64       * @param value to be pushed 
65       */
66      public PUSH(ConstantPoolGen cp, float value) {
67          if (value == 0.0) {
68              instruction = FCONST_0;
69          } else if (value == 1.0) {
70              instruction = FCONST_1;
71          } else if (value == 2.0) {
72              instruction = FCONST_2;
73          } else {
74              instruction = new LDC(cp.addFloat(value));
75          }
76      }
77  
78  
79      /***
80       * @param cp Constant pool
81       * @param value to be pushed 
82       */
83      public PUSH(ConstantPoolGen cp, long value) {
84          if (value == 0) {
85              instruction = LCONST_0;
86          } else if (value == 1) {
87              instruction = LCONST_1;
88          } else {
89              instruction = new LDC2_W(cp.addLong(value));
90          }
91      }
92  
93  
94      /***
95       * @param cp Constant pool
96       * @param value to be pushed 
97       */
98      public PUSH(ConstantPoolGen cp, double value) {
99          if (value == 0.0) {
100             instruction = DCONST_0;
101         } else if (value == 1.0) {
102             instruction = DCONST_1;
103         } else {
104             instruction = new LDC2_W(cp.addDouble(value));
105         }
106     }
107 
108 
109     /***
110      * @param cp Constant pool
111      * @param value to be pushed 
112      */
113     public PUSH(ConstantPoolGen cp, String value) {
114         if (value == null) {
115             instruction = ACONST_NULL;
116         } else {
117             instruction = new LDC(cp.addString(value));
118         }
119     }
120 
121 
122     /***
123      * @param cp Constant pool
124      * @param value to be pushed 
125      */
126     public PUSH(ConstantPoolGen cp, Number value) {
127         if ((value instanceof Integer) || (value instanceof Short) || (value instanceof Byte)) {
128             instruction = new PUSH(cp, value.intValue()).instruction;
129         } else if (value instanceof Double) {
130             instruction = new PUSH(cp, value.doubleValue()).instruction;
131         } else if (value instanceof Float) {
132             instruction = new PUSH(cp, value.floatValue()).instruction;
133         } else if (value instanceof Long) {
134             instruction = new PUSH(cp, value.longValue()).instruction;
135         } else {
136             throw new ClassGenException("What's this: " + value);
137         }
138     }
139 
140 
141     /***
142      * creates a push object from a Character value. Warning: Make sure not to attempt to allow
143      * autoboxing to create this value parameter, as an alternative constructor will be called
144      * 
145      * @param cp Constant pool
146      * @param value to be pushed 
147      */
148     public PUSH(ConstantPoolGen cp, Character value) {
149         this(cp, value.charValue());
150     }
151 
152 
153     /***
154      * @param cp Constant pool
155      * @param value to be pushed 
156      */
157     public PUSH(ConstantPoolGen cp, Boolean value) {
158         this(cp, value.booleanValue());
159     }
160 
161 
162     public final InstructionList getInstructionList() {
163         return new InstructionList(instruction);
164     }
165 
166 
167     public final Instruction getInstruction() {
168         return instruction;
169     }
170 
171 
172     /***
173      * @return mnemonic for instruction
174      */
175     public String toString() {
176         return instruction.toString() + " (PUSH)";
177     }
178 }