/* VariableStack Copyright (C) 1999-2002 Jochen Hoenicke. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2, 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 Lesser General Public License * along with this program; see the file COPYING.LESSER. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id$ */ package net.sf.jode.flow; import net.sf.jode.decompiler.LocalInfo; import net.sf.jode.expr.Expression; import net.sf.jode.expr.LocalLoadOperator; /** * This class represents the state of the stack at various points in * the program. Each entry is a anonymous local, which is used instead * of the PUSH / stack_i statements.
*
* This class is immutable, but note, that the local infos can get merged.
* @see FlowBlock#mapStackToLocal
* @see FlowBlock#removePush
*/
public class VariableStack {
public final static VariableStack EMPTY = new VariableStack();
final LocalInfo[] stackMap;
private VariableStack() {
stackMap = new LocalInfo[0];
}
private VariableStack(LocalInfo[] stack) {
stackMap = stack;
}
public boolean isEmpty() {
return stackMap.length == 0;
}
public VariableStack pop(int count) {
LocalInfo[] newStack = new LocalInfo[stackMap.length - count];
System.arraycopy(stackMap, 0, newStack, 0, stackMap.length - count);
return new VariableStack(newStack);
}
public VariableStack push(LocalInfo li) {
return poppush(0, li);
}
public VariableStack poppush(int count, LocalInfo li) {
LocalInfo[] newStack = new LocalInfo[stackMap.length - count + 1];
System.arraycopy(stackMap, 0, newStack, 0, stackMap.length - count);
newStack[stackMap.length - count] = li;
return new VariableStack(newStack);
}
public VariableStack peek(int count) {
LocalInfo[] peeked = new LocalInfo[count];
System.arraycopy(stackMap, stackMap.length - count, peeked, 0, count);
return new VariableStack(peeked);
}
public void merge(VariableStack other) {
if (stackMap.length != other.stackMap.length)
throw new IllegalArgumentException("stack length differs");
for (int i=0; i