+
+ CPGen(DataInput in) throws ClassGen.ClassReadExn, IOException {
+ usedSlots = in.readUnsignedShort();
+ if(usedSlots==0) throw new ClassGen.ClassReadExn("invalid used slots");
+
+ // these are to remember the CPRefEnt e1 and e2s we have to fix up
+ int[] e1s = new int[usedSlots];
+ int[] e2s = new int[usedSlots];
+
+ entriesByIndex = new Ent[usedSlots];
+
+ for(int index=1;index<usedSlots;index++) {
+ byte tag = in.readByte();
+ Ent e;
+ switch(tag) {
+ case 7: // Object Type
+ case 8: // String
+ case 9: // FieldRef
+ case 10: // MethodRef
+ case 11: // Instance Method Ref
+ case 12: // NameAndType
+ {
+ e = new CPRefEnt(this, tag);
+ e1s[index] = in.readUnsignedShort();
+ if(tag != 7 && tag != 8) e2s[index] = in.readUnsignedShort();
+ break;
+ }
+ case 3: // Integer
+ case 4: // Float
+ {
+ IntEnt ie;
+ e = ie = new IntEnt(this, tag);
+ ie.i = in.readInt();
+ break;
+ }
+ case 5: // Long
+ case 6: // Double
+ {
+ LongEnt le;
+ e = le = new LongEnt(this, tag);
+ le.l = in.readLong();
+ break;
+ }
+ case 1: // Utf8
+ {
+ Utf8Ent ue;
+ e = ue = new Utf8Ent(this);
+ ue.s = in.readUTF();
+ break;
+ }
+ default:
+ throw new ClassGen.ClassReadExn("invalid cp ent tag");
+ }
+ entriesByIndex[index] = e;
+ if (e instanceof LongEnt) index++;
+ }
+
+ for(int index=1;index<usedSlots;index++) {
+ int i = index;
+ Ent e = entriesByIndex[index];
+ if (e == null) throw new Error("should never happen: " + i + "/"+usedSlots);
+ if (e instanceof LongEnt) {
+ index++;
+ continue;
+ }
+ if (!(e instanceof CPRefEnt)) continue;
+ CPRefEnt ce = (CPRefEnt) e;
+ if(e1s[i] == 0 || e1s[i] >= usedSlots) throw new ClassGen.ClassReadExn("invalid cp index");
+ ce.e1 = entriesByIndex[e1s[i]];
+ if(ce.e1 == null) throw new ClassGen.ClassReadExn("invalid cp index");
+ if(ce.tag != 7 && ce.tag != 8) {
+ if(e2s[i] == 0 || e2s[i] >= usedSlots) throw new ClassGen.ClassReadExn("invalid cp index");
+ ce.e2 = entriesByIndex[e2s[i]];
+ if(ce.e2 == null) throw new ClassGen.ClassReadExn("invalid cp index");
+ }
+ switch(ce.tag) {
+ case 7:
+ case 8:
+ if(!(ce.e1 instanceof Utf8Ent)) throw new ClassGen.ClassReadExn("expected a utf8 ent");
+ break;
+ case 9:
+ case 10:
+ case 11:
+ if(!(ce.e1 instanceof CPRefEnt) || ((CPRefEnt)ce.e1).tag != 7)
+ throw new ClassGen.ClassReadExn("expected a type ent");
+ if(!(ce.e2 instanceof CPRefEnt) || ((CPRefEnt)ce.e2).tag != 12)
+ throw new ClassGen.ClassReadExn("expected a name and type ent");
+ break;
+ case 12:
+ if(!(ce.e1 instanceof Utf8Ent)) throw new ClassGen.ClassReadExn("expected a utf8 ent");
+ if(!(ce.e2 instanceof Utf8Ent)) throw new ClassGen.ClassReadExn("expected a utf8 ent");
+ break;
+ }
+ }
+ for(int i=1; i<usedSlots; i++) {
+ Ent e = entriesByIndex[i];
+ entries.put(e.key(), e);
+ if (e instanceof LongEnt) i++;
+ }
+ state = STABLE;
+ }