cleanup POP/DUP
[org.ibex.classgen.git] / src / org / ibex / classgen / JSSA.java
index e608b42..d6c15b7 100644 (file)
@@ -435,8 +435,8 @@ 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;
+            throw new IllegalStateException("unknown constant type");
         }
     }
 
@@ -483,10 +483,10 @@ public class JSSA extends MethodGen implements CGConst {
             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 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 //////////////////////////////////////////////////////////////////////////////
 
@@ -557,12 +557,16 @@ 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<args.length; i++) args[args.length-i-1] = pop();
+                Expr ret;
                 switch(op) {
-                    case INVOKEVIRTUAL:   return push(new InvokeVirtual(method, args, pop()));
-                    case INVOKEINTERFACE: return push(new InvokeInterface(method, args, pop()));
-                    case INVOKESPECIAL:   return push(new InvokeSpecial(method, args, pop()));
-                    case INVOKESTATIC:    return push(new InvokeStatic(method, args));
+                    case INVOKEVIRTUAL:   ret = new InvokeVirtual(method, args, pop()); break;
+                    case INVOKEINTERFACE: ret = new InvokeInterface(method, args, pop()); break;
+                    case INVOKESPECIAL:   ret = new InvokeSpecial(method, args, pop()); break;
+                    case INVOKESTATIC:    ret = new InvokeStatic(method, args); break;
+                    default: throw new Error("should never happen");
                 }
+                if(ret.getType() != Type.VOID) push(ret);
+                return ret;
             }
 
                 // Field Access //////////////////////////////////////////////////////////////////////////////