1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one or more
   7  * contributor license agreements.  See the NOTICE file distributed with
   8  * this work for additional information regarding copyright ownership.
   9  * The ASF licenses this file to You under the Apache License, Version 2.0
  10  * (the "License"); you may not use this file except in compliance with
  11  * the License.  You may obtain a copy of the License at
  12  *
  13  *      http://www.apache.org/licenses/LICENSE-2.0
  14  *
  15  * Unless required by applicable law or agreed to in writing, software
  16  * distributed under the License is distributed on an "AS IS" BASIS,
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18  * See the License for the specific language governing permissions and
  19  * limitations under the License.
  20  */
  21 
  22 package com.sun.org.apache.bcel.internal.generic;
  23 
  24 import com.sun.org.apache.bcel.internal.Constants;
  25 import java.io.*;
  26 
  27 /**
  28  * Wrapper class for push operations, which are implemented either as BIPUSH,
  29  * LDC or xCONST_n instructions.
  30  *
  31  * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  32  */
  33 public final class PUSH
  34   implements CompoundInstruction, VariableLengthInstruction, InstructionConstants
  35 {
  36   private Instruction instruction;
  37 
  38   /**
  39    * This constructor also applies for values of type short, char, byte
  40    *
  41    * @param cp Constant pool
  42    * @param value to be pushed
  43    */
  44   public PUSH(ConstantPoolGen cp, int value) {
  45     if((value >= -1) && (value <= 5)) // Use ICONST_n
  46       instruction = INSTRUCTIONS[Constants.ICONST_0 + value];
  47     else if((value >= -128) && (value <= 127)) // Use BIPUSH
  48       instruction = new BIPUSH((byte)value);
  49     else if((value >= -32768) && (value <= 32767)) // Use SIPUSH
  50       instruction = new SIPUSH((short)value);
  51     else // If everything fails create a Constant pool entry
  52       instruction = new LDC(cp.addInteger(value));
  53   }
  54 
  55   /**
  56    * @param cp Constant pool
  57    * @param value to be pushed
  58    */
  59   public PUSH(ConstantPoolGen cp, boolean value) {
  60     instruction = INSTRUCTIONS[Constants.ICONST_0 + (value? 1 : 0)];
  61   }
  62 
  63   /**
  64    * @param cp Constant pool
  65    * @param value to be pushed
  66    */
  67   public PUSH(ConstantPoolGen cp, float value) {
  68     if(value == 0.0)
  69       instruction = FCONST_0;
  70     else if(value == 1.0)
  71       instruction = FCONST_1;
  72     else if(value == 2.0)
  73       instruction = FCONST_2;
  74     else // Create a Constant pool entry
  75       instruction = new LDC(cp.addFloat(value));
  76   }
  77 
  78   /**
  79    * @param cp Constant pool
  80    * @param value to be pushed
  81    */
  82   public PUSH(ConstantPoolGen cp, long value) {
  83     if(value == 0)
  84       instruction = LCONST_0;
  85     else if(value == 1)
  86       instruction = LCONST_1;
  87     else // Create a Constant pool entry
  88       instruction = new LDC2_W(cp.addLong(value));
  89   }
  90 
  91   /**
  92    * @param cp Constant pool
  93    * @param value to be pushed
  94    */
  95   public PUSH(ConstantPoolGen cp, double value) {
  96     if(value == 0.0)
  97       instruction = DCONST_0;
  98     else if(value == 1.0)
  99       instruction = DCONST_1;
 100     else // Create a Constant pool entry
 101       instruction = new LDC2_W(cp.addDouble(value));
 102   }
 103 
 104   /**
 105    * @param cp Constant pool
 106    * @param value to be pushed
 107    */
 108   public PUSH(ConstantPoolGen cp, String value) {
 109     if(value == null)
 110       instruction = ACONST_NULL;
 111     else // Create a Constant pool entry
 112       instruction = new LDC(cp.addString(value));
 113   }
 114 
 115   /**
 116    * @param cp Constant pool
 117    * @param value to be pushed
 118    */
 119   public PUSH(ConstantPoolGen cp, Number value) {
 120     if((value instanceof Integer) || (value instanceof Short) || (value instanceof Byte))
 121       instruction = new PUSH(cp, value.intValue()).instruction;
 122     else if(value instanceof Double)
 123       instruction = new PUSH(cp, value.doubleValue()).instruction;
 124     else if(value instanceof Float)
 125       instruction = new PUSH(cp, value.floatValue()).instruction;
 126     else if(value instanceof Long)
 127       instruction = new PUSH(cp, value.longValue()).instruction;
 128     else
 129       throw new ClassGenException("What's this: " + value);
 130   }
 131 
 132   /**
 133    * @param cp Constant pool
 134    * @param value to be pushed
 135    */
 136   public PUSH(ConstantPoolGen cp, Character value) {
 137     this(cp, (int)value.charValue());
 138   }
 139 
 140   /**
 141    * @param cp Constant pool
 142    * @param value to be pushed
 143    */
 144   public PUSH(ConstantPoolGen cp, Boolean value) {
 145     this(cp, value.booleanValue());
 146   }
 147 
 148   public final InstructionList getInstructionList() {
 149     return new InstructionList(instruction);
 150   }
 151 
 152   public final Instruction getInstruction() {
 153     return instruction;
 154   }
 155 
 156   /**
 157    * @return mnemonic for instruction
 158    */
 159   public String toString() {
 160     return instruction.toString() + " (PUSH)";
 161   }
 162 }