/** * 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); }