Ejemplo n.º 1
0
  /**
   * Changes the index numbers of the local variables to append a new parameter. This method does
   * not update <code>LocalVariableAttribute</code>, <code>LocalVariableTypeAttribute</code>, <code>
   * StackMapTable</code>, or <code>StackMap</code>. These attributes must be explicitly updated.
   *
   * @param where the index of the new parameter.
   * @param size the type size of the new parameter (1 or 2).
   * @see LocalVariableAttribute#shiftIndex(int, int)
   * @see LocalVariableTypeAttribute#shiftIndex(int, int)
   * @see StackMapTable#insertLocal(int, int, int)
   * @see StackMap#insertLocal(int, int, int)
   */
  public void insertLocalVar(int where, int size) throws BadBytecode {
    CodeIterator ci = iterator();
    while (ci.hasNext()) shiftIndex(ci, where, size);

    setMaxLocals(getMaxLocals() + size);
  }
  /** Add a method to a class that simply delegates to the parent implementation of the method */
  public static void addDelegatingMethod(ClassFile file, MethodData mData)
      throws BadBytecode, DuplicateMemberException {
    MethodInfo m =
        new MethodInfo(file.getConstPool(), mData.getMethodName(), mData.getDescriptor());
    m.setAccessFlags(mData.getAccessFlags());
    Bytecode code = new Bytecode(file.getConstPool());

    String[] params = DescriptorUtils.descriptorStringToParameterArray(mData.getDescriptor());
    code.add(Opcode.ALOAD_0); // push this
    int count = 1; // zero is the this pointer
    int maxLocals = 1;
    for (String p : params) {
      // int char short boolean byte
      if (p.equals("I") || p.equals("C") || p.equals("S") || p.equals("Z") || p.equals("B")) {
        // push integer 0
        code.addIload(count);
        maxLocals++;
      }
      // long
      else if (p.equals("J")) {
        code.addLload(count);
        maxLocals += 2;
        count++;
      }
      // double
      else if (p.equals("D")) {
        code.addDload(count);
        maxLocals += 2;
        count++;
      }
      // float
      else if (p.equals("F")) {
        code.addFload(count);
        maxLocals++;
      }
      // arrays and reference types
      else {
        code.addAload(count);
        maxLocals++;
      }
      count++;
    }
    code.addInvokespecial(file.getSuperclass(), mData.getMethodName(), mData.getDescriptor());
    String p = DescriptorUtils.getReturnTypeInJvmFormat(mData.getDescriptor());
    // int char short boolean byte
    if (p.equals("I") || p.equals("C") || p.equals("S") || p.equals("Z") || p.equals("B")) {
      code.add(Opcode.IRETURN);
    }
    // long
    else if (p.equals("J")) {
      code.add(Opcode.LRETURN);
    }
    // double
    else if (p.equals("D")) {
      code.add(Opcode.DRETURN);
    }
    // float
    else if (p.equals("F")) {
      code.add(Opcode.FRETURN);
    }
    // void
    else if (p.equals("V")) {
      code.add(Opcode.RETURN);
    }
    // arrays and reference types
    else {
      code.add(Opcode.ARETURN);
    }
    CodeAttribute ca = code.toCodeAttribute();
    ca.computeMaxStack();
    ca.setMaxLocals(maxLocals);
    m.setCodeAttribute(ca);
    file.addMethod(m);
  }