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