ClassGen->ClassFile, ClassGen.FieldOrMethodRef->MemberRef
authoradam <adam@megacz.com>
Fri, 3 Jun 2005 05:26:47 +0000 (05:26 +0000)
committeradam <adam@megacz.com>
Fri, 3 Jun 2005 05:26:47 +0000 (05:26 +0000)
darcs-hash:20050603052647-5007d-f4f1e5a2d846a0d8c81fd7ae0ecede437ee50e05.gz

Makefile
src/org/ibex/classgen/CPGen.java
src/org/ibex/classgen/ClassFile.java [moved from src/org/ibex/classgen/ClassGen.java with 86% similarity]
src/org/ibex/classgen/FieldGen.java
src/org/ibex/classgen/FieldRef.java
src/org/ibex/classgen/MemberRef.java [new file with mode: 0644]
src/org/ibex/classgen/MethodGen.java
src/org/ibex/classgen/MethodRef.java

index c0b0454..4a9bb40 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,7 @@ $(classes): $(sources)
        $(JAVAC) -d build $(sources)
 
 test: $(classes)
-       java -cp build org.ibex.classgen.ClassGen
+       java -cp build org.ibex.classgen.ClassFile
 
 clean: 
        rm -rf build/*
index 052e28c..6b59a28 100644 (file)
@@ -25,7 +25,7 @@ class CPGen {
         
         void dump(DataOutput o) throws IOException { o.writeByte(tag); }
         String debugToString() { return toString(); } // so we can remove this method when not debugging
-        abstract Object key() throws ClassGen.ClassReadExn; // be careful using this, it drags in a bunch of code
+        abstract Object key() throws ClassFile.ClassReadExn; // be careful using this, it drags in a bunch of code
     }
     
     class IntEnt extends Ent {
@@ -81,14 +81,14 @@ class CPGen {
         }
         
         private String fixme() { throw new Error("fixme"); }
-        Object key() throws ClassGen.ClassReadExn {
+        Object key() throws ClassFile.ClassReadExn {
             switch(tag) {
                 case 7: return Type.instance(((Utf8Ent)e1).s);
                 case 8: return (((Utf8Ent)e1).s);
                 case 9: {
                     NameAndTypeKey nt = (NameAndTypeKey) e2.key();
                     Type t = Type.instance(nt.type);
-                    if(t == null) throw new ClassGen.ClassReadExn("invalid type descriptor");
+                    if(t == null) throw new ClassFile.ClassReadExn("invalid type descriptor");
                     return new FieldRef((Type.Class)e1.key(), nt.name, t);
                 }
                 case 10: case 11: {
@@ -160,7 +160,7 @@ class CPGen {
         return ent.n;
     }
 
-    public final Type getType(int index) throws ClassGen.ClassReadExn {
+    public final Type getType(int index) throws ClassFile.ClassReadExn {
         Ent e = getByIndex(index);
         if (e instanceof Utf8Ent) return Type.instance(((Utf8Ent)e).s);
         else return (Type)e.key();
@@ -214,8 +214,8 @@ class CPGen {
             ce.e1 = addUtf8(key.name);
             ce.e2 = addUtf8(key.type);
             ent = ce;
-        } else if(o instanceof ClassGen.FieldOrMethodRef) {
-            ClassGen.FieldOrMethodRef key = (ClassGen.FieldOrMethodRef) o;
+        } else if(o instanceof MemberRef) {
+            MemberRef key = (MemberRef) o;
             int tag = o instanceof FieldRef ? 9 : o instanceof MethodRef ? 10 : o instanceof MethodRef.I ? 11 : 0;
             if(tag == 0) throw new Error("should never happen");
             CPRefEnt ce = new CPRefEnt(tag);
@@ -227,7 +227,7 @@ class CPGen {
         }
         
         int spaces = ent instanceof LongEnt ? 2 : 1;        
-        if(usedSlots + spaces > 65536) throw new ClassGen.Exn("constant pool full");
+        if(usedSlots + spaces > 65536) throw new ClassFile.Exn("constant pool full");
         
         ent.n = state == OPEN ? 1 : usedSlots; // refcount or index
 
@@ -309,9 +309,9 @@ class CPGen {
         }
     }
     
-    CPGen(DataInput in) throws ClassGen.ClassReadExn, IOException {
+    CPGen(DataInput in) throws ClassFile.ClassReadExn, IOException {
         usedSlots = in.readUnsignedShort();
-        if(usedSlots==0) throw new ClassGen.ClassReadExn("invalid used slots");
+        if(usedSlots==0) throw new ClassFile.ClassReadExn("invalid used slots");
         
         // these are to remember the CPRefEnt e1 and e2s we have to fix up
         int[] e1s = new int[usedSlots];
@@ -363,7 +363,7 @@ class CPGen {
                     break;
                 }
                 default:
-                    throw new ClassGen.ClassReadExn("invalid cp ent tag");
+                    throw new ClassFile.ClassReadExn("invalid cp ent tag");
             }
             entriesByIndex[index] = e;
             if (e instanceof LongEnt) index++;
@@ -379,30 +379,30 @@ class CPGen {
             }
             if (!(e instanceof CPRefEnt)) continue;
             CPRefEnt ce = (CPRefEnt) e;
-            if(e1s[i] == 0 || e1s[i] >= usedSlots) throw new ClassGen.ClassReadExn("invalid cp index");
+            if(e1s[i] == 0 || e1s[i] >= usedSlots) throw new ClassFile.ClassReadExn("invalid cp index");
             ce.e1 = entriesByIndex[e1s[i]];
-            if(ce.e1 == null)  throw new ClassGen.ClassReadExn("invalid cp index");
+            if(ce.e1 == null)  throw new ClassFile.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");
+                if(e2s[i] == 0 || e2s[i] >= usedSlots) throw new ClassFile.ClassReadExn("invalid cp index");
                 ce.e2 = entriesByIndex[e2s[i]];
-                if(ce.e2 == null)  throw new ClassGen.ClassReadExn("invalid cp index");
+                if(ce.e2 == null)  throw new ClassFile.ClassReadExn("invalid cp index");
             }
             switch(ce.tag) {
                 case 7:
                 case 8:
-                    if(!(ce.e1 instanceof Utf8Ent)) throw new ClassGen.ClassReadExn("expected a utf8 ent");
+                    if(!(ce.e1 instanceof Utf8Ent)) throw new ClassFile.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");
+                        throw new ClassFile.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");
+                        throw new ClassFile.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");
+                    if(!(ce.e1 instanceof Utf8Ent)) throw new ClassFile.ClassReadExn("expected a utf8 ent");
+                    if(!(ce.e2 instanceof Utf8Ent)) throw new ClassFile.ClassReadExn("expected a utf8 ent");
                     break;
             }
         }
similarity index 86%
rename from src/org/ibex/classgen/ClassGen.java
rename to src/org/ibex/classgen/ClassFile.java
index 39bd113..6be6bfa 100644 (file)
@@ -4,7 +4,7 @@ import java.util.*;
 import java.io.*;
 
 /** Class generation object representing the whole classfile */
-public class ClassGen implements CGConst {
+public class ClassFile implements CGConst {
     private final Type.Class thisType;
     private final Type.Class superType;
     private final Type.Class[] interfaces;
@@ -60,22 +60,22 @@ public class ClassGen implements CGConst {
         sb.append("}");
     }
 
-    /** @see #ClassGen(Type.Class, Type.Class, int) */
-    public ClassGen(String name, String superName, int flags) {
+    /** @see #ClassFile(Type.Class, Type.Class, int) */
+    public ClassFile(String name, String superName, int flags) {
         this(Type.instance(name).asClass(), Type.instance(superName).asClass(), flags);
     }
 
-    /** @see #ClassGen(Type.Class, Type.Class, int, Type.Class[]) */
-    public ClassGen(Type.Class thisType, Type.Class superType, int flags) {
+    /** @see #ClassFile(Type.Class, Type.Class, int, Type.Class[]) */
+    public ClassFile(Type.Class thisType, Type.Class superType, int flags) {
         this(thisType, superType, flags, null);
     }
     
-    /** Creates a new ClassGen object 
+    /** Creates a new ClassFile object 
         @param thisType The type of the class to generate
         @param superType The superclass of the generated class (commonly Type.OBJECT) 
         @param flags The access flags for this class (ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_INTERFACE, and ACC_ABSTRACT)
     */
-    public ClassGen(Type.Class thisType, Type.Class superType, int flags, Type.Class[] interfaces) {
+    public ClassFile(Type.Class thisType, Type.Class superType, int flags, Type.Class[] interfaces) {
         if((flags & ~(ACC_PUBLIC|ACC_FINAL|ACC_SUPER|ACC_INTERFACE|ACC_ABSTRACT)) != 0)
             throw new IllegalArgumentException("invalid flags");
         this.thisType = thisType;
@@ -128,13 +128,13 @@ public class ClassGen implements CGConst {
     public void setSourceFile(String sourceFile) { this.sourceFile = sourceFile; }
     
     /** Writes the classfile data to the file specifed
-        @see ClassGen#dump(OutputStream)
+        @see ClassFile#dump(OutputStream)
     */
     public void dump(String file) throws IOException { dump(new File(file)); }
     
     /** Writes the classfile data to the file specified
         If <i>f</i> is a directory directory components under it are created for the package the class is in (like javac's -d option)
-        @see ClassGen#dump(OutputStream)
+        @see ClassFile#dump(OutputStream)
     */
     public void dump(File f) throws IOException {
         if(f.isDirectory()) {
@@ -200,18 +200,18 @@ public class ClassGen implements CGConst {
         attributes.dump(o); // attributes        
     }
     
-    public ClassGen read(File f) throws ClassReadExn, IOException {
+    public ClassFile read(File f) throws ClassReadExn, IOException {
         InputStream is = new FileInputStream(f);
-        ClassGen ret = read(is);
+        ClassFile ret = read(is);
         is.close();
         return ret;
     }
     
-    public ClassGen read(InputStream is) throws ClassReadExn, IOException {
-        return new ClassGen(new DataInputStream(new BufferedInputStream(is)));
+    public ClassFile read(InputStream is) throws ClassReadExn, IOException {
+        return new ClassFile(new DataInputStream(new BufferedInputStream(is)));
     }
 
-    ClassGen(DataInput i) throws ClassReadExn, IOException {
+    ClassFile(DataInput i) throws ClassReadExn, IOException {
         int magic = i.readInt();
         if (magic != 0xcafebabe) throw new ClassReadExn("invalid magic: " + Long.toString(0xffffffffL & magic, 16));
         minor = i.readShort();
@@ -242,27 +242,6 @@ public class ClassGen implements CGConst {
         public ClassReadExn(String s) { super(s); }
     }
     
-    /** A class representing a field or method reference. This is used as an argument to the INVOKE*, GET*, and PUT* bytecodes
-        @see MethodRef
-        @see FieldRef
-        @see MethodRef.I
-        @see FieldRef
-    */
-    public static abstract class FieldOrMethodRef {
-        Type.Class klass;
-        String name;
-        String descriptor;
-        
-        FieldOrMethodRef(Type.Class klass, String name, String descriptor) { this.klass = klass; this.name = name; this.descriptor = descriptor; }
-        FieldOrMethodRef(FieldOrMethodRef o) { this.klass = o.klass; this.name = o.name; this.descriptor = o.descriptor; }
-        public boolean equals(Object o_) {
-            if(!(o_ instanceof FieldOrMethodRef)) return false;
-            FieldOrMethodRef o = (FieldOrMethodRef) o_;
-            return o.klass.equals(klass) && o.name.equals(name) && o.descriptor.equals(descriptor);
-        }
-        public int hashCode() { return klass.hashCode() ^ name.hashCode() ^ descriptor.hashCode(); }
-    }
-    
     static class AttrGen {
         private final CPGen cp;
         private final Hashtable ht = new Hashtable();
@@ -327,15 +306,15 @@ public class ClassGen implements CGConst {
     public static void main(String[] args) throws Exception {
         if (args.length==1) {
             if (args[0].endsWith(".class")) {
-                System.out.println(new ClassGen(new DataInputStream(new FileInputStream(args[0]))));
+                System.out.println(new ClassFile(new DataInputStream(new FileInputStream(args[0]))));
             } else {
                 InputStream is = Class.forName(args[0]).getClassLoader().getResourceAsStream(args[0].replace('.', '/')+".class");
-                System.out.println(new ClassGen(new DataInputStream(is)));
+                System.out.println(new ClassFile(new DataInputStream(is)));
             }
         } else {
             /*
             Type.Class me = new Type.Class("Test");
-            ClassGen cg = new ClassGen("Test", "java.lang.Object", ACC_PUBLIC|ACC_SUPER|ACC_FINAL);
+            ClassFile cg = new ClassFile("Test", "java.lang.Object", ACC_PUBLIC|ACC_SUPER|ACC_FINAL);
             FieldGen fg = cg.addField("foo", Type.INT, ACC_PUBLIC|ACC_STATIC);
         
             MethodGen mg = cg.addMethod("main", Type.VOID, new Type[]{Type.arrayType(Type.STRING)}, ACC_STATIC|ACC_PUBLIC);
index 479a481..cf269d0 100644 (file)
@@ -3,19 +3,19 @@ package org.ibex.classgen;
 import java.io.*;
 
 /** Class representing a field in a generated classfile
-    @see ClassGen#addField */
+    @see ClassFile#addField */
 public class FieldGen implements CGConst {
     private final CPGen cp;
     private final String name;
     private final Type type;
     private final int flags;
-    private final ClassGen.AttrGen attrs;
+    private final ClassFile.AttrGen attrs;
     
     private Object constantValue;
 
     public String toString() { StringBuffer sb = new StringBuffer(); toString(sb); return sb.toString(); }
     public void   toString(StringBuffer sb) {
-        sb.append(ClassGen.flagsToString(flags));
+        sb.append(ClassFile.flagsToString(flags));
         sb.append(type);
         sb.append(" ");
         sb.append(name);
@@ -28,17 +28,17 @@ public class FieldGen implements CGConst {
         flags = in.readShort();
         name = cp.getUtf8ByIndex(in.readShort());
         type = cp.getType(in.readShort());
-        attrs = new ClassGen.AttrGen(cp, in);
+        attrs = new ClassFile.AttrGen(cp, in);
     }
 
-    FieldGen(ClassGen owner, String name, Type type, int flags) {
+    FieldGen(ClassFile owner, String name, Type type, int flags) {
         if((flags & ~(ACC_PUBLIC|ACC_PRIVATE|ACC_PROTECTED|ACC_VOLATILE|ACC_TRANSIENT|ACC_STATIC|ACC_FINAL)) != 0)
             throw new IllegalArgumentException("invalid flags");
         this.cp = owner.cp;
         this.name = name;
         this.type = type;
         this.flags = flags;
-        this.attrs = new ClassGen.AttrGen(cp);
+        this.attrs = new ClassFile.AttrGen(cp);
         
         cp.addUtf8(name);
         cp.addUtf8(type.getDescriptor());
index 62460e1..331ebe4 100644 (file)
@@ -7,7 +7,7 @@ GETFIELD, PUTFIELD, GETSTATIC, and PUTSTATCI bytecodes
 @see CGConst#GETSTATIC
 @see CGConst#PUTSTATIC
 */
-public class FieldRef extends ClassGen.FieldOrMethodRef {
+public class FieldRef extends MemberRef {
     /** Create a reference to field <i>name</i> of class <i>c</i> with the type <i>t</i>  */    
     public FieldRef(Type.Class c, String name, Type t) { super(c, name, t.getDescriptor()); }
     /** Equivalent to FieldRef(new Type.Class(s), ...)
diff --git a/src/org/ibex/classgen/MemberRef.java b/src/org/ibex/classgen/MemberRef.java
new file mode 100644 (file)
index 0000000..3c09960
--- /dev/null
@@ -0,0 +1,26 @@
+package org.ibex.classgen;
+
+import java.util.*;
+import java.io.*;
+
+/** A class representing a field or method reference. This is used as an argument to the INVOKE*, GET*, and PUT* bytecodes
+    @see MethodRef
+    @see FieldRef
+    @see MethodRef.I
+    @see FieldRef
+*/
+public abstract class MemberRef {
+    Type.Class klass;
+    String name;
+    String descriptor;
+        
+    MemberRef(Type.Class klass, String name, String descriptor) { this.klass = klass; this.name = name; this.descriptor = descriptor; }
+    MemberRef(MemberRef o) { this.klass = o.klass; this.name = o.name; this.descriptor = o.descriptor; }
+    public boolean equals(Object o_) {
+        if(!(o_ instanceof MemberRef)) return false;
+        MemberRef o = (MemberRef) o_;
+        return o.klass.equals(klass) && o.name.equals(name) && o.descriptor.equals(descriptor);
+    }
+    public int hashCode() { return klass.hashCode() ^ name.hashCode() ^ descriptor.hashCode(); }
+}
+    
index 2fde5d3..e2d3b68 100644 (file)
@@ -4,7 +4,7 @@ import java.io.*;
 import java.util.*;
 
 /** A class representing a method in a generated classfile
-    @see ClassGen#addMethod */
+    @see ClassFile#addMethod */
 public class MethodGen implements CGConst {
     private final static boolean EMIT_NOPS = false;
     
@@ -16,8 +16,8 @@ public class MethodGen implements CGConst {
     private final Type ret;
     private final Type[] args;
     private final int flags;
-    private final ClassGen.AttrGen attrs;
-    private final ClassGen.AttrGen codeAttrs;
+    private final ClassFile.AttrGen attrs;
+    private final ClassFile.AttrGen codeAttrs;
     private final Hashtable exnTable = new Hashtable();
     private final Hashtable thrownExceptions = new Hashtable();
     
@@ -31,7 +31,7 @@ public class MethodGen implements CGConst {
     
     public String toString() { StringBuffer sb = new StringBuffer(); toString(sb, "<init>"); return sb.toString(); }
     public void   toString(StringBuffer sb, String constructorName) {
-        sb.append(ClassGen.flagsToString(flags));
+        sb.append(ClassFile.flagsToString(flags));
         sb.append(ret);
         sb.append(" ");
 
@@ -59,10 +59,10 @@ public class MethodGen implements CGConst {
         //String args = descriptor.substring(1, descriptor.indexOf(')'));
         args = new Type[0]; // FIXME
         codeAttrs = null;
-        attrs = new ClassGen.AttrGen(cp, in);
+        attrs = new ClassFile.AttrGen(cp, in);
     }
 
-    MethodGen(ClassGen owner, String name, Type ret, Type[] args, int flags) {
+    MethodGen(ClassFile owner, String name, Type ret, Type[] args, int flags) {
         if((flags & ~(ACC_PUBLIC|ACC_PRIVATE|ACC_PROTECTED|ACC_STATIC|ACC_FINAL|ACC_SYNCHRONIZED|ACC_NATIVE|ACC_ABSTRACT|ACC_STRICT)) != 0)
             throw new IllegalArgumentException("invalid flags");
         this.cp = owner.cp;
@@ -71,8 +71,8 @@ public class MethodGen implements CGConst {
         this.args = args;
         this.flags = flags;
         
-        attrs = new ClassGen.AttrGen(cp);
-        codeAttrs = new ClassGen.AttrGen(cp);
+        attrs = new ClassFile.AttrGen(cp);
+        codeAttrs = new ClassFile.AttrGen(cp);
         
         cp.addUtf8(name);
         cp.addUtf8(getDescriptor());
@@ -511,7 +511,7 @@ public class MethodGen implements CGConst {
         }
         int codeSize = p;
         
-        if(codeSize >= 65536) throw new ClassGen.Exn("method too large in size");
+        if(codeSize >= 65536) throw new ClassFile.Exn("method too large in size");
         
         o.writeShort(maxStack);
         o.writeShort(maxLocals);
@@ -533,7 +533,7 @@ public class MethodGen implements CGConst {
             switch(op) {
                 case IINC: {
                     Pair pair = (Pair) arg;
-                    if(pair.i1 > 255 || pair.i2 < -128 || pair.i2 > 127) throw new ClassGen.Exn("overflow of iinc arg"); 
+                    if(pair.i1 > 255 || pair.i2 < -128 || pair.i2 > 127) throw new ClassFile.Exn("overflow of iinc arg"); 
                     o.writeByte(pair.i1);
                     o.writeByte(pair.i2);
                     break;
@@ -571,7 +571,7 @@ public class MethodGen implements CGConst {
                     if((opdata & OP_BRANCH_FLAG) != 0) {
                         int v = pc[((Integer)arg).intValue()] - pc[i];
                         if(argLength == 2) {
-                            if(v < -32768 || v > 32767) throw new ClassGen.Exn("overflow of s2 offset");
+                            if(v < -32768 || v > 32767) throw new ClassFile.Exn("overflow of s2 offset");
                             o.writeShort(v);
                         } else if(argLength == 4) {
                             o.writeInt(v);
@@ -588,10 +588,10 @@ public class MethodGen implements CGConst {
                     } else {
                         int iarg  = ((Integer)arg).intValue();
                         if(argLength == 1) {
-                            if(iarg < -128 || iarg >= 256) throw new ClassGen.Exn("overflow of s/u1 option");
+                            if(iarg < -128 || iarg >= 256) throw new ClassFile.Exn("overflow of s/u1 option");
                             o.writeByte(iarg);
                         } else if(argLength == 2) {
-                            if(iarg < -32768 || iarg >= 65536) throw new ClassGen.Exn("overflow of s/u2 option"); 
+                            if(iarg < -32768 || iarg >= 65536) throw new ClassFile.Exn("overflow of s/u2 option"); 
                             o.writeShort(iarg);
                         } else {
                             throw new Error("should never happen");
index 2f69e9a..4810bbb 100644 (file)
@@ -7,7 +7,7 @@ package org.ibex.classgen;
     @see CGConst#INVOKESPECIAL
     @see CGConst#INVOKEINTERFACE
 */
-public class MethodRef extends ClassGen.FieldOrMethodRef {
+public class MethodRef extends MemberRef {
     /** Create a reference to method <i>name</i> of class <i>c</i> with the return type <i>ret</i> and the
         arguments <i>args</i> */
     public MethodRef(Type.Class c, String name, Type ret, Type[] args) {