1 /*** 2 * ASM: a very small and fast Java bytecode manipulation framework 3 * Copyright (c) 2000-2005 INRIA, France Telecom 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of the copyright holders nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 package org.objectweb.asm.optimizer; 31 32 import org.objectweb.asm.ClassWriter; 33 34 /** 35 * A constant pool item. 36 * 37 * @author Eric Bruneton 38 */ 39 class Constant { 40 41 /** 42 * Type of this constant pool item. A single class is used to represent all 43 * constant pool item types, in order to minimize the bytecode size of this 44 * package. The value of this field is I, J, F, D, S, s, C, T, G, M, or N 45 * (for Constant Integer, Long, Float, Double, STR, UTF8, Class, NameType, 46 * Fieldref, Methodref, or InterfaceMethodref constant pool items 47 * respectively). 48 */ 49 char type; 50 51 /** 52 * Value of this item, for an integer item. 53 */ 54 int intVal; 55 56 /** 57 * Value of this item, for a long item. 58 */ 59 long longVal; 60 61 /** 62 * Value of this item, for a float item. 63 */ 64 float floatVal; 65 66 /** 67 * Value of this item, for a double item. 68 */ 69 double doubleVal; 70 71 /** 72 * First part of the value of this item, for items that do not hold a 73 * primitive value. 74 */ 75 String strVal1; 76 77 /** 78 * Second part of the value of this item, for items that do not hold a 79 * primitive value. 80 */ 81 String strVal2; 82 83 /** 84 * Third part of the value of this item, for items that do not hold a 85 * primitive value. 86 */ 87 String strVal3; 88 89 /** 90 * The hash code value of this constant pool item. 91 */ 92 int hashCode; 93 94 public Constant() { 95 } 96 97 public Constant(final Constant i) { 98 type = i.type; 99 intVal = i.intVal; 100 longVal = i.longVal; 101 floatVal = i.floatVal; 102 doubleVal = i.doubleVal; 103 strVal1 = i.strVal1; 104 strVal2 = i.strVal2; 105 strVal3 = i.strVal3; 106 hashCode = i.hashCode; 107 } 108 109 /** 110 * Sets this item to an integer item. 111 * 112 * @param intVal the value of this item. 113 */ 114 void set(final int intVal) { 115 this.type = 'I'; 116 this.intVal = intVal; 117 this.hashCode = 0x7FFFFFFF & (type + intVal); 118 } 119 120 /** 121 * Sets this item to a long item. 122 * 123 * @param longVal the value of this item. 124 */ 125 void set(final long longVal) { 126 this.type = 'J'; 127 this.longVal = longVal; 128 this.hashCode = 0x7FFFFFFF & (type + (int) longVal); 129 } 130 131 /** 132 * Sets this item to a float item. 133 * 134 * @param floatVal the value of this item. 135 */ 136 void set(final float floatVal) { 137 this.type = 'F'; 138 this.floatVal = floatVal; 139 this.hashCode = 0x7FFFFFFF & (type + (int) floatVal); 140 } 141 142 /** 143 * Sets this item to a double item. 144 * 145 * @param doubleVal the value of this item. 146 */ 147 void set(final double doubleVal) { 148 this.type = 'D'; 149 this.doubleVal = doubleVal; 150 this.hashCode = 0x7FFFFFFF & (type + (int) doubleVal); 151 } 152 153 /** 154 * Sets this item to an item that do not hold a primitive value. 155 * 156 * @param type the type of this item. 157 * @param strVal1 first part of the value of this item. 158 * @param strVal2 second part of the value of this item. 159 * @param strVal3 third part of the value of this item. 160 */ 161 void set( 162 final char type, 163 final String strVal1, 164 final String strVal2, 165 final String strVal3) 166 { 167 this.type = type; 168 this.strVal1 = strVal1; 169 this.strVal2 = strVal2; 170 this.strVal3 = strVal3; 171 switch (type) { 172 case 's': 173 case 'S': 174 case 'C': 175 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()); 176 return; 177 case 'T': 178 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() 179 * strVal2.hashCode()); 180 return; 181 // case 'G': 182 // case 'M': 183 // case 'N': 184 default: 185 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() 186 * strVal2.hashCode() * strVal3.hashCode()); 187 } 188 } 189 190 void write(final ClassWriter cw) { 191 switch (type) { 192 case 'I': 193 cw.newConst(new Integer(intVal)); 194 break; 195 case 'J': 196 cw.newConst(new Long(longVal)); 197 break; 198 case 'F': 199 cw.newConst(new Float(floatVal)); 200 break; 201 case 'D': 202 cw.newConst(new Double(doubleVal)); 203 break; 204 case 'S': 205 cw.newConst(strVal1); 206 break; 207 case 's': 208 cw.newUTF8(strVal1); 209 break; 210 case 'C': 211 cw.newClass(strVal1); 212 break; 213 case 'T': 214 cw.newNameType(strVal1, strVal2); 215 break; 216 case 'G': 217 cw.newField(strVal1, strVal2, strVal3); 218 break; 219 case 'M': 220 cw.newMethod(strVal1, strVal2, strVal3, false); 221 break; 222 case 'N': 223 cw.newMethod(strVal1, strVal2, strVal3, true); 224 break; 225 } 226 } 227 228 public boolean equals(final Object o) { 229 if (!(o instanceof Constant)) { 230 return false; 231 } 232 Constant c = (Constant) o; 233 if (c.type == type) { 234 switch (type) { 235 case 'I': 236 return c.intVal == intVal; 237 case 'J': 238 return c.longVal == longVal; 239 case 'F': 240 return c.floatVal == floatVal; 241 case 'D': 242 return c.doubleVal == doubleVal; 243 case 's': 244 case 'S': 245 case 'C': 246 return c.strVal1.equals(strVal1); 247 case 'T': 248 return c.strVal1.equals(strVal1) 249 && c.strVal2.equals(strVal2); 250 // case 'G': 251 // case 'M': 252 // case 'N': 253 default: 254 return c.strVal1.equals(strVal1) 255 && c.strVal2.equals(strVal2) 256 && c.strVal3.equals(strVal3); 257 } 258 } 259 return false; 260 } 261 262 public int hashCode() { 263 return hashCode; 264 } 265 } 266