diff options
Diffstat (limited to 'tools/gnu/classpath/tools/rmic/Variables.java')
-rw-r--r-- | tools/gnu/classpath/tools/rmic/Variables.java | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/tools/gnu/classpath/tools/rmic/Variables.java b/tools/gnu/classpath/tools/rmic/Variables.java new file mode 100644 index 000000000..bddf5f783 --- /dev/null +++ b/tools/gnu/classpath/tools/rmic/Variables.java @@ -0,0 +1,137 @@ +/* Variables.java -- + Copyright (c) 2004, 2005 + Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath 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, or (at your option) +any later version. + +GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. */ + +package gnu.classpath.tools.rmic; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; + +class Variables +{ + private final HashSet free = new HashSet(); + private final HashMap names = new HashMap(); + private final HashSet wides = new HashSet(); + private final HashSet declared = new HashSet(); + private boolean allocated = false; + + public void declare(Object name) + { + declare(name, 1); + } + + public void declareWide(Object name) + { + declare(name, 2); + } + + public void declare(Object name, int size) + { + if (allocated) + throw new IllegalStateException("cannot declare after allocating"); + if (size != 1 && size != 2) + throw new IllegalArgumentException("size must be 1 or 2"); + if (names.containsKey(name)) + throw new IllegalStateException("already allocated " + name); + + allocateNew(name, size); + declared.add(name); + } + + private int allocateNew(Object name, int size) + { + // total allocation size is first unallocated slot + int i = free.size() + names.size() + wides.size(); + names.put(name, new Integer(i)); + if (size == 2) wides.add(name); + return i; + } + + public int allocate(Object name) + { + return allocate(name, 1); + } + + public int allocateWide(Object name) + { + return allocate(name, 2); + } + + public int allocate(Object name, int size) + { + allocated = true; + if (size != 1 && size != 2) + throw new IllegalArgumentException("size must be 1 or 2"); + if (names.containsKey(name)) + throw new IllegalStateException("already allocated " + name); + + if (size == 2) + { + // look for consecutive free slots + for (Iterator it = free.iterator(); it.hasNext(); ) + { + Integer i = (Integer) it.next(); + Integer next = new Integer(i.intValue() + 1); + if (free.contains(next)) + { + free.remove(i); + free.remove(next); + wides.add(name); + names.put(name, i); + return i.intValue(); + } + } + } + else if (free.size() > 0) + { + Integer i = (Integer) free.iterator().next(); + free.remove(i); + names.put(name, i); + return i.intValue(); + } + + return allocateNew(name, size); + } + + public int deallocate(Object name) + { + if (! names.containsKey(name)) + throw new IllegalArgumentException("no variable " + name); + + if (declared.contains(name)) + throw new IllegalStateException(name + " can't be deallocated"); + + Integer i = (Integer) names.get(name); + names.remove(name); + free.add(i); + if (wides.remove(name)) + free.add(new Integer(i.intValue() + 1)); + return i.intValue(); + } + + public int get(Object name) + { + if (! names.containsKey(name)) + throw new IllegalArgumentException("no variable " + name); + + return ((Integer) names.get(name)).intValue(); + } +} |