001    package org.extendj.ast;
002    
003    import java.util.HashSet;
004    import java.io.File;
005    import java.util.Set;
006    import java.util.Collections;
007    import java.util.Collection;
008    import java.util.ArrayList;
009    import beaver.*;
010    import java.util.*;
011    import java.io.ByteArrayOutputStream;
012    import java.io.PrintStream;
013    import java.lang.reflect.InvocationTargetException;
014    import java.lang.reflect.Method;
015    import org.jastadd.util.*;
016    import java.util.zip.*;
017    import java.io.*;
018    import org.jastadd.util.PrettyPrintable;
019    import org.jastadd.util.PrettyPrinter;
020    import java.io.FileNotFoundException;
021    import java.io.BufferedInputStream;
022    import java.io.DataInputStream;
023    /**
024     * @ast class
025     * @aspect ConstantPool
026     * @declaredat /home/jesper/git/extendj/java4/backend/ConstantPool.jrag:38
027     */
028    public class ConstantPool extends java.lang.Object {
029      
030        public TypeDecl typeDecl;
031    
032      
033        public ConstantPool(TypeDecl typeDecl) {
034          this.typeDecl = typeDecl;
035        }
036    
037      
038    
039        public static final byte CONSTANT_Class              = 7;
040    
041      
042        public static final byte CONSTANT_Fieldref           = 9;
043    
044      
045        public static final byte CONSTANT_Methodref          = 10;
046    
047      
048        public static final byte CONSTANT_InterfaceMethodref = 11;
049    
050      
051        public static final byte CONSTANT_String             = 8;
052    
053      
054        public static final byte CONSTANT_Integer            = 3;
055    
056      
057        public static final byte CONSTANT_Float              = 4;
058    
059      
060        public static final byte CONSTANT_Long               = 5;
061    
062      
063        public static final byte CONSTANT_Double             = 6;
064    
065      
066        public static final byte CONSTANT_NameAndType        = 12;
067    
068      
069        public static final byte CONSTANT_Utf8               = 1;
070    
071      
072    
073        private int posCounter = 1;
074    
075      
076    
077        private ArrayList list = new ArrayList();
078    
079      
080    
081        private void addCPInfo(CPInfo info) {
082          info.pos = posCounter;
083          posCounter += info.size();
084          if (posCounter > 0xFFFF) {
085            throw new Error("Too many constants in class!");
086          }
087          list.add(info);
088        }
089    
090      
091    
092        // for debugging purposes
093        public int numElements() {
094          return list.size();
095        }
096    
097      
098        public String toString() {
099          StringBuffer s = new StringBuffer();
100          for(Iterator iter = list.iterator(); iter.hasNext(); ) {
101            s.append(iter.next().toString());
102            s.append("\n");
103          }
104          return s.toString();
105        }
106    
107      
108    
109        public void emit(DataOutputStream out) throws IOException {
110          out.writeChar(posCounter);
111          for(Iterator iter = list.iterator(); iter.hasNext(); ) {
112            CPInfo info = (CPInfo)iter.next();
113            info.emit(out);
114          }
115        }
116    
117      
118    
119        private int labelCounter = 1;
120    
121      
122        public int newLabel() {
123          return labelCounter++;
124        }
125    
126      
127    
128        private HashMap classConstants = new HashMap();
129    
130      
131        public int addClass(String name) {
132          Map map = classConstants;
133          Object key = name;
134          if(!map.containsKey(key)) {
135            CPInfo info = new ConstantClass(addUtf8(name.replace('.', '/')));
136            addCPInfo(info);
137            map.put(key, info);
138            String s = info.toString();
139            return info.pos;
140          }
141          CPInfo info = (CPInfo)map.get(key);
142          return info.pos;
143        }
144    
145      
146    
147        private HashMap fieldrefConstants = new HashMap();
148    
149      
150        public int addFieldref(String classname, String name, String type) {
151          Map map = fieldrefConstants;
152          Object key = classname + name + type;
153          if(!map.containsKey(key)) {
154            CPInfo info = new ConstantFieldref(addClass(classname), addNameAndType(name, type));
155            addCPInfo(info);
156            map.put(key, info);
157            String s = info.toString();
158            return info.pos;
159          }
160          CPInfo info = (CPInfo)map.get(key);
161          return info.pos;
162        }
163    
164      
165    
166        private HashMap methodrefConstants = new HashMap();
167    
168      
169        public int addMethodref(String classname, String name, String desc) {
170          Map map = methodrefConstants;
171          Object key = classname + name + desc;
172          if(!map.containsKey(key)) {
173            CPInfo info = new ConstantMethodref(addClass(classname), addNameAndType(name, desc));
174            addCPInfo(info);
175            map.put(key, info);
176            String s = info.toString();
177            return info.pos;
178          }
179          CPInfo info = (CPInfo)map.get(key);
180          return info.pos;
181        }
182    
183      
184    
185        private HashMap interfaceMethodrefConstants = new HashMap();
186    
187      
188        public int addInterfaceMethodref(String classname, String name, String desc) {
189          Map map = interfaceMethodrefConstants;
190          Object key = classname + name + desc;
191          if(!map.containsKey(key)) {
192            CPInfo info = new ConstantInterfaceMethodref(addClass(classname), addNameAndType(name, desc));
193            addCPInfo(info);
194            map.put(key, info);
195            String s = info.toString();
196            return info.pos;
197          }
198          CPInfo info = (CPInfo)map.get(key);
199          return info.pos;
200        }
201    
202      
203    
204        private HashMap nameAndTypeConstants = new HashMap();
205    
206      
207        public int addNameAndType(String name, String type) {
208          Map map = nameAndTypeConstants;
209          Object key = name + type;
210          if(!map.containsKey(key)) {
211            CPInfo info = new ConstantNameAndType(addUtf8(name), addUtf8(type));
212            addCPInfo(info);
213            map.put(key, info);
214            String s = info.toString();
215            return info.pos;
216          }
217          CPInfo info = (CPInfo)map.get(key);
218          return info.pos;
219        }
220    
221      
222    
223        private HashMap utf8Constants = new HashMap();
224    
225      
226        public int addUtf8(String name) {
227          Map map = utf8Constants;
228          Object key = name;
229          if(!map.containsKey(key)) {
230            CPInfo info = new ConstantUtf8(name);
231            addCPInfo(info);
232            map.put(key, info);
233            String s = info.toString();
234            return info.pos;
235          }
236          CPInfo info = (CPInfo)map.get(key);
237          return info.pos;
238        }
239    
240      
241    
242        private HashMap stringConstants = new HashMap();
243    
244      
245    
246        /**
247         * Add value to constant pool.
248         * @return index of value in constant pool
249         */
250        public int addConstant(String val) {
251          Map map = stringConstants;
252          Object key = val;
253          if(!map.containsKey(key)) {
254            CPInfo info = new ConstantString(addUtf8(val));
255            addCPInfo(info);
256            map.put(key, info);
257            String s = info.toString();
258            return info.pos;
259          }
260          CPInfo info = (CPInfo)map.get(key);
261          return info.pos;
262        }
263    
264      
265    
266        private HashMap intConstants = new HashMap();
267    
268      
269    
270        /**
271         * Add value to constant pool.
272         * @return index of value in constant pool
273         */
274        public int addConstant(int val) {
275          Map map = intConstants;
276          Object key = new Integer(val);
277          if(!map.containsKey(key)) {
278            CPInfo info = new ConstantInteger(val);
279            addCPInfo(info);
280            map.put(key, info);
281            return info.pos;
282          }
283          CPInfo info = (CPInfo)map.get(key);
284          return info.pos;
285        }
286    
287      
288    
289        private HashMap floatConstants = new HashMap();
290    
291      
292    
293        /**
294         * Add value to constant pool.
295         * @return index of value in constant pool
296         */
297        public int addConstant(float val) {
298          Map map = floatConstants;
299          Object key = new Float(val);
300          if(!map.containsKey(key)) {
301            CPInfo info = new ConstantFloat(val);
302            addCPInfo(info);
303            map.put(key, info);
304            return info.pos;
305          }
306          CPInfo info = (CPInfo)map.get(key);
307          return info.pos;
308        }
309    
310      
311    
312        private HashMap longConstants = new HashMap();
313    
314      
315    
316        /**
317         * Add value to constant pool.
318         * @return index of value in constant pool
319         */
320        public int addConstant(long val) {
321          Map map = longConstants;
322          Object key = new Long(val);
323          if(!map.containsKey(key)) {
324            CPInfo info = new ConstantLong(val);
325            addCPInfo(info);
326            map.put(key, info);
327            return info.pos;
328          }
329          CPInfo info = (CPInfo)map.get(key);
330          return info.pos;
331        }
332    
333      
334    
335        private HashMap doubleConstants = new HashMap();
336    
337      
338    
339        /**
340         * Add value to constant pool.
341         * @return index of value in constant pool
342         */
343        public int addConstant(double val) {
344          Map map = doubleConstants;
345          Object key = new Double(val);
346          if(!map.containsKey(key)) {
347            CPInfo info = new ConstantDouble(val);
348            addCPInfo(info);
349            map.put(key, info);
350            return info.pos;
351          }
352          CPInfo info = (CPInfo)map.get(key);
353          return info.pos;
354        }
355    
356    
357    }