/**
  * Optimizations for OP_convert_d: convert_d, convert_d -> convert_d pushbyte n, convert_d ->
  * pushdouble n pushint n, convert_d -> pushdouble n pushuint n, convert_d -> pushdouble n
  * pushdouble n, convert_d -> pushdouble n pushnan, convert_d -> pushnan lf32, convert_d -> lf32
  * lf64, convert_d -> lf64
  *
  * @param i The convert_d instruction
  */
 private void op_convert_d(InstructionInfo i) {
   InstructionInfo prev = previous(1);
   switch (prev.getOpcode()) {
     case OP_pushbyte:
       {
         // replace pushbyte, convert d with pushdouble - should be faster
         replace(
             1,
             InstructionFactory.getInstruction(
                 OP_pushdouble, new Double(convertByteImmediateToDouble(prev.getImmediate()))));
         break;
       }
     case OP_pushint:
     case OP_pushuint:
       {
         // replace pushint , convert d with pushdouble - should be faster
         replace(
             1,
             InstructionFactory.getInstruction(
                 OP_pushdouble, new Double(((Number) prev.getOperand(0)).doubleValue())));
         break;
       }
     case OP_pushdouble:
     case OP_pushnan:
     case OP_lf32:
     case OP_lf64:
     case OP_convert_d:
       {
         // result is already a double, just erase the op_convert_d
         delete(0);
         break;
       }
     default:
       {
         // nothing to do - instruction has already been added
       }
   }
 }
  /** Optimizations for OP_getlocal: setlocal N, getlocal N -> dup, setlocal N */
  private void OP_getlocal(InstructionInfo i) {
    InstructionInfo prev = previous(1);
    InstructionInfo cur = previous(0);

    switch (prev.getOpcode()) {
      case OP_setlocal:
        {
          if (cur.getInstruction().getImmediate() != prev.getInstruction().getImmediate())
            break; // set,get of different locals

          Instruction[] newInsns = {
            InstructionFactory.getInstruction(OP_dup), prev.getInstruction()
          };
          replace(1, newInsns);
          break;
        }
      default:
        {
          // nothing to do, instruction has already been added
        }
    }
  }
 @Override
 public void visitInstruction(int opcode, Object single_operand) {
   visitInstruction(InstructionFactory.getInstruction(opcode, single_operand));
 }
 @Override
 public void visitInstruction(int opcode, Object[] operands) {
   visitInstruction(InstructionFactory.getInstruction(opcode, operands));
 }
 @Override
 public void visitInstruction(int opcode, int immediate_operand) {
   visitInstruction(InstructionFactory.getInstruction(opcode, immediate_operand));
 }
 @Override
 public void visitInstruction(int opcode) {
   visitInstruction(InstructionFactory.getInstruction(opcode));
 }