KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > evaluation > Variables


1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  * of Java bytecode.
4  *
5  * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu)
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */

21 package proguard.evaluation;
22
23 import proguard.evaluation.value.*;
24
25 /**
26  * This class represents a local variable frame that contains <code>Value</code>
27  * objects. Values are generalizations of all values that have been stored in
28  * the respective variables.
29  *
30  * @author Eric Lafortune
31  */

32 public class Variables
33 {
34     private static final TopValue TOP_VALUE = new TopValue();
35
36
37     protected Value[] values;
38     protected int size;
39
40
41     /**
42      * Creates a new Variables object with a given maximum number of variables.
43      */

44     public Variables(int size)
45     {
46         this.values = new Value[size];
47         this.size = size;
48     }
49
50
51     /**
52      * Creates a Variables object that is a copy of the given Variables object.
53      */

54     public Variables(Variables variables)
55     {
56         // Create the values array.
57
this(variables.size);
58
59         // Copy the values.
60
initialize(variables);
61     }
62
63
64     /**
65      * Resets this Variables object, so that it can be reused.
66      */

67     public void reset(int size)
68     {
69         // Is the values array large enough?
70
if (size > values.length)
71         {
72             // Create a new one.
73
values = new Value[size];
74         }
75         else
76         {
77             // Clear the variables.
78
for (int index = 0; index < values.length; index++)
79             {
80                 values[index] = null;
81             }
82         }
83
84         this.size = size;
85     }
86
87
88     /**
89      * Initializes the values of this Variables object with the values of the
90      * given Variables object. The other object may have fewer values, in which
91      * case the remaining values are left unchanged.
92      */

93     public void initialize(Variables other)
94     {
95         if (this.size < other.size)
96         {
97             throw new IllegalArgumentException JavaDoc("Variable frame is too small ["+this.size+"] compared to other frame ["+other.size+"]");
98         }
99
100         // Copy the values.
101
System.arraycopy(other.values, 0, this.values, 0, other.size);
102     }
103
104
105     /**
106      * Generalizes the values of this Variables object with the values of the
107      * given Variables object.
108      * @param clearConflictingOtherVariables specifies whether the other
109      * variables should be cleared too,
110      * in case of conflicts.
111      * @return whether the generalization has made any difference.
112      */

113     public boolean generalize(Variables other,
114                               boolean clearConflictingOtherVariables)
115     {
116         if (this.size != other.size)
117         {
118             throw new IllegalArgumentException JavaDoc("Variable frames have different sizes ["+this.size+"] and ["+other.size+"]");
119         }
120
121         boolean changed = false;
122
123         for (int index = 0; index < size; index++)
124         {
125             Value thisValue = this.values[index];
126             Value otherValue = other.values[index];
127
128             // Occasionally, two values of different types might be present
129
// in the same variable in a variable frame (corresponding to
130
// two local variables that share the same index), at some point
131
// outside of their scopes. Don't generalize the variable then,
132
// but let it clear instead.
133
if (thisValue != null &&
134                 otherValue != null &&
135                 thisValue.computationalType() == otherValue.computationalType())
136             {
137                 Value newValue = thisValue.generalize(otherValue);
138
139                 changed = changed || !thisValue.equals(newValue);
140
141                 this.values[index] = newValue;
142             }
143             else
144             {
145                 changed = changed || thisValue != null;
146
147                 this.values[index] = null;
148
149                 if (clearConflictingOtherVariables)
150                 {
151                     other.values[index] = null;
152                 }
153             }
154         }
155
156         return changed;
157     }
158
159
160     /**
161      * Returns the number of variables.
162      */

163     public int size()
164     {
165         return size;
166     }
167
168
169     /**
170      * Gets the Value of the variable with the given index, without disturbing it.
171      */

172     public Value getValue(int index)
173     {
174         if (index < 0 ||
175             index >= size)
176         {
177             throw new IndexOutOfBoundsException JavaDoc("Variable index ["+index+"] out of bounds ["+size+"]");
178         }
179
180         return values[index];
181     }
182
183
184     /**
185      * Stores the given Value at the given variable index.
186      */

187     public void store(int index, Value value)
188     {
189         if (index < 0 ||
190             index >= size)
191         {
192             throw new IndexOutOfBoundsException JavaDoc("Variable index ["+index+"] out of bounds ["+size+"]");
193         }
194
195         // Store the value.
196
values[index] = value;
197
198         // Account for the extra space required by Category 2 values.
199
if (value.isCategory2())
200         {
201             values[index + 1] = TOP_VALUE;
202         }
203     }
204
205
206     /**
207      * Loads the Value from the variable with the given index.
208      */

209     public Value load(int index)
210     {
211         if (index < 0 ||
212             index >= size)
213         {
214             throw new IndexOutOfBoundsException JavaDoc("Variable index ["+index+"] out of bounds ["+size+"]");
215         }
216
217         return values[index];
218     }
219
220
221     // Load methods that provide convenient casts to the expected value types.
222

223     /**
224      * Loads the IntegerValue from the variable with the given index.
225      */

226     public IntegerValue iload(int index)
227     {
228         return load(index).integerValue();
229     }
230
231
232     /**
233      * Loads the LongValue from the variable with the given index.
234      */

235     public LongValue lload(int index)
236     {
237         return load(index).longValue();
238     }
239
240
241     /**
242      * Loads the FloatValue from the variable with the given index.
243      */

244     public FloatValue fload(int index)
245     {
246         return load(index).floatValue();
247     }
248
249
250     /**
251      * Loads the DoubleValue from the variable with the given index.
252      */

253     public DoubleValue dload(int index)
254     {
255         return load(index).doubleValue();
256     }
257
258
259     /**
260      * Loads the ReferenceValue from the variable with the given index.
261      */

262     public ReferenceValue aload(int index)
263     {
264         return load(index).referenceValue();
265     }
266
267
268     /**
269      * Loads the InstructionOffsetValue from the variable with the given index.
270      */

271     public InstructionOffsetValue oload(int index)
272     {
273         return load(index).instructionOffsetValue();
274     }
275
276
277     // Implementations for Object.
278

279     public boolean equals(Object JavaDoc object)
280     {
281         if (object == null ||
282             this.getClass() != object.getClass())
283         {
284             return false;
285         }
286
287         Variables other = (Variables)object;
288
289         if (this.size != other.size)
290         {
291             return false;
292         }
293
294         for (int index = 0; index < size; index++)
295         {
296             Value thisValue = this.values[index];
297             Value otherValue = other.values[index];
298
299             // Occasionally, two values of different types might be
300
// present in the same variable in a variable frame
301
// (corresponding to two local variables that share the
302
// same index), at some point outside of their scopes.
303
// We'll ignore these.
304
if (thisValue != null &&
305                 otherValue != null &&
306                 thisValue.computationalType() == otherValue.computationalType() &&
307                 !thisValue.equals(otherValue))
308             {
309                 return false;
310             }
311         }
312
313         return true;
314     }
315
316
317     public int hashCode()
318     {
319         int hashCode = size;
320
321         for (int index = 0; index < size; index++)
322         {
323             Value value = values[index];
324             if (value != null)
325             {
326                 hashCode ^= value.hashCode();
327             }
328         }
329
330         return hashCode;
331     }
332
333
334     public String JavaDoc toString()
335     {
336         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
337
338         for (int index = 0; index < size; index++)
339         {
340             Value value = values[index];
341             buffer = buffer.append('[')
342                            .append(value == null ? "empty" : value.toString())
343                            .append(']');
344         }
345
346         return buffer.toString();
347     }
348 }
349
Free Books   Free Magazines  
Popular Tags