Exemplo n.º 1
0
 /**
  * Returns the internal name of the top type on the stack.
  *
  * @return the name
  */
 private String tosKlassName() {
   StackProducer top = stack[sp - (isTopDoubleWord() ? 2 : 1)];
   if (top == null) {
     return "null";
   }
   return top.getType().getInternalName();
 }
Exemplo n.º 2
0
 /**
  * Changes the type of any object in a local variable or on the operand stack whose current type
  * is matches <code>fromType</code> to be <code>toType</code>.
  */
 public void replaceTypeWithType(Klass fromType, Klass toType) {
   for (int i = 0; i < localTypes.length; i++) {
     if (localTypes[i] == fromType) {
       localTypes[i] = toType;
     }
   }
   for (int i = 0; i < sp; i++) {
     StackProducer producer = stack[i];
     if (producer != null && producer.getType() == fromType) {
       producer.updateType(toType);
     }
   }
 }
Exemplo n.º 3
0
 /**
  * Determines if the operand stack or local variable array currently contains an entry whose type
  * is equal to or a subtype of a given type.
  *
  * @param type the type to search for
  * @return true if an entry was found
  */
 public boolean containsType(Klass type) {
   for (int i = 0; i < localTypes.length; i++) {
     if (type.isAssignableFrom(localTypes[i])) {
       return true;
     }
   }
   for (int i = 0; i < sp; i++) {
     StackProducer producer = stack[i];
     if (producer != null && type.isAssignableFrom(producer.getType())) {
       return true;
     }
   }
   return false;
 }
Exemplo n.º 4
0
  /**
   * Pops a value off the operand stack.
   *
   * @param type the type that the value popped off the operand stack must be assignable to
   * @return the instruction that produced the popped value
   */
  public StackProducer pop(Klass type) {
    StackProducer producer;
    if (type.isDoubleWord()) {
      if (sp < 2) {
        throw codeParser.verifyError("operand stack underflow");
      }
      if (!isTopDoubleWord()) {
        throw codeParser.verifyError("incompatible type on operand stack " + tosKlassName());
      }
      sp -= 2;
      producer = stack[sp];
    } else {
      if (sp < 1) {
        throw codeParser.verifyError("operand stack underflow");
      }
      if (isTopDoubleWord()) {
        throw codeParser.verifyError("incompatible type on operand stack " + tosKlassName());
      }
      producer = stack[--sp];

      /*
       * The primitive one-word, non-float types are all assignment compatible with each other
       */
      if (type.isPrimitive() && type != Klass.FLOAT) {

        type = Klass.INT;
      }
    }

    Assert.that(producer != null);

    /*
     * Interfaces are treated as java.lang.Object in the verifier.
     */
    if (type.isInterface()) {
      type = Klass.OBJECT;
    }

    /*
     * Verify that the instruction is producing the correct type.
     */
    if (!type.isAssignableFrom(producer.getType())) {
      throw codeParser.verifyError(
          "incompatible type: '" + type + "' is not assignable from '" + producer.getType() + "'");
    }

    return producer;
  }
Exemplo n.º 5
0
  /**
   * Pushes a value to the operand stack.
   *
   * @param producer the instruction producing the value being pushed
   */
  public void push(StackProducer producer) {
    Klass type = producer.getType();
    Assert.that(type != Klass.VOID);

    /*
     * Check for overflow and push the producer.
     */
    if (sp == maxStack) {
      throw codeParser.verifyError("operand stack overflow");
    }
    stack[sp++] = producer;

    /*
     * For long and double check for overflow and then add a null word to the stack.
     */
    if (type.isDoubleWord()) {
      if (sp == maxStack) {
        throw codeParser.verifyError("operand stack overflow");
      }
      stack[sp++] = null;
    }
  }
Exemplo n.º 6
0
 /**
  * Spill the result of an instruction.
  *
  * @param producer the instruction producing the value
  */
 public void spill(StackProducer producer) {
   if (!producer.isSpilt()) {
     producer.spill(allocateLocalForSpill(producer));
   }
 }
Exemplo n.º 7
0
 /**
  * Allocate local that is used for spilling.
  *
  * @param producer the instruction producing the value that needs to be spilled
  * @return a unique local to be used to hold the value
  */
 public Local allocateLocalForSpill(StackProducer producer) {
   Klass type = getLocalTypeFor(producer.getType());
   return new Local(type, --nextSpillLocalId, false);
 }
Exemplo n.º 8
0
 /**
  * Emulate the semantics of the <i>dup...</i> and <i>swap</i> bytecodes.
  *
  * @param opcode the opcode of an untyped stack manipulation instruction
  */
 public void doStackOp(int opcode) {
   switch (opcode) {
     case Opcode.opc_dup:
       {
         StackProducer x1 = pop(Klass.ONE_WORD);
         push(x1);
         push(x1);
         x1.setDuped(this);
         break;
       }
     case Opcode.opc_dup2:
       {
         if (!isTopDoubleWord()) {
           /*
            * Form 1:
            */
           StackProducer x1 = pop(Klass.ONE_WORD);
           StackProducer x2 = pop(Klass.ONE_WORD);
           push(x2);
           push(x1);
           push(x2);
           push(x1);
           x1.setDuped(this);
           x2.setDuped(this);
         } else {
           /*
            * Form 2:
            */
           StackProducer x1 = pop(Klass.TWO_WORD);
           push(x1);
           push(x1);
           x1.setDuped(this);
         }
         break;
       }
     case Opcode.opc_dup_x1:
       {
         StackProducer x1 = pop(Klass.ONE_WORD);
         StackProducer x2 = pop(Klass.ONE_WORD);
         push(x1);
         push(x2);
         push(x1);
         x1.setDuped(this);
         x2.setDuped(this);
         break;
       }
     case Opcode.opc_dup_x2:
       {
         StackProducer x1 = pop(Klass.ONE_WORD);
         if (!isTopDoubleWord()) {
           /*
            * Form 1:
            */
           StackProducer x2 = pop(Klass.ONE_WORD);
           StackProducer x3 = pop(Klass.ONE_WORD);
           push(x1);
           push(x3);
           push(x2);
           push(x1);
           x1.setDuped(this);
           x2.setDuped(this);
           x3.setDuped(this);
         } else {
           /*
            * Form 2:
            */
           StackProducer x2 = pop(Klass.TWO_WORD);
           push(x1);
           push(x2);
           push(x1);
           x1.setDuped(this);
           x2.setDuped(this);
         }
         break;
       }
     case Opcode.opc_dup2_x1:
       {
         if (!isTopDoubleWord()) {
           /*
            * Form 1:
            */
           StackProducer x1 = pop(Klass.ONE_WORD);
           StackProducer x2 = pop(Klass.ONE_WORD);
           StackProducer x3 = pop(Klass.ONE_WORD);
           push(x2);
           push(x1);
           push(x3);
           push(x2);
           push(x1);
           x1.setDuped(this);
           x2.setDuped(this);
           x3.setDuped(this);
         } else {
           /*
            * Form 2:
            */
           StackProducer x1 = pop(Klass.TWO_WORD);
           StackProducer x2 = pop(Klass.ONE_WORD);
           push(x1);
           push(x2);
           push(x1);
           x1.setDuped(this);
           x2.setDuped(this);
         }
         break;
       }
     case Opcode.opc_dup2_x2:
       {
         if (!isTopDoubleWord()) {
           StackProducer x1 = pop(Klass.ONE_WORD);
           StackProducer x2 = pop(Klass.ONE_WORD);
           if (!isTopDoubleWord()) {
             /*
              * Form 1:
              */
             StackProducer x3 = pop(Klass.ONE_WORD);
             StackProducer x4 = pop(Klass.ONE_WORD);
             push(x2);
             push(x1);
             push(x4);
             push(x3);
             push(x2);
             push(x1);
             x1.setDuped(this);
             x2.setDuped(this);
             x3.setDuped(this);
             x4.setDuped(this);
           } else {
             /*
              * Form 3:
              */
             StackProducer x3 = pop(Klass.TWO_WORD);
             push(x2);
             push(x1);
             push(x3);
             push(x2);
             push(x1);
             x1.setDuped(this);
             x2.setDuped(this);
             x3.setDuped(this);
           }
         } else {
           StackProducer x1 = pop(Klass.TWO_WORD);
           if (!isTopDoubleWord()) {
             /*
              * Form 2:
              */
             StackProducer x2 = pop(Klass.ONE_WORD);
             StackProducer x3 = pop(Klass.ONE_WORD);
             push(x1);
             push(x3);
             push(x2);
             push(x1);
             x1.setDuped(this);
             x2.setDuped(this);
             x3.setDuped(this);
           } else {
             /*
              * Form 4:
              */
             StackProducer x2 = pop(Klass.TWO_WORD);
             push(x1);
             push(x2);
             push(x1);
             x1.setDuped(this);
             x2.setDuped(this);
           }
         }
         break;
       }
     case Opcode.opc_swap:
       {
         StackProducer x1 = pop(Klass.ONE_WORD);
         StackProducer x2 = pop(Klass.ONE_WORD);
         push(x1);
         push(x2);
         x1.setDuped(this);
         x2.setDuped(this);
         break;
       }
     default:
       {
         Assert.that(false, "unknown dup/swap opcode: " + opcode);
       }
   }
 }