summaryrefslogtreecommitdiff
path: root/src/proguard/evaluation/Stack.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/proguard/evaluation/Stack.java')
-rw-r--r--src/proguard/evaluation/Stack.java560
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();
- }
-}