// Copyright (c) Corporation for National Research Initiatives package org.python.compiler; import java.util.*; import java.io.*; class Bytes { public byte[] data; Bytes(ByteArrayOutputStream data) { this.data = data.toByteArray(); } public boolean equals(Object o) { if (o instanceof Bytes) { byte[] odata = ((Bytes) o).data; int n = data.length; if (odata.length != n) return false; for (int i = 0; i < n; i++) { if (data[i] != odata[i]) return false; } return true; } return false; } public int hashCode() { int h = 0xa538; int n = data.length; for (int i = 0; i < n; i++) h = h ^ data[i]; return h; } } public class ConstantPool { Hashtable constants; int index; DataOutputStream tdata; ByteArrayOutputStream pool, tarray; int[] sizes; public ConstantPool() { constants = new Hashtable(); index = 0; pool = new ByteArrayOutputStream(); tarray = new ByteArrayOutputStream(); tdata = new DataOutputStream(tarray); sizes = new int[256]; } public void write(DataOutputStream stream) throws IOException { stream.writeShort(index + 1); stream.write(pool.toByteArray()); } public int addConstant(int slots) throws IOException { //tarray.flush(); //byte[] data = tarray.toByteArray(); Bytes data = new Bytes(tarray); tarray.reset(); Integer i = (Integer) constants.get(data); if (i == null) { pool.write(data.data); i = new Integer(index); constants.put(data, i); if (index + 1 >= sizes.length) { int[] new_sizes = new int[sizes.length * 2]; System.arraycopy(sizes, 0, new_sizes, 0, sizes.length); sizes = new_sizes; } sizes[index + 1] = slots; index += slots; } //System.out.print("Constant: "); //for(int j=0; j<data.length; j++) // System.out.print(Integer.toString(data[j])+", "); //System.out.println(""); return i.intValue() + 1; } public int UTF8(String s) throws IOException { tdata.writeByte(1); tdata.writeUTF(s); return addConstant(1); } public int Class(String s) throws IOException { int c = UTF8(s); tdata.writeByte(7); tdata.writeShort(c); return addConstant(1); } public int Fieldref(String c, String name, String type) throws IOException { int ic = Class(c); int nt = NameAndType(name, type); tdata.writeByte(9); tdata.writeShort(ic); tdata.writeShort(nt); int size = 1; if (type.equals("D") || type.equals("J")) size = 2; int index = addConstant(1); sizes[index] = size; //System.out.println("field: "+c+", "+name+", "+type+": "+index); return index; } public static int sigSize(String sig, boolean includeReturn) { int stack = 0; int i = 0; char[] c = sig.toCharArray(); int n = c.length; boolean ret = false; boolean array = false; while (++i < n) { switch (c[i]) { case ')': if (!includeReturn) return stack; ret = true; continue; case '[': array = true; continue; case 'V': continue; case 'D': case 'J': if (array) { if (ret) stack += 1; else stack -= 1; array = false; } else { if (ret) stack += 2; else stack -= 2; } break; case 'L': while (c[++i] != ';') { ; } default: if (ret) stack++; else stack--; array = false; } } return stack; } public int Methodref(String c, String name, String type) throws IOException { int ic = Class(c); int nt = NameAndType(name, type); tdata.writeByte(10); tdata.writeShort(ic); tdata.writeShort(nt); int index = addConstant(1); sizes[index] = sigSize(type, true); //System.out.println("method: "+c+", "+name+", "+type+": "+index); return index; } public int InterfaceMethodref(String c, String name, String type) throws IOException { int ic = Class(c); int nt = NameAndType(name, type); tdata.writeByte(11); tdata.writeShort(ic); tdata.writeShort(nt); int index = addConstant(1); sizes[index] = sigSize(type, true); return index; } public int String(String s) throws IOException { int i = UTF8(s); tdata.writeByte(8); tdata.writeShort(i); return addConstant(1); } public int Integer(int i) throws IOException { tdata.writeByte(3); tdata.writeInt(i); return addConstant(1); } public int Float(float f) throws IOException { tdata.writeByte(4); tdata.writeFloat(f); return addConstant(1); } public int Long(long l) throws IOException { tdata.writeByte(5); tdata.writeLong(l); return addConstant(2); } public int Double(double d) throws IOException { tdata.writeByte(6); tdata.writeDouble(d); return addConstant(2); } public int NameAndType(String name, String type) throws IOException { int n = UTF8(name); int t = UTF8(type); tdata.writeByte(12); tdata.writeShort(n); tdata.writeShort(t); return addConstant(1); } public static void main(String[] args) throws Exception { ConstantPool cp = new ConstantPool(); System.out.println("c: " + cp.Class("org/python/core/PyString")); System.out.println("c: " + cp.Class("org/python/core/PyString")); for (int i = 0; i < args.length; i++) System.out.println(args[i] + ": " + sigSize(args[i], true)); } }