From 1be1acc8b4262fd60e615446a866dc5c54eb0a45 Mon Sep 17 00:00:00 2001 From: adam Date: Mon, 27 Jun 2005 08:37:31 +0000 Subject: [PATCH] reformatting darcs-hash:20050627083731-5007d-44f230c632fc0777b7b3fb1f63cca216e637cfb9.gz --- src/org/ibex/classgen/MethodGen.java | 429 +++++++++++++++++----------------- 1 file changed, 217 insertions(+), 212 deletions(-) diff --git a/src/org/ibex/classgen/MethodGen.java b/src/org/ibex/classgen/MethodGen.java index 96193da..acb6c5c 100644 --- a/src/org/ibex/classgen/MethodGen.java +++ b/src/org/ibex/classgen/MethodGen.java @@ -26,82 +26,19 @@ public class MethodGen implements CGConst { private Object[] arg; private ConstantPool.Ent[] cparg; - public void debugToString(StringBuffer sb, String constructorName) { - // This is intentionally a local variable so it can be removed by gcclass - final String[] OP_NAMES = new String[]{ - "nop", "aconst_null", "iconst_m1", "iconst_0", "iconst_1", "iconst_2", - "iconst_3", "iconst_4", "iconst_5", "lconst_0", "lconst_1", "fconst_0", - "fconst_1", "fconst_2", "dconst_0", "dconst_1", "bipush", "sipush", - "ldc", "ldc_w", "ldc2_w", "iload", "lload", "fload", - "dload", "aload", "iload_0", "iload_1", "iload_2", "iload_3", - "lload_0", "lload_1", "lload_2", "lload_3", "fload_0", "fload_1", - "fload_2", "fload_3", "dload_0", "dload_1", "dload_2", "dload_3", - "aload_0", "aload_1", "aload_2", "aload_3", "iaload", "laload", - "faload", "daload", "aaload", "baload", "caload", "saload", - "istore", "lstore", "fstore", "dstore", "astore", "istore_0", - "istore_1", "istore_2", "istore_3", "lstore_0", "lstore_1", "lstore_2", - "lstore_3", "fstore_0", "fstore_1", "fstore_2", "fstore_3", "dstore_0", - "dstore_1", "dstore_2", "dstore_3", "astore_0", "astore_1", "astore_2", - "astore_3", "iastore", "lastore", "fastore", "dastore", "aastore", - "bastore", "castore", "sastore", "pop", "pop2", "dup", - "dup_x1", "dup_x2", "dup2", "dup2_x1", "dup2_x2", "swap", - "iadd", "ladd", "fadd", "dadd", "isub", "lsub", - "fsub", "dsub", "imul", "lmul", "fmul", "dmul", - "idiv", "ldiv", "fdiv", "ddiv", "irem", "lrem", - "frem", "drem", "ineg", "lneg", "fneg", "dneg", - "ishl", "lshl", "ishr", "lshr", "iushr", "lushr", - "iand", "land", "ior", "lor", "ixor", "lxor", - "iinc", "i2l", "i2f", "i2d", "l2i", "l2f", - "l2d", "f2i", "f2l", "f2d", "d2i", "d2l", - "d2f", "i2b", "i2c", "i2s", "lcmp", "fcmpl", - "fcmpg", "dcmpl", "dcmpg", "ifeq", "ifne", "iflt", - "ifge", "ifgt", "ifle", "if_icmpeq", "if_icmpne", "if_icmplt", - "if_icmpge", "if_icmpgt", "if_icmple", "if_acmpeq", "if_acmpne", "goto", - "jsr", "ret", "tableswitch", "lookupswitch", "ireturn", "lreturn", - "freturn", "dreturn", "areturn", "return", "getstatic", "putstatic", - "getfield", "putfield", "invokevirtual", "invokespecial", "invokestatic", "invokeinterface", - "", "new", "newarray", "anewarray", "arraylength", "athrow", - "checkcast", "instanceof", "monitorenter", "monitorexit", "wide", "multianewarray", - "ifnull", "ifnonnull", "goto_w", "jsr_w", "", "", - "", "", "", "", "", "", - "", "", "", "", "", "", - "", "", "", "", "", "", - "", "", "", "", "", "", - "", "", "", "", "", "", - "", "", "", "", "", "", - "", "", "", "", "", "", - "", "", "", "", "", "", - "", "", "", "" - }; + // Constructors ////////////////////////////////////////////////////////////////////////////// + + MethodGen(Type.Class.Method method, int flags) { + if ((flags & ~VALID_METHOD_FLAGS) != 0) throw new IllegalArgumentException("invalid flags"); + this.method = method; + this.flags = flags; - sb.append(" ").append(ClassFile.flagsToString(flags,false)); - sb.append(method.debugToString()); - if(thrownExceptions.size() > 0) { - sb.append("throws"); - for(Enumeration e = thrownExceptions.keys();e.hasMoreElements();) - sb.append(" ").append(((Type.Class)e.nextElement()).debugToString()).append(","); - sb.setLength(sb.length()-1); - sb.append(" "); - } - if((flags & (NATIVE|ABSTRACT))==0) { - sb.append("{\n"); - for(int i=0;i 0) { @@ -142,6 +79,8 @@ public class MethodGen implements CGConst { } } } + + // Parsing ////////////////////////////////////////////////////////////////////////////// final int[] parseCode(DataInputStream in, int codeLen, ConstantPool cp) throws IOException { int[] map = new int[codeLen]; @@ -151,12 +90,12 @@ public class MethodGen implements CGConst { byte op = in.readByte(); int opdata = OP_DATA[op&0xff]; //System.err.println("Processing " + Integer.toString(op&0xff,16) + " at " + pc); - if((opdata&OP_VALID_FLAG)==0) throw new ClassFile.ClassReadExn("invalid bytecode " + (op&0xff)); + if ((opdata&OP_VALID_FLAG)==0) throw new ClassFile.ClassReadExn("invalid bytecode " + (op&0xff)); int argLength = opdata & OP_ARG_LENGTH_MASK; int mypc = pc; map[mypc] = size(); pc += 1 + (argLength == 7 ? 0 : argLength); - if(argLength == 0) { add(op); continue; } + if (argLength == 0) { add(op); continue; } Object arg; switch(op) { case IINC: @@ -164,12 +103,12 @@ public class MethodGen implements CGConst { break; case TABLESWITCH: case LOOKUPSWITCH: - SI si; - for(;(pc&3) != 0;pc++) if(in.readByte() != 0) throw new ClassFile.ClassReadExn("invalid padding"); + Switch si; + for(;(pc&3) != 0;pc++) if (in.readByte() != 0) throw new ClassFile.ClassReadExn("invalid padding"); int def = in.readInt() + mypc; pc += 4; - if(op == LOOKUPSWITCH) { - LSI lsi = new LSI(in.readInt()); + if (op == LOOKUPSWITCH) { + Switch.Lookup lsi = new Switch.Lookup(in.readInt()); pc += 4; for(int i=0;i= max || bytecodeMap[startPC] < 0) throw new ClassFile.ClassReadExn("invalid startPC"); - if(endPC >= max || bytecodeMap[endPC] < 0) throw new ClassFile.ClassReadExn("invalid startPC"); - if(handlerPC >= max || bytecodeMap[handlerPC] < 0) throw new ClassFile.ClassReadExn("invalid startPC"); + if (startPC >= max || bytecodeMap[startPC] < 0) throw new ClassFile.ClassReadExn("invalid startPC"); + if (endPC >= max || bytecodeMap[endPC] < 0) throw new ClassFile.ClassReadExn("invalid startPC"); + if (handlerPC >= max || bytecodeMap[handlerPC] < 0) throw new ClassFile.ClassReadExn("invalid startPC"); this.start = bytecodeMap[startPC]; this.end = bytecodeMap[endPC]; this.handler = bytecodeMap[handlerPC]; @@ -333,7 +261,7 @@ public class MethodGen implements CGConst { this.handler = handler; this.type = type; } - void finish(ConstantPool cp) { if(type != null) cp.add(type); } + void finish(ConstantPool cp) { if (type != null) cp.add(type); } void dump(DataOutput o, int[] pc, int endPC, ConstantPool cp) throws IOException { o.writeShort(pc[start]); o.writeShort(end==pc.length ? endPC : pc[end]); @@ -358,22 +286,24 @@ public class MethodGen implements CGConst { */ public final void addThrow(Type.Class type) { thrownExceptions.put(type, type); } - private final void grow() { if(size == capacity) grow(size+1); } + private final void grow() { if (size == capacity) grow(size+1); } private final void grow(int newCap) { - if(capacity == NO_CODE) throw new IllegalStateException("method can't have code"); - if(newCap <= capacity) return; + if (capacity == NO_CODE) throw new IllegalStateException("method can't have code"); + if (newCap <= capacity) return; newCap = Math.max(newCap, capacity == 0 ? 256 : capacity*2); byte[] op2 = new byte[newCap]; - if(capacity != 0) System.arraycopy(op, 0, op2, 0, size); + if (capacity != 0) System.arraycopy(op, 0, op2, 0, size); op = op2; Object[] arg2 = new Object[newCap]; - if(capacity != 0) System.arraycopy(arg, 0, arg2, 0, size); + if (capacity != 0) System.arraycopy(arg, 0, arg2, 0, size); arg = arg2; capacity = newCap; } + + // Accessors ////////////////////////////////////////////////////////////////////////////// /** Returns the size (in instructions) of this method @return The size of the method (in instructions) @@ -384,7 +314,7 @@ public class MethodGen implements CGConst { /** Add a bytecode (with no argument) to the method */ public final int add(byte op) { int s = size; - if(s == capacity) grow(); + if (s == capacity) grow(); this.op[s] = op; size++; return s; @@ -395,17 +325,17 @@ public class MethodGen implements CGConst { /** Adds a bytecode, op, with argument arg to the method @return The position of the new bytecode */ - public final int add(byte op, Object arg) { if(capacity == size) grow(); set(size, op, arg); return size++; } + public final int add(byte op, Object arg) { if (capacity == size) grow(); set(size, op, arg); return size++; } /** Adds a bytecode with a boolean argument - equivalent to add(op, arg?1:0); @return The position of the new bytecode @see #add(byte, int) */ - public final int add(byte op, boolean arg) { if(capacity == size) grow(); set(size, op, arg); return size++; } + public final int add(byte op, boolean arg) { if (capacity == size) grow(); set(size, op, arg); return size++; } /** Adds a bytecode with an integer argument. This is equivalent to add(op, new Integer(arg)), but optimized to prevent the allocation when possible @return The position of the new bytecode @see #add(byte, Object) */ - public final int add(byte op, int arg) { if(capacity == size) grow(); set(size, op, arg); return size++; } + public final int add(byte op, int arg) { if (capacity == size) grow(); set(size, op, arg); return size++; } /** Gets the bytecode at position pos @exception ArrayIndexOutOfBoundException if pos < 0 || pos >= size() @@ -453,14 +383,14 @@ public class MethodGen implements CGConst { case 4: op = ICONST_4; break OUTER; case 5: op = ICONST_5; break OUTER; } - if(n >= -128 && n <= 127) { op = BIPUSH; arg = N(n); } - else if(n >= -32768 && n <= 32767) { op = SIPUSH; arg = N(n); } + if (n >= -128 && n <= 127) { op = BIPUSH; arg = N(n); } + else if (n >= -32768 && n <= 32767) { op = SIPUSH; arg = N(n); } else { arg = N(n); } break; case ILOAD: case ISTORE: case LLOAD: case LSTORE: case FLOAD: case FSTORE: case DLOAD: case DSTORE: case ALOAD: case ASTORE: - if(n >= maxLocals) maxLocals = n + 1; - if(n >= 0 && n <= 3) { + if (n >= maxLocals) maxLocals = n + 1; + if (n >= 0 && n <= 3) { byte base = 0; switch(op) { case ILOAD: base = ILOAD_0; break; @@ -499,36 +429,32 @@ public class MethodGen implements CGConst { return; case LDC: // set(int, byte, int) always handles these opts itself - if(arg instanceof Integer) { set(pos, op, ((Integer)arg).intValue()); return; } - if(arg instanceof Boolean) { set(pos, op, ((Boolean)arg).booleanValue()); return; } + if (arg instanceof Integer) { set(pos, op, ((Integer)arg).intValue()); return; } + if (arg instanceof Boolean) { set(pos, op, ((Boolean)arg).booleanValue()); return; } - if(arg instanceof Long) { + if (arg instanceof Long) { long l = ((Long)arg).longValue(); - if(l == 0L || l == 1L) { + if (l == 0L || l == 1L) { this.op[pos] = l == 0L ? LCONST_0 : LCONST_1; this.arg[pos] = null; return; } op = LDC2_W; - } else if(arg instanceof Double) { + } else if (arg instanceof Double) { op = LDC2_W; } break; } - if((OP_DATA[op&0xff]&OP_VALID_FLAG) == 0) throw new IllegalArgumentException("unknown bytecode"); + if ((OP_DATA[op&0xff]&OP_VALID_FLAG) == 0) throw new IllegalArgumentException("unknown bytecode"); this.op[pos] = op; this.arg[pos] = arg; } - /** This class represents the arguments to the TABLESWITH and LOOKUPSWITCH bytecodes - @see MethodGen.TSI - @see MethodGen.LSI - */ - public static abstract class SI { + public static abstract class Switch { public final Object[] targets; public Object defaultTarget; - SI(int size) { targets = new Object[size]; } + Switch(int size) { targets = new Object[size]; } public void setTarget(int pos, Object val) { targets[pos] = val; } public void setTarget(int pos, int val) { targets[pos] = N(val); } public void setDefaultTarget(int val) { setDefaultTarget(N(val)); } @@ -539,33 +465,31 @@ public class MethodGen implements CGConst { public int getDefaultTarget() { return ((Integer)defaultTarget).intValue(); } abstract int length(); - } - /** This class represents the arguments to the TABLESWITCH bytecode */ - public static class TSI extends SI { - public final int lo; - public final int hi; - public TSI(int lo, int hi) { - super(hi-lo+1); - this.lo = lo; - this.hi = hi; + public static class Table extends Switch { + public final int lo; + public final int hi; + public Table(int lo, int hi) { + super(hi-lo+1); + this.lo = lo; + this.hi = hi; + } + public void setTargetForVal(int val, Object o) { setTarget(val-lo, o); } + public void setTargetForVal(int val, int n) { setTarget(val-lo, n); } + + int length() { return 12 + targets.length * 4; } // 4bytes/target, hi, lo, default } - public void setTargetForVal(int val, Object o) { setTarget(val-lo, o); } - public void setTargetForVal(int val, int n) { setTarget(val-lo, n); } - - int length() { return 12 + targets.length * 4; } // 4bytes/target, hi, lo, default - } - /** This class represents the arguments to the LOOKUPSWITCH bytecode */ - public static class LSI extends SI { - public final int[] vals; - public LSI(int size) { - super(size); - this.vals = new int[size]; + public static class Lookup extends Table { + public final int[] vals; + public Lookup(int size) { + super(size); + this.vals = new int[size]; + } + public final void setVal(int pos, int val) { vals[pos] = val; } + + int length() { return 8 + targets.length * 8; } // key/val per target, default, count } - public final void setVal(int pos, int val) { vals[pos] = val; } - - int length() { return 8 + targets.length * 8; } // key/val per target, default, count } /** This class represents the arguments to byecodes that take two integer arguments. */ @@ -606,13 +530,13 @@ public class MethodGen implements CGConst { for(Enumeration e = thrownExceptions.keys();e.hasMoreElements();) cp.add(e.nextElement()); - if(size == NO_CODE) return; + if (size == NO_CODE) return; for(int i=0;i 0) attrs.put("Exceptions",""); + if ((flags & (NATIVE|ABSTRACT))==0) attrs.put("Code",""); + if (thrownExceptions.size() > 0) attrs.put("Exceptions",""); attrs.finish(cp); codeAttrs.finish(cp); @@ -648,14 +572,14 @@ public class MethodGen implements CGConst { private Object resolveTarget(Object arg) { int target; - if(arg instanceof PhantomTarget) { + if (arg instanceof PhantomTarget) { target = ((PhantomTarget)arg).getTarget(); - if(target == -1) throw new IllegalStateException("unresolved phantom target"); + if (target == -1) throw new IllegalStateException("unresolved phantom target"); arg = N(target); } else { target = ((Integer)arg).intValue(); } - if(target < 0 || target >= size) + if (target < 0 || target >= size) throw new IllegalStateException("invalid target address " + target + "/" + size); return arg; } @@ -683,7 +607,7 @@ public class MethodGen implements CGConst { int j; maxpc[i] = p; - if((opdata & OP_BRANCH_FLAG)!= 0) { + if ((opdata & OP_BRANCH_FLAG)!= 0) { try { arg[i] = resolveTarget(arg[i]); } catch(RuntimeException e) { @@ -697,24 +621,24 @@ public class MethodGen implements CGConst { case GOTO: case JSR: { int arg = ((Integer)this.arg[i]).intValue(); - if(arg < i && p - maxpc[arg] <= 32768) p += 3; + if (arg < i && p - maxpc[arg] <= 32768) p += 3; else p += 5; continue; } case NOP: - if(EMIT_NOPS) p++; + if (EMIT_NOPS) p++; continue; case LOOKUPSWITCH: case TABLESWITCH: { - SI si = (SI) arg[i]; + Switch si = (Switch) arg[i]; Object[] targets = si.targets; for(j=0;j 255) { + if (arg > 255) { this.op[i] = WIDE; this.arg[i] = new Wide(op, arg); p += 4; @@ -737,7 +661,7 @@ public class MethodGen implements CGConst { } case IINC: { Pair pair = (Pair) this.arg[i]; - if(pair.i1 > 255 || pair.i2 < -128 || pair.i2 > 127) { + if (pair.i1 > 255 || pair.i2 < -128 || pair.i2 > 127) { this.op[i] = WIDE; this.arg[i] = new Wide(IINC, pair.i1, pair.i2); p += 6; @@ -747,7 +671,7 @@ public class MethodGen implements CGConst { } case LDC: j = cp.getIndex(cparg[i]); - if(j >= 256) { + if (j >= 256) { this.op[i] = op = LDC_W; p += 3; continue; @@ -755,7 +679,7 @@ public class MethodGen implements CGConst { break; default: } - if((j = (opdata&OP_ARG_LENGTH_MASK)) == 7) throw new Error("shouldn't be here " + Integer.toString(op&0xff,16)); + if ((j = (opdata&OP_ARG_LENGTH_MASK)) == 7) throw new Error("shouldn't be here " + Integer.toString(op&0xff,16)); p += 1 + j; } @@ -766,7 +690,7 @@ public class MethodGen implements CGConst { case JSR: { int arg = ((Integer)this.arg[i]).intValue(); int diff = maxpc[arg] - maxpc[i]; - if(diff < -32768 || diff > 32767) + if (diff < -32768 || diff > 32767) op[i] = op[i] == GOTO ? GOTO_W : JSR_W; break; } @@ -779,15 +703,15 @@ public class MethodGen implements CGConst { pc[i] = p; switch(op) { case NOP: - if(EMIT_NOPS) p++; + if (EMIT_NOPS) p++; break; case TABLESWITCH: case LOOKUPSWITCH: { - SI si = (SI) arg[i]; + Switch si = (Switch) arg[i]; p++; // opcode itself p = (p + 3) & ~3; // padding p += 4; // default - if(op == TABLESWITCH) p += 4 + 4 + si.size() * 4; // lo, hi, targets + if (op == TABLESWITCH) p += 4 + 4 + si.size() * 4; // lo, hi, targets else p += 4 + si.size() * 4 * 2; // count, key, val * targets break; } @@ -796,14 +720,14 @@ public class MethodGen implements CGConst { break; default: { int l = OP_DATA[op&0xff] & OP_ARG_LENGTH_MASK; - if(l == 7) throw new Error("shouldn't be here"); + if (l == 7) throw new Error("shouldn't be here"); p += 1 + l; } } } int codeSize = p; - if(codeSize >= 65536) throw new ClassFile.Exn("method too large in size"); + if (codeSize >= 65536) throw new ClassFile.Exn("method too large in size"); o.writeShort(maxStack); o.writeShort(maxLocals); @@ -813,11 +737,11 @@ public class MethodGen implements CGConst { for(i=0;i 255 || pair.i2 < -128 || pair.i2 > 127) throw new ClassFile.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; } case TABLESWITCH: case LOOKUPSWITCH: { - SI si = (SI) arg; + Switch si = (Switch) arg; int mypc = pc[i]; for(p = pc[i]+1;(p&3)!=0;p++) o.writeByte(0); o.writeInt(pc[si.getDefaultTarget()] - mypc); - if(op == LOOKUPSWITCH) { - int[] vals = ((LSI)si).vals; + if (op == LOOKUPSWITCH) { + int[] vals = ((Switch.Lookup)si).vals; o.writeInt(si.size()); for(int j=0;j= 256) throw new ClassFile.Exn("overflow of dimensions in multianewarray"); + if (v >= 256) throw new ClassFile.Exn("overflow of dimensions in multianewarray"); o.writeByte(v); break; } @@ -871,30 +795,30 @@ public class MethodGen implements CGConst { o.writeByte(0); break; default: - if((opdata & OP_BRANCH_FLAG) != 0) { + if ((opdata & OP_BRANCH_FLAG) != 0) { int v = pc[((Integer)arg).intValue()] - pc[i]; - if(argLength == 2) { - if(v < -32768 || v > 32767) throw new ClassFile.Exn("overflow of s2 offset"); + if (argLength == 2) { + if (v < -32768 || v > 32767) throw new ClassFile.Exn("overflow of s2 offset"); o.writeShort(v); - } else if(argLength == 4) { + } else if (argLength == 4) { o.writeInt(v); } else { throw new Error("should never happen"); } - } else if((opdata & OP_CPENT_FLAG) != 0) { + } else if ((opdata & OP_CPENT_FLAG) != 0) { int v = cp.getIndex(cparg[i]); - if(argLength == 1) o.writeByte(v); - else if(argLength == 2) o.writeShort(v); + if (argLength == 1) o.writeByte(v); + else if (argLength == 2) o.writeShort(v); else throw new Error("should never happen"); - } else if(argLength == 7) { + } else if (argLength == 7) { throw new Error("should never happen - variable length instruction not explicitly handled"); } else { int iarg = ((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"); + if (argLength == 1) { + if ((opdata & OP_UNSIGNED_FLAG) != 0 ? iarg >= 256 : (iarg < -128 || iarg >= 128)) throw new ClassFile.Exn("overflow of s/u1 option"); o.writeByte(iarg); - } else if(argLength == 2) { - if((opdata & OP_UNSIGNED_FLAG) != 0 ? iarg >= 65536 : (iarg < -32768 || iarg >= 32768)) throw new ClassFile.Exn("overflow of s/u2 option"); + } else if (argLength == 2) { + if ((opdata & OP_UNSIGNED_FLAG) != 0 ? iarg >= 65536 : (iarg < -32768 || iarg >= 32768)) throw new ClassFile.Exn("overflow of s/u2 option"); o.writeShort(iarg); } else { throw new Error("should never happen"); @@ -904,7 +828,7 @@ public class MethodGen implements CGConst { } } - //if(baos.size() - 8 != codeSize) throw new Error("we didn't output what we were supposed to"); + //if (baos.size() - 8 != codeSize) throw new Error("we didn't output what we were supposed to"); o.writeShort(exnTable.size()); for(i=0;i 0) { + if (thrownExceptions.size() > 0) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream o = new DataOutputStream(baos); o.writeShort(thrownExceptions.size()); @@ -930,7 +854,7 @@ public class MethodGen implements CGConst { } void dump(DataOutput o, ConstantPool cp) throws IOException { - if((flags & (NATIVE|ABSTRACT))==0) generateCode(cp); + if ((flags & (NATIVE|ABSTRACT))==0) generateCode(cp); generateExceptions(cp); o.writeShort(flags); @@ -1007,4 +931,85 @@ public class MethodGen implements CGConst { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }; + + // Debugging ////////////////////////////////////////////////////////////////////////////// + + public void debugToString(StringBuffer sb, String constructorName) { + // This is intentionally a local variable so it can be removed by gcclass + final String[] OP_NAMES = new String[]{ + "nop", "aconst_null", "iconst_m1", "iconst_0", "iconst_1", "iconst_2", + "iconst_3", "iconst_4", "iconst_5", "lconst_0", "lconst_1", "fconst_0", + "fconst_1", "fconst_2", "dconst_0", "dconst_1", "bipush", "sipush", + "ldc", "ldc_w", "ldc2_w", "iload", "lload", "fload", + "dload", "aload", "iload_0", "iload_1", "iload_2", "iload_3", + "lload_0", "lload_1", "lload_2", "lload_3", "fload_0", "fload_1", + "fload_2", "fload_3", "dload_0", "dload_1", "dload_2", "dload_3", + "aload_0", "aload_1", "aload_2", "aload_3", "iaload", "laload", + "faload", "daload", "aaload", "baload", "caload", "saload", + "istore", "lstore", "fstore", "dstore", "astore", "istore_0", + "istore_1", "istore_2", "istore_3", "lstore_0", "lstore_1", "lstore_2", + "lstore_3", "fstore_0", "fstore_1", "fstore_2", "fstore_3", "dstore_0", + "dstore_1", "dstore_2", "dstore_3", "astore_0", "astore_1", "astore_2", + "astore_3", "iastore", "lastore", "fastore", "dastore", "aastore", + "bastore", "castore", "sastore", "pop", "pop2", "dup", + "dup_x1", "dup_x2", "dup2", "dup2_x1", "dup2_x2", "swap", + "iadd", "ladd", "fadd", "dadd", "isub", "lsub", + "fsub", "dsub", "imul", "lmul", "fmul", "dmul", + "idiv", "ldiv", "fdiv", "ddiv", "irem", "lrem", + "frem", "drem", "ineg", "lneg", "fneg", "dneg", + "ishl", "lshl", "ishr", "lshr", "iushr", "lushr", + "iand", "land", "ior", "lor", "ixor", "lxor", + "iinc", "i2l", "i2f", "i2d", "l2i", "l2f", + "l2d", "f2i", "f2l", "f2d", "d2i", "d2l", + "d2f", "i2b", "i2c", "i2s", "lcmp", "fcmpl", + "fcmpg", "dcmpl", "dcmpg", "ifeq", "ifne", "iflt", + "ifge", "ifgt", "ifle", "if_icmpeq", "if_icmpne", "if_icmplt", + "if_icmpge", "if_icmpgt", "if_icmple", "if_acmpeq", "if_acmpne", "goto", + "jsr", "ret", "tableswitch", "lookupswitch", "ireturn", "lreturn", + "freturn", "dreturn", "areturn", "return", "getstatic", "putstatic", + "getfield", "putfield", "invokevirtual", "invokespecial", "invokestatic", "invokeinterface", + "", "new", "newarray", "anewarray", "arraylength", "athrow", + "checkcast", "instanceof", "monitorenter", "monitorexit", "wide", "multianewarray", + "ifnull", "ifnonnull", "goto_w", "jsr_w", "", "", + "", "", "", "", "", "", + "", "", "", "", "", "", + "", "", "", "", "", "", + "", "", "", "", "", "", + "", "", "", "", "", "", + "", "", "", "", "", "", + "", "", "", "", "", "", + "", "", "", "", "", "", + "", "", "", "" + }; + + sb.append(" ").append(ClassFile.flagsToString(flags,false)); + sb.append(method.debugToString()); + if (thrownExceptions.size() > 0) { + sb.append("throws"); + for(Enumeration e = thrownExceptions.keys();e.hasMoreElements();) + sb.append(" ").append(((Type.Class)e.nextElement()).debugToString()).append(","); + sb.setLength(sb.length()-1); + sb.append(" "); + } + if ((flags & (NATIVE|ABSTRACT))==0) { + sb.append("{\n"); + for(int i=0;i