OSDN Git Service

Merged gcj-eclipse branch to trunk.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / tools / gnu / classpath / tools / rmic / Variables.java
1 /* Variables.java --
2    Copyright (c) 2004, 2005
3    Free Software Foundation, Inc.
4
5 This file is part of GNU Classpath.
6
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING.  If not, write to the
19 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 02111-1307 USA. */
21
22 package gnu.classpath.tools.rmic;
23
24 import java.util.HashMap;
25 import java.util.HashSet;
26 import java.util.Iterator;
27
28 class Variables
29 {
30   private final HashSet free = new HashSet();
31   private final HashMap names = new HashMap();
32   private final HashSet wides = new HashSet();
33   private final HashSet declared = new HashSet();
34   private boolean allocated = false;
35
36   public void declare(Object name)
37   {
38     declare(name, 1);
39   }
40
41   public void declareWide(Object name)
42   {
43     declare(name, 2);
44   }
45
46   public void declare(Object name, int size)
47   {
48     if (allocated)
49       throw new IllegalStateException("cannot declare after allocating");
50     if (size != 1 && size != 2)
51       throw new IllegalArgumentException("size must be 1 or 2");
52     if (names.containsKey(name))
53       throw new IllegalStateException("already allocated " + name);
54
55     allocateNew(name, size);
56     declared.add(name);
57   }
58
59   private int allocateNew(Object name, int size)
60   {
61     // total allocation size is first unallocated slot
62     int i = free.size() + names.size() + wides.size();
63     names.put(name, new Integer(i));
64     if (size == 2) wides.add(name);
65     return i;
66   }
67
68   public int allocate(Object name)
69   {
70     return allocate(name, 1);
71   }
72
73   public int allocateWide(Object name)
74   {
75     return allocate(name, 2);
76   }
77
78   public int allocate(Object name, int size)
79   {
80     allocated = true;
81     if (size != 1 && size != 2)
82       throw new IllegalArgumentException("size must be 1 or 2");
83     if (names.containsKey(name))
84       throw new IllegalStateException("already allocated " + name);
85
86     if (size == 2)
87       {
88         // look for consecutive free slots
89         for (Iterator it = free.iterator(); it.hasNext(); )
90           {
91             Integer i = (Integer) it.next();
92             Integer next = new Integer(i.intValue() + 1);
93             if (free.contains(next))
94               {
95                 free.remove(i);
96                 free.remove(next);
97                 wides.add(name);
98                 names.put(name, i);
99                 return i.intValue();
100               }
101           }
102       }
103     else if (free.size() > 0)
104       {
105         Integer i = (Integer) free.iterator().next();
106         free.remove(i);
107         names.put(name, i);
108         return i.intValue();
109       }
110
111     return allocateNew(name, size);
112   }
113
114   public int deallocate(Object name)
115   {
116     if (! names.containsKey(name))
117       throw new IllegalArgumentException("no variable " + name);
118
119     if (declared.contains(name))
120       throw new IllegalStateException(name + " can't be deallocated");
121
122     Integer i = (Integer) names.get(name);
123     names.remove(name);
124     free.add(i);
125     if (wides.remove(name))
126       free.add(new Integer(i.intValue() + 1));
127     return i.intValue();
128   }
129
130   public int get(Object name)
131   {
132     if (! names.containsKey(name))
133       throw new IllegalArgumentException("no variable " + name);
134
135     return ((Integer) names.get(name)).intValue();
136   }
137 }