1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 */ 4 /* 5 * Licensed to the Apache Software Foundation (ASF) under one or more 6 * contributor license agreements. See the NOTICE file distributed with 7 * this work for additional information regarding copyright ownership. 8 * The ASF licenses this file to You under the Apache License, Version 2.0 9 * (the "License"); you may not use this file except in compliance with 10 * the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 package com.sun.org.apache.bcel.internal.generic; 22 23 import com.sun.org.apache.bcel.internal.Const; 24 25 /** 26 * Wrapper class for push operations, which are implemented either as BIPUSH, 27 * LDC or xCONST_n instructions. 28 * 29 * @version $Id: PUSH.java 1749598 2016-06-21 20:36:33Z ggregory $ 30 */ 31 public final class PUSH implements CompoundInstruction, VariableLengthInstruction { 32 33 private Instruction instruction; 34 35 36 /** 37 * This constructor also applies for values of type short, char, byte 38 * 39 * @param cp Constant pool 40 * @param value to be pushed 41 */ 42 public PUSH(final ConstantPoolGen cp, final int value) { 43 if ((value >= -1) && (value <= 5)) { 44 instruction = InstructionConst.getInstruction(Const.ICONST_0 + value); 45 } else if (Instruction.isValidByte(value)) { 46 instruction = new BIPUSH((byte) value); 47 } else if (Instruction.isValidShort(value)) { 48 instruction = new SIPUSH((short) value); 49 } else { 50 instruction = new LDC(cp.addInteger(value)); 51 } 52 } 53 54 55 /** 56 * @param cp Constant pool 57 * @param value to be pushed 58 */ 59 public PUSH(final ConstantPoolGen cp, final boolean value) { 60 instruction = InstructionConst.getInstruction(Const.ICONST_0 + (value ? 1 : 0)); 61 } 62 63 64 /** 65 * @param cp Constant pool 66 * @param value to be pushed 67 */ 68 public PUSH(final ConstantPoolGen cp, final float value) { 69 if (value == 0.0) { 70 instruction = InstructionConst.FCONST_0; 71 } else if (value == 1.0) { 72 instruction = InstructionConst.FCONST_1; 73 } else if (value == 2.0) { 74 instruction = InstructionConst.FCONST_2; 75 } else { 76 instruction = new LDC(cp.addFloat(value)); 77 } 78 } 79 80 81 /** 82 * @param cp Constant pool 83 * @param value to be pushed 84 */ 85 public PUSH(final ConstantPoolGen cp, final long value) { 86 if (value == 0) { 87 instruction = InstructionConst.LCONST_0; 88 } else if (value == 1) { 89 instruction = InstructionConst.LCONST_1; 90 } else { 91 instruction = new LDC2_W(cp.addLong(value)); 92 } 93 } 94 95 96 /** 97 * @param cp Constant pool 98 * @param value to be pushed 99 */ 100 public PUSH(final ConstantPoolGen cp, final double value) { 101 if (value == 0.0) { 102 instruction = InstructionConst.DCONST_0; 103 } else if (value == 1.0) { 104 instruction = InstructionConst.DCONST_1; 105 } else { 106 instruction = new LDC2_W(cp.addDouble(value)); 107 } 108 } 109 110 111 /** 112 * @param cp Constant pool 113 * @param value to be pushed 114 */ 115 public PUSH(final ConstantPoolGen cp, final String value) { 116 if (value == null) { 117 instruction = InstructionConst.ACONST_NULL; 118 } else { 119 instruction = new LDC(cp.addString(value)); 120 } 121 } 122 123 /** 124 * 125 * @param cp 126 * @param value 127 * @since 6.0 128 */ 129 public PUSH(final ConstantPoolGen cp, final ObjectType value) { 130 if (value == null) { 131 instruction = InstructionConst.ACONST_NULL; 132 } else { 133 instruction = new LDC(cp.addClass(value)); 134 } 135 } 136 137 /** 138 * @param cp Constant pool 139 * @param value to be pushed 140 */ 141 public PUSH(final ConstantPoolGen cp, final Number value) { 142 if ((value instanceof Integer) || (value instanceof Short) || (value instanceof Byte)) { 143 instruction = new PUSH(cp, value.intValue()).instruction; 144 } else if (value instanceof Double) { 145 instruction = new PUSH(cp, value.doubleValue()).instruction; 146 } else if (value instanceof Float) { 147 instruction = new PUSH(cp, value.floatValue()).instruction; 148 } else if (value instanceof Long) { 149 instruction = new PUSH(cp, value.longValue()).instruction; 150 } else { 151 throw new ClassGenException("What's this: " + value); 152 } 153 } 154 155 156 /** 157 * creates a push object from a Character value. Warning: Make sure not to attempt to allow 158 * autoboxing to create this value parameter, as an alternative constructor will be called 159 * 160 * @param cp Constant pool 161 * @param value to be pushed 162 */ 163 public PUSH(final ConstantPoolGen cp, final Character value) { 164 this(cp, value.charValue()); 165 } 166 167 168 /** 169 * @param cp Constant pool 170 * @param value to be pushed 171 */ 172 public PUSH(final ConstantPoolGen cp, final Boolean value) { 173 this(cp, value.booleanValue()); 174 } 175 176 177 @Override 178 public final InstructionList getInstructionList() { 179 return new InstructionList(instruction); 180 } 181 182 183 public final Instruction getInstruction() { 184 return instruction; 185 } 186 187 188 /** 189 * @return mnemonic for instruction 190 */ 191 @Override 192 public String toString() { 193 return instruction + " (PUSH)"; 194 } 195 }