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;
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();
private byte[] op;
private Object[] arg;
- MethodGen(DataInput in) { throw new Error("Brian is lame"); }
- MethodGen(ClassGen owner, String name, Type ret, Type[] args, int flags) {
+ public String toString() { StringBuffer sb = new StringBuffer(); toString(sb, "<init>"); return sb.toString(); }
+ public void toString(StringBuffer sb, String constructorName) {
+ sb.append(ClassFile.flagsToString(flags));
+ sb.append(ret);
+ sb.append(" ");
+
+ if (name.equals("<clinit>")) sb.append("static ");
+ else {
+ if (name.equals("<init>")) sb.append(constructorName);
+ else sb.append(name);
+ sb.append("(");
+ for(int i=0; i<args.length; i++)
+ sb.append((i==0?"":", ")+args[i]);
+ sb.append(") ");
+ }
+ sb.append("{");
+ sb.append("}");
+ // FIXME: attrs, body
+ }
+
+ MethodGen(CPGen cp, DataInput in) throws IOException {
+ this.cp = cp;
+ flags = in.readShort();
+ name = cp.getUtf8ByIndex(in.readShort());
+ String descriptor = cp.getUtf8ByIndex(in.readShort());
+ String ret = descriptor.substring(descriptor.indexOf(')')+1);
+ this.ret = Type.instance(ret);
+ //String args = descriptor.substring(1, descriptor.indexOf(')'));
+ args = new Type[0]; // FIXME
+ codeAttrs = null;
+ attrs = new ClassFile.AttrGen(cp, in);
+ }
+
+ 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;
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());
@param handler The instruction of the excepton handler
@param type The type of exception that is to be handled (MUST inherit from Throwable)
*/
- public final void addExceptionHandler(int start, int end, int handler, Type.Object type) {
+ public final void addExceptionHandler(int start, int end, int handler, Type.Class type) {
exnTable.put(type, new ExnTableEnt(start, end, handler, cp.add(type)));
}
NOTE: This isn't enforced by the JVM. This is for reference only. A method can throw exceptions not declared to be thrown
@param type The type of exception that can be thrown
*/
- public final void addThrow(Type.Object type) {
+ public final void addThrow(Type.Class type) {
thrownExceptions.put(type, cp.add(type));
}
}
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);
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;
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);
} 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");