X-Git-Url: http://git.megacz.com/?p=org.ibex.classgen.git;a=blobdiff_plain;f=src%2Forg%2Fibex%2Fclassgen%2FJSSA.java;h=16af019a09d6d6ed757df99ae0fbdce7ad38d801;hp=090fc974cad98c5fa942e56cf2008183bd9e3c93;hb=4b586655926ec3807715ede09e642f050c336f79;hpb=ca09a8a35d494bff3fc0cf1ea112521980515a5e diff --git a/src/org/ibex/classgen/JSSA.java b/src/org/ibex/classgen/JSSA.java index 090fc97..16af019 100644 --- a/src/org/ibex/classgen/JSSA.java +++ b/src/org/ibex/classgen/JSSA.java @@ -13,56 +13,39 @@ public class JSSA extends MethodGen implements CGConst { public JSSA(Type.Class c, DataInput in, ConstantPool cp) throws IOException { super(c, in, cp); - local = new Expr[maxLocals]; - stack = new Expr[maxStack]; - for(int i=0; i="); } } public class Le extends PrimitiveComparison { public Le(Expr e1, Expr e2) { super(e1, e2, "<="); } } + + // Math Operations ////////////////////////////////////////////////////////////////////////////// public class BinMath extends BinExpr { public BinMath(Expr e1, Expr e2, String show) { super(e2, e1, show); - if(e1.getType() != e2.getType()) throw new IllegalArgumentException("types disagree"); + if (e1.getType() != e2.getType()) throw new IllegalArgumentException("types disagree"); } public Type getType() { return e1.getType(); } } @@ -239,8 +295,8 @@ public class JSSA extends MethodGen implements CGConst { public BitShiftExpr(Expr e1, Expr e2, String show) { super(e1,e2,show); Type t = e1.getType(); - if(t != Type.INT && t != Type.LONG) throw new IllegalArgumentException("type mismatch"); - if(e2.getType() != Type.INT) throw new IllegalArgumentException("type mismatch"); + if (t != Type.INT && t != Type.LONG) throw new IllegalArgumentException("type mismatch"); + if (e2.getType() != Type.INT) throw new IllegalArgumentException("type mismatch"); } public Type getType() { return e1.getType(); } } @@ -248,13 +304,14 @@ public class JSSA extends MethodGen implements CGConst { public class Shr extends BitShiftExpr { public Shr(Expr e, Expr e2) { super(e, e2, ">>"); } } public class Ushr extends BitShiftExpr { public Ushr(Expr e, Expr e2) { super(e, e2, ">>>"); } } + // Other operations ////////////////////////////////////////////////////////////////////////////// public class Cast extends Expr { final Expr e; final Type t; public Cast(Expr e, Type t) { - if(e.getType().isRef() != t.isRef()) throw new IllegalArgumentException("invalid cast"); + if (e.getType().isRef() != t.isRef()) throw new IllegalArgumentException("invalid cast"); // FEATURE: Check that one is a subclass of the other if it is a ref this.e = e; this.t = t; @@ -266,7 +323,7 @@ public class JSSA extends MethodGen implements CGConst { final Expr e; final Type.Ref t; public InstanceOf(Expr e, Type.Ref t) { - if(!e.getType().isRef()) throw new IllegalArgumentException("can't do an instanceof check on a non-ref"); + if (!e.getType().isRef()) throw new IllegalArgumentException("can't do an instanceof check on a non-ref"); this.e = e; this.t = t; } @@ -276,7 +333,7 @@ public class JSSA extends MethodGen implements CGConst { public class Throw extends Op { public final Expr e; public Throw(Expr e) { - if(!e.getType().isRef()) throw new IllegalArgumentException("can't throw a non ref"); + if (!e.getType().isRef()) throw new IllegalArgumentException("can't throw a non ref"); // FEATURE: CHeck that it is a subclass of Throwable this.e = e; } @@ -305,6 +362,7 @@ public class JSSA extends MethodGen implements CGConst { public final Type.Class t; public Type getType() { return t; } public New(Type.Class t) { this.t = t; } + public String _toString() { return "new " + t + "()"; } } public class NewArray extends Expr { @@ -313,12 +371,28 @@ public class JSSA extends MethodGen implements CGConst { public NewArray(Type.Array t, Expr[] dims) { this.t = t; this.dims = dims; } public NewArray(Type.Array t, Expr dim) { this(t,new Expr[]{dim}); } public Type getType() { return t; } + public String _toString() { + Type base = t; + int totalDims = 0; + while(base.isArray()) { + totalDims++; + base = base.asArray().getElementType(); + } + StringBuffer sb = new StringBuffer("new " + base); + for(int i=0;i") ? "super" : method.name); - args(sb); - return sb.toString(); - } + public String _toString() { return _toString(method.name.equals("") + ? method.getDeclaringClass().getName() + : method.name); } } - public class InvokeInterface extends InvokeVirtual{public InvokeInterface(Type.Class.Method m, Expr[] a, Expr e){super(m,a,e);}} + public class InvokeInterface extends InvokeVirtual{ + public InvokeInterface(Type.Class.Method m, Expr[] a, Expr e) { super(m,a,e); } } public class InvokeVirtual extends Invoke { public final Expr instance; public InvokeVirtual(Type.Class.Method m, Expr[] a, Expr e) { super(m, a); instance = e; } - public String toString() { + public String _toString() { return _toString(method.name); } + protected String _toString(String name) { StringBuffer sb = new StringBuffer(); - sb.append(method.name); + sb.append(instance+"."); + sb.append(name); args(sb); return sb.toString(); } @@ -423,8 +499,9 @@ public class JSSA extends MethodGen implements CGConst { private final Object o; public Constant(int i) { this(new Integer(i)); } public Constant(Object o) { this.o = o; } - public String toString() { return o.toString(); } + public String toString() { return o == null ? "null" : o instanceof String ? "\"" + o + "\"" : o.toString(); } public Type getType() { + if (o == null) return Type.NULL; if (o instanceof Byte) return Type.BYTE; if (o instanceof Short) return Type.SHORT; if (o instanceof Character) return Type.CHAR; @@ -432,8 +509,9 @@ public class JSSA extends MethodGen implements CGConst { if (o instanceof Long) return Type.LONG; if (o instanceof Double) return Type.DOUBLE; if (o instanceof Float) return Type.FLOAT; - if (o instanceof ConstantPool.Ent) throw new Error("unimplemented"); - throw new Error("this should not happen"); + if (o instanceof Integer) return Type.INT; + if (o instanceof String) return Type.STRING; + throw new IllegalStateException("unknown constant type"); } } @@ -462,28 +540,33 @@ public class JSSA extends MethodGen implements CGConst { // Stack manipulations ////////////////////////////////////////////////////////////////////////////// - case ACONST_NULL: return stack[sp++] = new Constant(null); - case ICONST_M1: return stack[sp++] = new Constant(-1); - case ICONST_0: case LCONST_0: case FCONST_0: case DCONST_0: push(new Constant(0)); return null; - case ICONST_1: case LCONST_1: case FCONST_1: case DCONST_1: push(new Constant(1)); return null; - case ICONST_2: case FCONST_2: push(new Constant(2)); return null; - case ICONST_3: push(new Constant(3)); return null; - case ICONST_4: push(new Constant(4)); return null; - case ICONST_5: push(new Constant(5)); return null; - case ILOAD: case LLOAD: case FLOAD: case DLOAD: case ALOAD: return push(local[i1]); - case ILOAD_0: case LLOAD_0: case FLOAD_0: case DLOAD_0: case ALOAD_0: return push(local[0]); - case ILOAD_1: case LLOAD_1: case FLOAD_1: case DLOAD_1: case ALOAD_1: return push(local[1]); - case ALOAD_2: case DLOAD_2: case FLOAD_2: case LLOAD_2: case ILOAD_2: return push(local[2]); - case ILOAD_3: case LLOAD_3: case FLOAD_3: case DLOAD_3: case ALOAD_3: return push(local[3]); - case ISTORE: case LSTORE: case FSTORE: case DSTORE: case ASTORE: local[i1] = pop(); return null; - case ISTORE_0: case LSTORE_0: case FSTORE_0: case DSTORE_0: case ASTORE_0: local[0] = pop(); return null; - case ISTORE_1: case LSTORE_1: case FSTORE_1: case DSTORE_1: case ASTORE_1: local[1] = pop(); return null; - case ASTORE_2: case DSTORE_2: case FSTORE_2: case LSTORE_2: case ISTORE_2: local[2] = pop(); return null; - case ISTORE_3: case LSTORE_3: case FSTORE_3: case DSTORE_3: case ASTORE_3: local[3] = pop(); return null; - case POP: stack[--sp] = null; - case POP2: stack[--sp] = null; stack[--sp] = null; /** fixme: pops a WORD, not an item */ - case DUP: stack[sp] = stack[sp-1]; sp++; - case DUP2: stack[sp] = stack[sp-2]; stack[sp+1] = stack[sp-1]; sp+=2; + case ACONST_NULL: push(new Constant(null)); return null; + case ICONST_M1: push(new Constant(-1)); return null; + case ICONST_0: case LCONST_0: case FCONST_0: case DCONST_0: push(new Constant(0)); return null; + case ICONST_1: case LCONST_1: case FCONST_1: case DCONST_1: push(new Constant(1)); return null; + case ICONST_2: case FCONST_2: push(new Constant(2)); return null; + case ICONST_3: push(new Constant(3)); return null; + case ICONST_4: push(new Constant(4)); return null; + case ICONST_5: push(new Constant(5)); return null; + case ILOAD: case LLOAD: case FLOAD: case DLOAD: case ALOAD: push(locals[pc][i1]); return null; + case ILOAD_0: case LLOAD_0: case FLOAD_0: case DLOAD_0: case ALOAD_0: push(locals[pc][0]); return null; + case ILOAD_1: case LLOAD_1: case FLOAD_1: case DLOAD_1: case ALOAD_1: push(locals[pc][1]); return null; + case ALOAD_2: case DLOAD_2: case FLOAD_2: case LLOAD_2: case ILOAD_2: push(locals[pc][2]); return null; + case ILOAD_3: case LLOAD_3: case FLOAD_3: case DLOAD_3: case ALOAD_3: push(locals[pc][3]); return null; + case ISTORE: case LSTORE: case FSTORE: case DSTORE: case ASTORE: + locals[pc+1][i1].merge(pop()); return null; + case ISTORE_0: case LSTORE_0: case FSTORE_0: case DSTORE_0: case ASTORE_0: + locals[pc+1][0].merge(pop()); return null; + case ISTORE_1: case LSTORE_1: case FSTORE_1: case DSTORE_1: case ASTORE_1: + locals[pc+1][1].merge(pop()); return null; + case ASTORE_2: case DSTORE_2: case FSTORE_2: case LSTORE_2: case ISTORE_2: + locals[pc+1][2].merge(pop()); return null; + case ISTORE_3: case LSTORE_3: case FSTORE_3: case DSTORE_3: case ASTORE_3: + locals[pc+1][3].merge(pop()); return null; + case POP: pop(); return null; + case POP2: pop(); pop(); return null; + case DUP: push(stacks[pc][sps[pc]-1]); return null; + case DUP2: push(stacks[pc][sps[pc]-2]); push(stacks[pc][sps[pc]-1]); return null; // Conversions ////////////////////////////////////////////////////////////////////////////// @@ -501,19 +584,19 @@ public class JSSA extends MethodGen implements CGConst { // Math ////////////////////////////////////////////////////////////////////////////// - case IADD: case LADD: case FADD: case DADD: push(new Add(pop(), pop())); return null; - case ISUB: case LSUB: case FSUB: case DSUB: push(new Sub(pop(), pop())); return null; - case IMUL: case LMUL: case FMUL: case DMUL: push(new Mul(pop(), pop())); return null; - case IREM: case LREM: case FREM: case DREM: push(new Rem(pop(), pop())); return null; - //case INEG: case LNEG: case FNEG: case DNEG: push(new Neg(pop())); return null; - case IDIV: case LDIV: case FDIV: case DDIV: push(new Div(pop(), pop())); return null; - case ISHL: case LSHL: push(new Shl(pop(), pop())); return null; - case ISHR: case LSHR: push(new Shr(pop(), pop())); return null; + case IADD: case LADD: case FADD: case DADD: push(new Add(pop(), pop())); return null; + case ISUB: case LSUB: case FSUB: case DSUB: push(new Sub(pop(), pop())); return null; + case IMUL: case LMUL: case FMUL: case DMUL: push(new Mul(pop(), pop())); return null; + case IREM: case LREM: case FREM: case DREM: push(new Rem(pop(), pop())); return null; + case INEG: case LNEG: case FNEG: case DNEG: push(new Neg(pop())); return null; + case IDIV: case LDIV: case FDIV: case DDIV: push(new Div(pop(), pop())); return null; + case ISHL: case LSHL: push(new Shl(pop(), pop())); return null; + case ISHR: case LSHR: push(new Shr(pop(), pop())); return null; case IUSHR: case LUSHR: push(new Ushr(pop(), pop())); return null; - case IAND: case LAND: push(new And(pop(), pop())); return null; - case IOR: case LOR: push(new Or(pop(), pop())); return null; - case IXOR: case LXOR: push(new Xor(pop(), pop())); return null; - case IINC: return local[i1] = new Add(local[i1], new Constant(i2)); + case IAND: case LAND: push(new And(pop(), pop())); return null; + case IOR: case LOR: push(new Or(pop(), pop())); return null; + case IXOR: case LXOR: push(new Xor(pop(), pop())); return null; + case IINC: return locals[pc+1][i1] = phi(new Add(locals[pc][i1], new Constant(i2))); // Control and branching ////////////////////////////////////////////////////////////////////////////// @@ -544,9 +627,11 @@ public class JSSA extends MethodGen implements CGConst { // Array manipulations ////////////////////////////////////////////////////////////////////////////// case IALOAD: case LALOAD: case FALOAD: case DALOAD: case AALOAD: - case BALOAD: case CALOAD: case SALOAD: push(new ArrayGet(pop(), pop())); return null; + case BALOAD: case CALOAD: case SALOAD: + return seqPush(new ArrayGet(pop(), pop())); case IASTORE: case LASTORE: case FASTORE: case DASTORE: case AASTORE: - case BASTORE: case CASTORE: case SASTORE: return new ArrayPut(pop(), pop(), pop()); + case BASTORE: case CASTORE: case SASTORE: + return new ArrayPut(pop(), pop(), pop()); // Invocation ////////////////////////////////////////////////////////////////////////////// @@ -554,64 +639,52 @@ public class JSSA extends MethodGen implements CGConst { Type.Class.Method method = (Type.Class.Method)arg; Expr args[] = new Expr[method.getNumArgs()]; for(int i=0; i