⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codeiterator.java

📁 Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京技术学院的数学和计算机科学系的 Shigeru Chiba 所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
    /**     * Inserts a gap in front of the instruction at the given     * index <code>pos</code>.     * Branch offsets and the exception table are also updated.     * The inserted gap is filled with NOP.  The gap length may be     * extended to a multiple of 4.     *     * <p>If the instruction at the given index is at the beginning     * of a block statement,     * then the gap is inserted within that block.     *     * @param pos               the index at which a gap is inserted.     * @param length            gap length.     * @return the length of the inserted gap.     *          It might be bigger than <code>length</code>.     */    public int insertGap(int pos, int length) throws BadBytecode {        return insertGapCore(pos, length, false);    }    /**     * Inserts an exclusive gap     * before the next instruction that would be returned by     * <code>next()</code> (not before the instruction returned     * by tha last call to <code>next()</code>).     * Branch offsets and the exception table are also updated.     * The inserted gap is filled with NOP.  The gap length may be     * extended to a multiple of 4.     *     * <p>If the next instruction is at the beginning of a block statement,     * then the gap is excluded from that block.     *     * @param length            gap length     * @return  the index indicating the first byte of the inserted gap.     */    public int insertExGap(int length) throws BadBytecode {        int pos = currentPos;        insertGapCore(currentPos, length, true);        return pos;    }    /**     * Inserts an exclusive gap in front of the instruction at the given     * index <code>pos</code>.     * Branch offsets and the exception table are also updated.     * The inserted gap is filled with NOP.  The gap length may be     * extended to a multiple of 4.     *     * <p>If the instruction at the given index is at the beginning     * of a block statement,     * then the gap is excluded from that block.     *     * @param pos               the index at which a gap is inserted.     * @param length            gap length.     * @return the length of the inserted gap.     *          It might be bigger than <code>length</code>.     */    public int insertExGap(int pos, int length) throws BadBytecode {        return insertGapCore(pos, length, true);    }    /**     * @return the length of the really inserted gap.     */    private int insertGapCore(int pos, int length, boolean exclusive)        throws BadBytecode    {        if (length <= 0)            return 0;        int cur = currentPos;        byte[] c = insertGap(bytecode, pos, length, exclusive,                             get().getExceptionTable(), codeAttr);        int length2 = c.length - bytecode.length;        if (cur >= pos)            currentPos = cur + length2;        codeAttr.setCode(c);        bytecode = c;        endPos = getCodeLength();        updateCursors(pos, length2);        return length2;    }    /**     * Is called when a gap is inserted.  The default implementation is empty.     * A subclass can override this method so that cursors will be updated.     *     * @param pos           the position where a gap is inserted.     * @param length        the length of the gap.     */    protected void updateCursors(int pos, int length) {        // empty    }    /**     * Copies and inserts the entries in the given exception table     * at the beginning of the exception table in the code attribute     * edited by this object.     *     * @param offset    the value added to the code positions included     *                          in the entries.     */    public void insert(ExceptionTable et, int offset) {        codeAttr.getExceptionTable().add(0, et, offset);    }    /**     * Appends the given bytecode sequence at the end.     *     * @param code      the bytecode appended.     * @return  the position of the first byte of the appended bytecode.     */    public int append(byte[] code) {        int size = getCodeLength();        int len = code.length;        if (len <= 0)            return size;        appendGap(len);        byte[] dest = bytecode;        for (int i = 0; i < len; ++i)            dest[i + size] = code[i];        return size;    }    /**     * Appends a gap at the end of the bytecode sequence.     *     * @param gapLength            gap length     */    public void appendGap(int gapLength) {        byte[] code = bytecode;        int codeLength = code.length;        byte[] newcode = new byte[codeLength + gapLength];        int i;        for (i = 0; i < codeLength; ++i)            newcode[i] = code[i];        for (i = codeLength; i < codeLength + gapLength; ++i)            newcode[i] = NOP;        codeAttr.setCode(newcode);        bytecode = newcode;        endPos = getCodeLength();    }    /**     * Copies and appends the entries in the given exception table     * at the end of the exception table in the code attribute     * edited by this object.     *     * @param offset    the value added to the code positions included     *                          in the entries.     */    public void append(ExceptionTable et, int offset) {        ExceptionTable table = codeAttr.getExceptionTable();        table.add(table.size(), et, offset);    }    /* opcodeLegth is used for implementing nextOpcode().     */    private static final int opcodeLength[] = {        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 3,        3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1,        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1,        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3,        3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 0, 0, 1, 1, 1, 1, 1, 1, 3, 3,        3, 3, 3, 3, 3, 5, 0, 3, 2, 3, 1, 1, 3, 3, 1, 1, 0, 4, 3, 3,        5, 5    };    // 0 .. UNUSED (186), LOOKUPSWITCH, TABLESWITCH, WIDE    /**     * Calculates the index of the next opcode.     */    static int nextOpcode(byte[] code, int index)        throws BadBytecode    {        int opcode;        try {            opcode = code[index] & 0xff;        }        catch (IndexOutOfBoundsException e) {            throw new BadBytecode("invalid opcode address");        }        try {            int len = opcodeLength[opcode];            if (len > 0)                return index + len;            else if (opcode == WIDE)                if (code[index + 1] == (byte)IINC)      // WIDE IINC                    return index + 6;                else                    return index + 4;           // WIDE ...            else {                int index2 = (index & ~3) + 8;                if (opcode == LOOKUPSWITCH) {                    int npairs = ByteArray.read32bit(code, index2);                    return index2 + npairs * 8 + 4;                }                else if (opcode == TABLESWITCH) {                    int low = ByteArray.read32bit(code, index2);                    int high = ByteArray.read32bit(code, index2 + 4);                    return index2 + (high - low + 1) * 4 + 8;                }                // else                //     throw new BadBytecode(opcode);            }        }        catch (IndexOutOfBoundsException e) {        }        // opcode is UNUSED or an IndexOutOfBoundsException was thrown.        throw new BadBytecode(opcode);    }    // methods for implementing insertGap().    /* If "where" is the beginning of a block statement, then the inserted     * gap is also included in the block statement.     * "where" must indicate the first byte of an opcode.     * The inserted gap is filled with NOP.  gapLength may be extended to     * a multiple of 4.     */    static byte[] insertGap(byte[] code, int where, int gapLength,                boolean exclusive, ExceptionTable etable, CodeAttribute ca)        throws BadBytecode    {        if (gapLength <= 0)            return code;        try {            return insertGap0(code, where, gapLength, exclusive, etable, ca);        }        catch (AlignmentException e) {            try {                return insertGap0(code, where, (gapLength + 3) & ~3,                                  exclusive, etable, ca);            }            catch (AlignmentException e2) {                throw new RuntimeException("fatal error?");            }        }    }    private static byte[] insertGap0(byte[] code, int where, int gapLength,                                boolean exclusive, ExceptionTable etable,                                CodeAttribute ca)        throws BadBytecode, AlignmentException    {        int codeLength = code.length;        byte[] newcode = new byte[codeLength + gapLength];        insertGap2(code, where, gapLength, codeLength, newcode, exclusive);        etable.shiftPc(where, gapLength, exclusive);        LineNumberAttribute na            = (LineNumberAttribute)ca.getAttribute(LineNumberAttribute.tag);        if (na != null)            na.shiftPc(where, gapLength, exclusive);        LocalVariableAttribute va = (LocalVariableAttribute)ca.getAttribute(                                                LocalVariableAttribute.tag);        if (va != null)            va.shiftPc(where, gapLength, exclusive);        LocalVariableAttribute vta            = (LocalVariableAttribute)ca.getAttribute(                                              LocalVariableAttribute.typeTag);        if (vta != null)            vta.shiftPc(where, gapLength, exclusive);        return newcode;    }    private static void insertGap2(byte[] code, int where, int gapLength,                        int endPos, byte[] newcode, boolean exclusive)        throws BadBytecode, AlignmentException    {        int nextPos;        int i = 0;        int j = 0;        for (; i < endPos; i = nextPos) {            if (i == where) {                int j2 = j + gapLength;                while (j < j2)                    newcode[j++] = NOP;            }            nextPos = nextOpcode(code, i);            int inst = code[i] & 0xff;            // if<cond>, if_icmp<cond>, if_acmp<cond>, goto, jsr            if ((153 <= inst && inst <= 168)                || inst == IFNULL || inst == IFNONNULL) {                /* 2bytes *signed* offset */                int offset = (code[i + 1] << 8) | (code[i + 2] & 0xff);                offset = newOffset(i, offset, where, gapLength, exclusive);                newcode[j] = code[i];                ByteArray.write16bit(offset, newcode, j + 1);                j += 3;            }            else if (inst == GOTO_W || inst == JSR_W) {                /* 4bytes offset */                int offset = ByteArray.read32bit(code, i + 1);                offset = newOffset(i, offset, where, gapLength, exclusive);                newcode[j++] = code[i];                ByteArray.write32bit(offset, newcode, j);                j += 4;            }            else if (inst == TABLESWITCH) {                if (i != j && (gapLength & 3) != 0)                    throw new AlignmentException();                int i0 = i;                int i2 = (i & ~3) + 4;  // 0-3 byte padding                while (i0 < i2)                    newcode[j++] = code[i0++];                int defaultbyte = newOffset(i, ByteArray.read32bit(code, i2),                                            where, gapLength, exclusive);                ByteArray.write32bit(defaultbyte, newcode, j);                int lowbyte = ByteArray.read32bit(code, i2 + 4);                ByteArray.write32bit(lowbyte, newcode, j + 4);                int highbyte = ByteArray.read32bit(code, i2 + 8);                ByteArray.write32bit(highbyte, newcode, j + 8);                j += 12;                i0 = i2 + 12;                i2 = i0 + (highbyte - lowbyte + 1) * 4;                while (i0 < i2) {                    int offset = newOffset(i, ByteArray.read32bit(code, i0),                                           where, gapLength, exclusive);                    ByteArray.write32bit(offset, newcode, j);                    j += 4;                    i0 += 4;                }            }            else if (inst == LOOKUPSWITCH) {                if (i != j && (gapLength & 3) != 0)                    throw new AlignmentException();                int i0 = i;                int i2 = (i & ~3) + 4;  // 0-3 byte padding                while (i0 < i2)                    newcode[j++] = code[i0++];                int defaultbyte = newOffset(i, ByteArray.read32bit(code, i2),                                            where, gapLength, exclusive);                ByteArray.write32bit(defaultbyte, newcode, j);                int npairs = ByteArray.read32bit(code, i2 + 4);                ByteArray.write32bit(npairs, newcode, j + 4);                j += 8;                i0 = i2 + 8;                i2 = i0 + npairs * 8;                while (i0 < i2) {                    ByteArray.copy32bit(code, i0, newcode, j);                    int offset = newOffset(i,                                        ByteArray.read32bit(code, i0 + 4),                                        where, gapLength, exclusive);                    ByteArray.write32bit(offset, newcode, j + 4);                    j += 8;                    i0 += 8;                }            }            else                while (i < nextPos)                    newcode[j++] = code[i++];            }    }    private static int newOffset(int i, int offset, int where,                                 int gapLength, boolean exclusive) {        int target = i + offset;        if (i < where) {            if (where < target || (exclusive && where == target))                offset += gapLength;        }        else            if (target < where || (!exclusive && where == target))                offset -= gapLength;        return offset;    }}class AlignmentException extends Exception {}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -