001: // Copyright (c) Corporation for National Research Initiatives
002: package org.python.compiler;
003:
004: import java.util.*;
005: import java.io.*;
006:
007: class Bytes {
008: public byte[] data;
009:
010: Bytes(ByteArrayOutputStream data) {
011: this .data = data.toByteArray();
012: }
013:
014: public boolean equals(Object o) {
015: if (o instanceof Bytes) {
016: byte[] odata = ((Bytes) o).data;
017: int n = data.length;
018: if (odata.length != n)
019: return false;
020: for (int i = 0; i < n; i++) {
021: if (data[i] != odata[i])
022: return false;
023: }
024: return true;
025: }
026: return false;
027: }
028:
029: public int hashCode() {
030: int h = 0xa538;
031: int n = data.length;
032: for (int i = 0; i < n; i++)
033: h = h ^ data[i];
034: return h;
035: }
036: }
037:
038: public class ConstantPool {
039: Hashtable constants;
040: int index;
041: DataOutputStream tdata;
042: ByteArrayOutputStream pool, tarray;
043: int[] sizes;
044:
045: public ConstantPool() {
046: constants = new Hashtable();
047: index = 0;
048: pool = new ByteArrayOutputStream();
049: tarray = new ByteArrayOutputStream();
050: tdata = new DataOutputStream(tarray);
051: sizes = new int[256];
052: }
053:
054: public void write(DataOutputStream stream) throws IOException {
055: stream.writeShort(index + 1);
056: stream.write(pool.toByteArray());
057: }
058:
059: public int addConstant(int slots) throws IOException {
060: //tarray.flush();
061: //byte[] data = tarray.toByteArray();
062: Bytes data = new Bytes(tarray);
063: tarray.reset();
064: Integer i = (Integer) constants.get(data);
065: if (i == null) {
066: pool.write(data.data);
067: i = new Integer(index);
068: constants.put(data, i);
069: if (index + 1 >= sizes.length) {
070: int[] new_sizes = new int[sizes.length * 2];
071: System.arraycopy(sizes, 0, new_sizes, 0, sizes.length);
072: sizes = new_sizes;
073: }
074: sizes[index + 1] = slots;
075: index += slots;
076: }
077: //System.out.print("Constant: ");
078: //for(int j=0; j<data.length; j++)
079: // System.out.print(Integer.toString(data[j])+", ");
080: //System.out.println("");
081: return i.intValue() + 1;
082: }
083:
084: public int UTF8(String s) throws IOException {
085: tdata.writeByte(1);
086: tdata.writeUTF(s);
087: return addConstant(1);
088: }
089:
090: public int Class(String s) throws IOException {
091: int c = UTF8(s);
092: tdata.writeByte(7);
093: tdata.writeShort(c);
094: return addConstant(1);
095: }
096:
097: public int Fieldref(String c, String name, String type)
098: throws IOException {
099: int ic = Class(c);
100: int nt = NameAndType(name, type);
101: tdata.writeByte(9);
102: tdata.writeShort(ic);
103: tdata.writeShort(nt);
104: int size = 1;
105: if (type.equals("D") || type.equals("J"))
106: size = 2;
107: int index = addConstant(1);
108: sizes[index] = size;
109: //System.out.println("field: "+c+", "+name+", "+type+": "+index);
110: return index;
111: }
112:
113: public static int sigSize(String sig, boolean includeReturn) {
114: int stack = 0;
115: int i = 0;
116: char[] c = sig.toCharArray();
117: int n = c.length;
118: boolean ret = false;
119: boolean array = false;
120:
121: while (++i < n) {
122: switch (c[i]) {
123: case ')':
124: if (!includeReturn)
125: return stack;
126: ret = true;
127: continue;
128: case '[':
129: array = true;
130: continue;
131: case 'V':
132: continue;
133: case 'D':
134: case 'J':
135: if (array) {
136: if (ret)
137: stack += 1;
138: else
139: stack -= 1;
140: array = false;
141: } else {
142: if (ret)
143: stack += 2;
144: else
145: stack -= 2;
146: }
147: break;
148: case 'L':
149: while (c[++i] != ';') {
150: ;
151: }
152: default:
153: if (ret)
154: stack++;
155: else
156: stack--;
157: array = false;
158: }
159: }
160: return stack;
161: }
162:
163: public int Methodref(String c, String name, String type)
164: throws IOException {
165: int ic = Class(c);
166: int nt = NameAndType(name, type);
167:
168: tdata.writeByte(10);
169: tdata.writeShort(ic);
170: tdata.writeShort(nt);
171: int index = addConstant(1);
172: sizes[index] = sigSize(type, true);
173: //System.out.println("method: "+c+", "+name+", "+type+": "+index);
174: return index;
175: }
176:
177: public int InterfaceMethodref(String c, String name, String type)
178: throws IOException {
179: int ic = Class(c);
180: int nt = NameAndType(name, type);
181:
182: tdata.writeByte(11);
183: tdata.writeShort(ic);
184: tdata.writeShort(nt);
185: int index = addConstant(1);
186: sizes[index] = sigSize(type, true);
187: return index;
188: }
189:
190: public int String(String s) throws IOException {
191: int i = UTF8(s);
192: tdata.writeByte(8);
193: tdata.writeShort(i);
194: return addConstant(1);
195: }
196:
197: public int Integer(int i) throws IOException {
198: tdata.writeByte(3);
199: tdata.writeInt(i);
200: return addConstant(1);
201: }
202:
203: public int Float(float f) throws IOException {
204: tdata.writeByte(4);
205: tdata.writeFloat(f);
206: return addConstant(1);
207: }
208:
209: public int Long(long l) throws IOException {
210: tdata.writeByte(5);
211: tdata.writeLong(l);
212: return addConstant(2);
213: }
214:
215: public int Double(double d) throws IOException {
216: tdata.writeByte(6);
217: tdata.writeDouble(d);
218: return addConstant(2);
219: }
220:
221: public int NameAndType(String name, String type) throws IOException {
222: int n = UTF8(name);
223: int t = UTF8(type);
224:
225: tdata.writeByte(12);
226: tdata.writeShort(n);
227: tdata.writeShort(t);
228: return addConstant(1);
229: }
230:
231: public static void main(String[] args) throws Exception {
232: ConstantPool cp = new ConstantPool();
233:
234: System.out
235: .println("c: " + cp.Class("org/python/core/PyString"));
236: System.out
237: .println("c: " + cp.Class("org/python/core/PyString"));
238:
239: for (int i = 0; i < args.length; i++)
240: System.out.println(args[i] + ": " + sigSize(args[i], true));
241: }
242: }
|