1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/*
2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ProGuard -- shrinking, optimization, obfuscation, and preverification
3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *             of Java bytecode.
4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
5b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
6b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
7b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is free software; you can redistribute it and/or modify it
8b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * under the terms of the GNU General Public License as published by the Free
9b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Software Foundation; either version 2 of the License, or (at your option)
10b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * any later version.
11b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
12b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is distributed in the hope that it will be useful, but WITHOUT
13b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * more details.
16b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
17b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * You should have received a copy of the GNU General Public License along
18b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * with this program; if not, write to the Free Software Foundation, Inc.,
19b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */
21b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopackage proguard.evaluation;
22b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
23b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.evaluation.value.*;
24b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/**
26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This class represents a local variable frame that contains <code>Value</code>
27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * objects. Values are generalizations of all values that have been stored in
28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * the respective variables.
29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune
31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */
32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic class Variables
33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{
34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private static final TopValue TOP_VALUE = new TopValue();
35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected Value[] values;
38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected int     size;
39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Creates a new Variables object with a given maximum number of variables.
43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public Variables(int size)
45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        this.values = new Value[size];
47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        this.size   = size;
48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Creates a Variables object that is a copy of the given Variables object.
53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public Variables(Variables variables)
55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Create the values array.
57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        this(variables.size);
58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Copy the values.
60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        initialize(variables);
61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Resets this Variables object, so that it can be reused.
66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void reset(int size)
68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Is the values array large enough?
70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (size > values.length)
71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Create a new one.
73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            values = new Value[size];
74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        else
76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Clear the variables.
78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            for (int index = 0; index < values.length; index++)
79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
80b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                values[index] = null;
81b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
82b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
83b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
84b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        this.size = size;
85b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
86b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
87b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
88b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
89b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Initializes the values of this Variables object with the values of the
90b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * given Variables object. The other object may have fewer values, in which
91b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * case the remaining values are left unchanged.
92b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
93b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void initialize(Variables other)
94b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
95b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (this.size < other.size)
96b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
97b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            throw new IllegalArgumentException("Variable frame is too small ["+this.size+"] compared to other frame ["+other.size+"]");
98b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
99b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
100b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Copy the values.
101b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        System.arraycopy(other.values, 0, this.values, 0, other.size);
102b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
103b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
105b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
106b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Generalizes the values of this Variables object with the values of the
107b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * given Variables object.
108b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * @param clearConflictingOtherVariables specifies whether the other
109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     *                                       variables should be cleared too,
110b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     *                                       in case of conflicts.
111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * @return whether the generalization has made any difference.
112b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public boolean generalize(Variables other,
114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                              boolean   clearConflictingOtherVariables)
115b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
116b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (this.size != other.size)
117b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
118b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            throw new IllegalArgumentException("Variable frames have different sizes ["+this.size+"] and ["+other.size+"]");
119b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
120b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
121b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        boolean changed = false;
122b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
123b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        for (int index = 0; index < size; index++)
124b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
125b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            Value thisValue  = this.values[index];
126b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            Value otherValue = other.values[index];
127b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
128b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Occasionally, two values of different types might be present
129b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // in the same variable in a variable frame (corresponding to
130b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // two local variables that share the same index), at some point
131b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // outside of their scopes. Don't generalize the variable then,
132b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // but let it clear instead.
133b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (thisValue  != null &&
134b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                otherValue != null &&
135b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                thisValue.computationalType() == otherValue.computationalType())
136b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
137b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                Value newValue = thisValue.generalize(otherValue);
138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                changed = changed || !thisValue.equals(newValue);
140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                this.values[index] = newValue;
142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            else
144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                changed = changed || thisValue != null;
146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                this.values[index] = null;
148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
149b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                if (clearConflictingOtherVariables)
150b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                {
151b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    other.values[index] = null;
152b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                }
153b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
154b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
155b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
156b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return changed;
157b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
158b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
159b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
160b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
161b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Returns the number of variables.
162b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
163b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public int size()
164b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
165b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return size;
166b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
167b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
168b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
169b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
170b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Gets the Value of the variable with the given index, without disturbing it.
171b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
172b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public Value getValue(int index)
173b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
174b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (index < 0 ||
175b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            index >= size)
176b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
177b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            throw new IndexOutOfBoundsException("Variable index ["+index+"] out of bounds ["+size+"]");
178b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
179b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
180b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return values[index];
181b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
182b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
183b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
184b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
185b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Stores the given Value at the given variable index.
186b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
187b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void store(int index, Value value)
188b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
189b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (index < 0 ||
190b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            index >= size)
191b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
192b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            throw new IndexOutOfBoundsException("Variable index ["+index+"] out of bounds ["+size+"]");
193b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
194b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
195b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Store the value.
196b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[index] = value;
197b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
198b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Account for the extra space required by Category 2 values.
199b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (value.isCategory2())
200b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
201b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            values[index + 1] = TOP_VALUE;
202b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
203b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
204b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
205b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
206b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
207b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Loads the Value from the variable with the given index.
208b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
209b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public Value load(int index)
210b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
211b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (index < 0 ||
212b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            index >= size)
213b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
214b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            throw new IndexOutOfBoundsException("Variable index ["+index+"] out of bounds ["+size+"]");
215b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
216b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
217b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return values[index];
218b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
219b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
220b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
221b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Load methods that provide convenient casts to the expected value types.
222b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
223b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
224b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Loads the IntegerValue from the variable with the given index.
225b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
226b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public IntegerValue iload(int index)
227b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
228b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return load(index).integerValue();
229b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
230b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
231b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
232b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
233b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Loads the LongValue from the variable with the given index.
234b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
235b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public LongValue lload(int index)
236b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
237b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return load(index).longValue();
238b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
239b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
240b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
241b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
242b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Loads the FloatValue from the variable with the given index.
243b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
244b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public FloatValue fload(int index)
245b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
246b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return load(index).floatValue();
247b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
248b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
249b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
250b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
251b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Loads the DoubleValue from the variable with the given index.
252b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
253b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public DoubleValue dload(int index)
254b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
255b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return load(index).doubleValue();
256b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
257b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
258b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
259b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
260b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Loads the ReferenceValue from the variable with the given index.
261b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
262b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public ReferenceValue aload(int index)
263b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
264b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return load(index).referenceValue();
265b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
266b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
267b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
268b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
269b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Loads the InstructionOffsetValue from the variable with the given index.
270b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
271b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public InstructionOffsetValue oload(int index)
272b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
273b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return load(index).instructionOffsetValue();
274b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
275b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
276b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
277b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for Object.
278b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
279b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public boolean equals(Object object)
280b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
281b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (object == null ||
282b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            this.getClass() != object.getClass())
283b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
284b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            return false;
285b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
286b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
287b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Variables other = (Variables)object;
288b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
289b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (this.size != other.size)
290b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
291b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            return false;
292b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
293b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
294b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        for (int index = 0; index < size; index++)
295b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
296b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            Value thisValue  = this.values[index];
297b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            Value otherValue = other.values[index];
298b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
299b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Occasionally, two values of different types might be
300b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // present in the same variable in a variable frame
301b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // (corresponding to two local variables that share the
302b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // same index), at some point outside of their scopes.
303b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // We'll ignore these.
304b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (thisValue  != null &&
305b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                otherValue != null &&
306b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                thisValue.computationalType() == otherValue.computationalType() &&
307b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                !thisValue.equals(otherValue))
308b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
309b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                return false;
310b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
311b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
312b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
313b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return true;
314b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
315b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
316b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
317b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public int hashCode()
318b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
319b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int hashCode = size;
320b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
321b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        for (int index = 0; index < size; index++)
322b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
323b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            Value value = values[index];
324b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (value != null)
325b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
326b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                hashCode ^= value.hashCode();
327b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
328b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
329b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
330b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return hashCode;
331b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
332b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
333b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
334b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public String toString()
335b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
336b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        StringBuffer buffer = new StringBuffer();
337b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
338b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        for (int index = 0; index < size; index++)
339b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
340b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            Value value = values[index];
341b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            buffer = buffer.append('[')
342b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                           .append(value == null ? "empty" : value.toString())
343b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                           .append(']');
344b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
345b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
346b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return buffer.toString();
347b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
348b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato}
349