Example #1
0
File: Frame.java Project: kevx/csp
 /**
  * Simulates the action of the given instruction on the output stack frame.
  *
  * @param opcode the opcode of the instruction.
  * @param arg the operand of the instruction, if any.
  * @param cw the class writer to which this label belongs.
  * @param item the operand of the instructions, if any.
  */
 void execute(final int opcode, final int arg, final ClassWriter cw, final Item item) {
   int t1, t2, t3, t4;
   switch (opcode) {
     case Opcodes.NOP:
     case Opcodes.INEG:
     case Opcodes.LNEG:
     case Opcodes.FNEG:
     case Opcodes.DNEG:
     case Opcodes.I2B:
     case Opcodes.I2C:
     case Opcodes.I2S:
     case Opcodes.GOTO:
     case Opcodes.RETURN:
       break;
     case Opcodes.ACONST_NULL:
       push(NULL);
       break;
     case Opcodes.ICONST_M1:
     case Opcodes.ICONST_0:
     case Opcodes.ICONST_1:
     case Opcodes.ICONST_2:
     case Opcodes.ICONST_3:
     case Opcodes.ICONST_4:
     case Opcodes.ICONST_5:
     case Opcodes.BIPUSH:
     case Opcodes.SIPUSH:
     case Opcodes.ILOAD:
       push(INTEGER);
       break;
     case Opcodes.LCONST_0:
     case Opcodes.LCONST_1:
     case Opcodes.LLOAD:
       push(LONG);
       push(TOP);
       break;
     case Opcodes.FCONST_0:
     case Opcodes.FCONST_1:
     case Opcodes.FCONST_2:
     case Opcodes.FLOAD:
       push(FLOAT);
       break;
     case Opcodes.DCONST_0:
     case Opcodes.DCONST_1:
     case Opcodes.DLOAD:
       push(DOUBLE);
       push(TOP);
       break;
     case Opcodes.LDC:
       switch (item.type) {
         case ClassWriter.INT:
           push(INTEGER);
           break;
         case ClassWriter.LONG:
           push(LONG);
           push(TOP);
           break;
         case ClassWriter.FLOAT:
           push(FLOAT);
           break;
         case ClassWriter.DOUBLE:
           push(DOUBLE);
           push(TOP);
           break;
         case ClassWriter.CLASS:
           push(OBJECT | cw.addType("java/lang/Class"));
           break;
         case ClassWriter.STR:
           push(OBJECT | cw.addType("java/lang/String"));
           break;
         case ClassWriter.MTYPE:
           push(OBJECT | cw.addType("java/lang/invoke/MethodType"));
           break;
           // case ClassWriter.MHANDLE_BASE + [1..9]:
         default:
           push(OBJECT | cw.addType("java/lang/invoke/MethodHandle"));
       }
       break;
     case Opcodes.ALOAD:
       push(get(arg));
       break;
     case Opcodes.IALOAD:
     case Opcodes.BALOAD:
     case Opcodes.CALOAD:
     case Opcodes.SALOAD:
       pop(2);
       push(INTEGER);
       break;
     case Opcodes.LALOAD:
     case Opcodes.D2L:
       pop(2);
       push(LONG);
       push(TOP);
       break;
     case Opcodes.FALOAD:
       pop(2);
       push(FLOAT);
       break;
     case Opcodes.DALOAD:
     case Opcodes.L2D:
       pop(2);
       push(DOUBLE);
       push(TOP);
       break;
     case Opcodes.AALOAD:
       pop(1);
       t1 = pop();
       push(ELEMENT_OF + t1);
       break;
     case Opcodes.ISTORE:
     case Opcodes.FSTORE:
     case Opcodes.ASTORE:
       t1 = pop();
       set(arg, t1);
       if (arg > 0) {
         t2 = get(arg - 1);
         // if t2 is of kind STACK or LOCAL we cannot know its size!
         if (t2 == LONG || t2 == DOUBLE) {
           set(arg - 1, TOP);
         } else if ((t2 & KIND) != BASE) {
           set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE);
         }
       }
       break;
     case Opcodes.LSTORE:
     case Opcodes.DSTORE:
       pop(1);
       t1 = pop();
       set(arg, t1);
       set(arg + 1, TOP);
       if (arg > 0) {
         t2 = get(arg - 1);
         // if t2 is of kind STACK or LOCAL we cannot know its size!
         if (t2 == LONG || t2 == DOUBLE) {
           set(arg - 1, TOP);
         } else if ((t2 & KIND) != BASE) {
           set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE);
         }
       }
       break;
     case Opcodes.IASTORE:
     case Opcodes.BASTORE:
     case Opcodes.CASTORE:
     case Opcodes.SASTORE:
     case Opcodes.FASTORE:
     case Opcodes.AASTORE:
       pop(3);
       break;
     case Opcodes.LASTORE:
     case Opcodes.DASTORE:
       pop(4);
       break;
     case Opcodes.POP:
     case Opcodes.IFEQ:
     case Opcodes.IFNE:
     case Opcodes.IFLT:
     case Opcodes.IFGE:
     case Opcodes.IFGT:
     case Opcodes.IFLE:
     case Opcodes.IRETURN:
     case Opcodes.FRETURN:
     case Opcodes.ARETURN:
     case Opcodes.TABLESWITCH:
     case Opcodes.LOOKUPSWITCH:
     case Opcodes.ATHROW:
     case Opcodes.MONITORENTER:
     case Opcodes.MONITOREXIT:
     case Opcodes.IFNULL:
     case Opcodes.IFNONNULL:
       pop(1);
       break;
     case Opcodes.POP2:
     case Opcodes.IF_ICMPEQ:
     case Opcodes.IF_ICMPNE:
     case Opcodes.IF_ICMPLT:
     case Opcodes.IF_ICMPGE:
     case Opcodes.IF_ICMPGT:
     case Opcodes.IF_ICMPLE:
     case Opcodes.IF_ACMPEQ:
     case Opcodes.IF_ACMPNE:
     case Opcodes.LRETURN:
     case Opcodes.DRETURN:
       pop(2);
       break;
     case Opcodes.DUP:
       t1 = pop();
       push(t1);
       push(t1);
       break;
     case Opcodes.DUP_X1:
       t1 = pop();
       t2 = pop();
       push(t1);
       push(t2);
       push(t1);
       break;
     case Opcodes.DUP_X2:
       t1 = pop();
       t2 = pop();
       t3 = pop();
       push(t1);
       push(t3);
       push(t2);
       push(t1);
       break;
     case Opcodes.DUP2:
       t1 = pop();
       t2 = pop();
       push(t2);
       push(t1);
       push(t2);
       push(t1);
       break;
     case Opcodes.DUP2_X1:
       t1 = pop();
       t2 = pop();
       t3 = pop();
       push(t2);
       push(t1);
       push(t3);
       push(t2);
       push(t1);
       break;
     case Opcodes.DUP2_X2:
       t1 = pop();
       t2 = pop();
       t3 = pop();
       t4 = pop();
       push(t2);
       push(t1);
       push(t4);
       push(t3);
       push(t2);
       push(t1);
       break;
     case Opcodes.SWAP:
       t1 = pop();
       t2 = pop();
       push(t1);
       push(t2);
       break;
     case Opcodes.IADD:
     case Opcodes.ISUB:
     case Opcodes.IMUL:
     case Opcodes.IDIV:
     case Opcodes.IREM:
     case Opcodes.IAND:
     case Opcodes.IOR:
     case Opcodes.IXOR:
     case Opcodes.ISHL:
     case Opcodes.ISHR:
     case Opcodes.IUSHR:
     case Opcodes.L2I:
     case Opcodes.D2I:
     case Opcodes.FCMPL:
     case Opcodes.FCMPG:
       pop(2);
       push(INTEGER);
       break;
     case Opcodes.LADD:
     case Opcodes.LSUB:
     case Opcodes.LMUL:
     case Opcodes.LDIV:
     case Opcodes.LREM:
     case Opcodes.LAND:
     case Opcodes.LOR:
     case Opcodes.LXOR:
       pop(4);
       push(LONG);
       push(TOP);
       break;
     case Opcodes.FADD:
     case Opcodes.FSUB:
     case Opcodes.FMUL:
     case Opcodes.FDIV:
     case Opcodes.FREM:
     case Opcodes.L2F:
     case Opcodes.D2F:
       pop(2);
       push(FLOAT);
       break;
     case Opcodes.DADD:
     case Opcodes.DSUB:
     case Opcodes.DMUL:
     case Opcodes.DDIV:
     case Opcodes.DREM:
       pop(4);
       push(DOUBLE);
       push(TOP);
       break;
     case Opcodes.LSHL:
     case Opcodes.LSHR:
     case Opcodes.LUSHR:
       pop(3);
       push(LONG);
       push(TOP);
       break;
     case Opcodes.IINC:
       set(arg, INTEGER);
       break;
     case Opcodes.I2L:
     case Opcodes.F2L:
       pop(1);
       push(LONG);
       push(TOP);
       break;
     case Opcodes.I2F:
       pop(1);
       push(FLOAT);
       break;
     case Opcodes.I2D:
     case Opcodes.F2D:
       pop(1);
       push(DOUBLE);
       push(TOP);
       break;
     case Opcodes.F2I:
     case Opcodes.ARRAYLENGTH:
     case Opcodes.INSTANCEOF:
       pop(1);
       push(INTEGER);
       break;
     case Opcodes.LCMP:
     case Opcodes.DCMPL:
     case Opcodes.DCMPG:
       pop(4);
       push(INTEGER);
       break;
     case Opcodes.JSR:
     case Opcodes.RET:
       throw new RuntimeException("JSR/RET are not supported with computeFrames option");
     case Opcodes.GETSTATIC:
       push(cw, item.strVal3);
       break;
     case Opcodes.PUTSTATIC:
       pop(item.strVal3);
       break;
     case Opcodes.GETFIELD:
       pop(1);
       push(cw, item.strVal3);
       break;
     case Opcodes.PUTFIELD:
       pop(item.strVal3);
       pop();
       break;
     case Opcodes.INVOKEVIRTUAL:
     case Opcodes.INVOKESPECIAL:
     case Opcodes.INVOKESTATIC:
     case Opcodes.INVOKEINTERFACE:
       pop(item.strVal3);
       if (opcode != Opcodes.INVOKESTATIC) {
         t1 = pop();
         if (opcode == Opcodes.INVOKESPECIAL && item.strVal2.charAt(0) == '<') {
           init(t1);
         }
       }
       push(cw, item.strVal3);
       break;
     case Opcodes.INVOKEDYNAMIC:
       pop(item.strVal2);
       push(cw, item.strVal2);
       break;
     case Opcodes.NEW:
       push(UNINITIALIZED | cw.addUninitializedType(item.strVal1, arg));
       break;
     case Opcodes.NEWARRAY:
       pop();
       switch (arg) {
         case Opcodes.T_BOOLEAN:
           push(ARRAY_OF | BOOLEAN);
           break;
         case Opcodes.T_CHAR:
           push(ARRAY_OF | CHAR);
           break;
         case Opcodes.T_BYTE:
           push(ARRAY_OF | BYTE);
           break;
         case Opcodes.T_SHORT:
           push(ARRAY_OF | SHORT);
           break;
         case Opcodes.T_INT:
           push(ARRAY_OF | INTEGER);
           break;
         case Opcodes.T_FLOAT:
           push(ARRAY_OF | FLOAT);
           break;
         case Opcodes.T_DOUBLE:
           push(ARRAY_OF | DOUBLE);
           break;
           // case Opcodes.T_LONG:
         default:
           push(ARRAY_OF | LONG);
           break;
       }
       break;
     case Opcodes.ANEWARRAY:
       String s = item.strVal1;
       pop();
       if (s.charAt(0) == '[') {
         push(cw, '[' + s);
       } else {
         push(ARRAY_OF | OBJECT | cw.addType(s));
       }
       break;
     case Opcodes.CHECKCAST:
       s = item.strVal1;
       pop();
       if (s.charAt(0) == '[') {
         push(cw, s);
       } else {
         push(OBJECT | cw.addType(s));
       }
       break;
       // case Opcodes.MULTIANEWARRAY:
     default:
       pop(arg);
       push(cw, item.strVal1);
       break;
   }
 }