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