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