コード例 #1
0
 /**
  * Generates the instructions to box the top stack value. This value is replaced by its boxed
  * equivalent on top of the stack.
  *
  * @param type the type of the top stack value.
  */
 public void box(final Type type) {
   if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
     return;
   }
   if (type == Type.VOID_TYPE) {
     push((String) null);
   } else {
     Type boxed = type;
     switch (type.getSort()) {
       case Type.BYTE:
         boxed = BYTE_TYPE;
         break;
       case Type.BOOLEAN:
         boxed = BOOLEAN_TYPE;
         break;
       case Type.SHORT:
         boxed = SHORT_TYPE;
         break;
       case Type.CHAR:
         boxed = CHARACTER_TYPE;
         break;
       case Type.INT:
         boxed = INTEGER_TYPE;
         break;
       case Type.FLOAT:
         boxed = FLOAT_TYPE;
         break;
       case Type.LONG:
         boxed = LONG_TYPE;
         break;
       case Type.DOUBLE:
         boxed = DOUBLE_TYPE;
         break;
     }
     newInstance(boxed);
     if (type.getSize() == 2) {
       // Pp -> Ppo -> oPpo -> ooPpo -> ooPp -> o
       dupX2();
       dupX2();
       pop();
     } else {
       // p -> po -> opo -> oop -> o
       dupX1();
       swap();
     }
     invokeConstructor(boxed, new Method("<init>", Type.VOID_TYPE, new Type[] {type}));
   }
 }
コード例 #2
0
 /**
  * Generates the instructions to unbox the top stack value. This value is replaced by its unboxed
  * equivalent on top of the stack.
  *
  * @param type the type of the top stack value.
  */
 public void unbox(final Type type) {
   Type t = NUMBER_TYPE;
   Method sig = null;
   switch (type.getSort()) {
     case Type.VOID:
       return;
     case Type.CHAR:
       t = CHARACTER_TYPE;
       sig = CHAR_VALUE;
       break;
     case Type.BOOLEAN:
       t = BOOLEAN_TYPE;
       sig = BOOLEAN_VALUE;
       break;
     case Type.DOUBLE:
       sig = DOUBLE_VALUE;
       break;
     case Type.FLOAT:
       sig = FLOAT_VALUE;
       break;
     case Type.LONG:
       sig = LONG_VALUE;
       break;
     case Type.INT:
     case Type.SHORT:
     case Type.BYTE:
       sig = INT_VALUE;
   }
   if (sig == null) {
     checkCast(type);
   } else {
     checkCast(t);
     invokeVirtual(t, sig);
   }
 }
コード例 #3
0
 /**
  * Generates the instruction to push the given value on the stack.
  *
  * @param value the value to be pushed on the stack.
  */
 public void push(final Type value) {
   if (value == null) {
     mv.visitInsn(Opcodes.ACONST_NULL);
   } else {
     switch (value.getSort()) {
       case Type.BOOLEAN:
         mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Boolean", "TYPE", CLDESC);
         break;
       case Type.CHAR:
         mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Char", "TYPE", CLDESC);
         break;
       case Type.BYTE:
         mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Byte", "TYPE", CLDESC);
         break;
       case Type.SHORT:
         mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Short", "TYPE", CLDESC);
         break;
       case Type.INT:
         mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Integer", "TYPE", CLDESC);
         break;
       case Type.FLOAT:
         mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Float", "TYPE", CLDESC);
         break;
       case Type.LONG:
         mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Long", "TYPE", CLDESC);
         break;
       case Type.DOUBLE:
         mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Double", "TYPE", CLDESC);
         break;
       default:
         mv.visitLdcInsn(value);
     }
   }
 }
コード例 #4
0
 /**
  * Generates the instruction to create a new array.
  *
  * @param type the type of the array elements.
  */
 public void newArray(final Type type) {
   int typ;
   switch (type.getSort()) {
     case Type.BOOLEAN:
       typ = Opcodes.T_BOOLEAN;
       break;
     case Type.CHAR:
       typ = Opcodes.T_CHAR;
       break;
     case Type.BYTE:
       typ = Opcodes.T_BYTE;
       break;
     case Type.SHORT:
       typ = Opcodes.T_SHORT;
       break;
     case Type.INT:
       typ = Opcodes.T_INT;
       break;
     case Type.FLOAT:
       typ = Opcodes.T_FLOAT;
       break;
     case Type.LONG:
       typ = Opcodes.T_LONG;
       break;
     case Type.DOUBLE:
       typ = Opcodes.T_DOUBLE;
       break;
     default:
       typeInsn(Opcodes.ANEWARRAY, type);
       return;
   }
   mv.visitIntInsn(Opcodes.NEWARRAY, typ);
 }
コード例 #5
0
 /**
  * Generates the instructions to jump to a label based on the comparison of the top two stack
  * values.
  *
  * @param type the type of the top two stack values.
  * @param mode how these values must be compared. One of EQ, NE, LT, GE, GT, LE.
  * @param label where to jump if the comparison result is <tt>true</tt>.
  */
 public void ifCmp(final Type type, final int mode, final Label label) {
   int intOp = -1;
   switch (type.getSort()) {
     case Type.LONG:
       mv.visitInsn(Opcodes.LCMP);
       break;
     case Type.DOUBLE:
       mv.visitInsn(Opcodes.DCMPG);
       break;
     case Type.FLOAT:
       mv.visitInsn(Opcodes.FCMPG);
       break;
     case Type.ARRAY:
     case Type.OBJECT:
       switch (mode) {
         case EQ:
           mv.visitJumpInsn(Opcodes.IF_ACMPEQ, label);
           return;
         case NE:
           mv.visitJumpInsn(Opcodes.IF_ACMPNE, label);
           return;
       }
       throw new IllegalArgumentException("Bad comparison for type " + type);
     default:
       switch (mode) {
         case EQ:
           intOp = Opcodes.IF_ICMPEQ;
           break;
         case NE:
           intOp = Opcodes.IF_ICMPNE;
           break;
         case GE:
           intOp = Opcodes.IF_ICMPGE;
           break;
         case LT:
           intOp = Opcodes.IF_ICMPLT;
           break;
         case LE:
           intOp = Opcodes.IF_ICMPLE;
           break;
         case GT:
           intOp = Opcodes.IF_ICMPGT;
           break;
       }
       mv.visitJumpInsn(intOp, label);
       return;
   }
   int jumpMode = mode;
   switch (mode) {
     case GE:
       jumpMode = LT;
       break;
     case LE:
       jumpMode = GT;
       break;
   }
   mv.visitJumpInsn(jumpMode, label);
 }
コード例 #6
0
 /**
  * Generates an invoke method instruction.
  *
  * @param opcode the instruction's opcode.
  * @param type the class in which the method is defined.
  * @param method the method to be invoked.
  */
 private void invokeInsn(final int opcode, final Type type, final Method method) {
   String owner = type.getSort() == Type.ARRAY ? type.getDescriptor() : type.getInternalName();
   mv.visitMethodInsn(opcode, owner, method.getName(), method.getDescriptor());
 }