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

📄 bytecode.java

📁 Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京技术学院的数学和计算机科学系的 Shigeru Chiba 所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* * 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;import javassist.CtClass;import javassist.CtPrimitiveType;class ByteVector implements Cloneable {    private byte[] buffer;    private int size;    public ByteVector() {        buffer = new byte[64];        size = 0;    }    public Object clone() throws CloneNotSupportedException {        ByteVector bv = (ByteVector)super.clone();        bv.buffer = (byte[])buffer.clone();        return bv;    }    public final int getSize() { return size; }    public final byte[] copy() {        byte[] b = new byte[size];        arraycopy(buffer, b, size);        return b;    }    public int read(int offset) {        if (offset < 0 || size <= offset)            throw new ArrayIndexOutOfBoundsException(offset);        return buffer[offset];    }    public void write(int offset, int value) {        if (offset < 0 || size <= offset)            throw new ArrayIndexOutOfBoundsException(offset);        buffer[offset] = (byte)value;    }    public void add(int code) {        addGap(1);        buffer[size - 1] = (byte)code;    }    public void addGap(int length) {        if (size + length > buffer.length) {            int newSize = size << 1;            if (newSize < size + length)                newSize = size + length;            byte[] newBuf = new byte[newSize];            arraycopy(buffer, newBuf, size);            buffer = newBuf;        }        size += length;    }    private static void arraycopy(byte[] src, byte[] dest, int size) {        for (int i = 0; i < size; i++)            dest[i] = src[i];    }}/** * A utility class for producing a bytecode sequence. * * <p>A <code>Bytecode</code> object is an unbounded array * containing bytecode.  For example, * * <ul><pre>ConstPool cp = ...;    // constant pool table * Bytecode b = new Bytecode(cp, 1, 0); * b.addIconst(3); * b.addReturn(CtClass.intType); * CodeAttribute ca = b.toCodeAttribute();</ul></pre> * * <p>This program produces a Code attribute including a bytecode * sequence: * * <ul><pre>iconst_3 * ireturn</pre></ul> * * @see ConstPool * @see CodeAttribute */public class Bytecode extends ByteVector implements Cloneable, Opcode {    /**     * Represents the <code>CtClass</code> file using the     * constant pool table given to this <code>Bytecode</code> object.     */    public static final CtClass THIS = ConstPool.THIS;    ConstPool constPool;    int maxStack, maxLocals;    ExceptionTable tryblocks;    private int stackDepth;    /**     * Constructs a <code>Bytecode</code> object with an empty bytecode     * sequence.     *     * <p>The parameters <code>stacksize</code> and <code>localvars</code>     * specify initial values     * of <code>max_stack</code> and <code>max_locals</code>.     * They can be changed later.     *     * @param cp                constant pool table.     * @param stacksize         <code>max_stack</code>.     * @param localvars         <code>max_locals</code>.     */    public Bytecode(ConstPool cp, int stacksize, int localvars) {        constPool = cp;        maxStack = stacksize;        maxLocals = localvars;        tryblocks = new ExceptionTable(cp);        stackDepth = 0;    }    /**     * Constructs a <code>Bytecode</code> object with an empty bytecode     * sequence.  The initial values of <code>max_stack</code> and     * <code>max_locals</code> are zero.     *      * @param cp            constant pool table.     * @see Bytecode#setMaxStack(int)     * @see Bytecode#setMaxLocals(int)     */    public Bytecode(ConstPool cp) {        this(cp, 0, 0);    }    /**     * Creates and returns a copy of this object.     * The constant pool object is shared between this object     * and the cloned object.     */    public Object clone() {        try {            Bytecode bc = (Bytecode)super.clone();            bc.tryblocks = (ExceptionTable)tryblocks.clone();            return bc;        }        catch (CloneNotSupportedException cnse) {            throw new RuntimeException(cnse);        }    }    /**     * Gets a constant pool table.     */    public ConstPool getConstPool() { return constPool; }    /**     * Returns <code>exception_table</code>.     */    public ExceptionTable getExceptionTable() { return tryblocks; }    /**     * Converts to a <code>CodeAttribute</code>.     */    public CodeAttribute toCodeAttribute() {        return new CodeAttribute(constPool, maxStack, maxLocals,                                 get(), tryblocks);    }    /**     * Returns the length of the bytecode sequence.     */    public int length() {        return getSize();    }    /**     * Returns the produced bytecode sequence.     */    public byte[] get() {        return copy();    }    /**     * Gets <code>max_stack</code>.     */    public int getMaxStack() { return maxStack; }    /**     * Sets <code>max_stack</code>.     *     * <p>This value may be automatically updated when an instruction     * is appended.  A <code>Bytecode</code> object maintains the current     * stack depth whenever an instruction is added     * by <code>addOpcode()</code>.  For example, if DUP is appended,     * the current stack depth is increased by one.  If the new stack     * depth is more than <code>max_stack</code>, then it is assigned     * to <code>max_stack</code>.  However, if branch instructions are     * appended, the current stack depth may not be correctly maintained.     *     * @see #addOpcode(int)     */    public void setMaxStack(int size) {        maxStack = size;    }    /**     * Gets <code>max_locals</code>.     */    public int getMaxLocals() { return maxLocals; }    /**     * Sets <code>max_locals</code>.     */    public void setMaxLocals(int size) {        maxLocals = size;    }    /**     * Sets <code>max_locals</code>.     *     * <p>This computes the number of local variables     * used to pass method parameters and sets <code>max_locals</code>     * to that number plus <code>locals</code>.     *     * @param isStatic          true if <code>params</code> must be     *                          interpreted as parameters to a static method.     * @param params            parameter types.     * @param locals            the number of local variables excluding     *                          ones used to pass parameters.     */    public void setMaxLocals(boolean isStatic, CtClass[] params,                             int locals) {        if (!isStatic)            ++locals;        if (params != null) {            CtClass doubleType = CtClass.doubleType;            CtClass longType = CtClass.longType;            int n = params.length;            for (int i = 0; i < n; ++i) {                CtClass type = params[i];                if (type == doubleType || type == longType)                    locals += 2;                else                    ++locals;            }        }        maxLocals = locals;    }    /**     * Increments <code>max_locals</code>.     */    public void incMaxLocals(int diff) {        maxLocals += diff;    }    /**     * Adds a new entry of <code>exception_table</code>.     */    public void addExceptionHandler(int start, int end,                                    int handler, CtClass type) {        addExceptionHandler(start, end, handler,                            constPool.addClassInfo(type));    }    /**     * Adds a new entry of <code>exception_table</code>.     *     * @param type      the fully-qualified name of a throwable class.     */    public void addExceptionHandler(int start, int end,                                    int handler, String type) {        addExceptionHandler(start, end, handler,                            constPool.addClassInfo(type));    }    /**     * Adds a new entry of <code>exception_table</code>.     */    public void addExceptionHandler(int start, int end,                                    int handler, int type) {        tryblocks.add(start, end, handler, type);    }    /**     * Returns the length of bytecode sequence     * that have been added so far.     */    public int currentPc() {        return getSize();    }    /**     * Reads a signed 8bit value at the offset from the beginning of the     * bytecode sequence.     *     * @throws ArrayIndexOutOfBoundsException   if offset is invalid.     */    public int read(int offset) {        return super.read(offset);    }    /**     * Reads a signed 16bit value at the offset from the beginning of the     * bytecode sequence.     */    public int read16bit(int offset) {        int v1 = read(offset);        int v2 = read(offset + 1);        return (v1 << 8) + (v2 & 0xff);    }    /**     * Reads a signed 32bit value at the offset from the beginning of the     * bytecode sequence.     */    public int read32bit(int offset) {        int v1 = read16bit(offset);        int v2 = read16bit(offset + 2);        return (v1 << 16) + (v2 & 0xffff);    }    /**     * Writes an 8bit value at the offset from the beginning of the     * bytecode sequence.     *     * @throws ArrayIndexOutOfBoundsException   if offset is invalid.     */    public void write(int offset, int value) {        super.write(offset, value);    }    /**     * Writes an 16bit value at the offset from the beginning of the     * bytecode sequence.     */    public void write16bit(int offset, int value) {        write(offset, value >> 8);        write(offset + 1, value);    }    /**     * Writes an 32bit value at the offset from the beginning of the     * bytecode sequence.     */    public void write32bit(int offset, int value) {        write16bit(offset, value >> 16);        write16bit(offset + 2, value);    }    /**     * Appends an 8bit value to the end of the bytecode sequence.     */    public void add(int code) {        super.add(code);    }    /**     * Appends a 32bit value to the end of the bytecode sequence.     */    public void add32bit(int value) {        add(value >> 24);        add(value >> 16);        add(value >> 8);        add(value);    }    /**     * Appends the length-byte gap to the end of the bytecode sequence.     *     * @param length    the gap length in byte.     */    public void addGap(int length) {        super.addGap(length);    }    /**     * Appends an 8bit opcode to the end of the bytecode sequence.     * The current stack depth is updated.     * <code>max_stack</code> is updated if the current stack depth     * is the deepest so far.     *     * <p>Note: some instructions such as INVOKEVIRTUAL does not     * update the current stack depth since the increment depends     * on the method signature.     * <code>growStack()</code> must be explicitly called.     */    public void addOpcode(int code) {        add(code);        growStack(STACK_GROW[code]);    }    /**     * Increases the current stack depth.     * It also updates <code>max_stack</code> if the current stack depth     * is the deepest so far.     *     * @param diff      the number added to the current stack depth.     */    public void growStack(int diff) {        setStackDepth(stackDepth + diff);    }    /**     * Returns the current stack depth.     */    public int getStackDepth() { return stackDepth; }    /**     * Sets the current stack depth.     * It also updates <code>max_stack</code> if the current stack depth     * is the deepest so far.     *     * @param depth     new value.     */    public void setStackDepth(int depth) {        stackDepth = depth;        if (stackDepth > maxStack)            maxStack = stackDepth;    }    /**     * Appends a 16bit value to the end of the bytecode sequence.     * It never changes the current stack depth.     */    public void addIndex(int index) {        add(index >> 8);        add(index);    }    /**     * Appends ALOAD or (WIDE) ALOAD_&lt;n&gt;     *     * @param n         an index into the local variable array.     */    public void addAload(int n) {        if (n < 4)            addOpcode(42 + n);          // aload_<n>        else if (n < 0x100) {            addOpcode(ALOAD);           // aload            add(n);        }        else {            addOpcode(WIDE);            addOpcode(ALOAD);            addIndex(n);        }    }    /**     * Appends ASTORE or (WIDE) ASTORE_&lt;n&gt;     *

⌨️ 快捷键说明

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