rlm@10
|
1 /***
|
rlm@10
|
2 * ASM: a very small and fast Java bytecode manipulation framework
|
rlm@10
|
3 * Copyright (c) 2000-2005 INRIA, France Telecom
|
rlm@10
|
4 * All rights reserved.
|
rlm@10
|
5 *
|
rlm@10
|
6 * Redistribution and use in source and binary forms, with or without
|
rlm@10
|
7 * modification, are permitted provided that the following conditions
|
rlm@10
|
8 * are met:
|
rlm@10
|
9 * 1. Redistributions of source code must retain the above copyright
|
rlm@10
|
10 * notice, this list of conditions and the following disclaimer.
|
rlm@10
|
11 * 2. Redistributions in binary form must reproduce the above copyright
|
rlm@10
|
12 * notice, this list of conditions and the following disclaimer in the
|
rlm@10
|
13 * documentation and/or other materials provided with the distribution.
|
rlm@10
|
14 * 3. Neither the name of the copyright holders nor the names of its
|
rlm@10
|
15 * contributors may be used to endorse or promote products derived from
|
rlm@10
|
16 * this software without specific prior written permission.
|
rlm@10
|
17 *
|
rlm@10
|
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
rlm@10
|
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
rlm@10
|
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
rlm@10
|
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
rlm@10
|
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
rlm@10
|
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
rlm@10
|
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
rlm@10
|
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
rlm@10
|
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
rlm@10
|
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
rlm@10
|
28 * THE POSSIBILITY OF SUCH DAMAGE.
|
rlm@10
|
29 */
|
rlm@10
|
30 package clojure.asm;
|
rlm@10
|
31
|
rlm@10
|
32 /**
|
rlm@10
|
33 * A constant pool item. Constant pool items can be created with the 'newXXX'
|
rlm@10
|
34 * methods in the {@link ClassWriter} class.
|
rlm@10
|
35 *
|
rlm@10
|
36 * @author Eric Bruneton
|
rlm@10
|
37 */
|
rlm@10
|
38 final class Item{
|
rlm@10
|
39
|
rlm@10
|
40 /**
|
rlm@10
|
41 * Index of this item in the constant pool.
|
rlm@10
|
42 */
|
rlm@10
|
43 int index;
|
rlm@10
|
44
|
rlm@10
|
45 /**
|
rlm@10
|
46 * Type of this constant pool item. A single class is used to represent all
|
rlm@10
|
47 * constant pool item types, in order to minimize the bytecode size of this
|
rlm@10
|
48 * package. The value of this field is one of {@link ClassWriter#INT},
|
rlm@10
|
49 * {@link ClassWriter#LONG}, {@link ClassWriter#FLOAT},
|
rlm@10
|
50 * {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8},
|
rlm@10
|
51 * {@link ClassWriter#STR}, {@link ClassWriter#CLASS},
|
rlm@10
|
52 * {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
|
rlm@10
|
53 * {@link ClassWriter#METH}, {@link ClassWriter#IMETH}.
|
rlm@10
|
54 * <p/>
|
rlm@10
|
55 * Special Item types are used for Items that are stored in the ClassWriter
|
rlm@10
|
56 * {@link ClassWriter#typeTable}, instead of the constant pool, in order to
|
rlm@10
|
57 * avoid clashes with normal constant pool items in the ClassWriter constant
|
rlm@10
|
58 * pool's hash table. These special item types are
|
rlm@10
|
59 * {@link ClassWriter#TYPE_NORMAL}, {@link ClassWriter#TYPE_UNINIT} and
|
rlm@10
|
60 * {@link ClassWriter#TYPE_MERGED}.
|
rlm@10
|
61 */
|
rlm@10
|
62 int type;
|
rlm@10
|
63
|
rlm@10
|
64 /**
|
rlm@10
|
65 * Value of this item, for an integer item.
|
rlm@10
|
66 */
|
rlm@10
|
67 int intVal;
|
rlm@10
|
68
|
rlm@10
|
69 /**
|
rlm@10
|
70 * Value of this item, for a long item.
|
rlm@10
|
71 */
|
rlm@10
|
72 long longVal;
|
rlm@10
|
73
|
rlm@10
|
74 /**
|
rlm@10
|
75 * First part of the value of this item, for items that do not hold a
|
rlm@10
|
76 * primitive value.
|
rlm@10
|
77 */
|
rlm@10
|
78 String strVal1;
|
rlm@10
|
79
|
rlm@10
|
80 /**
|
rlm@10
|
81 * Second part of the value of this item, for items that do not hold a
|
rlm@10
|
82 * primitive value.
|
rlm@10
|
83 */
|
rlm@10
|
84 String strVal2;
|
rlm@10
|
85
|
rlm@10
|
86 /**
|
rlm@10
|
87 * Third part of the value of this item, for items that do not hold a
|
rlm@10
|
88 * primitive value.
|
rlm@10
|
89 */
|
rlm@10
|
90 String strVal3;
|
rlm@10
|
91
|
rlm@10
|
92 /**
|
rlm@10
|
93 * The hash code value of this constant pool item.
|
rlm@10
|
94 */
|
rlm@10
|
95 int hashCode;
|
rlm@10
|
96
|
rlm@10
|
97 /**
|
rlm@10
|
98 * Link to another constant pool item, used for collision lists in the
|
rlm@10
|
99 * constant pool's hash table.
|
rlm@10
|
100 */
|
rlm@10
|
101 Item next;
|
rlm@10
|
102
|
rlm@10
|
103 /**
|
rlm@10
|
104 * Constructs an uninitialized {@link Item}.
|
rlm@10
|
105 */
|
rlm@10
|
106 Item(){
|
rlm@10
|
107 }
|
rlm@10
|
108
|
rlm@10
|
109 /**
|
rlm@10
|
110 * Constructs an uninitialized {@link Item} for constant pool element at
|
rlm@10
|
111 * given position.
|
rlm@10
|
112 *
|
rlm@10
|
113 * @param index index of the item to be constructed.
|
rlm@10
|
114 */
|
rlm@10
|
115 Item(final int index){
|
rlm@10
|
116 this.index = index;
|
rlm@10
|
117 }
|
rlm@10
|
118
|
rlm@10
|
119 /**
|
rlm@10
|
120 * Constructs a copy of the given item.
|
rlm@10
|
121 *
|
rlm@10
|
122 * @param index index of the item to be constructed.
|
rlm@10
|
123 * @param i the item that must be copied into the item to be constructed.
|
rlm@10
|
124 */
|
rlm@10
|
125 Item(final int index, final Item i){
|
rlm@10
|
126 this.index = index;
|
rlm@10
|
127 type = i.type;
|
rlm@10
|
128 intVal = i.intVal;
|
rlm@10
|
129 longVal = i.longVal;
|
rlm@10
|
130 strVal1 = i.strVal1;
|
rlm@10
|
131 strVal2 = i.strVal2;
|
rlm@10
|
132 strVal3 = i.strVal3;
|
rlm@10
|
133 hashCode = i.hashCode;
|
rlm@10
|
134 }
|
rlm@10
|
135
|
rlm@10
|
136 /**
|
rlm@10
|
137 * Sets this item to an integer item.
|
rlm@10
|
138 *
|
rlm@10
|
139 * @param intVal the value of this item.
|
rlm@10
|
140 */
|
rlm@10
|
141 void set(final int intVal){
|
rlm@10
|
142 this.type = ClassWriter.INT;
|
rlm@10
|
143 this.intVal = intVal;
|
rlm@10
|
144 this.hashCode = 0x7FFFFFFF & (type + intVal);
|
rlm@10
|
145 }
|
rlm@10
|
146
|
rlm@10
|
147 /**
|
rlm@10
|
148 * Sets this item to a long item.
|
rlm@10
|
149 *
|
rlm@10
|
150 * @param longVal the value of this item.
|
rlm@10
|
151 */
|
rlm@10
|
152 void set(final long longVal){
|
rlm@10
|
153 this.type = ClassWriter.LONG;
|
rlm@10
|
154 this.longVal = longVal;
|
rlm@10
|
155 this.hashCode = 0x7FFFFFFF & (type + (int) longVal);
|
rlm@10
|
156 }
|
rlm@10
|
157
|
rlm@10
|
158 /**
|
rlm@10
|
159 * Sets this item to a float item.
|
rlm@10
|
160 *
|
rlm@10
|
161 * @param floatVal the value of this item.
|
rlm@10
|
162 */
|
rlm@10
|
163 void set(final float floatVal){
|
rlm@10
|
164 this.type = ClassWriter.FLOAT;
|
rlm@10
|
165 this.intVal = Float.floatToRawIntBits(floatVal);
|
rlm@10
|
166 this.hashCode = 0x7FFFFFFF & (type + (int) floatVal);
|
rlm@10
|
167 }
|
rlm@10
|
168
|
rlm@10
|
169 /**
|
rlm@10
|
170 * Sets this item to a double item.
|
rlm@10
|
171 *
|
rlm@10
|
172 * @param doubleVal the value of this item.
|
rlm@10
|
173 */
|
rlm@10
|
174 void set(final double doubleVal){
|
rlm@10
|
175 this.type = ClassWriter.DOUBLE;
|
rlm@10
|
176 this.longVal = Double.doubleToRawLongBits(doubleVal);
|
rlm@10
|
177 this.hashCode = 0x7FFFFFFF & (type + (int) doubleVal);
|
rlm@10
|
178 }
|
rlm@10
|
179
|
rlm@10
|
180 /**
|
rlm@10
|
181 * Sets this item to an item that do not hold a primitive value.
|
rlm@10
|
182 *
|
rlm@10
|
183 * @param type the type of this item.
|
rlm@10
|
184 * @param strVal1 first part of the value of this item.
|
rlm@10
|
185 * @param strVal2 second part of the value of this item.
|
rlm@10
|
186 * @param strVal3 third part of the value of this item.
|
rlm@10
|
187 */
|
rlm@10
|
188 void set(
|
rlm@10
|
189 final int type,
|
rlm@10
|
190 final String strVal1,
|
rlm@10
|
191 final String strVal2,
|
rlm@10
|
192 final String strVal3){
|
rlm@10
|
193 this.type = type;
|
rlm@10
|
194 this.strVal1 = strVal1;
|
rlm@10
|
195 this.strVal2 = strVal2;
|
rlm@10
|
196 this.strVal3 = strVal3;
|
rlm@10
|
197 switch(type)
|
rlm@10
|
198 {
|
rlm@10
|
199 case ClassWriter.UTF8:
|
rlm@10
|
200 case ClassWriter.STR:
|
rlm@10
|
201 case ClassWriter.CLASS:
|
rlm@10
|
202 case ClassWriter.TYPE_NORMAL:
|
rlm@10
|
203 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
|
rlm@10
|
204 return;
|
rlm@10
|
205 case ClassWriter.NAME_TYPE:
|
rlm@10
|
206 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
|
rlm@10
|
207 * strVal2.hashCode());
|
rlm@10
|
208 return;
|
rlm@10
|
209 // ClassWriter.FIELD:
|
rlm@10
|
210 // ClassWriter.METH:
|
rlm@10
|
211 // ClassWriter.IMETH:
|
rlm@10
|
212 default:
|
rlm@10
|
213 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
|
rlm@10
|
214 * strVal2.hashCode() * strVal3.hashCode());
|
rlm@10
|
215 }
|
rlm@10
|
216 }
|
rlm@10
|
217
|
rlm@10
|
218 /**
|
rlm@10
|
219 * Indicates if the given item is equal to this one.
|
rlm@10
|
220 *
|
rlm@10
|
221 * @param i the item to be compared to this one.
|
rlm@10
|
222 * @return <tt>true</tt> if the given item if equal to this one,
|
rlm@10
|
223 * <tt>false</tt> otherwise.
|
rlm@10
|
224 */
|
rlm@10
|
225 boolean isEqualTo(final Item i){
|
rlm@10
|
226 if(i.type == type)
|
rlm@10
|
227 {
|
rlm@10
|
228 switch(type)
|
rlm@10
|
229 {
|
rlm@10
|
230 case ClassWriter.INT:
|
rlm@10
|
231 case ClassWriter.FLOAT:
|
rlm@10
|
232 return i.intVal == intVal;
|
rlm@10
|
233 case ClassWriter.TYPE_MERGED:
|
rlm@10
|
234 case ClassWriter.LONG:
|
rlm@10
|
235 case ClassWriter.DOUBLE:
|
rlm@10
|
236 return i.longVal == longVal;
|
rlm@10
|
237 case ClassWriter.UTF8:
|
rlm@10
|
238 case ClassWriter.STR:
|
rlm@10
|
239 case ClassWriter.CLASS:
|
rlm@10
|
240 case ClassWriter.TYPE_NORMAL:
|
rlm@10
|
241 return i.strVal1.equals(strVal1);
|
rlm@10
|
242 case ClassWriter.TYPE_UNINIT:
|
rlm@10
|
243 return i.intVal == intVal && i.strVal1.equals(strVal1);
|
rlm@10
|
244 case ClassWriter.NAME_TYPE:
|
rlm@10
|
245 return i.strVal1.equals(strVal1)
|
rlm@10
|
246 && i.strVal2.equals(strVal2);
|
rlm@10
|
247 // ClassWriter.FIELD:
|
rlm@10
|
248 // ClassWriter.METH:
|
rlm@10
|
249 // ClassWriter.IMETH:
|
rlm@10
|
250 default:
|
rlm@10
|
251 return i.strVal1.equals(strVal1)
|
rlm@10
|
252 && i.strVal2.equals(strVal2)
|
rlm@10
|
253 && i.strVal3.equals(strVal3);
|
rlm@10
|
254 }
|
rlm@10
|
255 }
|
rlm@10
|
256 return false;
|
rlm@10
|
257 }
|
rlm@10
|
258 }
|