lots of formatting, refactored out Type.fromArraySpec()
[org.ibex.classgen.git] / src / org / ibex / classgen / JSSA.java
index d14efef..6cf8d07 100644 (file)
@@ -53,15 +53,15 @@ public class JSSA extends MethodGen implements CGConst {
     private int sp = 0;
     
     private Expr push(Expr e) {
-        if(sp == stack.length) {
+        if (sp == stack.length) {
             for(int i=0;i<stack.length;i++) System.err.println("Stack " + i + ": " + stack[i]);
             throw new IllegalStateException("stack overflow (" + stack.length + ")");
         }
-        if(e.getType() == Type.VOID) throw new IllegalArgumentException("can't push a void");
+        if (e.getType() == Type.VOID) throw new IllegalArgumentException("can't push a void");
         return stack[sp++] = e;
     }
     private Expr pop() {
-        if(sp == 0) throw new IllegalStateException("stack underflow");
+        if (sp == 0) throw new IllegalStateException("stack underflow");
         return stack[--sp];
     }
     
@@ -109,7 +109,7 @@ public class JSSA extends MethodGen implements CGConst {
         public abstract Type getType();
         
         public final String toString() { return exprToString(this); }
-        public String _toString() { return super.toString(); } // Adam is going to hate me for this
+        public String _toString() { return super.toString(); } // Adam is going to hate me for this (yes; why is this here?)
     }
 
     /**
@@ -147,7 +147,7 @@ public class JSSA extends MethodGen implements CGConst {
     public class Not extends Expr {
         public final Expr e;
         public Not(Expr e) {
-            if(e.getType() != Type.BOOLEAN) throw new IllegalArgumentException("not needs a boolean expression");
+            if (e.getType() != Type.BOOLEAN) throw new IllegalArgumentException("not needs a boolean expression");
             this.e = e;
         }
         public Type getType() { return Type.BOOLEAN; }
@@ -157,7 +157,7 @@ public class JSSA extends MethodGen implements CGConst {
     public class Neg extends Expr {
         public final Expr e;
         public Neg(Expr e) {
-            if(!e.getType().isPrimitive()) throw new IllegalArgumentException("can only negate a primitive");
+            if (!e.getType().isPrimitive()) throw new IllegalArgumentException("can only negate a primitive");
             this.e = e;
         }
         public Type getType() { return e.getType(); }
@@ -185,9 +185,9 @@ public class JSSA extends MethodGen implements CGConst {
     public class Eq extends Comparison {
         public Eq(Expr e1, Expr e2) {
             super(e1, e2, "=="); 
-            if(e1.getType().isPrimitive() != e2.getType().isPrimitive())
+            if (e1.getType().isPrimitive() != e2.getType().isPrimitive())
                 throw new IllegalArgumentException("type mismatch");
-            if(e1.getType().isPrimitive() && e1.getType() != e2.getType())
+            if (e1.getType().isPrimitive() && e1.getType() != e2.getType())
                 throw new IllegalArgumentException("type mismatch");            
             // FEATURE: Check if we can compare these classes
         }
@@ -197,7 +197,7 @@ public class JSSA extends MethodGen implements CGConst {
     public class PrimitiveComparison extends Comparison {
         public PrimitiveComparison(Expr e1, Expr e2, String show) {
             super(e1, e2, show);
-            if(!e1.getType().isPrimitive() || e1.getType() != e2.getType()) throw new IllegalArgumentException("type mismatch");
+            if (!e1.getType().isPrimitive() || e1.getType() != e2.getType()) throw new IllegalArgumentException("type mismatch");
         }
     }
     
@@ -206,12 +206,13 @@ public class JSSA extends MethodGen implements CGConst {
     public class Ge extends PrimitiveComparison { public Ge(Expr e1, Expr e2) { super(e1, e2, ">="); } }
     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(); }
     }
@@ -229,8 +230,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(); }
     }
@@ -238,13 +239,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; 
@@ -256,7 +258,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; 
         }
@@ -266,7 +268,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; 
         }
@@ -323,7 +325,7 @@ public class JSSA extends MethodGen implements CGConst {
         public Return() { this(VOID_EXPR); }
         public Return(Expr e) {
             this.e = e; 
-            if(Type.unify(method.getReturnType(),e.getType()) != method.getReturnType())
+            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()); }
@@ -409,9 +411,12 @@ public class JSSA extends MethodGen implements CGConst {
     public class InvokeStatic    extends Invoke  { public InvokeStatic(Type.Class.Method m, Expr[] a) { super(m,a); } }
     public class InvokeSpecial   extends InvokeVirtual {
         public InvokeSpecial(Type.Class.Method m, Expr[] a, Expr e) { super(m,a,e); }
-        public String _toString() { return _toString(method.name.equals("<init>") ? method.getDeclaringClass().getName() : method.name); }
+        public String _toString() { return _toString(method.name.equals("<init>")
+                                                     ? 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; }
@@ -470,28 +475,28 @@ public class JSSA extends MethodGen implements CGConst {
 
                 // Stack manipulations //////////////////////////////////////////////////////////////////////////////
 
-            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(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 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 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(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 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;
 
                 // Conversions //////////////////////////////////////////////////////////////////////////////
 
@@ -509,18 +514,18 @@ 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 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));
 
                 // Control and branching //////////////////////////////////////////////////////////////////////////////
@@ -572,7 +577,7 @@ public class JSSA extends MethodGen implements CGConst {
                     case INVOKESTATIC:    ret = new InvokeStatic(method, args); break;
                     default: throw new Error("should never happen");
                 }
-                if(ret.getType() != Type.VOID) push(ret);
+                if (ret.getType() != Type.VOID) push(ret);
                 return new Seq(ret);
             }
 
@@ -586,21 +591,7 @@ public class JSSA extends MethodGen implements CGConst {
                 // Allocation //////////////////////////////////////////////////////////////////////////////
 
             case NEW:               push(new New((Type.Class)arg)); return null;
-            case NEWARRAY: {
-                Type base;
-                switch(((Integer)arg).intValue()) {
-                    case 4: base = Type.BOOLEAN; break;
-                    case 5: base = Type.CHAR; break;
-                    case 6: base = Type.FLOAT; break;
-                    case 7: base = Type.DOUBLE; break;
-                    case 8: base = Type.BYTE; break;
-                    case 9: base = Type.SHORT; break;
-                    case 10: base = Type.INT; break;
-                    case 11: base = Type.LONG; break;
-                    default: throw new IllegalStateException("invalid array type");
-                }
-                return seqPush(new NewArray(base.makeArray(),pop()));
-            }
+            case NEWARRAY:          return seqPush(new NewArray(Type.fromArraySpec(((Integer)arg).intValue()).makeArray(), pop()));
             case ANEWARRAY:         push(new NewArray(((Type.Ref)arg).makeArray(), pop())); return null;
             case MULTIANEWARRAY: {
                 MethodGen.MultiANewArray mana = (MethodGen.MultiANewArray) arg;
@@ -623,7 +614,7 @@ public class JSSA extends MethodGen implements CGConst {
             case TABLESWITCH:    return new Branch((MethodGen.Switch)arg);
             case LOOKUPSWITCH:   return new Branch((MethodGen.Switch)arg);
 
-                /*
+                /* FIXME
             case MONITORENTER:   Op.monitorEnter(pop());
             case MONITOREXIT:    Op.monitorExit(pop());
                 */
@@ -681,14 +672,14 @@ public class JSSA extends MethodGen implements CGConst {
     private Map bindingMap;
     private int nextVar;
     String exprToString(Expr e) {
-        if(e instanceof Constant) return e._toString();
+        if (e instanceof Constant) return e._toString();
         String s = (String)bindingMap.get(e);
-        if(s != null) return s;
+        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";
+        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);