001 /*** 002 * ASM: a very small and fast Java bytecode manipulation framework 003 * Copyright (c) 2000-2005 INRIA, France Telecom 004 * All rights reserved. 005 * 006 * Redistribution and use in source and binary forms, with or without 007 * modification, are permitted provided that the following conditions 008 * are met: 009 * 1. Redistributions of source code must retain the above copyright 010 * notice, this list of conditions and the following disclaimer. 011 * 2. Redistributions in binary form must reproduce the above copyright 012 * notice, this list of conditions and the following disclaimer in the 013 * documentation and/or other materials provided with the distribution. 014 * 3. Neither the name of the copyright holders nor the names of its 015 * contributors may be used to endorse or promote products derived from 016 * this software without specific prior written permission. 017 * 018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 021 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 022 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 028 * THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030 package net.sourceforge.retroweaver.optimizer; 031 032 import org.objectweb.asm.ClassWriter; 033 034 /** 035 * A constant pool item. 036 * 037 * @author Eric Bruneton 038 */ 039 public 040 class Constant { 041 042 /** 043 * Type of this constant pool item. A single class is used to represent all 044 * constant pool item types, in order to minimize the bytecode size of this 045 * package. The value of this field is I, J, F, D, S, s, C, T, G, M, or N 046 * (for Constant Integer, Long, Float, Double, STR, UTF8, Class, NameType, 047 * Fieldref, Methodref, or InterfaceMethodref constant pool items 048 * respectively). 049 */ 050 char type; 051 052 /** 053 * Value of this item, for an integer item. 054 */ 055 int intVal; 056 057 /** 058 * Value of this item, for a long item. 059 */ 060 long longVal; 061 062 /** 063 * Value of this item, for a float item. 064 */ 065 float floatVal; 066 067 /** 068 * Value of this item, for a double item. 069 */ 070 double doubleVal; 071 072 /** 073 * First part of the value of this item, for items that do not hold a 074 * primitive value. 075 */ 076 String strVal1; 077 078 /** 079 * Second part of the value of this item, for items that do not hold a 080 * primitive value. 081 */ 082 String strVal2; 083 084 /** 085 * Third part of the value of this item, for items that do not hold a 086 * primitive value. 087 */ 088 String strVal3; 089 090 /** 091 * The hash code value of this constant pool item. 092 */ 093 int hashCode; 094 095 public Constant() { 096 } 097 098 public Constant(final Constant i) { 099 type = i.type; 100 intVal = i.intVal; 101 longVal = i.longVal; 102 floatVal = i.floatVal; 103 doubleVal = i.doubleVal; 104 strVal1 = i.strVal1; 105 strVal2 = i.strVal2; 106 strVal3 = i.strVal3; 107 hashCode = i.hashCode; 108 } 109 110 /** 111 * Sets this item to an integer item. 112 * 113 * @param intVal the value of this item. 114 */ 115 void set(final int intVal) { 116 this.type = 'I'; 117 this.intVal = intVal; 118 this.hashCode = 0x7FFFFFFF & (type + intVal); 119 } 120 121 /** 122 * Sets this item to a long item. 123 * 124 * @param longVal the value of this item. 125 */ 126 void set(final long longVal) { 127 this.type = 'J'; 128 this.longVal = longVal; 129 this.hashCode = 0x7FFFFFFF & (type + (int) longVal); 130 } 131 132 /** 133 * Sets this item to a float item. 134 * 135 * @param floatVal the value of this item. 136 */ 137 void set(final float floatVal) { 138 this.type = 'F'; 139 this.floatVal = floatVal; 140 this.hashCode = 0x7FFFFFFF & (type + (int) floatVal); 141 } 142 143 /** 144 * Sets this item to a double item. 145 * 146 * @param doubleVal the value of this item. 147 */ 148 void set(final double doubleVal) { 149 this.type = 'D'; 150 this.doubleVal = doubleVal; 151 this.hashCode = 0x7FFFFFFF & (type + (int) doubleVal); 152 } 153 154 /** 155 * Sets this item to an item that do not hold a primitive value. 156 * 157 * @param type the type of this item. 158 * @param strVal1 first part of the value of this item. 159 * @param strVal2 second part of the value of this item. 160 * @param strVal3 third part of the value of this item. 161 */ 162 void set( 163 final char type, 164 final String strVal1, 165 final String strVal2, 166 final String strVal3) 167 { 168 this.type = type; 169 this.strVal1 = strVal1; 170 this.strVal2 = strVal2; 171 this.strVal3 = strVal3; 172 switch (type) { 173 case 's': 174 case 'S': 175 case 'C': 176 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()); 177 return; 178 case 'T': 179 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() 180 * strVal2.hashCode()); 181 return; 182 // case 'G': 183 // case 'M': 184 // case 'N': 185 default: 186 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() 187 * strVal2.hashCode() * strVal3.hashCode()); 188 } 189 } 190 191 public 192 void write(final ClassWriter cw) { 193 switch (type) { 194 case 'I': 195 cw.newConst(new Integer(intVal)); // NOPMD by xlv 196 break; 197 case 'J': 198 cw.newConst(new Long(longVal)); 199 break; 200 case 'F': 201 cw.newConst(new Float(floatVal)); 202 break; 203 case 'D': 204 cw.newConst(new Double(doubleVal)); 205 break; 206 case 'S': 207 cw.newConst(strVal1); 208 break; 209 case 's': 210 cw.newUTF8(strVal1); 211 break; 212 case 'C': 213 cw.newClass(strVal1); 214 break; 215 case 'T': 216 cw.newNameType(strVal1, strVal2); 217 break; 218 case 'G': 219 cw.newField(strVal1, strVal2, strVal3); 220 break; 221 case 'M': 222 cw.newMethod(strVal1, strVal2, strVal3, false); 223 break; 224 case 'N': 225 cw.newMethod(strVal1, strVal2, strVal3, true); 226 break; 227 } 228 } 229 230 public boolean equals(final Object o) { 231 if (!(o instanceof Constant)) { 232 return false; 233 } 234 Constant c = (Constant) o; 235 if (c.type == type) { 236 switch (type) { 237 case 'I': 238 return c.intVal == intVal; 239 case 'J': 240 return c.longVal == longVal; 241 case 'F': 242 return c.floatVal == floatVal; 243 case 'D': 244 return c.doubleVal == doubleVal; 245 case 's': 246 case 'S': 247 case 'C': 248 return c.strVal1.equals(strVal1); 249 case 'T': 250 return c.strVal1.equals(strVal1) 251 && c.strVal2.equals(strVal2); 252 // case 'G': 253 // case 'M': 254 // case 'N': 255 default: 256 return c.strVal1.equals(strVal1) 257 && c.strVal2.equals(strVal2) 258 && c.strVal3.equals(strVal3); 259 } 260 } 261 return false; 262 } 263 264 public int hashCode() { 265 return hashCode; 266 } 267 }