summaryrefslogtreecommitdiff
path: root/tools/gnu/classpath/tools/rmic/Variables.java
diff options
context:
space:
mode:
Diffstat (limited to 'tools/gnu/classpath/tools/rmic/Variables.java')
-rw-r--r--tools/gnu/classpath/tools/rmic/Variables.java137
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();
+ }
+}