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