allow Type.Primitive as an arg to NEWARRAY
[org.ibex.classgen.git] / src / org / ibex / classgen / MethodGen.java
index c4ebfe9..ef40595 100644 (file)
@@ -5,20 +5,18 @@ import java.util.*;
 
 /** A class representing a method in a generated classfile
     @see ClassFile#addMethod */
-public class MethodGen extends Type.Class.Method.Body implements CGConst {
+public class MethodGen extends Type.Class.Method.Body {
     private final static boolean EMIT_NOPS = false;
     
     private static final int NO_CODE = -1;
 
     public final Type.Class.Method method;
-    private final int flags;
-    private final ClassFile.AttrGen attrs;
     private final ClassFile.AttrGen codeAttrs;
     private final Vector exnTable = new Vector();
     private final Hashtable thrownExceptions = new Hashtable();
     
-    private int maxStack = 16;
-    private int maxLocals;
+    int maxStack = 16;
+    int maxLocals;
     
     private int size;
     private int capacity;
@@ -30,16 +28,10 @@ public class MethodGen extends Type.Class.Method.Body implements CGConst {
     // Constructors //////////////////////////////////////////////////////////////////////////////
 
     MethodGen(Type.Class.Method method, int flags) {
-        method.super();
-        if ((flags & ~VALID_METHOD_FLAGS) != 0) throw new IllegalArgumentException("invalid flags");
+        method.super(flags, new ClassFile.AttrGen());
         this.method = method;
-        this.flags = flags;
-        
-        attrs = new ClassFile.AttrGen();
         codeAttrs = new ClassFile.AttrGen();
-        
-        if (((flags & INTERFACE) != 0) || (flags & (ABSTRACT|NATIVE)) != 0) size = capacity = -1;
-        
+        if (!isConcrete()) size = capacity = -1;
         maxLocals = Math.max(method.getNumArgs() + (flags&STATIC)==0 ? 1 : 0, 4);
     }
 
@@ -47,16 +39,13 @@ public class MethodGen extends Type.Class.Method.Body implements CGConst {
         this(in.readShort(), cp.getUtf8KeyByIndex(in.readShort()), c, in, cp); }
 
     private MethodGen(short flags, String name, Type.Class c, DataInput in, ConstantPool cp) throws IOException {
-        this(flags, name, c.method(name+cp.getUtf8KeyByIndex(in.readShort())), c, in, cp); }
+        this(flags, name, c.method(name,cp.getUtf8KeyByIndex(in.readShort())), c, in, cp); }
     private MethodGen(short flags, String name, Type.Class.Method m,
                       Type.Class c, DataInput in, ConstantPool cp) throws IOException {
-        m.super();
-        this.flags = flags;
-        if ((flags & ~VALID_METHOD_FLAGS) != 0) throw new ClassFile.ClassReadExn("invalid flags");
-        this.method = c.method(name,typeDescriptor);
-        this.attrs = new ClassFile.AttrGen(in,cp);
+        m.super(flags, new ClassFile.AttrGen(in,cp));
+        this.method = m;
         
-        if ((flags & (NATIVE|ABSTRACT))==0)  {
+        if (isConcrete())  {
             byte[] codeAttr = (byte[]) attrs.get("Code");
             if (codeAttr == null) throw new ClassFile.ClassReadExn("code attr expected");
             DataInputStream ci = new DataInputStream(new ByteArrayInputStream(codeAttr));
@@ -144,7 +133,7 @@ public class MethodGen extends Type.Class.Method.Body implements CGConst {
                     break;
                 }
                 case MULTIANEWARRAY:
-                    arg = new MultiANewArray((Type.Class)cp.getKeyByIndex(in.readUnsignedShort()),in.readUnsignedByte());
+                    arg = new MultiANewArray((Type.Array)cp.getKeyByIndex(in.readUnsignedShort()),in.readUnsignedByte());
                     break;
                 case INVOKEINTERFACE: {
                     ConstantPool.Ent ent = cp.getByIndex(in.readUnsignedShort());
@@ -543,9 +532,9 @@ public class MethodGen extends Type.Class.Method.Body implements CGConst {
     }
     
     public static class MultiANewArray {
-        public Type.Class type;
+        public Type.Array type;
         public int dims;
-        public MultiANewArray(Type.Class type, int dims) { this.type = type; this.dims = dims; }
+        public MultiANewArray(Type.Array type, int dims) { this.type = type; this.dims = dims; }
     }
     
     public static class Wide {
@@ -853,7 +842,9 @@ public class MethodGen extends Type.Class.Method.Body implements CGConst {
                     } else if (argLength == 7) {
                         throw new Error("should never happen - variable length instruction not explicitly handled");
                     } else {
-                        int iarg  = ((Integer)arg).intValue();
+                        int iarg  = (arg instanceof Type.Primitive)
+                            ? ((Type.Primitive)arg).toArraySpec()
+                            : ((Integer)arg).intValue();
                         if (argLength == 1) {
                             if ((opdata & OP_UNSIGNED_FLAG) != 0 ? iarg >= 256 : (iarg < -128 || iarg >= 128))
                                 throw new ClassFile.Exn("overflow of s/u1 option");
@@ -1007,9 +998,9 @@ public class MethodGen extends Type.Class.Method.Body implements CGConst {
             sb.append(i).append(": ");
             sb.append(OP_NAMES[op[i]&0xff]);
             String s = null;
-            if (arg[i] instanceof Type) s = ((Type)arg[i]).debugToString();
+            if (arg[i] instanceof Type) s = ((Type)arg[i]).toString();
             else if (arg[i] instanceof Type.Class.Member) s = ((Type.Class.Member)arg[i]).toString();
-            else if (arg[i] instanceof String) s = "\"" + s + "\"";
+            else if (arg[i] instanceof String) s = "\"" + arg[i] + "\"";
             else if (arg[i] != null) s = arg[i].toString();
             if (s != null) sb.append(" ").append(s);
             sb.append("\n");