diff options
Diffstat (limited to 'src/proguard/evaluation/Stack.java')
-rw-r--r-- | src/proguard/evaluation/Stack.java | 560 |
1 files changed, 0 insertions, 560 deletions
diff --git a/src/proguard/evaluation/Stack.java b/src/proguard/evaluation/Stack.java deleted file mode 100644 index 9294853..0000000 --- a/src/proguard/evaluation/Stack.java +++ /dev/null @@ -1,560 +0,0 @@ -/* - * ProGuard -- shrinking, optimization, obfuscation, and preverification - * of Java bytecode. - * - * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -package proguard.evaluation; - -import proguard.evaluation.value.*; - -import java.util.Arrays; - -/** - * This class represents an operand stack that contains <code>Value</code> - * objects. - * - * @author Eric Lafortune - */ -public class Stack -{ - private static final TopValue TOP_VALUE = new TopValue(); - - - protected Value[] values; - protected int currentSize; - protected int actualMaxSize; - - - /** - * Creates a new Stack with a given maximum size, accounting for the double - * space required by Category 2 values. - */ - public Stack(int maxSize) - { - values = new Value[maxSize]; - } - - - /** - * Creates a Stack that is a copy of the given Stack. - */ - public Stack(Stack stack) - { - // Create the values array. - this(stack.values.length); - - // Copy the stack contents. - copy(stack); - } - - - /** - * Returns the actual maximum stack size that was required for all stack - * operations, accounting for the double space required by Category 2 values. - */ - public int getActualMaxSize() - { - return actualMaxSize; - } - - - /** - * Resets this Stack, so that it can be reused. - */ - public void reset(int maxSize) - { - // Is the values array large enough? - if (maxSize > values.length) - { - // Create a new one. - values = new Value[maxSize]; - } - - // Clear the sizes. - clear(); - - actualMaxSize = 0; - } - - - /** - * Copies the values of the given Stack into this Stack. - */ - public void copy(Stack other) - { - // Is the values array large enough? - if (other.values.length > values.length) - { - // Create a new one. - values = new Value[other.values.length]; - } - - // Copy the stack contents. - System.arraycopy(other.values, 0, this.values, 0, other.currentSize); - - // Copy the sizes. - currentSize = other.currentSize; - actualMaxSize = other.actualMaxSize; - } - - - /** - * Generalizes the values of this Stack with the values of the given Stack. - * The stacks must have the same current sizes. - * @return whether the generalization has made any difference. - */ - public boolean generalize(Stack other) - { - if (this.currentSize != other.currentSize) - { - throw new IllegalArgumentException("Stacks have different current sizes ["+this.currentSize+"] and ["+other.currentSize+"]"); - } - - boolean changed = false; - - // Generalize the stack values. - for (int index = 0; index < currentSize; index++) - { - Value thisValue = this.values[index]; - - if (thisValue != null) - { - Value newValue = null; - - Value otherValue = other.values[index]; - - if (otherValue != null) - { - newValue = thisValue.generalize(otherValue); - } - - changed = changed || !thisValue.equals(newValue); - - values[index] = newValue; - } - } - - // Check if the other stack extends beyond this one. - if (this.actualMaxSize < other.actualMaxSize) - { - this.actualMaxSize = other.actualMaxSize; - } - - return changed; - } - - - /** - * Clears the stack. - */ - public void clear() - { - // Clear the stack contents. - Arrays.fill(values, 0, currentSize, null); - - currentSize = 0; - } - - - /** - * Returns the number of elements currently on the stack, accounting for the - * double space required by Category 2 values. - */ - public int size() - { - return currentSize; - } - - - /** - * Gets the specified Value from the stack, without disturbing it. - * @param index the index of the stack element, counting from the bottom - * of the stack. - * @return the value at the specified position. - */ - public Value getBottom(int index) - { - return values[index]; - } - - - /** - * Sets the specified Value on the stack, without disturbing it. - * @param index the index of the stack element, counting from the bottom - * of the stack. - * @param value the value to set. - */ - public void setBottom(int index, Value value) - { - values[index] = value; - } - - - /** - * Gets the specified Value from the stack, without disturbing it. - * @param index the index of the stack element, counting from the top - * of the stack. - * @return the value at the specified position. - */ - public Value getTop(int index) - { - return values[currentSize - index - 1]; - } - - - /** - * Sets the specified Value on the stack, without disturbing it. - * @param index the index of the stack element, counting from the top - * of the stack. - * @param value the value to set. - */ - public void setTop(int index, Value value) - { - values[currentSize - index - 1] = value; - } - - - /** - * Removes the specified Value from the stack. - * @param index the index of the stack element, counting from the top - * of the stack. - */ - public void removeTop(int index) - { - System.arraycopy(values, currentSize - index, - values, currentSize - index - 1, - index); - currentSize--; - } - - - /** - * Pushes the given Value onto the stack. - */ - public void push(Value value) - { - // Account for the extra space required by Category 2 values. - if (value.isCategory2()) - { - values[currentSize++] = TOP_VALUE; - } - - // Push the value. - values[currentSize++] = value; - - // Update the maximum actual size; - if (actualMaxSize < currentSize) - { - actualMaxSize = currentSize; - } - } - - - /** - * Pops the top Value from the stack. - */ - public Value pop() - { - Value value = values[--currentSize]; - - values[currentSize] = null; - - // Account for the extra space required by Category 2 values. - if (value.isCategory2()) - { - values[--currentSize] = null; - } - - return value; - } - - - // Pop methods that provide convenient casts to the expected value types. - - /** - * Pops the top IntegerValue from the stack. - */ - public IntegerValue ipop() - { - return pop().integerValue(); - } - - - /** - * Pops the top LongValue from the stack. - */ - public LongValue lpop() - { - return pop().longValue(); - } - - - /** - * Pops the top FloatValue from the stack. - */ - public FloatValue fpop() - { - return pop().floatValue(); - } - - - /** - * Pops the top DoubleValue from the stack. - */ - public DoubleValue dpop() - { - return pop().doubleValue(); - } - - - /** - * Pops the top ReferenceValue from the stack. - */ - public ReferenceValue apop() - { - return pop().referenceValue(); - } - - - /** - * Pops the top InstructionOffsetValue from the stack. - */ - public InstructionOffsetValue opop() - { - return pop().instructionOffsetValue(); - } - - - /** - * Pops the top category 1 value from the stack. - */ - public void pop1() - { - values[--currentSize] = null; - } - - - /** - * Pops the top category 2 value from the stack (or alternatively, two - * Category 1 stack elements). - */ - public void pop2() - { - values[--currentSize] = null; - values[--currentSize] = null; - } - - - /** - * Duplicates the top Category 1 value. - */ - public void dup() - { - values[currentSize] = values[currentSize - 1].category1Value(); - - currentSize++; - - // Update the maximum actual size; - if (actualMaxSize < currentSize) - { - actualMaxSize = currentSize; - } - } - - - /** - * Duplicates the top Category 1 value, one Category 1 element down the - * stack. - */ - public void dup_x1() - { - values[currentSize] = values[currentSize - 1].category1Value(); - values[currentSize - 1] = values[currentSize - 2].category1Value(); - values[currentSize - 2] = values[currentSize ]; - - currentSize++; - - // Update the maximum actual size; - if (actualMaxSize < currentSize) - { - actualMaxSize = currentSize; - } - } - - - /** - * Duplicates the top Category 1 value, two Category 1 elements (or one - * Category 2 element) down the stack. - */ - public void dup_x2() - { - values[currentSize] = values[currentSize - 1].category1Value(); - values[currentSize - 1] = values[currentSize - 2]; - values[currentSize - 2] = values[currentSize - 3]; - values[currentSize - 3] = values[currentSize ]; - - currentSize++; - - // Update the maximum actual size; - if (actualMaxSize < currentSize) - { - actualMaxSize = currentSize; - } - } - - /** - * Duplicates the top Category 2 value (or alternatively, the equivalent - * Category 1 stack elements). - */ - public void dup2() - { - values[currentSize ] = values[currentSize - 2]; - values[currentSize + 1] = values[currentSize - 1]; - - currentSize += 2; - - // Update the maximum actual size; - if (actualMaxSize < currentSize) - { - actualMaxSize = currentSize; - } - } - - - /** - * Duplicates the top Category 2 value, one Category 1 element down the - * stack (or alternatively, the equivalent Category 1 stack values). - */ - public void dup2_x1() - { - values[currentSize + 1] = values[currentSize - 1]; - values[currentSize ] = values[currentSize - 2]; - values[currentSize - 1] = values[currentSize - 3]; - values[currentSize - 2] = values[currentSize + 1]; - values[currentSize - 3] = values[currentSize ]; - - currentSize += 2; - - // Update the maximum actual size; - if (actualMaxSize < currentSize) - { - actualMaxSize = currentSize; - } - } - - - /** - * Duplicates the top Category 2 value, one Category 2 stack element down - * the stack (or alternatively, the equivalent Category 1 stack values). - */ - public void dup2_x2() - { - values[currentSize + 1] = values[currentSize - 1]; - values[currentSize ] = values[currentSize - 2]; - values[currentSize - 1] = values[currentSize - 3]; - values[currentSize - 2] = values[currentSize - 4]; - values[currentSize - 3] = values[currentSize + 1]; - values[currentSize - 4] = values[currentSize ]; - - currentSize += 2; - - // Update the maximum actual size; - if (actualMaxSize < currentSize) - { - actualMaxSize = currentSize; - } - } - - - /** - * Swaps the top two Category 1 values. - */ - public void swap() - { - Value value1 = values[currentSize - 1].category1Value(); - Value value2 = values[currentSize - 2].category1Value(); - - values[currentSize - 1] = value2; - values[currentSize - 2] = value1; - } - - - // Implementations for Object. - - public boolean equals(Object object) - { - if (object == null || - this.getClass() != object.getClass()) - { - return false; - } - - Stack other = (Stack)object; - - if (this.currentSize != other.currentSize) - { - return false; - } - - for (int index = 0; index < currentSize; index++) - { - Value thisValue = this.values[index]; - Value otherValue = other.values[index]; - if (thisValue == null ? otherValue != null : - !thisValue.equals(otherValue)) - { - return false; - } - } - - return true; - } - - - public int hashCode() - { - int hashCode = currentSize; - - for (int index = 0; index < currentSize; index++) - { - Value value = values[index]; - if (value != null) - { - hashCode ^= value.hashCode(); - } - } - - return hashCode; - } - - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - for (int index = 0; index < currentSize; index++) - { - Value value = values[index]; - buffer = buffer.append('[') - .append(value == null ? "empty" : value.toString()) - .append(']'); - } - - return buffer.toString(); - } -} |