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.objectweb.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: * Value of this item, for a float item.
075: */
076: float floatVal;
077:
078: /**
079: * Value of this item, for a double item.
080: */
081: double doubleVal;
082:
083: /**
084: * First part of the value of this item, for items that do not hold a
085: * primitive value.
086: */
087: String strVal1;
088:
089: /**
090: * Second part of the value of this item, for items that do not hold a
091: * primitive value.
092: */
093: String strVal2;
094:
095: /**
096: * Third part of the value of this item, for items that do not hold a
097: * primitive value.
098: */
099: String strVal3;
100:
101: /**
102: * The hash code value of this constant pool item.
103: */
104: int hashCode;
105:
106: /**
107: * Link to another constant pool item, used for collision lists in the
108: * constant pool's hash table.
109: */
110: Item next;
111:
112: /**
113: * Constructs an uninitialized {@link Item}.
114: */
115: Item() {
116: }
117:
118: /**
119: * Constructs an uninitialized {@link Item} for constant pool element at
120: * given position.
121: *
122: * @param index index of the item to be constructed.
123: */
124: Item(final int index) {
125: this .index = index;
126: }
127:
128: /**
129: * Constructs a copy of the given item.
130: *
131: * @param index index of the item to be constructed.
132: * @param i the item that must be copied into the item to be constructed.
133: */
134: Item(final int index, final Item i) {
135: this .index = index;
136: type = i.type;
137: intVal = i.intVal;
138: longVal = i.longVal;
139: floatVal = i.floatVal;
140: doubleVal = i.doubleVal;
141: strVal1 = i.strVal1;
142: strVal2 = i.strVal2;
143: strVal3 = i.strVal3;
144: hashCode = i.hashCode;
145: }
146:
147: /**
148: * Sets this item to an integer item.
149: *
150: * @param intVal the value of this item.
151: */
152: void set(final int intVal) {
153: this .type = ClassWriter.INT;
154: this .intVal = intVal;
155: this .hashCode = 0x7FFFFFFF & (type + intVal);
156: }
157:
158: /**
159: * Sets this item to a long item.
160: *
161: * @param longVal the value of this item.
162: */
163: void set(final long longVal) {
164: this .type = ClassWriter.LONG;
165: this .longVal = longVal;
166: this .hashCode = 0x7FFFFFFF & (type + (int) longVal);
167: }
168:
169: /**
170: * Sets this item to a float item.
171: *
172: * @param floatVal the value of this item.
173: */
174: void set(final float floatVal) {
175: this .type = ClassWriter.FLOAT;
176: this .floatVal = floatVal;
177: this .hashCode = 0x7FFFFFFF & (type + (int) floatVal);
178: }
179:
180: /**
181: * Sets this item to a double item.
182: *
183: * @param doubleVal the value of this item.
184: */
185: void set(final double doubleVal) {
186: this .type = ClassWriter.DOUBLE;
187: this .doubleVal = doubleVal;
188: this .hashCode = 0x7FFFFFFF & (type + (int) doubleVal);
189: }
190:
191: /**
192: * Sets this item to an item that do not hold a primitive value.
193: *
194: * @param type the type of this item.
195: * @param strVal1 first part of the value of this item.
196: * @param strVal2 second part of the value of this item.
197: * @param strVal3 third part of the value of this item.
198: */
199: void set(final int type, final String strVal1,
200: final String strVal2, final String strVal3) {
201: this .type = type;
202: this .strVal1 = strVal1;
203: this .strVal2 = strVal2;
204: this .strVal3 = strVal3;
205: switch (type) {
206: case ClassWriter.UTF8:
207: case ClassWriter.STR:
208: case ClassWriter.CLASS:
209: case ClassWriter.TYPE_NORMAL:
210: hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
211: return;
212: case ClassWriter.NAME_TYPE:
213: hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
214: * strVal2.hashCode());
215: return;
216: // ClassWriter.FIELD:
217: // ClassWriter.METH:
218: // ClassWriter.IMETH:
219: default:
220: hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
221: * strVal2.hashCode() * strVal3.hashCode());
222: }
223: }
224:
225: /**
226: * Indicates if the given item is equal to this one.
227: *
228: * @param i the item to be compared to this one.
229: * @return <tt>true</tt> if the given item if equal to this one,
230: * <tt>false</tt> otherwise.
231: */
232: boolean isEqualTo(final Item i) {
233: if (i.type == type) {
234: switch (type) {
235: case ClassWriter.INT:
236: return i.intVal == intVal;
237: case ClassWriter.TYPE_MERGED:
238: case ClassWriter.LONG:
239: return i.longVal == longVal;
240: case ClassWriter.FLOAT:
241: return i.floatVal == floatVal;
242: case ClassWriter.DOUBLE:
243: return i.doubleVal == doubleVal;
244: case ClassWriter.UTF8:
245: case ClassWriter.STR:
246: case ClassWriter.CLASS:
247: case ClassWriter.TYPE_NORMAL:
248: return i.strVal1.equals(strVal1);
249: case ClassWriter.TYPE_UNINIT:
250: return i.intVal == intVal && i.strVal1.equals(strVal1);
251: case ClassWriter.NAME_TYPE:
252: return i.strVal1.equals(strVal1)
253: && i.strVal2.equals(strVal2);
254: // ClassWriter.FIELD:
255: // ClassWriter.METH:
256: // ClassWriter.IMETH:
257: default:
258: return i.strVal1.equals(strVal1)
259: && i.strVal2.equals(strVal2)
260: && i.strVal3.equals(strVal3);
261: }
262: }
263: return false;
264: }
265: }
|