001: /*
002: * @(#)ConstantPool.java 1.3 05/06/27
003: *
004: * Copyright (c) 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
005: *
006: * See the file "LICENSE.txt" for information on usage and redistribution of
007: * this file, and for a DISCLAIMER OF ALL WARRANTIES.
008: */
009: package pnuts.compiler;
010:
011: import java.io.DataOutputStream;
012: import java.io.IOException;
013: import java.io.UTFDataFormatException;
014:
015: class ConstantPool {
016: private static final int initialSize = 256;
017:
018: private byte constant_pool[] = new byte[initialSize];
019:
020: private int top = 0;
021:
022: private int index = 1;
023:
024: private ConstantSet utfSet = new ConstantSet(32);
025:
026: private ConstantSet classSet = new ConstantSet(32);
027:
028: private ConstantSet fieldRefSet = new ConstantSet(32);
029:
030: private ConstantSet methodRefSet = new ConstantSet(32);
031:
032: public short addConstant(int k) {
033: ensure(5);
034: constant_pool[top++] = Constants.CONSTANT_Integer;
035: constant_pool[top++] = (byte) (k >> 24);
036: constant_pool[top++] = (byte) (k >> 16);
037: constant_pool[top++] = (byte) (k >> 8);
038: constant_pool[top++] = (byte) k;
039: return (short) index++;
040: }
041:
042: public short addConstant(long k) {
043: ensure(9);
044: constant_pool[top++] = Constants.CONSTANT_Long;
045: constant_pool[top++] = (byte) (k >> 56);
046: constant_pool[top++] = (byte) (k >> 48);
047: constant_pool[top++] = (byte) (k >> 40);
048: constant_pool[top++] = (byte) (k >> 32);
049: constant_pool[top++] = (byte) (k >> 24);
050: constant_pool[top++] = (byte) (k >> 16);
051: constant_pool[top++] = (byte) (k >> 8);
052: constant_pool[top++] = (byte) k;
053: short _index = (short) index;
054: index += 2;
055: return _index;
056: }
057:
058: short addConstant(float k) {
059: ensure(5);
060: constant_pool[top++] = Constants.CONSTANT_Float;
061: int bits = Float.floatToIntBits(k);
062: constant_pool[top++] = (byte) (bits >> 24);
063: constant_pool[top++] = (byte) (bits >> 16);
064: constant_pool[top++] = (byte) (bits >> 8);
065: constant_pool[top++] = (byte) bits;
066: return (short) index++;
067: }
068:
069: public short addConstant(double k) {
070: ensure(9);
071: constant_pool[top++] = Constants.CONSTANT_Double;
072: long bits = Double.doubleToLongBits(k);
073: constant_pool[top++] = (byte) (bits >> 56);
074: constant_pool[top++] = (byte) (bits >> 48);
075: constant_pool[top++] = (byte) (bits >> 40);
076: constant_pool[top++] = (byte) (bits >> 32);
077: constant_pool[top++] = (byte) (bits >> 24);
078: constant_pool[top++] = (byte) (bits >> 16);
079: constant_pool[top++] = (byte) (bits >> 8);
080: constant_pool[top++] = (byte) bits;
081: short _index = (short) index;
082: index += 2;
083: return _index;
084: }
085:
086: public short addConstant(String k) {
087: Slot slot = utfSet.getSlot(k);
088: short[] _index = (short[]) slot.value;
089: if (_index == null) {
090: _index = new short[] { (short) index++, (short) -1 };
091: slot.value = _index;
092: try {
093: addUTF(k);
094: } catch (UTFDataFormatException e) {
095: throw new ClassFileException();
096: }
097: }
098: if (_index[1] == -1) {
099: _index[1] = (short) index++;
100: ensure(3);
101: constant_pool[top++] = Constants.CONSTANT_String;
102: constant_pool[top++] = (byte) (_index[0] >> 8);
103: constant_pool[top++] = (byte) _index[0];
104: }
105: return _index[1];
106: }
107:
108: public void addUTF(String str) throws UTFDataFormatException {
109: char[] chars = str.toCharArray();
110: int strlen = chars.length;
111: int utflen = 0;
112:
113: for (int i = 0; i < strlen; i++) {
114: int c = (int) chars[i];
115: if ((c >= 0x0001) && (c <= 0x007F)) {
116: utflen++;
117: } else if (c > 0x07FF) {
118: utflen += 3;
119: } else {
120: utflen += 2;
121: }
122: }
123: if (utflen > 0xFFFF) {
124: throw new UTFDataFormatException(String.valueOf(str));
125: }
126: ensure(utflen + 3);
127: constant_pool[top++] = Constants.CONSTANT_Utf8;
128: constant_pool[top++] = (byte) ((utflen >>> 8) & 0xFF);
129: constant_pool[top++] = (byte) ((utflen >>> 0) & 0xFF);
130:
131: for (int i = 0; i < strlen; i++) {
132: int c = (int) chars[i];
133: if ((c >= 0x0001) && (c <= 0x007F)) {
134: constant_pool[top++] = (byte) c;
135: } else if (c > 0x07FF) {
136: constant_pool[top++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
137: constant_pool[top++] = (byte) (0x80 | ((c >> 6) & 0x3F));
138: constant_pool[top++] = (byte) (0x80 | ((c >> 0) & 0x3F));
139: } else {
140: constant_pool[top++] = (byte) (0xC0 | ((c >> 6) & 0x1F));
141: constant_pool[top++] = (byte) (0x80 | ((c >> 0) & 0x3F));
142: }
143: }
144: }
145:
146: public short addUTF8(String str) {
147: Slot slot = utfSet.getSlot(str);
148: short[] _index = (short[]) slot.value;
149: if (_index == null) {
150: _index = new short[] { (short) index++, (short) -1 };
151: slot.value = _index;
152: try {
153: addUTF(str);
154: } catch (UTFDataFormatException e) {
155: throw new ClassFileException();
156: }
157: }
158: return _index[0];
159: }
160:
161: public short addNameAndType(short nameIndex, short typeIndex) {
162: ensure(5);
163: constant_pool[top++] = Constants.CONSTANT_NameAndType;
164: constant_pool[top++] = (byte) (nameIndex >> 8);
165: constant_pool[top++] = (byte) nameIndex;
166: constant_pool[top++] = (byte) (typeIndex >> 8);
167: constant_pool[top++] = (byte) typeIndex;
168: return (short) index++;
169: }
170:
171: short addClass(short classIndex) {
172: Slot slot = classSet.getSlot(new Short(classIndex));
173: Short _index = (Short) slot.value;
174: if (_index == null) {
175: ensure(3);
176: constant_pool[top++] = Constants.CONSTANT_Class;
177: constant_pool[top++] = (byte) (classIndex >> 8);
178: constant_pool[top++] = (byte) (classIndex);
179: _index = new Short((short) index++);
180: slot.value = _index;
181: }
182: return _index.shortValue();
183: }
184:
185: public short addClass(String className) {
186: return addClass(addUTF8(className.replace('.', '/')));
187: }
188:
189: public short addFieldRef(String className, String fieldName,
190: String fieldType) {
191: Slot slot = fieldRefSet.getSlot(className + " " + fieldName
192: + " " + fieldType);
193:
194: Short _index = (Short) slot.value;
195: if (_index == null) {
196: short nameIndex = addUTF8(fieldName);
197: short typeIndex = addUTF8(fieldType);
198: short nameAndTypeIndex = addNameAndType(nameIndex,
199: typeIndex);
200: short classIndex = addClass(className);
201: ensure(5);
202: constant_pool[top++] = Constants.CONSTANT_Fieldref;
203: constant_pool[top++] = (byte) (classIndex >> 8);
204: constant_pool[top++] = (byte) classIndex;
205: constant_pool[top++] = (byte) (nameAndTypeIndex >> 8);
206: constant_pool[top++] = (byte) nameAndTypeIndex;
207: _index = new Short((short) index++);
208: slot.value = _index;
209: }
210: return _index.shortValue();
211: }
212:
213: public short addMethodRef(String className, String methodName,
214: String fieldType) {
215: Slot slot = methodRefSet.getSlot(className + " " + methodName
216: + " " + fieldType);
217: Short _index = (Short) slot.value;
218: if (_index == null) {
219: short nameIndex = addUTF8(methodName);
220: short typeIndex = addUTF8(fieldType);
221: short nameAndTypeIndex = addNameAndType(nameIndex,
222: typeIndex);
223: short classIndex = addClass(className);
224: ensure(5);
225: constant_pool[top++] = Constants.CONSTANT_Methodref;
226: constant_pool[top++] = (byte) (classIndex >> 8);
227: constant_pool[top++] = (byte) classIndex;
228: constant_pool[top++] = (byte) (nameAndTypeIndex >> 8);
229: constant_pool[top++] = (byte) nameAndTypeIndex;
230: _index = new Short((short) index++);
231: slot.value = _index;
232: }
233: return _index.shortValue();
234: }
235:
236: short addInterfaceMethodRef(String className, String methodName,
237: String methodType) {
238: short nameIndex = addUTF8(methodName);
239: short typeIndex = addUTF8(methodType);
240: short nameAndTypeIndex = addNameAndType(nameIndex, typeIndex);
241: short classIndex = addClass(className);
242: ensure(5);
243: constant_pool[top++] = Constants.CONSTANT_InterfaceMethodref;
244: constant_pool[top++] = (byte) (classIndex >> 8);
245: constant_pool[top++] = (byte) classIndex;
246: constant_pool[top++] = (byte) (nameAndTypeIndex >> 8);
247: constant_pool[top++] = (byte) nameAndTypeIndex;
248: return (short) index++;
249: }
250:
251: public void write(ByteBuffer buf) {
252: buf.add((short) index);
253: buf.add(constant_pool, 0, top);
254: }
255:
256: public void write(DataOutputStream out) throws IOException {
257: out.writeShort((short) index);
258: out.write(constant_pool, 0, top);
259: }
260:
261: final void ensure(int room) {
262: if ((top + room) >= constant_pool.length) {
263: byte tmp[] = constant_pool;
264: constant_pool = new byte[(constant_pool.length * 2) + top
265: + room + 1];
266: System.arraycopy(tmp, 0, constant_pool, 0, top);
267: }
268: }
269: }
|