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

📄 codeattr.java

📁 本人根据自己的实际情况
💻 JAVA
字号:
/**
 *
 */
package gen.info.attr;

import gen.ByteCodes;
import gen.ClassFile;
import gen.constvalue.AttrInfoTag;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Code attribute used in MethodInfo
 *
 * @author liuyi
 *
 */
public class CodeAttr extends AttributeInfo implements AttrInfoTag, ByteCodes {
    /** the max depth of stack while executing this function */
    private short maxStack;
    
    /**
     * the max number of local variables while executing this function, including parameters
     * Notice: a long/double equals two variables
     */
    private short maxLocals;
    
    /** the length of this function codes */
    private int codeLength;
    
    /** the codes of this function */
    private byte[] code;
    private int codeLen;
    
    /** exception table length = exceptionTable.size() */
    private List exceptionTable;
    
    /**
     * attribute information list
     * attributes_count = attributes.size()
     */
    private List attributes;
    
    private List operations;
    
    private ClassFile classFile;
    
    /**
     * @param tag
     */
    public CodeAttr(ClassFile classFile) {
        super(ATTR_Code);//super.length问题待处理
        this.classFile = classFile;
        
        this.nameIndex = classFile.getCodeStrIndex();
        
        maxStack = 100;
        maxLocals = 1;
        code = new byte[16];
        codeLen = 0;
        exceptionTable = new ArrayList();
        attributes = new ArrayList();
        operations = new ArrayList();
    }
    
    public short getMaxStack(){
        return maxStack;
    }
    
    public short getMaxLocals(){
        return maxLocals;
    }
    
    public byte[] getCode(){
        byte[] ret = new byte[codeLen];
        for(int i = 0; i<codeLen; i++){
            ret[i] = code[i];
        }
        
        return ret;
    }
    
    public void setMaxLocals(int localCount){
        this.maxLocals = (short)(localCount + 1);
    }
    
    public void incMaxLocalsBy(int step){
        maxLocals += (short)step;
    }
    
    public void setMaxStack(int maxStack){
        this.maxStack = (short)maxStack;
    }
    
    public int getCodeOffset() {
        return codeLen;
    }
    
    private void emit1(int od){
        if(codeLen == code.length){
            expandsCode();
        }
        code[codeLen++] = (byte)od;
    }
    
    private void emit2(int od){
        if(codeLen + 1 >= code.length){
            emit1(od >> 8);
            emit1(od);
        }else{
            code[codeLen++] = (byte)(od >> 8);
            code[codeLen++] = (byte)od;
        }
    }
    
    public void emitop(int op){
        operations.add(new Operation(codeLen));
        emit1(op);
    }
    
    public void emitop1(int op, int od){
        operations.add(new Operation(codeLen, codeLen + 1, 1));
        emit1(op);
        emit1(od);
    }
    
    public void emitop2(int op, int od){
        operations.add(new Operation(codeLen, codeLen + 1, 2));
        emit1(op);
        emit2(od);
    }
    
    public void refill2(int offset, int bcode){
        code[offset] = (byte)(bcode >> 8);
        code[offset + 1] = (byte)bcode;
    }
    
    private void expandsCode() {
        int len = code.length;
        byte[] newcode = new byte[len*2];
        for(int i = 0; i<codeLen; i++){
            newcode[i] = code[i];
        }
        code = newcode;
    }
    
    private void expandsCode(int add){
        int len = code.length;
        byte[] newcode = new byte[len + add];
        for(int i = 0; i<codeLen; i++){
            newcode[i] = code[i];
        }
        code = newcode;
    }
    
    public void toBinary(DataOutputStream writer) throws IOException {
        writer.writeShort(nameIndex);
        writer.writeInt(8 + codeLen + 4);   //attribute_length
        writer.writeShort(maxStack);
        writer.writeShort(maxLocals);
        writer.writeInt(codeLen);
        writer.write(code, 0, codeLen);
        writer.writeShort(exceptionTable.size());
        writer.writeShort(attributes.size());
    }
    
    public String toString(){
        StringBuffer buffer = new StringBuffer();
        buffer.append(" Code:\n  Stack=" + maxStack + ", Locals=" + maxLocals + "\n");
        
        Iterator it = operations.iterator();
        while(it.hasNext()){
            buffer.append("  " + ((Operation)it.next()).toString() + "\n");
        }
        return buffer.toString();
    }
    
    private class Operation {
        
        private int opOffset;
        
        private int odOffset;
        
        /** available value is 0, 1 or 2 */
        private int odLen;
        
        public Operation(int opOffset){
            this.opOffset = opOffset;
            odOffset = -1;
            odLen = 0;
        }
        
        public Operation(int opOffset, int odOffset, int odLen){
            this.opOffset = opOffset;
            this.odOffset = odOffset;
            this.odLen = odLen;
        }
        
        private int getInt(byte high, byte low){
            int highInt = (high < 0)? high + 256: high;
            int lowInt = (low < 0)? low + 256: low;
            return highInt << 8 | lowInt;
        }
        
        public String toString(){
            StringBuffer buffer = new StringBuffer();
            int op = code[opOffset];
            op = (op >= 0)? op: op + 256;
            buffer.append(opOffset + ":\t" + mnem(op));
            
            if(odLen == 1){
                if(op == ldc1){
                    buffer.append("\t#" + code[odOffset] + "; // " + classFile.getRefString(code[odOffset]));
                }else{
                    buffer.append("\t" + code[odOffset]);
                }
            }else if(odLen == 2){
                int index = getInt(code[odOffset], code[odOffset + 1]);
                if(op == getstatic || op == getfield || op == putfield || op == invokevirtual || op == invokespecial
                        || op == new_){
                    buffer.append("\t#" + index + "; // " + classFile.getRefString(index));
                }else if(op == goto_ || op == ifeq || op == ifne || op == ifgt || op == iflt || op == ifge || op == ifle){
                    buffer.append("\t" + (index + opOffset));
                }else{
                    buffer.append("\t" + index);
                }
            }
            return buffer.toString();
        }
    }
    
    private String mnem(int opCode){
        //opCode = (opCode >= 0)? opCode: opCode + 256;
        return Mneumonics.mnem[opCode];
    }
    
    private static class Mneumonics {
        
        private Mneumonics() {
            super();
        }
        
        private static final String[] mnem = new String[ByteCodeCount];
        static {
            mnem[nop] = "nop";
            mnem[aconst_null] = "aconst_null";
            mnem[iconst_m1] = "iconst_m1";
            mnem[iconst_0] = "iconst_0";
            mnem[iconst_1] = "iconst_1";
            mnem[iconst_2] = "iconst_2";
            mnem[iconst_3] = "iconst_3";
            mnem[iconst_4] = "iconst_4";
            mnem[iconst_5] = "iconst_5";
            mnem[lconst_0] = "lconst_0";
            mnem[lconst_1] = "lconst_1";
            mnem[fconst_0] = "fconst_0";
            mnem[fconst_1] = "fconst_1";
            mnem[fconst_2] = "fconst_2";
            mnem[dconst_0] = "dconst_0";
            mnem[dconst_1] = "dconst_1";
            mnem[bipush] = "bipush";
            mnem[sipush] = "sipush";
            mnem[ldc1] = "ldc1";
            mnem[ldc2] = "ldc2";
            mnem[ldc2w] = "ldc2w";
            mnem[iload] = "iload";
            mnem[lload] = "lload";
            mnem[fload] = "fload";
            mnem[dload] = "dload";
            mnem[aload] = "aload";
            mnem[iload_0] = "iload_0";
            mnem[lload_0] = "lload_0";
            mnem[fload_0] = "fload_0";
            mnem[dload_0] = "dload_0";
            mnem[aload_0] = "aload_0";
            mnem[iload_1] = "iload_1";
            mnem[lload_1] = "lload_1";
            mnem[fload_1] = "fload_1";
            mnem[dload_1] = "dload_1";
            mnem[aload_1] = "aload_1";
            mnem[iload_2] = "iload_2";
            mnem[lload_2] = "lload_2";
            mnem[fload_2] = "fload_2";
            mnem[dload_2] = "dload_2";
            mnem[aload_2] = "aload_2";
            mnem[iload_3] = "iload_3";
            mnem[lload_3] = "lload_3";
            mnem[fload_3] = "fload_3";
            mnem[dload_3] = "dload_3";
            mnem[aload_3] = "aload_3";
            mnem[iaload] = "iaload";
            mnem[laload] = "laload";
            mnem[faload] = "faload";
            mnem[daload] = "daload";
            mnem[aaload] = "aaload";
            mnem[baload] = "baload";
            mnem[caload] = "caload";
            mnem[saload] = "saload";
            mnem[istore] = "istore";
            mnem[lstore] = "lstore";
            mnem[fstore] = "fstore";
            mnem[dstore] = "dstore";
            mnem[astore] = "astore";
            mnem[istore_0] = "istore_0";
            mnem[lstore_0] = "lstore_0";
            mnem[fstore_0] = "fstore_0";
            mnem[dstore_0] = "dstore_0";
            mnem[astore_0] = "astore_0";
            mnem[istore_1] = "istore_1";
            mnem[lstore_1] = "lstore_1";
            mnem[fstore_1] = "fstore_1";
            mnem[dstore_1] = "dstore_1";
            mnem[astore_1] = "astore_1";
            mnem[istore_2] = "istore_2";
            mnem[lstore_2] = "lstore_2";
            mnem[fstore_2] = "fstore_2";
            mnem[dstore_2] = "dstore_2";
            mnem[astore_2] = "astore_2";
            mnem[istore_3] = "istore_3";
            mnem[lstore_3] = "lstore_3";
            mnem[fstore_3] = "fstore_3";
            mnem[dstore_3] = "dstore_3";
            mnem[astore_3] = "astore_3";
            mnem[iastore] = "iastore";
            mnem[lastore] = "lastore";
            mnem[fastore] = "fastore";
            mnem[dastore] = "dastore";
            mnem[aastore] = "aastore";
            mnem[bastore] = "bastore";
            mnem[castore] = "castore";
            mnem[sastore] = "sastore";
            mnem[pop] = "pop";
            mnem[pop2] = "pop2";
            mnem[dup] = "dup";
            mnem[dup_x1] = "dup_x1";
            mnem[dup_x2] = "dup_x2";
            mnem[dup2] = "dup2";
            mnem[dup2_x1] = "dup2_x1";
            mnem[dup2_x2] = "dup2_x2";
            mnem[swap] = "swap";
            mnem[iadd] = "iadd";
            mnem[ladd] = "ladd";
            mnem[fadd] = "fadd";
            mnem[dadd] = "dadd";
            mnem[isub] = "isub";
            mnem[lsub] = "lsub";
            mnem[fsub] = "fsub";
            mnem[dsub] = "dsub";
            mnem[imul] = "imul";
            mnem[lmul] = "lmul";
            mnem[fmul] = "fmul";
            mnem[dmul] = "dmul";
            mnem[idiv] = "idiv";
            mnem[ldiv] = "ldiv";
            mnem[fdiv] = "fdiv";
            mnem[ddiv] = "ddiv";
            mnem[imod] = "imod";
            mnem[lmod] = "lmod";
            mnem[fmod] = "fmod";
            mnem[dmod] = "dmod";
            mnem[ineg] = "ineg";
            mnem[lneg] = "lneg";
            mnem[fneg] = "fneg";
            mnem[dneg] = "dneg";
            mnem[ishl] = "ishl";
            mnem[lshl] = "lshl";
            mnem[ishr] = "ishr";
            mnem[lshr] = "lshr";
            mnem[iushr] = "iushr";
            mnem[lushr] = "lushr";
            mnem[iand] = "iand";
            mnem[land] = "land";
            mnem[ior] = "ior";
            mnem[lor] = "lor";
            mnem[ixor] = "ixor";
            mnem[lxor] = "lxor";
            mnem[iinc] = "iinc";
            mnem[i2l] = "i2l";
            mnem[i2f] = "i2f";
            mnem[i2d] = "i2d";
            mnem[l2i] = "l2i";
            mnem[l2f] = "l2f";
            mnem[l2d] = "l2d";
            mnem[f2i] = "f2i";
            mnem[f2l] = "f2l";
            mnem[f2d] = "f2d";
            mnem[d2i] = "d2i";
            mnem[d2l] = "d2l";
            mnem[d2f] = "d2f";
            mnem[int2byte] = "int2byte";
            mnem[int2char] = "int2char";
            mnem[int2short] = "int2short";
            mnem[lcmp] = "lcmp";
            mnem[fcmpl] = "fcmpl";
            mnem[fcmpg] = "fcmpg";
            mnem[dcmpl] = "dcmpl";
            mnem[dcmpg] = "dcmpg";
            mnem[ifeq] = "ifeq";
            mnem[ifne] = "ifne";
            mnem[iflt] = "iflt";
            mnem[ifge] = "ifge";
            mnem[ifgt] = "ifgt";
            mnem[ifle] = "ifle";
            mnem[if_icmpeq] = "if_icmpeq";
            mnem[if_icmpne] = "if_icmpne";
            mnem[if_icmplt] = "if_icmplt";
            mnem[if_icmpge] = "if_icmpge";
            mnem[if_icmpgt] = "if_icmpgt";
            mnem[if_icmple] = "if_icmple";
            mnem[if_acmpeq] = "if_acmpeq";
            mnem[if_acmpne] = "if_acmpne";
            mnem[goto_] = "goto_";
            mnem[jsr] = "jsr";
            mnem[ret] = "ret";
            mnem[tableswitch] = "tableswitch";
            mnem[lookupswitch] = "lookupswitch";
            mnem[ireturn] = "ireturn";
            mnem[lreturn] = "lreturn";
            mnem[freturn] = "freturn";
            mnem[dreturn] = "dreturn";
            mnem[areturn] = "areturn";
            mnem[return_] = "return_";
            mnem[getstatic] = "getstatic";
            mnem[putstatic] = "putstatic";
            mnem[getfield] = "getfield";
            mnem[putfield] = "putfield";
            mnem[invokevirtual] = "invokevirtual";
            mnem[invokespecial] = "invokespecial";
            mnem[invokestatic] = "invokestatic";
            mnem[invokeinterface] = "invokeinterface";
            mnem[newfromname] = "newfromname";
            mnem[new_] = "new_";
            mnem[newarray] = "newarray";
            mnem[anewarray] = "anewarray";
            mnem[arraylength] = "arraylength";
            mnem[athrow] = "athrow";
            mnem[checkcast] = "checkcast";
            mnem[instanceof_] = "instanceof_";
            mnem[monitorenter] = "monitorenter";
            mnem[monitorexit] = "monitorexit";
            mnem[wide] = "wide";
            mnem[multianewarray] = "multianewarray";
            mnem[if_acmp_null] = "if_acmp_null";
            mnem[if_acmp_nonnull] = "if_acmp_nonnull";
            mnem[goto_w] = "goto_w";
            mnem[jsr_w] = "jsr_w";
            mnem[breakpoint] = "breakpoint";
        }
    }
}

class ExceptionTable {
    
    /** executes [startPc, endPc) part of code array when catch exception */
    private short startPc;
    private short endPc;
    
    /** uncertain */
    private short handlerPc;
    
    /** index of constant pool, referring a ConstantClassInfo */
    private short catchType;
}

⌨️ 快捷键说明

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