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

📄 codeiterator.java

📁 Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京技术学院的数学和计算机科学系的 Shigeru Chiba 所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * Javassist, a Java-bytecode translator toolkit. * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License.  Alternatively, the contents of this file may be used under * the terms of the GNU Lesser General Public License Version 2.1 or later. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. */package javassist.bytecode;/** * An iterator for editing a code attribute. * * <p>If there are multiple <code>CodeIterator</code>s referring to the * same <code>Code_attribute</code>, then inserting a gap by one * <code>CodeIterator</code> will break the other * <code>CodeIterator</code>. * * <p>This iterator does not provide <code>remove()</code>. * If a piece of code in a <code>Code_attribute</code> is unnecessary, * it should be overwritten with <code>NOP</code>. * * @see CodeAttribute#iterator() */public class CodeIterator implements Opcode {    protected CodeAttribute codeAttr;    protected byte[] bytecode;    protected int endPos;    protected int currentPos;    protected CodeIterator(CodeAttribute ca) {        codeAttr = ca;        bytecode = ca.getCode();        begin();    }    /**     * Moves to the first instruction.     */    public void begin() {        currentPos = 0;        endPos = getCodeLength();    }    /**     * Moves to the given index.     *     * <p>The index of the next instruction is set to the given index.     * The successive call to <code>next()</code>     * returns the index that has been given to <code>move()</code>.     *     * <p>Note that the index is into the byte array returned by     * <code>get().getCode()</code>.     *     * @see CodeAttribute#getCode()     */    public void move(int index) {        currentPos = index;    }    /**     * Returns a Code attribute read with this iterator.     */    public CodeAttribute get() {        return codeAttr;    }    /**     * Returns <code>code_length</code> of <code>Code_attribute</code>.     */    public int getCodeLength() {        return bytecode.length;    }    /**     * Returns the unsigned 8bit value at the given index.     */    public int byteAt(int index) { return bytecode[index] & 0xff; }    /**     * Writes an 8bit value at the given index.     */    public void writeByte(int value, int index) {        bytecode[index] = (byte)value;    }    /**     * Returns the unsigned 16bit value at the given index.     */    public int u16bitAt(int index) {        return ByteArray.readU16bit(bytecode, index);    }    /**     * Returns the signed 16bit value at the given index.     */    public int s16bitAt(int index) {        return ByteArray.readS16bit(bytecode, index);    }    /**     * Writes a 16 bit integer at the index.     */    public void write16bit(int value, int index) {        ByteArray.write16bit(value, bytecode, index);    }    /**     * Returns the signed 32bit value at the given index.     */    public int s32bitAt(int index) {        return ByteArray.read32bit(bytecode, index);    }    /**     * Writes a 32bit integer at the index.     */    public void write32bit(int value, int index) {        ByteArray.write32bit(value, bytecode, index);    }    /**     * Writes a byte array at the index.     *     * @param code	may be a zero-length array.     */    public void write(byte[] code, int index) {        int len = code.length;        for (int j = 0; j < len; ++j)            bytecode[index++] = code[j];    }    /**     * Returns true if there is more instructions.     */    public boolean hasNext() { return currentPos < endPos; }    /**     * Returns the index of the next instruction     * (not the operand following the current opcode).     *     * <p>Note that the index is into the byte array returned by     * <code>get().getCode()</code>.     *     * @see CodeAttribute#getCode()     * @see CodeIterator#byteAt(int)     */    public int next() throws BadBytecode {        int pos = currentPos;        currentPos = nextOpcode(bytecode, pos);        return pos;    }    /**     * Obtains the value that the next call     * to <code>next()</code> will return.     *     * <p>This method is side-effects free.     * Successive calls to <code>lookAhead()</code> return the     * same value until <code>next()</code> is called.     */    public int lookAhead() {        return currentPos;    }    /**     * Moves to the instruction for     * either <code>super()</code> or <code>this()</code>.     *     * <p>This method skips all the instructions for computing arguments     * to <code>super()</code> or <code>this()</code>, which should be     * placed at the beginning of a constructor body.     *     * <p>This method returns the index of INVOKESPECIAL instruction     * executing <code>super()</code> or <code>this()</code>.     * A successive call to <code>next()</code> returns the     * index of the next instruction following that INVOKESPECIAL.     *     * <p>This method works only for a constructor.     *     * @return  the index of the INVOKESPECIAL instruction, or -1     *          if a constructor invocation is not found.     */    public int skipConstructor() throws BadBytecode {        return skipSuperConstructor0(-1);    }    /**     * Moves to the instruction for <code>super()</code>.     *     * <p>This method skips all the instructions for computing arguments to     * <code>super()</code>, which should be     * placed at the beginning of a constructor body.     *     * <p>This method returns the index of INVOKESPECIAL instruction     * executing <code>super()</code>.     * A successive call to <code>next()</code> returns the     * index of the next instruction following that INVOKESPECIAL.     *     * <p>This method works only for a constructor.     *     * @return  the index of the INVOKESPECIAL instruction, or -1     *          if a super constructor invocation is not found     *          but <code>this()</code> is found.     */    public int skipSuperConstructor() throws BadBytecode {        return skipSuperConstructor0(0);    }    /**     * Moves to the instruction for <code>this()</code>.     *     * <p>This method skips all the instructions for computing arguments to     * <code>this()</code>, which should be     * placed at the beginning of a constructor body.     *     * <p>This method returns the index of INVOKESPECIAL instruction     * executing <code>this()</code>.     * A successive call to <code>next()</code> returns the     * index of the next instruction following that INVOKESPECIAL.     *     * <p>This method works only for a constructor.     *     * @return  the index of the INVOKESPECIAL instruction, or -1     *          if a explicit constructor invocation is not found     *          but <code>super()</code> is found.     */    public int skipThisConstructor() throws BadBytecode {        return skipSuperConstructor0(1);    }    /* skipSuper        1: this(), 0: super(), -1: both.     */    private int skipSuperConstructor0(int skipThis) throws BadBytecode {        begin();        ConstPool cp = codeAttr.getConstPool();        String thisClassName = codeAttr.getDeclaringClass();        int nested = 0;        while (hasNext()) {            int index = next();            int c = byteAt(index);            if (c == NEW)                ++nested;            else if (c == INVOKESPECIAL) {                int mref = ByteArray.readU16bit(bytecode, index + 1);                if (cp.getMethodrefName(mref).equals(MethodInfo.nameInit))                    if (--nested < 0) {                        if (skipThis < 0)                            return index;                        String cname = cp.getMethodrefClassName(mref);                        if (cname.equals(thisClassName) == (skipThis > 0))                            return index;                        else                            break;                    }            }        }        begin();        return -1;    }    /**     * Inserts the given bytecode sequence     * 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.     *     * <p>If the next instruction is at the beginning of a block statement,     * then the bytecode is inserted within that block.     *     * <p>An extra gap may be inserted at the end of the inserted     * bytecode sequence for adjusting alignment if the code attribute     * includes <code>LOOKUPSWITCH</code> or <code>TABLESWITCH</code>.     *     * @param code      inserted bytecode sequence.     * @return          the index indicating the first byte of the     *                  inserted byte sequence.     */    public int insert(byte[] code)        throws BadBytecode    {        int pos = currentPos;        insert0(currentPos, code, false);        return pos;    }    /**     * Inserts the given bytecode sequence     * before the instruction at the given index <code>pos</code>.     * Branch offsets and the exception table are also updated.     *     * <p>If the instruction at the given index is at the beginning     * of a block statement,     * then the bytecode is inserted within that block.     *     * <p>An extra gap may be inserted at the end of the inserted     * bytecode sequence for adjusting alignment if the code attribute     * includes <code>LOOKUPSWITCH</code> or <code>TABLESWITCH</code>.     *     * @param pos       the index at which a byte sequence is inserted.     * @param code      inserted bytecode sequence.     */    public void insert(int pos, byte[] code) throws BadBytecode {        insert0(pos, code, false);    }    /**     * Inserts the given bytecode sequence exclusively     * 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.     *     * <p>If the next instruction is at the beginning of a block statement,     * then the bytecode is excluded from that block.     *     * <p>An extra gap may be inserted at the end of the inserted     * bytecode sequence for adjusting alignment if the code attribute     * includes <code>LOOKUPSWITCH</code> or <code>TABLESWITCH</code>.     *     * @param code      inserted bytecode sequence.     * @return          the index indicating the first byte of the     *                  inserted byte sequence.     */    public int insertEx(byte[] code)        throws BadBytecode    {        int pos = currentPos;        insert0(currentPos, code, true);        return pos;    }    /**     * Inserts the given bytecode sequence exclusively     * before the instruction at the given index <code>pos</code>.     * Branch offsets and the exception table are also updated.     *     * <p>If the instruction at the given index is at the beginning     * of a block statement,     * then the bytecode is excluded from that block.     *     * <p>An extra gap may be inserted at the end of the inserted     * bytecode sequence for adjusting alignment if the code attribute     * includes <code>LOOKUPSWITCH</code> or <code>TABLESWITCH</code>.     *     * @param pos       the index at which a byte sequence is inserted.     * @param code      inserted bytecode sequence.     */    public void insertEx(int pos, byte[] code) throws BadBytecode {        insert0(pos, code, true);    }    private void insert0(int pos, byte[] code, boolean exclusive)        throws BadBytecode    {        int len = code.length;        if (len <= 0)            return;        insertGapCore(pos, len, exclusive);     // currentPos will change.        for (int j = 0; j < len; ++j)            bytecode[pos++] = code[j];    }    /**     * Inserts a 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 inserted within that block.     *     * @param length            gap length     * @return  the index indicating the first byte of the inserted gap.     */    public int insertGap(int length) throws BadBytecode {        int pos = currentPos;        insertGapCore(currentPos, length, false);        return pos;    }

⌨️ 快捷键说明

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