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 Constant()94 public Constant() { 95 } 96 Constant(final Constant i)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 */ set(final int intVal)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 */ set(final long longVal)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 */ set(final float floatVal)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 */ set(final double doubleVal)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 */ set( final char type, final String strVal1, final String strVal2, final String strVal3)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 write(final ClassWriter cw)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 equals(final Object o)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 hashCode()262 public int hashCode() { 263 return hashCode; 264 } 265 } 266