X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;ds=sidebyside;f=src%2Forg%2Fibex%2Fclassgen%2FMethodGen.java;h=d0cfee3a931929a22696d6e165b615c378f14954;hb=8475b9cbaddccb3f2b9bd72ff81638ffee9cb3d5;hp=492cd767967c33a9c7ac1ad45362c590af61f58f;hpb=dc4fbb006da7df82565b577df089ff24ca0baece;p=org.ibex.classgen.git diff --git a/src/org/ibex/classgen/MethodGen.java b/src/org/ibex/classgen/MethodGen.java index 492cd76..d0cfee3 100644 --- a/src/org/ibex/classgen/MethodGen.java +++ b/src/org/ibex/classgen/MethodGen.java @@ -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; @@ -26,20 +24,44 @@ public class MethodGen extends Type.Class.Method.Body implements CGConst { private Object[] arg; private ConstantPool.Ent[] cparg; + public void insertBlank(int idx) { + for(int i=0;i= idx) si.setDefaultTarget(pos+1); + for(int j=0;j= idx) si.setTarget(j, pos+1); + } + break; + } + default: + if (OP_BRANCH(op[i])) { + int pos = ((Integer)arg[i]).intValue(); + if (pos >= idx) arg[i] = N(pos+1); + } + break; + } + } + size++; + for(int i=size; i>idx; i--) { + op[i] = op[i-1]; + arg[i] = arg[i-1]; + cparg = null; + } + } + // 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 +69,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"); + m.super(flags, new ClassFile.AttrGen(in,cp)); this.method = m; - this.attrs = new ClassFile.AttrGen(in,cp); - 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 +163,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 +562,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 +872,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 +1028,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(); - else if (arg[i] instanceof Type.Class.Member) s = ((Type.Class.Member)arg[i]).debugToString(); - else if (arg[i] instanceof String) s = "\"" + s + "\""; + 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 = "\"" + arg[i] + "\""; else if (arg[i] != null) s = arg[i].toString(); if (s != null) sb.append(" ").append(s); sb.append("\n");