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 com.tc.asm;
030:
031: /**
032: * A constant pool item. Constant pool items can be created with the 'newXXX'
033: * methods in the {@link ClassWriter} class.
034: *
035: * @author Eric Bruneton
036: */
037: final class Item {
038:
039: /**
040: * Index of this item in the constant pool.
041: */
042: int index;
043:
044: /**
045: * Type of this constant pool item. A single class is used to represent all
046: * constant pool item types, in order to minimize the bytecode size of this
047: * package. The value of this field is one of {@link ClassWriter#INT},
048: * {@link ClassWriter#LONG}, {@link ClassWriter#FLOAT},
049: * {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8},
050: * {@link ClassWriter#STR}, {@link ClassWriter#CLASS},
051: * {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
052: * {@link ClassWriter#METH}, {@link ClassWriter#IMETH}.
053: *
054: * Special Item types are used for Items that are stored in the ClassWriter
055: * {@link ClassWriter#typeTable}, instead of the constant pool, in order to
056: * avoid clashes with normal constant pool items in the ClassWriter constant
057: * pool's hash table. These special item types are
058: * {@link ClassWriter#TYPE_NORMAL}, {@link ClassWriter#TYPE_UNINIT} and
059: * {@link ClassWriter#TYPE_MERGED}.
060: */
061: int type;
062:
063: /**
064: * Value of this item, for an integer item.
065: */
066: int intVal;
067:
068: /**
069: * Value of this item, for a long item.
070: */
071: long longVal;
072:
073: /**
074: * First part of the value of this item, for items that do not hold a
075: * primitive value.
076: */
077: String strVal1;
078:
079: /**
080: * Second part of the value of this item, for items that do not hold a
081: * primitive value.
082: */
083: String strVal2;
084:
085: /**
086: * Third part of the value of this item, for items that do not hold a
087: * primitive value.
088: */
089: String strVal3;
090:
091: /**
092: * The hash code value of this constant pool item.
093: */
094: int hashCode;
095:
096: /**
097: * Link to another constant pool item, used for collision lists in the
098: * constant pool's hash table.
099: */
100: Item next;
101:
102: /**
103: * Constructs an uninitialized {@link Item}.
104: */
105: Item() {
106: }
107:
108: /**
109: * Constructs an uninitialized {@link Item} for constant pool element at
110: * given position.
111: *
112: * @param index index of the item to be constructed.
113: */
114: Item(final int index) {
115: this .index = index;
116: }
117:
118: /**
119: * Constructs a copy of the given item.
120: *
121: * @param index index of the item to be constructed.
122: * @param i the item that must be copied into the item to be constructed.
123: */
124: Item(final int index, final Item i) {
125: this .index = index;
126: type = i.type;
127: intVal = i.intVal;
128: longVal = i.longVal;
129: strVal1 = i.strVal1;
130: strVal2 = i.strVal2;
131: strVal3 = i.strVal3;
132: hashCode = i.hashCode;
133: }
134:
135: /**
136: * Sets this item to an integer item.
137: *
138: * @param intVal the value of this item.
139: */
140: void set(final int intVal) {
141: this .type = ClassWriter.INT;
142: this .intVal = intVal;
143: this .hashCode = 0x7FFFFFFF & (type + intVal);
144: }
145:
146: /**
147: * Sets this item to a long item.
148: *
149: * @param longVal the value of this item.
150: */
151: void set(final long longVal) {
152: this .type = ClassWriter.LONG;
153: this .longVal = longVal;
154: this .hashCode = 0x7FFFFFFF & (type + (int) longVal);
155: }
156:
157: /**
158: * Sets this item to a float item.
159: *
160: * @param floatVal the value of this item.
161: */
162: void set(final float floatVal) {
163: this .type = ClassWriter.FLOAT;
164: this .intVal = Float.floatToRawIntBits(floatVal);
165: this .hashCode = 0x7FFFFFFF & (type + (int) floatVal);
166: }
167:
168: /**
169: * Sets this item to a double item.
170: *
171: * @param doubleVal the value of this item.
172: */
173: void set(final double doubleVal) {
174: this .type = ClassWriter.DOUBLE;
175: this .longVal = Double.doubleToRawLongBits(doubleVal);
176: this .hashCode = 0x7FFFFFFF & (type + (int) doubleVal);
177: }
178:
179: /**
180: * Sets this item to an item that do not hold a primitive value.
181: *
182: * @param type the type of this item.
183: * @param strVal1 first part of the value of this item.
184: * @param strVal2 second part of the value of this item.
185: * @param strVal3 third part of the value of this item.
186: */
187: void set(final int type, final String strVal1,
188: final String strVal2, final String strVal3) {
189: this .type = type;
190: this .strVal1 = strVal1;
191: this .strVal2 = strVal2;
192: this .strVal3 = strVal3;
193: switch (type) {
194: case ClassWriter.UTF8:
195: case ClassWriter.STR:
196: case ClassWriter.CLASS:
197: case ClassWriter.TYPE_NORMAL:
198: hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
199: return;
200: case ClassWriter.NAME_TYPE:
201: hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
202: * strVal2.hashCode());
203: return;
204: // ClassWriter.FIELD:
205: // ClassWriter.METH:
206: // ClassWriter.IMETH:
207: default:
208: hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
209: * strVal2.hashCode() * strVal3.hashCode());
210: }
211: }
212:
213: /**
214: * Indicates if the given item is equal to this one.
215: *
216: * @param i the item to be compared to this one.
217: * @return <tt>true</tt> if the given item if equal to this one,
218: * <tt>false</tt> otherwise.
219: */
220: boolean isEqualTo(final Item i) {
221: if (i.type == type) {
222: switch (type) {
223: case ClassWriter.INT:
224: case ClassWriter.FLOAT:
225: return i.intVal == intVal;
226: case ClassWriter.TYPE_MERGED:
227: case ClassWriter.LONG:
228: case ClassWriter.DOUBLE:
229: return i.longVal == longVal;
230: case ClassWriter.UTF8:
231: case ClassWriter.STR:
232: case ClassWriter.CLASS:
233: case ClassWriter.TYPE_NORMAL:
234: return i.strVal1.equals(strVal1);
235: case ClassWriter.TYPE_UNINIT:
236: return i.intVal == intVal && i.strVal1.equals(strVal1);
237: case ClassWriter.NAME_TYPE:
238: return i.strVal1.equals(strVal1)
239: && i.strVal2.equals(strVal2);
240: // ClassWriter.FIELD:
241: // ClassWriter.METH:
242: // ClassWriter.IMETH:
243: default:
244: return i.strVal1.equals(strVal1)
245: && i.strVal2.equals(strVal2)
246: && i.strVal3.equals(strVal3);
247: }
248: }
249: return false;
250: }
251: }
|