X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fibex%2Fclassgen%2FCPGen.java;h=e22fd9e92ea75564560527cb7966e6471f911f6c;hb=9b8b835136fbb1c781662651ff76bc1d5d849742;hp=fc13c4d08aa33e4542078e90e1f421f0c84d525c;hpb=bc9112573cba51be5e7d285ccd3e496be4278c63;p=org.ibex.classgen.git diff --git a/src/org/ibex/classgen/CPGen.java b/src/org/ibex/classgen/CPGen.java index fc13c4d..e22fd9e 100644 --- a/src/org/ibex/classgen/CPGen.java +++ b/src/org/ibex/classgen/CPGen.java @@ -11,14 +11,17 @@ class CPGen { private Hashtable entries = new Hashtable(); private int nextIndex = 1; // 0 is reserved private int count; - private boolean sealed; + private int state; + private static final int OPEN = 0; + private static final int STABLE = 1; // existing entries won't change + private static final int SEALED = 2; // no new entries CPGen() { } /* * Entries */ - abstract static class Ent implements Sort.Comparable { + abstract static class Ent { int index; int tag; @@ -27,14 +30,6 @@ class CPGen { int getIndex() { return index; } void dump(DataOutput o) throws IOException { o.writeByte(tag); } - - public int compareTo(Object o) { - if(!(o instanceof Ent)) return 1; - int oi = ((Ent)o).index; - if(index < oi) return -1; - if(index > oi) return 1; - return 0; - } } static class OneU4Ent extends Ent { @@ -79,7 +74,8 @@ class CPGen { /* * Methods */ - public void seal() { sealed = true; } + public void seal() { if(state >= SEALED) throw new IllegalStateException(); state = SEALED; } + public void stable() { if(state >= STABLE) throw new IllegalStateException(); state = STABLE; } public final Ent get(Object o) { return (Ent) entries.get(o); } public final Ent getUtf8(String s) { return get(new Utf8Key(s)); } @@ -97,15 +93,12 @@ class CPGen { public final Ent addNameAndType(String name, String descriptor) { return add(new ClassGen.NameAndType(name,descriptor)); } public final Ent addUtf8(String s) { return add(new Utf8Key(s)); } - // FEATURE: Don't resolve indexes until dump (for optimize) public final Ent add(Object o) { - if(sealed) throw new IllegalStateException("constant pool is sealed"); + if(state == SEALED) throw new IllegalStateException("constant pool is sealed"); Ent ent = get(o); if(ent != null) return ent; - if(nextIndex == 65536) throw new ClassGen.Exn("constant pool full"); - if(o instanceof Type.Object) { CPRefEnt ce = new CPRefEnt(7); ce.e1 = addUtf8(((Type.Object)o).internalForm()); @@ -152,8 +145,12 @@ class CPGen { throw new IllegalArgumentException("Unknown type passed to add"); } - ent.index = nextIndex++; - if(ent instanceof LongEnt) nextIndex++; + int spaces = ent instanceof LongEnt ? 2 : 1; + + if(nextIndex + spaces > 65536) throw new ClassGen.Exn("constant pool full"); + + ent.index = nextIndex; + nextIndex += spaces; count++; entries.put(o,ent); @@ -162,15 +159,20 @@ class CPGen { public int size() { return nextIndex; } + private static final Sort.CompareFunc compareFunc = new Sort.CompareFunc() { + public int compare(Object a_, Object b_) { + return ((Ent)a_).index - ((Ent)b_).index; + } + }; public void dump(DataOutput o) throws IOException { Ent[] ents = new Ent[count]; int i=0; Enumeration e = entries.keys(); while(e.hasMoreElements()) ents[i++] = (Ent) entries.get(e.nextElement()); if(i != count) throw new Error("should never happen"); - Sort.sort(ents); + Sort.sort(ents,compareFunc); for(i=0;i