X-Git-Url: http://git.megacz.com/?p=org.ibex.classgen.git;a=blobdiff_plain;f=src%2Forg%2Fibex%2Fclassgen%2FJSSA.java;h=2fc521ace03c227e2eec2ee45040f42d2af51988;hp=6cf8d07edb613141ffc76006ea96593d6edaeca2;hb=7b7d64efd6761d48aabe652945e907e9309bccd0;hpb=9271b834f0f1ca988f0374cad6a8cc0cce274ee0 diff --git a/src/org/ibex/classgen/JSSA.java b/src/org/ibex/classgen/JSSA.java index 6cf8d07..2fc521a 100644 --- a/src/org/ibex/classgen/JSSA.java +++ b/src/org/ibex/classgen/JSSA.java @@ -13,29 +13,51 @@ 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]; - int n=0; - if (!isStatic()) - local[n++] = new Argument("this",method.getDeclaringClass()); - for(int i=0;i="); } } public class Le extends PrimitiveComparison { public Le(Expr e1, Expr e2) { super(e1, e2, "<="); } } + // Math Operations ////////////////////////////////////////////////////////////////////////////// @@ -212,7 +294,8 @@ public class JSSA extends MethodGen implements CGConst { 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() != null && e2.getType() != null && e1.getType() != e2.getType()) + throw new IllegalArgumentException("types disagree"); } public Type getType() { return e1.getType(); } } @@ -265,7 +348,24 @@ public class JSSA extends MethodGen implements CGConst { public Type getType() { return Type.BOOLEAN; } } - public class Throw extends Op { + public class Branch extends Op { + Expr destination = null; + public Branch(Expr destination) { this.destination = destination; } + public Branch(MethodGen.Switch s) { /* FIXME */ } + public Branch() { } + public void branchTo() { if (destination != null) branchTo(destination); } + private void branchTo(Expr e) { + if (e instanceof Phi) { + Phi phi = (Phi)e; + for(int i=0; i>"; } } public class New extends Expr { @@ -320,17 +440,6 @@ public class JSSA extends MethodGen implements CGConst { } } - public class Return extends Op { - final Expr e; - public Return() { this(VOID_EXPR); } - public Return(Expr e) { - this.e = e; - if (Type.unify(method.getReturnType(),e.getType()) != method.getReturnType()) - throw new IllegalArgumentException("type mismatch"); - } - public String toString() { return e.getType() == Type.VOID ? "return" : ("return "+e.toString()); } - } - /** GETFIELD and GETSTATIC */ public class Get extends Expr { final Type.Class.Field f; @@ -434,7 +543,7 @@ 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 == null ? "null" : o instanceof String ? "\"" + o + "\"" : 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; @@ -469,6 +578,8 @@ public class JSSA extends MethodGen implements CGConst { i1 = p.i1; i2 = p.i2; } + if (arg instanceof Number) i1 = ((Integer)arg).intValue(); + Label label = (arg instanceof Label) ? (Label)arg : null; switch(op) { case NOP: return null; @@ -483,20 +594,25 @@ public class JSSA extends MethodGen implements CGConst { 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(local[i1]); return null; - case ILOAD_0: case LLOAD_0: case FLOAD_0: case DLOAD_0: case ALOAD_0: push(local[0]); return null; - case ILOAD_1: case LLOAD_1: case FLOAD_1: case DLOAD_1: case ALOAD_1: push(local[1]); return null; - case ALOAD_2: case DLOAD_2: case FLOAD_2: case LLOAD_2: case ILOAD_2: push(local[2]); return null; - case ILOAD_3: case LLOAD_3: case FLOAD_3: case DLOAD_3: case ALOAD_3: push(local[3]); return null; - 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 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(stack[sp-1]); return null; - case DUP2: push(stack[sp-2]); push(stack[sp-2]); return null; + case DUP: push(stack[sp-1]); return null; + case DUP2: push(stack[sp-2]); push(stack[sp-1]); return null; // Conversions ////////////////////////////////////////////////////////////////////////////// @@ -526,31 +642,31 @@ public class JSSA extends MethodGen implements CGConst { 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 IINC: return locals[pc+1][i1] = phi(new Add(locals[pc][i1], new Constant(i2))); // Control and branching ////////////////////////////////////////////////////////////////////////////// - case IFNULL: return new Branch(new Eq(pop(), new Constant(null)), new Label(i1)); - case IFNONNULL: return new Branch(new Not(new Eq(pop(),new Constant(null))),new Label(i1)); - case IFEQ: return new Branch( new Eq(new Constant(0), pop()), arg); - case IFNE: return new Branch(new Not(new Eq(new Constant(0), pop())), arg); - case IFLT: return new Branch( new Lt(new Constant(0), pop()), arg); - case IFGE: return new Branch(new Not(new Lt(new Constant(0), pop())), arg); - case IFGT: return new Branch( new Gt(new Constant(0), pop()), arg); - case IFLE: return new Branch(new Not(new Gt(new Constant(0), pop())), arg); - case IF_ICMPEQ: return new Branch( new Eq(pop(), pop()), arg); - case IF_ICMPNE: return new Branch(new Not(new Eq(pop(), pop())), arg); - case IF_ICMPLT: return new Branch( new Lt(pop(), pop()), arg); - case IF_ICMPGE: return new Branch(new Not(new Lt(pop(), pop())), arg); - case IF_ICMPGT: return new Branch( new Gt(pop(), pop()), arg); - case IF_ICMPLE: return new Branch(new Not(new Gt(pop(), pop())), arg); - case IF_ACMPEQ: return new Branch( new Eq(pop(), pop()), arg); - case IF_ACMPNE: return new Branch(new Not(new Eq(pop(), pop())), arg); - case ATHROW: return new Throw(pop()); - case GOTO: return new Branch(new Label(i1)); - case JSR: return new JSR(new Label(i1)); - case RET: return new RET(); - case RETURN: return new Return(); + case IFNULL: return new If(new Eq(pop(), new Constant(null)), new Label(i1)); + case IFNONNULL: return new If(new Not(new Eq(pop(),new Constant(null))),new Label(i1)); + case IFEQ: return new If( new Eq(new Constant(0), pop()), new Label(i1)); + case IFNE: return new If(new Not(new Eq(new Constant(0), pop())), new Label(i1)); + case IFLT: return new If( new Lt(new Constant(0), pop()), new Label(i1)); + case IFGE: return new If(new Not(new Lt(new Constant(0), pop())), new Label(i1)); + case IFGT: return new If( new Gt(new Constant(0), pop()), new Label(i1)); + case IFLE: return new If(new Not(new Gt(new Constant(0), pop())), new Label(i1)); + case IF_ICMPEQ: return new If( new Eq(pop(), pop()), new Label(i1)); + case IF_ICMPNE: return new If(new Not(new Eq(pop(), pop())), new Label(i1)); + case IF_ICMPLT: return new If( new Lt(pop(), pop()), new Label(i1)); + case IF_ICMPGE: return new If(new Not(new Lt(pop(), pop())), new Label(i1)); + case IF_ICMPGT: return new If( new Gt(pop(), pop()), new Label(i1)); + case IF_ICMPLE: return new If(new Not(new Gt(pop(), pop())), new Label(i1)); + case IF_ACMPEQ: return new If( new Eq(pop(), pop()), new Label(i1)); + case IF_ACMPNE: return new If(new Not(new Eq(pop(), pop())), new Label(i1)); + case ATHROW: return new Throw(pop()); + case GOTO: return new Goto(locals[pc][i1]); + case JSR: push(new Label(pc)); return new JSR(new Label(i1)); + case RET: return new RET(pop()); + case RETURN: return new Return(); case IRETURN: case LRETURN: case FRETURN: case DRETURN: case ARETURN: return new Return(pop()); @@ -671,20 +787,6 @@ public class JSSA extends MethodGen implements CGConst { private Map bindingMap; private int nextVar; - String exprToString(Expr e) { - if (e instanceof Constant) return e._toString(); - String s = (String)bindingMap.get(e); - if (s != null) return s; - String prefix; - if (e.getType() == Type.VOID) return e._toString(); - else if (e.getType() == Type.DOUBLE || e.getType() == Type.FLOAT) prefix = "f"; - else if (e.getType().isPrimitive()) prefix = "i"; - else if (e.getType().isArray()) prefix = "a"; - else prefix = "o"; - s = prefix + (nextVar++); - bindingMap.put(e,s); - return "(" + s + " = " + e._toString() + ")"; - } public static void main(String[] args) throws Exception { InputStream is = Class.forName(args[0]).getClassLoader().getResourceAsStream(args[0].replace('.', '/')+".class");