1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/*
2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ProGuard -- shrinking, optimization, obfuscation, and preverification
3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *             of Java bytecode.
4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
52270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom * Copyright (c) 2002-2014 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
25b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangimport java.util.Arrays;
26b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/**
28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This class represents an operand stack that contains <code>Value</code>
29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * objects.
30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune
32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */
33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic class Stack
34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{
35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private static final TopValue TOP_VALUE = new TopValue();
36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected Value[] values;
39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected int     currentSize;
40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected int     actualMaxSize;
41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Creates a new Stack with a given maximum size, accounting for the double
45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * space required by Category 2 values.
46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public Stack(int maxSize)
48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values = new Value[maxSize];
50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Creates a Stack that is a copy of the given Stack.
55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public Stack(Stack stack)
57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Create the values array.
59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        this(stack.values.length);
60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Copy the stack contents.
62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        copy(stack);
63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Returns the actual maximum stack size that was required for all stack
68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * operations, accounting for the double space required by Category 2 values.
69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public int getActualMaxSize()
71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return actualMaxSize;
73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Resets this Stack, so that it can be reused.
78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void reset(int maxSize)
80b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
81b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Is the values array large enough?
82b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (maxSize > values.length)
83b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
84b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Create a new one.
85b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            values = new Value[maxSize];
86b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
87b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
88b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Clear the sizes.
89b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        clear();
90b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
91b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        actualMaxSize = 0;
92b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
93b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
94b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
95b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
96b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Copies the values of the given Stack into this Stack.
97b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
98b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void copy(Stack other)
99b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
100b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Is the values array large enough?
101b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (other.values.length > values.length)
102b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
103b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Create a new one.
104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            values = new Value[other.values.length];
105b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
106b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
107b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Copy the stack contents.
108b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        System.arraycopy(other.values, 0, this.values, 0, other.currentSize);
109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
110b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Copy the sizes.
111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        currentSize   = other.currentSize;
112b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        actualMaxSize = other.actualMaxSize;
113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
115b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
116b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
117b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Generalizes the values of this Stack with the values of the given Stack.
118b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * The stacks must have the same current sizes.
119b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * @return whether the generalization has made any difference.
120b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
121b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public boolean generalize(Stack other)
122b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
123b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (this.currentSize != other.currentSize)
124b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
125b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            throw new IllegalArgumentException("Stacks have different current sizes ["+this.currentSize+"] and ["+other.currentSize+"]");
126b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
127b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
128b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        boolean changed = false;
129b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
130b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Generalize the stack values.
131b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        for (int index = 0; index < currentSize; index++)
132b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
133b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            Value thisValue  = this.values[index];
134b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
135b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (thisValue != null)
136b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
137b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                Value newValue = null;
138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                Value otherValue = other.values[index];
140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                if (otherValue != null)
142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                {
143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    newValue = thisValue.generalize(otherValue);
144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                }
145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                changed = changed || !thisValue.equals(newValue);
147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                values[index] = newValue;
149b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
150b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
151b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
152b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Check if the other stack extends beyond this one.
153b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (this.actualMaxSize < other.actualMaxSize)
154b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
155b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            this.actualMaxSize = other.actualMaxSize;
156b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
157b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
158b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return changed;
159b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
160b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
161b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
162b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
163b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Clears the stack.
164b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
165b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void clear()
166b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
167b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Clear the stack contents.
168b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        Arrays.fill(values, 0, currentSize, null);
169b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
170b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        currentSize = 0;
171b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
172b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
173b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
174b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
175b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Returns the number of elements currently on the stack, accounting for the
176b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * double space required by Category 2 values.
177b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
178b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public int size()
179b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
180b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return currentSize;
181b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
182b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
183b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
184b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
185b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Gets the specified Value from the stack, without disturbing it.
186b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * @param index the index of the stack element, counting from the bottom
187b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     *              of the stack.
188b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * @return the value at the specified position.
189b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
190b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public Value getBottom(int index)
191b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
192b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return values[index];
193b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
194b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
195b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
196b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
197b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Sets the specified Value on the stack, without disturbing it.
198b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * @param index the index of the stack element, counting from the bottom
199b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     *              of the stack.
200b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * @param value the value to set.
201b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
202b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void setBottom(int index, Value value)
203b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
204b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[index] = value;
205b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
206b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
207b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
208b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
209b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Gets the specified Value from the stack, without disturbing it.
210b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * @param index the index of the stack element, counting from the top
211b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     *              of the stack.
212b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * @return the value at the specified position.
213b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
214b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public Value getTop(int index)
215b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
216b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return values[currentSize - index - 1];
217b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
218b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
219b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
220b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
221b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Sets the specified Value on the stack, without disturbing it.
222b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * @param index the index of the stack element, counting from the top
223b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     *              of the stack.
224b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * @param value the value to set.
225b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
226b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void setTop(int index, Value value)
227b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
228b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize - index - 1] = value;
229b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
230b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
231b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
232b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
233b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Removes the specified Value from the stack.
234b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * @param index the index of the stack element, counting from the top
235b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     *              of the stack.
236b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
237b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void removeTop(int index)
238b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
239b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        System.arraycopy(values, currentSize - index,
240b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                         values, currentSize - index - 1,
241b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                         index);
242b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        currentSize--;
243b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
244b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
245b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
246b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
247b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Pushes the given Value onto the stack.
248b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
249b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void push(Value value)
250b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
251b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Account for the extra space required by Category 2 values.
252b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (value.isCategory2())
253b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
254b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            values[currentSize++] = TOP_VALUE;
255b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
256b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
257b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Push the value.
258b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize++] = value;
259b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
260b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Update the maximum actual size;
261b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (actualMaxSize < currentSize)
262b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
263b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            actualMaxSize = currentSize;
264b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
265b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
266b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
267b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
268b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
269b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Pops the top Value from the stack.
270b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
271b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public Value pop()
272b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
273b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Value value = values[--currentSize];
274b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
275b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize] = null;
276b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
277b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Account for the extra space required by Category 2 values.
278b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (value.isCategory2())
279b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
280b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            values[--currentSize] = null;
281b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
282b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
283b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return value;
284b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
285b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
286b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
287b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Pop methods that provide convenient casts to the expected value types.
288b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
289b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
290b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Pops the top IntegerValue from the stack.
291b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
292b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public IntegerValue ipop()
293b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
294b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return pop().integerValue();
295b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
296b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
297b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
298b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
299b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Pops the top LongValue from the stack.
300b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
301b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public LongValue lpop()
302b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
303b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return pop().longValue();
304b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
305b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
306b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
307b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
308b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Pops the top FloatValue from the stack.
309b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
310b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public FloatValue fpop()
311b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
312b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return pop().floatValue();
313b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
314b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
315b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
316b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
317b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Pops the top DoubleValue from the stack.
318b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
319b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public DoubleValue dpop()
320b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
321b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return pop().doubleValue();
322b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
323b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
324b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
325b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
326b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Pops the top ReferenceValue from the stack.
327b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
328b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public ReferenceValue apop()
329b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
330b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return pop().referenceValue();
331b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
332b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
333b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
334b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
335b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Pops the top InstructionOffsetValue from the stack.
336b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
337b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public InstructionOffsetValue opop()
338b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
339b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return pop().instructionOffsetValue();
340b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
341b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
342b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
343b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
344b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Pops the top category 1 value from the stack.
345b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
346b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void pop1()
347b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
348b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[--currentSize] = null;
349b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
350b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
351b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
352b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
353b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Pops the top category 2 value from the stack (or alternatively, two
354b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Category 1 stack elements).
355b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
356b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void pop2()
357b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
358b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[--currentSize] = null;
359b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[--currentSize] = null;
360b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
361b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
362b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
363b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
364b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Duplicates the top Category 1 value.
365b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
366b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void dup()
367b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
368b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize] = values[currentSize - 1].category1Value();
369b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
370b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        currentSize++;
371b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
372b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Update the maximum actual size;
373b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (actualMaxSize < currentSize)
374b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
375b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            actualMaxSize = currentSize;
376b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
377b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
378b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
379b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
380b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
381b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Duplicates the top Category 1 value, one Category 1 element down the
382b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * stack.
383b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
384b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void dup_x1()
385b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
386b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize]     = values[currentSize - 1].category1Value();
387b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize - 1] = values[currentSize - 2].category1Value();
388b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize - 2] = values[currentSize    ];
389b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
390b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        currentSize++;
391b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
392b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Update the maximum actual size;
393b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (actualMaxSize < currentSize)
394b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
395b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            actualMaxSize = currentSize;
396b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
397b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
398b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
399b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
400b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
401b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Duplicates the top Category 1 value, two Category 1 elements (or one
402b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Category 2 element) down the stack.
403b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
404b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void dup_x2()
405b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
406b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize]     = values[currentSize - 1].category1Value();
407b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize - 1] = values[currentSize - 2];
408b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize - 2] = values[currentSize - 3];
409b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize - 3] = values[currentSize    ];
410b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
411b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        currentSize++;
412b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
413b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Update the maximum actual size;
414b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (actualMaxSize < currentSize)
415b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
416b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            actualMaxSize = currentSize;
417b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
418b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
419b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
420b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
421b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Duplicates the top Category 2 value (or alternatively, the equivalent
422b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Category 1 stack elements).
423b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
424b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void dup2()
425b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
426b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize    ] = values[currentSize - 2];
427b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize + 1] = values[currentSize - 1];
428b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
429b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        currentSize += 2;
430b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
431b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Update the maximum actual size;
432b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (actualMaxSize < currentSize)
433b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
434b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            actualMaxSize = currentSize;
435b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
436b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
437b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
438b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
439b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
440b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Duplicates the top Category 2 value, one Category 1 element down the
441b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * stack (or alternatively, the equivalent Category 1 stack values).
442b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
443b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void dup2_x1()
444b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
445b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize + 1] = values[currentSize - 1];
446b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize    ] = values[currentSize - 2];
447b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize - 1] = values[currentSize - 3];
448b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize - 2] = values[currentSize + 1];
449b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize - 3] = values[currentSize    ];
450b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
451b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        currentSize += 2;
452b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
453b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Update the maximum actual size;
454b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (actualMaxSize < currentSize)
455b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
456b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            actualMaxSize = currentSize;
457b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
458b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
459b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
460b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
461b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
462b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Duplicates the top Category 2 value, one Category 2 stack element down
463b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * the stack (or alternatively, the equivalent Category 1 stack values).
464b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
465b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void dup2_x2()
466b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
467b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize + 1] = values[currentSize - 1];
468b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize    ] = values[currentSize - 2];
469b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize - 1] = values[currentSize - 3];
470b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize - 2] = values[currentSize - 4];
471b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize - 3] = values[currentSize + 1];
472b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize - 4] = values[currentSize    ];
473b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
474b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        currentSize += 2;
475b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
476b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Update the maximum actual size;
477b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (actualMaxSize < currentSize)
478b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
479b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            actualMaxSize = currentSize;
480b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
481b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
482b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
483b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
484b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
485b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Swaps the top two Category 1 values.
486b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
487b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void swap()
488b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
489b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Value value1 = values[currentSize - 1].category1Value();
490b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Value value2 = values[currentSize - 2].category1Value();
491b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
492b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize - 1] = value2;
493b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        values[currentSize - 2] = value1;
494b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
495b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
496b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
497b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for Object.
498b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
499b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public boolean equals(Object object)
500b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
501b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (object == null ||
502b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            this.getClass() != object.getClass())
503b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
504b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            return false;
505b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
506b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
507b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Stack other = (Stack)object;
508b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
509b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (this.currentSize != other.currentSize)
510b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
511b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            return false;
512b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
513b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
514b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        for (int index = 0; index < currentSize; index++)
515b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
516b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            Value thisValue  = this.values[index];
517b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            Value otherValue = other.values[index];
518b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (thisValue == null ? otherValue != null :
519b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                    !thisValue.equals(otherValue))
520b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
521b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                return false;
522b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
523b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
524b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
525b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return true;
526b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
527b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
528b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
529b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public int hashCode()
530b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
531b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int hashCode = currentSize;
532b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
533b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        for (int index = 0; index < currentSize; index++)
534b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
535b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            Value value = values[index];
536b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (value != null)
537b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
538b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                hashCode ^= value.hashCode();
539b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
540b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
541b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
542b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return hashCode;
543b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
544b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
545b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
546b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public String toString()
547b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
548b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        StringBuffer buffer = new StringBuffer();
549b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
550b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        for (int index = 0; index < currentSize; index++)
551b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
552b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            Value value = values[index];
553b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            buffer = buffer.append('[')
554b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                           .append(value == null ? "empty" : value.toString())
555b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                           .append(']');
556b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
557b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
558b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return buffer.toString();
559b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
560b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato}
561