KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jode > bytecode > GrowableConstantPool


1 /* GrowableConstantPool Copyright (C) 1999-2002 Jochen Hoenicke.
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU Lesser General Public License as published by
5  * the Free Software Foundation; either version 2, or (at your option)
6  * any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; see the file COPYING.LESSER. If not, write to
15  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
16  *
17  * $Id: GrowableConstantPool.java,v 1.10.2.1 2002/05/28 17:34:00 hoenicke Exp $
18  */

19
20 package jode.bytecode;
21 import java.io.DataOutputStream JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.util.Hashtable JavaDoc;
24
25 /**
26  * This class represent a constant pool, where new constants can be added to.
27  *
28  * @author Jochen Hoenicke
29  */

30 public class GrowableConstantPool extends ConstantPool {
31     Hashtable JavaDoc entryToIndex = new Hashtable JavaDoc();
32     boolean written;
33
34     /**
35      * This class is used as key to the entryToIndex hashtable
36      */

37     private class Key {
38     int tag;
39     Object JavaDoc objData;
40     int intData;
41
42     public Key(int tag, Object JavaDoc objData, int intData) {
43         this.tag = tag;
44         this.objData = objData;
45         this.intData = intData;
46     }
47
48     public int hashCode() {
49         return tag ^ objData.hashCode() ^ intData;
50     }
51
52     public boolean equals(Object JavaDoc o) {
53         if (o instanceof Key) {
54         Key k = (Key) o;
55         return tag == k.tag && intData == k.intData
56             && objData.equals(k.objData);
57         }
58         return false;
59     }
60     }
61
62     public GrowableConstantPool () {
63     count = 1;
64     tags = new int[128];
65     indices1 = new int[128];
66     indices2 = new int[128];
67     constants = new Object JavaDoc[128];
68     written = false;
69     }
70
71     public final void grow(int wantedSize) {
72     if (written)
73         throw new IllegalStateException JavaDoc("adding to written ConstantPool");
74     if (tags.length < wantedSize) {
75         int newSize = Math.max(tags.length*2, wantedSize);
76         int[] tmpints = new int[newSize];
77         System.arraycopy(tags, 0, tmpints, 0, count);
78         tags = tmpints;
79         tmpints = new int[newSize];
80         System.arraycopy(indices1, 0, tmpints, 0, count);
81         indices1 = tmpints;
82         tmpints = new int[newSize];
83         System.arraycopy(indices2, 0, tmpints, 0, count);
84         indices2 = tmpints;
85         Object JavaDoc[] tmpobjs = new Object JavaDoc[newSize];
86         System.arraycopy(constants, 0, tmpobjs, 0, count);
87         constants = tmpobjs;
88     }
89     }
90
91     private int putConstant(int tag, Object JavaDoc constant) {
92     Key key = new Key(tag, constant, 0);
93     Integer JavaDoc index = (Integer JavaDoc) entryToIndex.get(key);
94     if (index != null)
95         return index.intValue();
96     int newIndex = count;
97     grow(count + 1);
98     tags[newIndex] = tag;
99     constants[newIndex] = constant;
100     entryToIndex.put(key, new Integer JavaDoc(newIndex));
101     count++;
102     return newIndex;
103     }
104
105     private int putLongConstant(int tag, Object JavaDoc constant) {
106     Key key = new Key(tag, constant, 0);
107     Integer JavaDoc index = (Integer JavaDoc) entryToIndex.get(key);
108     if (index != null)
109         return index.intValue();
110     int newIndex = count;
111     grow(count + 2);
112     tags[newIndex] = tag;
113     tags[newIndex+1] = -tag;
114     constants[newIndex] = constant;
115     entryToIndex.put(key, new Integer JavaDoc(newIndex));
116     count += 2;
117     return newIndex;
118     }
119
120     int putIndexed(int tag, Object JavaDoc obj1, int index1, int index2) {
121     Key key = new Key(tag, obj1, index2);
122     Integer JavaDoc indexObj = (Integer JavaDoc) entryToIndex.get(key);
123     if (indexObj != null) {
124         /* Maybe this was a reserved, but not filled entry */
125         int index = indexObj.intValue();
126         indices1[index] = index1;
127         indices2[index] = index2;
128         return index;
129     }
130     grow(count+1);
131     tags[count] = tag;
132     indices1[count] = index1;
133     indices2[count] = index2;
134     entryToIndex.put(key, new Integer JavaDoc(count));
135     return count++;
136     }
137
138     public final int putUTF8(String JavaDoc utf) {
139     return putConstant(UTF8, utf);
140     }
141
142     public int putClassName(String JavaDoc name) {
143     name = name.replace('.','/');
144     TypeSignature.checkTypeSig("L"+name+";");
145     return putIndexed(CLASS, name, putUTF8(name), 0);
146     }
147
148     public int putClassType(String JavaDoc name) {
149     TypeSignature.checkTypeSig(name);
150     if (name.charAt(0) == 'L')
151         name = name.substring(1, name.length()-1);
152     else if (name.charAt(0) != '[')
153         throw new IllegalArgumentException JavaDoc("wrong class type: "+name);
154     return putIndexed(CLASS, name, putUTF8(name), 0);
155     }
156
157     public int putRef(int tag, Reference ref) {
158     String JavaDoc className = ref.getClazz();
159     String JavaDoc typeSig = ref.getType();
160     if (tag == FIELDREF)
161         TypeSignature.checkTypeSig(typeSig);
162     else
163         TypeSignature.checkMethodTypeSig(typeSig);
164
165
166     int classIndex = putClassType(className);
167     int nameIndex = putUTF8(ref.getName());
168     int typeIndex = putUTF8(typeSig);
169     int nameTypeIndex = putIndexed(NAMEANDTYPE,
170                        ref.getName(), nameIndex, typeIndex);
171     return putIndexed(tag, className, classIndex, nameTypeIndex);
172     }
173
174     /**
175      * Puts a constant into this constant pool
176      * @param c the constant, must be of type
177      * Integer, Long, Float, Double or String
178      * @return the index into the pool of this constant.
179      */

180     public int putConstant(Object JavaDoc c) {
181     if (c instanceof String JavaDoc) {
182         return putIndexed(STRING, c, putUTF8((String JavaDoc) c), 0);
183     } else {
184         int tag;
185         if (c instanceof Integer JavaDoc)
186         tag = INTEGER;
187         else if (c instanceof Float JavaDoc)
188         tag = FLOAT;
189         else
190         throw new IllegalArgumentException JavaDoc
191             ("illegal constant " + c + " of type: " + c.getClass());
192         return putConstant(tag, c);
193         }
194     }
195
196     /**
197      * Puts a constant into this constant pool
198      * @param c the constant, must be of type
199      * Integer, Long, Float, Double or String
200      * @return the index into the pool of this constant.
201      */

202     public int putLongConstant(Object JavaDoc c) {
203     int tag;
204     if (c instanceof Long JavaDoc)
205         tag = LONG;
206     else if (c instanceof Double JavaDoc)
207         tag = DOUBLE;
208     else
209         throw new IllegalArgumentException JavaDoc
210         ("illegal long constant " + c + " of type: " + c.getClass());
211     return putLongConstant(tag, c);
212     }
213
214     /**
215      * Reserve an entry in this constant pool for a constant (for ldc).
216      * @param c the constant, must be of type
217      * Integer, Long, Float, Double or String
218      * @return the reserved index into the pool of this constant.
219      */

220     public int reserveConstant(Object JavaDoc c) {
221     if (c instanceof String JavaDoc) {
222         return putIndexed(STRING, c, -1, 0);
223     } else {
224         return putConstant(c);
225         }
226     }
227
228     /**
229      * Reserve an entry in this constant pool for a constant (for ldc).
230      * @param c the constant, must be of type
231      * Integer, Long, Float, Double or String
232      * @return the reserved index into the pool of this constant.
233      */

234     public int reserveLongConstant(Object JavaDoc c) {
235     return putLongConstant(c);
236     }
237
238     public int copyConstant(ConstantPool cp, int index)
239     throws ClassFormatException {
240     return putConstant(cp.getConstant(index));
241     }
242
243     public void write(DataOutputStream JavaDoc stream)
244     throws IOException JavaDoc {
245     written = true;
246     stream.writeShort(count);
247     for (int i=1; i< count; i++) {
248         int tag = tags[i];
249             stream.writeByte(tag);
250             switch (tag) {
251         case CLASS:
252         stream.writeShort(indices1[i]);
253         break;
254         case FIELDREF:
255         case METHODREF:
256         case INTERFACEMETHODREF:
257         stream.writeShort(indices1[i]);
258         stream.writeShort(indices2[i]);
259         break;
260         case STRING:
261         stream.writeShort(indices1[i]);
262         break;
263         case INTEGER:
264         stream.writeInt(((Integer JavaDoc)constants[i]).intValue());
265         break;
266         case FLOAT:
267         stream.writeFloat(((Float JavaDoc)constants[i]).floatValue());
268         break;
269         case LONG:
270         stream.writeLong(((Long JavaDoc)constants[i]).longValue());
271         i++;
272         break;
273         case DOUBLE:
274         stream.writeDouble(((Double JavaDoc)constants[i]).doubleValue());
275         i++;
276         break;
277         case NAMEANDTYPE:
278         stream.writeShort(indices1[i]);
279         stream.writeShort(indices2[i]);
280         break;
281         case UTF8:
282         stream.writeUTF((String JavaDoc)constants[i]);
283         break;
284         default:
285         throw new ClassFormatException("unknown constant tag");
286             }
287     }
288     }
289 }
290
Popular Tags