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 }