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: */package org.ejb3unit.asm.optimizer;
030:
031: import org.ejb3unit.asm.ClassWriter;
032:
033: /**
034: * A constant pool item.
035: *
036: * @author Eric Bruneton
037: */
038: class Constant {
039:
040: /**
041: * Type of this constant pool item. A single class is used to represent all
042: * constant pool item types, in order to minimize the bytecode size of this
043: * package. The value of this field is I, J, F, D, S, s, C, T, G, M, or N
044: * (for Constant Integer, Long, Float, Double, STR, UTF8, Class, NameType,
045: * Fieldref, Methodref, or InterfaceMethodref constant pool items
046: * respectively).
047: */
048: char type;
049:
050: /**
051: * Value of this item, for an integer item.
052: */
053: int intVal;
054:
055: /**
056: * Value of this item, for a long item.
057: */
058: long longVal;
059:
060: /**
061: * Value of this item, for a float item.
062: */
063: float floatVal;
064:
065: /**
066: * Value of this item, for a double item.
067: */
068: double doubleVal;
069:
070: /**
071: * First part of the value of this item, for items that do not hold a
072: * primitive value.
073: */
074: String strVal1;
075:
076: /**
077: * Second part of the value of this item, for items that do not hold a
078: * primitive value.
079: */
080: String strVal2;
081:
082: /**
083: * Third part of the value of this item, for items that do not hold a
084: * primitive value.
085: */
086: String strVal3;
087:
088: /**
089: * The hash code value of this constant pool item.
090: */
091: int hashCode;
092:
093: public Constant() {
094: }
095:
096: public Constant(final Constant i) {
097: type = i.type;
098: intVal = i.intVal;
099: longVal = i.longVal;
100: floatVal = i.floatVal;
101: doubleVal = i.doubleVal;
102: strVal1 = i.strVal1;
103: strVal2 = i.strVal2;
104: strVal3 = i.strVal3;
105: hashCode = i.hashCode;
106: }
107:
108: /**
109: * Sets this item to an integer item.
110: *
111: * @param intVal the value of this item.
112: */
113: void set(final int intVal) {
114: this .type = 'I';
115: this .intVal = intVal;
116: this .hashCode = 0x7FFFFFFF & (type + intVal);
117: }
118:
119: /**
120: * Sets this item to a long item.
121: *
122: * @param longVal the value of this item.
123: */
124: void set(final long longVal) {
125: this .type = 'J';
126: this .longVal = longVal;
127: this .hashCode = 0x7FFFFFFF & (type + (int) longVal);
128: }
129:
130: /**
131: * Sets this item to a float item.
132: *
133: * @param floatVal the value of this item.
134: */
135: void set(final float floatVal) {
136: this .type = 'F';
137: this .floatVal = floatVal;
138: this .hashCode = 0x7FFFFFFF & (type + (int) floatVal);
139: }
140:
141: /**
142: * Sets this item to a double item.
143: *
144: * @param doubleVal the value of this item.
145: */
146: void set(final double doubleVal) {
147: this .type = 'D';
148: this .doubleVal = doubleVal;
149: this .hashCode = 0x7FFFFFFF & (type + (int) doubleVal);
150: }
151:
152: /**
153: * Sets this item to an item that do not hold a primitive value.
154: *
155: * @param type the type of this item.
156: * @param strVal1 first part of the value of this item.
157: * @param strVal2 second part of the value of this item.
158: * @param strVal3 third part of the value of this item.
159: */
160: void set(final char type, final String strVal1,
161: final String strVal2, final String strVal3) {
162: this .type = type;
163: this .strVal1 = strVal1;
164: this .strVal2 = strVal2;
165: this .strVal3 = strVal3;
166: switch (type) {
167: case 's':
168: case 'S':
169: case 'C':
170: hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
171: return;
172: case 'T':
173: hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
174: * strVal2.hashCode());
175: return;
176: // case 'G':
177: // case 'M':
178: // case 'N':
179: default:
180: hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
181: * strVal2.hashCode() * strVal3.hashCode());
182: }
183: }
184:
185: void write(final ClassWriter cw) {
186: switch (type) {
187: case 'I':
188: cw.newConst(new Integer(intVal));
189: break;
190: case 'J':
191: cw.newConst(new Long(longVal));
192: break;
193: case 'F':
194: cw.newConst(new Float(floatVal));
195: break;
196: case 'D':
197: cw.newConst(new Double(doubleVal));
198: break;
199: case 'S':
200: cw.newConst(strVal1);
201: break;
202: case 's':
203: cw.newUTF8(strVal1);
204: break;
205: case 'C':
206: cw.newClass(strVal1);
207: break;
208: case 'T':
209: cw.newNameType(strVal1, strVal2);
210: break;
211: case 'G':
212: cw.newField(strVal1, strVal2, strVal3);
213: break;
214: case 'M':
215: cw.newMethod(strVal1, strVal2, strVal3, false);
216: break;
217: case 'N':
218: cw.newMethod(strVal1, strVal2, strVal3, true);
219: break;
220: }
221: }
222:
223: public boolean equals(final Object o) {
224: if (!(o instanceof Constant)) {
225: return false;
226: }
227: Constant c = (Constant) o;
228: if (c.type == type) {
229: switch (type) {
230: case 'I':
231: return c.intVal == intVal;
232: case 'J':
233: return c.longVal == longVal;
234: case 'F':
235: return c.floatVal == floatVal;
236: case 'D':
237: return c.doubleVal == doubleVal;
238: case 's':
239: case 'S':
240: case 'C':
241: return c.strVal1.equals(strVal1);
242: case 'T':
243: return c.strVal1.equals(strVal1)
244: && c.strVal2.equals(strVal2);
245: // case 'G':
246: // case 'M':
247: // case 'N':
248: default:
249: return c.strVal1.equals(strVal1)
250: && c.strVal2.equals(strVal2)
251: && c.strVal3.equals(strVal3);
252: }
253: }
254: return false;
255: }
256:
257: public int hashCode() {
258: return hashCode;
259: }
260: }
|