<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-204  評論-149  文章-0  trackbacks-0

    前一個是直接生成了一個一個方法對原方法進行調用,現在直接在原方法上進行修改
    即將


    public class StringBuilder
    {
        
    private String buildString(int length) {

            String result 
    = "";
            
    for (int i = 0; i < length; i++{
                result 
    += (char)(i%26 + 'a');
            }

            System.out.println(result);

            
    return result;
        }

        
        
        
    public static void main(String[] argv) {
            StringBuilder inst 
    = new StringBuilder();
            
    for (int i = 0; i < argv.length; i++{
                String result 
    = inst.buildString(Integer.parseInt(argv[i]));
                System.out.println(
    "Constructed string of length " +
                    result.length());
            }

        }

    }



    改成:

    public class StringBuilder
    {
        
    private String buildString(int length) {
            
            System.out.println("start start start");
            long starttime = System.currentTimeMillis();

            
            String result 
    = "";
            
    for (int i = 0; i < length; i++{
                result 
    += (char)(i%26 + 'a');
            }

            System.out.println(result);
            
            System.out.println("Call to buildString$impl took " +
                    (System.currentTimeMillis()-starttime) + " ms.");
            System.out.println("end end end end");

            
            
    return result;
        }

        
        
        
    public static void main(String[] argv) {
            StringBuilder inst 
    = new StringBuilder();
            
    for (int i = 0; i < argv.length; i++{
                String result 
    = inst.buildString(Integer.parseInt(argv[i]));
                System.out.println(
    "Constructed string of length " +
                    result.length());
            }

        }

    }



    修改代碼如下:

    import java.io.FileOutputStream;
    import java.util.Iterator;

    import org.apache.bcel.Constants;
    import org.apache.bcel.classfile.ClassParser;
    import org.apache.bcel.classfile.JavaClass;
    import org.apache.bcel.classfile.LineNumberTable;
    import org.apache.bcel.classfile.LocalVariableTable;
    import org.apache.bcel.classfile.Method;
    import org.apache.bcel.generic.ClassGen;
    import org.apache.bcel.generic.ConstantPoolGen;
    import org.apache.bcel.generic.InstructionConstants;
    import org.apache.bcel.generic.InstructionFactory;
    import org.apache.bcel.generic.InstructionHandle;
    import org.apache.bcel.generic.InstructionList;
    import org.apache.bcel.generic.InvokeInstruction;
    import org.apache.bcel.generic.LocalVariableGen;
    import org.apache.bcel.generic.MethodGen;
    import org.apache.bcel.generic.ObjectType;
    import org.apache.bcel.generic.PUSH;
    import org.apache.bcel.generic.Type;


    public class BCELTiming2 {
        
        
    private static void modifyWrapper(ClassGen cgen,Method method){
            
            InstructionFactory ifact 
    = new InstructionFactory(cgen);
            ConstantPoolGen pgen 
    = cgen.getConstantPool();
            
            String cname 
    = cgen.getClassName();
            
            MethodGen wrapgen 
    = new MethodGen(method,cname,pgen);
            
            
    //除掉這個原來的方法
            cgen.removeMethod(method);
            
            
            System.out.println(
    "打印出這個方法看看---------------------------------start");
            System.out.println(wrapgen.toString());
            System.out.println(
    "打印出這個方法看看---------------------------------end");
            
            
            
            InstructionList ilist 
    = wrapgen.getInstructionList();
            System.out.println(
    "看看這個方法的InstructionList-----------------------------start");
            System.out.println(ilist.toString());
            System.out.println(
    "看看這個方法的InstructionList-----------------------------start");
            
            System.out.println(
    "看看這個方法InstructionList的各個InstructionHandle的信息--------------------start");
            Iterator handleIt 
    = ilist.iterator();
            
            
    while(handleIt.hasNext()){
                InstructionHandle iHandle 
    = (InstructionHandle)handleIt.next();
                System.out.println(iHandle.getAttributes());
                System.out.println(iHandle.toString());
            }

            
            System.out.println(
    "看看這個方法InstructionList的各個InstructionHandle的信息--------------------end");
            
            System.out.println(
    "先看看此方法的LocalVariableTable的信息--------------------------------------start");
            LocalVariableTable lvt 
    = wrapgen.getLocalVariableTable(pgen);
            System.out.println(lvt.toString());
            System.out.println(
    "先看看此方法的LocalVariableTable的信息--------------------------------------end");
            
            LineNumberTable lnt 
    = wrapgen.getLineNumberTable(pgen);
            System.out.println(
    "LineNumberTable--------------------------------------start");
            System.out.println(lnt.toString());
            System.out.println(
    "LineNumberTable--------------------------------------end");
            
            
            Type returnType 
    = wrapgen.getReturnType();
            
            Type[] types 
    = wrapgen.getArgumentTypes();
            
    int slot = wrapgen.isStatic()?0:1;//非靜態方法slot 0處應該存儲的是this
            //// 這種方式與Java如何處理方法調用有關。對于非靜態的方法,每次調用的第一個(隱藏的)參數是目標對象的this引用(就是位置0儲存的內容)。
            for(int i = 0;i<types.length;i++){
                slot 
    += types[i].getSize();//long,double的size為2
            }

            
            
    /*
             * 判斷原來的方法用到了哪些局部變量,獲得局部變量中已經用到的最大索引
             * 將新產生的局部變量加到最大索引后,本來準備自己寫的
             * BCEL中已經這樣的方法了
             
    */

            
            LocalVariableGen lvg 
    = wrapgen.addLocalVariable("starttime", Type.LONG, nullnull);
            
            
            
    //先插入一條打印語句不使用局部變量
            InstructionList printlnList = ifact.createPrintln("start test start test start test start test");
            
            InvokeInstruction invokestatic 
    = ifact.createInvoke("java.lang.System"
                    
    "currentTimeMillis", Type.LONG, Type.NO_ARGS, Constants.INVOKESTATIC);
            
            
            InstructionHandle firstHandle 
    = printlnList.append(invokestatic);
            
    //這個會不會將局部變量為2的地方的局部變量給覆蓋,然后此局部變量也沒有定義名字??slot這個index怎么來確定
            
    //slot現在應該為2,之前代碼塊放的是result信息是aload,
            
    //寫到新產生的局部變量的索引處
            printlnList.append(InstructionFactory.createStore(Type.LONG, lvg.getIndex()));
            
            
    //加入到之前的inlist中
            ilist.insert(printlnList);
            
            
    //
            
            
    //在語句最后在打印結束語句,不能簡單插入在最后面,加入方法有返回值,則要插入在return 之前
            
    //在return的時候,還要先將return的引用加入到操作數棧,怎么獲取result在局部變量中index
            InstructionHandle insertposition =null;
            
    if(returnType.getType()!=Type.VOID.getType()){
                insertposition = ilist.getEnd().getPrev();

                
            }
    else{
                
    //返回值為Type.void的話,由于沒有返回值,因此只需要在return指令前加就夠了,往前取一個即可
                insertposition = ilist.getEnd();
            }

            InstructionList tempList 
    = new InstructionList();
            tempList.append(ifact.createFieldAccess(
    "java.lang.System"
                    , 
    "out"new ObjectType("java.io.PrintStream"), 
                    Constants.GETSTATIC));
            
            tempList.append(InstructionFactory.DUP);
            tempList.append(InstructionFactory.DUP);
            
            String text 
    = "Call to method "+wrapgen.getName()+" took ";
            tempList.append(
    new PUSH(pgen,text));
            tempList.append(ifact.createInvoke(
    "java.io.PrintStream"
                    
    "print", Type.VOID, new Type[]{Type.STRING}
                    Constants.INVOKEVIRTUAL));
            tempList.append(ifact.createInvoke(
    "java.lang.System"
                    
    "currentTimeMillis", Type.LONG, Type.NO_ARGS, 
                    Constants.INVOKESTATIC));
            
    //獲取之前的的starttime局部變量
            tempList.append(InstructionFactory.createLoad(Type.LONG, lvg.getIndex()));
            tempList.append(InstructionConstants.LSUB);
            tempList.append(ifact.createInvoke(
    "java.io.PrintStream"
                    
    "print", Type.VOID, new Type[]{Type.LONG}
                    Constants.INVOKEVIRTUAL));
            tempList.append(
    new PUSH(pgen," ms."));
            tempList.append(ifact.createInvoke(
    "java.io.PrintStream"
                    
    "println", Type.VOID, new Type[]{Type.STRING}
                    Constants.INVOKEVIRTUAL));
            
            
    //在return之前的最后一句是打印end end end.信息
            tempList.append(ifact.createPrintln("end end end end end end end end end end"));
            
            ilist.insert(insertposition,tempList);
            
            
            
            
            
            
            
    //        LocalVariableGen lvgen  = new LocalVariableGen(slot,"start",Type.LONG,null,null);
            
            
    //finalize the construted method
            wrapgen.stripAttributes(false);
            wrapgen.setMaxStack();
            wrapgen.setMaxLocals();

            cgen.addMethod(wrapgen.getMethod());
            
            System.out.println();
            System.out.println();
            System.out.println(wrapgen.getInstructionList());
            ilist.dispose();
            
        }

        
        
        
        
        
        
    public static void main(String[] args) {
            
            args[
    0]="D:\\java to eclipse\\javaeclipsestudy\\workspace\\BCELTest\\bin\\StringBuilder.class";
            args[
    1]="buildString";
            String targetClassfile 
    = "StringBuilder.class";
            
    if(args.length==2 && args[0].endsWith(".class")){
                
    try{
                    JavaClass jclas 
    = new ClassParser(args[0]).parse();
                    
                    ClassGen cgen 
    = new ClassGen(jclas);
                    Method[] methods 
    = jclas.getMethods();
                    
                    
    int index;
                    
    for(index =0;index<methods.length;index++){
                        
    if(methods[index].getName().equals(args[1])){
                            
    break;
                        }

                    }

                    
    if(index<methods.length){
                        modifyWrapper(cgen,methods[index]);
                        FileOutputStream fos 
    = new FileOutputStream(targetClassfile);
                        cgen.getJavaClass().dump(fos);
                        fos.close();
                    }
    else{
                        System.err.println(
    "Method " + args[1]+"not found in"+ args[0]);
                    }

                }
    catch(Exception e){
                    e.printStackTrace();
                }

            }
    else{
                System.out.println(
    "usage: class-file method-name");
            }


        }



    }

    posted on 2009-08-13 22:53 Frank_Fang 閱讀(1983) 評論(2)  編輯  收藏 所屬分類: bcel javassist

    評論:
    # re: 用 BCEL 設計字節碼(二)直接在原方法上加指令 2009-08-15 20:59 | Frank_Fang
    --------------------------------33
    --------------------------------33
    0
    2
    CONSTANT_Utf8[1]("SourceFile")
    true
    CONSTANT_Utf8[1]("StringBuilder.java")
    1
    StringBuilder.java
    StringBuilder.java
    ---------------------------------------------------------------------------
    1:CONSTANT_Class[7](name_index = 2)
    2:CONSTANT_Utf8[1]("StringBuilder")
    3:CONSTANT_Class[7](name_index = 4)
    4:CONSTANT_Utf8[1]("java/lang/Object")
    5:CONSTANT_Utf8[1]("")
    6:CONSTANT_Utf8[1]("()V")
    7:CONSTANT_Utf8[1]("Code")
    8:CONSTANT_Methodref[10](class_index = 3, name_and_type_index = 9)
    9:CONSTANT_NameAndType[12](name_index = 5, signature_index = 6)
    10:CONSTANT_Utf8[1]("LineNumberTable")
    11:CONSTANT_Utf8[1]("LocalVariableTable")
    12:CONSTANT_Utf8[1]("this")
    13:CONSTANT_Utf8[1]("LStringBuilder;")
    14:CONSTANT_Utf8[1]("buildString")
    15:CONSTANT_Utf8[1]("(I)Ljava/lang/String;")
    16:CONSTANT_String[8](string_index = 17)
    17:CONSTANT_Utf8[1]("")
    18:CONSTANT_Class[7](name_index = 19)
    19:CONSTANT_Utf8[1]("java/lang/StringBuilder")
    20:CONSTANT_Methodref[10](class_index = 21, name_and_type_index = 23)
    21:CONSTANT_Class[7](name_index = 22)
    22:CONSTANT_Utf8[1]("java/lang/String")
    23:CONSTANT_NameAndType[12](name_index = 24, signature_index = 25)
    24:CONSTANT_Utf8[1]("valueOf")
    25:CONSTANT_Utf8[1]("(Ljava/lang/Object;)Ljava/lang/String;")
    26:CONSTANT_Methodref[10](class_index = 18, name_and_type_index = 27)
    27:CONSTANT_NameAndType[12](name_index = 5, signature_index = 28)
    28:CONSTANT_Utf8[1]("(Ljava/lang/String;)V")
    29:CONSTANT_Methodref[10](class_index = 18, name_and_type_index = 30)
    30:CONSTANT_NameAndType[12](name_index = 31, signature_index = 32)
    31:CONSTANT_Utf8[1]("append")
    32:CONSTANT_Utf8[1]("(C)Ljava/lang/StringBuilder;")
    33:CONSTANT_Methodref[10](class_index = 18, name_and_type_index = 34)
    34:CONSTANT_NameAndType[12](name_index = 35, signature_index = 36)
    35:CONSTANT_Utf8[1]("toString")
    36:CONSTANT_Utf8[1]("()Ljava/lang/String;")
    37:CONSTANT_Fieldref[9](class_index = 38, name_and_type_index = 40)
    *********************ConstantFieldref start**********************
    cc.toString : CONSTANT_Class[7](name_index = 39)
    java/lang/System
    cnat.toString : CONSTANT_NameAndType[12](name_index = 41, signature_index = 42)
    out
    Ljava/io/PrintStream;
    **********************ConstantFieldref end*******************************
    38:CONSTANT_Class[7](name_index = 39)
    39:CONSTANT_Utf8[1]("java/lang/System")
    40:CONSTANT_NameAndType[12](name_index = 41, signature_index = 42)
    41:CONSTANT_Utf8[1]("out")
    42:CONSTANT_Utf8[1]("Ljava/io/PrintStream;")
    43:CONSTANT_Methodref[10](class_index = 44, name_and_type_index = 46)
    44:CONSTANT_Class[7](name_index = 45)
    45:CONSTANT_Utf8[1]("java/io/PrintStream")
    46:CONSTANT_NameAndType[12](name_index = 47, signature_index = 28)
    47:CONSTANT_Utf8[1]("println")
    48:CONSTANT_Utf8[1]("length")
    49:CONSTANT_Utf8[1]("I")
    50:CONSTANT_Utf8[1]("result")
    51:CONSTANT_Utf8[1]("Ljava/lang/String;")
    52:CONSTANT_Utf8[1]("i")
    53:CONSTANT_Utf8[1]("main")
    54:CONSTANT_Utf8[1]("([Ljava/lang/String;)V")
    55:CONSTANT_Methodref[10](class_index = 1, name_and_type_index = 9)
    56:CONSTANT_Methodref[10](class_index = 57, name_and_type_index = 59)
    57:CONSTANT_Class[7](name_index = 58)
    58:CONSTANT_Utf8[1]("java/lang/Integer")
    59:CONSTANT_NameAndType[12](name_index = 60, signature_index = 61)
    60:CONSTANT_Utf8[1]("parseInt")
    61:CONSTANT_Utf8[1]("(Ljava/lang/String;)I")
    62:CONSTANT_Methodref[10](class_index = 1, name_and_type_index = 63)
    63:CONSTANT_NameAndType[12](name_index = 14, signature_index = 15)
    64:CONSTANT_String[8](string_index = 65)
    65:CONSTANT_Utf8[1]("Constructed string of length ")
    66:CONSTANT_Methodref[10](class_index = 21, name_and_type_index = 67)
    67:CONSTANT_NameAndType[12](name_index = 48, signature_index = 68)
    68:CONSTANT_Utf8[1]("()I")
    69:CONSTANT_Methodref[10](class_index = 18, name_and_type_index = 70)
    70:CONSTANT_NameAndType[12](name_index = 31, signature_index = 71)
    71:CONSTANT_Utf8[1]("(I)Ljava/lang/StringBuilder;")
    72:CONSTANT_Utf8[1]("argv")
    73:CONSTANT_Utf8[1]("[Ljava/lang/String;")
    74:CONSTANT_Utf8[1]("inst")
    75:CONSTANT_Utf8[1]("SourceFile")
    76:CONSTANT_Utf8[1]("StringBuilder.java")
    --------------------------域----------------------------
    -----------域的長度,此類定義的成員變量的個數-------------0




    start method method method-----------------------------------
    方法訪問標志
    1
    方法訪問名稱

    CONSTANT_Utf8[1]("")
    方法簽名
    ()V
    CONSTANT_Utf8[1]("()V")
    方法的參數類型
    方法的返回類型
    void
    方法的ExceptionTable屬性----------方法的throws聲明的異常信息------------------------
    exceptionTable==null true
    方法的Code---------------------------------------------
    7
    CONSTANT_Utf8[1]("Code")
    code.getLength() 屬性結構中attribute length 的長度 47
    code.getCode().length 屬性結構中的code數組的長度 code_length 的長度 5
    給出該方法在執行中任何點操作數棧上字的最大個數 1
    給出該方法使用的局部變量的個數,包括調用時傳遞給方法的參數 1
    code的字節信息調用code.getCode()返回byte[] [B@10b4199
    ce.length===========0
    code 內部結構中的各異常信息結構------------方法內部的try 塊catch的信息----------
    方法的Code的LineNumberTable
    方法的Code的LocalVariableTable
    LocalVariableTable
    localvariableTable==null false
    lvs==null false
    lvs.length======1
    --------------------第 0 個局部變量的信息
    lv.getStartPC()=0| lv.getLength=5| lv.getNameIndex()=12 | lv.getName()=this| lv.getSignatureIndex()=13 | lv.getSignature()=LStringBuilder; |lv.getIndex()=0
    完整的code.toString的信息
    public void ()
    Code(max_stack = 1, max_locals = 1, code_length = 5)
    0: aload_0
    1: invokespecial java.lang.Object. ()V (8)
    4: return

    Attribute(s) =
    LineNumber(0, 2)
    LocalVariable(start_pc = 0, length = 5, index = 0:StringBuilder this)

    end method method method-----------------------------------


    start method method method-----------------------------------
    方法訪問標志
    2
    方法訪問名稱
    buildString
    CONSTANT_Utf8[1]("buildString")
    方法簽名
    (I)Ljava/lang/String;
    CONSTANT_Utf8[1]("(I)Ljava/lang/String;")
    方法的參數類型
    int方法的返回類型
    java.lang.String
    方法的ExceptionTable屬性----------方法的throws聲明的異常信息------------------------
    exceptionTable==null true
    方法的Code---------------------------------------------
    7
    CONSTANT_Utf8[1]("Code")
    code.getLength() 屬性結構中attribute length 的長度 143
    code.getCode().length 屬性結構中的code數組的長度 code_length 的長度 51
    給出該方法在執行中任何點操作數棧上字的最大個數 3
    給出該方法使用的局部變量的個數,包括調用時傳遞給方法的參數 4
    code的字節信息調用code.getCode()返回byte[] [B@1ffbd68
    ce.length===========0
    code 內部結構中的各異常信息結構------------方法內部的try 塊catch的信息----------
    方法的Code的LineNumberTable
    方法的Code的LocalVariableTable
    LocalVariableTable
    localvariableTable==null false
    lvs==null false
    lvs.length======4
    --------------------第 0 個局部變量的信息
    lv.getStartPC()=0| lv.getLength=51| lv.getNameIndex()=12 | lv.getName()=this| lv.getSignatureIndex()=13 | lv.getSignature()=LStringBuilder; |lv.getIndex()=0
    --------------------第 1 個局部變量的信息
    lv.getStartPC()=0| lv.getLength=51| lv.getNameIndex()=48 | lv.getName()=length| lv.getSignatureIndex()=49 | lv.getSignature()=I |lv.getIndex()=1
    --------------------第 2 個局部變量的信息
    lv.getStartPC()=3| lv.getLength=48| lv.getNameIndex()=50 | lv.getName()=result| lv.getSignatureIndex()=51 | lv.getSignature()=Ljava/lang/String; |lv.getIndex()=2
    --------------------第 3 個局部變量的信息
    lv.getStartPC()=5| lv.getLength=37| lv.getNameIndex()=52 | lv.getName()=i| lv.getSignatureIndex()=49 | lv.getSignature()=I |lv.getIndex()=3
    完整的code.toString的信息
    private String buildString(int length)
    Code(max_stack = 3, max_locals = 4, code_length = 51)
    0: ldc "" (16)
    2: astore_2
    3: iconst_0
    4: istore_3
    5: goto #37
    8: new (18)
    11: dup
    12: aload_2
    13: invokestatic java.lang.String.valueOf (Ljava/lang/Object;)Ljava/lang/String; (20)
    16: invokespecial java.lang.StringBuilder. (Ljava/lang/String;)V (26)
    19: iload_3
    20: bipush 26
    22: irem
    23: bipush 97
    25: iadd
    26: i2c
    27: invokevirtual java.lang.StringBuilder.append (C)Ljava/lang/StringBuilder; (29)
    30: invokevirtual java.lang.StringBuilder.toString ()Ljava/lang/String; (33)
    33: astore_2
    34: iinc %3 1
    37: iload_3
    38: iload_1
    39: if_icmplt #8
    42: getstatic java.lang.System.out Ljava/io/PrintStream; (37)
    45: aload_2
    46: invokevirtual java.io.PrintStream.println (Ljava/lang/String;)V (43)
    49: aload_2
    50: areturn

    Attribute(s) =
    LineNumber(0, 6), LineNumber(3, 7), LineNumber(8, 8), LineNumber(34, 7),
    LineNumber(42, 10), LineNumber(49, 12)
    LocalVariable(start_pc = 0, length = 51, index = 0:StringBuilder this)
    LocalVariable(start_pc = 0, length = 51, index = 1:int length)
    LocalVariable(start_pc = 3, length = 48, index = 2:String result)
    LocalVariable(start_pc = 5, length = 37, index = 3:int i)

    end method method method-----------------------------------


    start method method method-----------------------------------
    方法訪問標志
    9
    方法訪問名稱
    main
    CONSTANT_Utf8[1]("main")
    方法簽名
    ([Ljava/lang/String;)V
    CONSTANT_Utf8[1]("([Ljava/lang/String;)V")
    方法的參數類型
    java.lang.String[]方法的返回類型
    void
    方法的ExceptionTable屬性----------方法的throws聲明的異常信息------------------------
    exceptionTable==null true
    方法的Code---------------------------------------------
    7
    CONSTANT_Utf8[1]("Code")
    code.getLength() 屬性結構中attribute length 的長度 159
    code.getCode().length 屬性結構中的code數組的長度 code_length 的長度 59
    給出該方法在執行中任何點操作數棧上字的最大個數 4
    給出該方法使用的局部變量的個數,包括調用時傳遞給方法的參數 4
    code的字節信息調用code.getCode()返回byte[] [B@ec16a4
    ce.length===========0
    code 內部結構中的各異常信息結構------------方法內部的try 塊catch的信息----------
    方法的Code的LineNumberTable
    方法的Code的LocalVariableTable
    LocalVariableTable
    localvariableTable==null false
    lvs==null false
    lvs.length======4
    --------------------第 0 個局部變量的信息
    lv.getStartPC()=0| lv.getLength=59| lv.getNameIndex()=72 | lv.getName()=argv| lv.getSignatureIndex()=73 | lv.getSignature()=[Ljava/lang/String; |lv.getIndex()=0
    --------------------第 1 個局部變量的信息
    lv.getStartPC()=8| lv.getLength=51| lv.getNameIndex()=74 | lv.getName()=inst| lv.getSignatureIndex()=13 | lv.getSignature()=LStringBuilder; |lv.getIndex()=1
    --------------------第 2 個局部變量的信息
    lv.getStartPC()=10| lv.getLength=48| lv.getNameIndex()=52 | lv.getName()=i| lv.getSignatureIndex()=49 | lv.getSignature()=I |lv.getIndex()=2
    --------------------第 3 個局部變量的信息
    lv.getStartPC()=24| lv.getLength=25| lv.getNameIndex()=50 | lv.getName()=result| lv.getSignatureIndex()=51 | lv.getSignature()=Ljava/lang/String; |lv.getIndex()=3
    完整的code.toString的信息
    public static void main(String[] argv)
    Code(max_stack = 4, max_locals = 4, code_length = 59)
    0: new (1)
    3: dup
    4: invokespecial StringBuilder. ()V (55)
    7: astore_1
    8: iconst_0
    9: istore_2
    10: goto #52
    13: aload_1
    14: aload_0
    15: iload_2
    16: aaload
    17: invokestatic java.lang.Integer.parseInt (Ljava/lang/String;)I (56)
    20: invokespecial StringBuilder.buildString (I)Ljava/lang/String; (62)
    23: astore_3
    24: getstatic java.lang.System.out Ljava/io/PrintStream; (37)
    27: new (18)
    30: dup
    31: ldc "Constructed string of length " (64)
    33: invokespecial java.lang.StringBuilder. (Ljava/lang/String;)V (26)
    36: aload_3
    37: invokevirtual java.lang.String.length ()I (66)
    40: invokevirtual java.lang.StringBuilder.append (I)Ljava/lang/StringBuilder; (69)
    43: invokevirtual java.lang.StringBuilder.toString ()Ljava/lang/String; (33)
    46: invokevirtual java.io.PrintStream.println (Ljava/lang/String;)V (43)
    49: iinc %2 1
    52: iload_2
    53: aload_0
    54: arraylength
    55: if_icmplt #13
    58: return

    Attribute(s) =
    LineNumber(0, 17), LineNumber(8, 18), LineNumber(13, 19), LineNumber(24, 20),
    LineNumber(36, 21), LineNumber(46, 20), LineNumber(49, 18), LineNumber(58, 23)

    LocalVariable(start_pc = 0, length = 59, index = 0:String[] argv)
    LocalVariable(start_pc = 8, length = 51, index = 1:StringBuilder inst)
    LocalVariable(start_pc = 10, length = 48, index = 2:int i)
    LocalVariable(start_pc = 24, length = 25, index = 3:String result)

    end method method method-----------------------------------


      回復  更多評論
      
    # re: 用 BCEL 設計字節碼(二)直接在原方法上加指令 2009-08-15 21:08 | Frank_Fang
    這個是修改后的方法的字節碼信息

    --------------------------------33
    --------------------------------33
    0
    2
    CONSTANT_Utf8[1]("SourceFile")
    true
    CONSTANT_Utf8[1]("StringBuilder.java")
    1
    StringBuilder.java
    StringBuilder.java
    ---------------------------------------------------------------------------
    1:CONSTANT_Class[7](name_index = 2)
    2:CONSTANT_Utf8[1]("StringBuilder")
    3:CONSTANT_Class[7](name_index = 4)
    4:CONSTANT_Utf8[1]("java/lang/Object")
    5:CONSTANT_Utf8[1]("<init>")
    6:CONSTANT_Utf8[1]("()V")
    7:CONSTANT_Utf8[1]("Code")
    8:CONSTANT_Methodref[10](class_index = 3, name_and_type_index = 9)
    9:CONSTANT_NameAndType[12](name_index = 5, signature_index = 6)
    10:CONSTANT_Utf8[1]("LineNumberTable")
    11:CONSTANT_Utf8[1]("LocalVariableTable")
    12:CONSTANT_Utf8[1]("this")
    13:CONSTANT_Utf8[1]("LStringBuilder;")
    14:CONSTANT_Utf8[1]("buildString")
    15:CONSTANT_Utf8[1]("(I)Ljava/lang/String;")
    16:CONSTANT_String[8](string_index = 17)
    17:CONSTANT_Utf8[1]("")
    18:CONSTANT_Class[7](name_index = 19)
    19:CONSTANT_Utf8[1]("java/lang/StringBuilder")
    20:CONSTANT_Methodref[10](class_index = 21, name_and_type_index = 23)
    21:CONSTANT_Class[7](name_index = 22)
    22:CONSTANT_Utf8[1]("java/lang/String")
    23:CONSTANT_NameAndType[12](name_index = 24, signature_index = 25)
    24:CONSTANT_Utf8[1]("valueOf")
    25:CONSTANT_Utf8[1]("(Ljava/lang/Object;)Ljava/lang/String;")
    26:CONSTANT_Methodref[10](class_index = 18, name_and_type_index = 27)
    27:CONSTANT_NameAndType[12](name_index = 5, signature_index = 28)
    28:CONSTANT_Utf8[1]("(Ljava/lang/String;)V")
    29:CONSTANT_Methodref[10](class_index = 18, name_and_type_index = 30)
    30:CONSTANT_NameAndType[12](name_index = 31, signature_index = 32)
    31:CONSTANT_Utf8[1]("append")
    32:CONSTANT_Utf8[1]("(C)Ljava/lang/StringBuilder;")
    33:CONSTANT_Methodref[10](class_index = 18, name_and_type_index = 34)
    34:CONSTANT_NameAndType[12](name_index = 35, signature_index = 36)
    35:CONSTANT_Utf8[1]("toString")
    36:CONSTANT_Utf8[1]("()Ljava/lang/String;")
    37:CONSTANT_Fieldref[9](class_index = 38, name_and_type_index = 40)
    *********************ConstantFieldref start**********************
    cc.toString : CONSTANT_Class[7](name_index = 39)
    java/lang/System
    cnat.toString : CONSTANT_NameAndType[12](name_index = 41, signature_index = 42)
    out
    Ljava/io/PrintStream;
    **********************ConstantFieldref end*******************************
    38:CONSTANT_Class[7](name_index = 39)
    39:CONSTANT_Utf8[1]("java/lang/System")
    40:CONSTANT_NameAndType[12](name_index = 41, signature_index = 42)
    41:CONSTANT_Utf8[1]("out")
    42:CONSTANT_Utf8[1]("Ljava/io/PrintStream;")
    43:CONSTANT_Methodref[10](class_index = 44, name_and_type_index = 46)
    44:CONSTANT_Class[7](name_index = 45)
    45:CONSTANT_Utf8[1]("java/io/PrintStream")
    46:CONSTANT_NameAndType[12](name_index = 47, signature_index = 28)
    47:CONSTANT_Utf8[1]("println")
    48:CONSTANT_Utf8[1]("length")
    49:CONSTANT_Utf8[1]("I")
    50:CONSTANT_Utf8[1]("result")
    51:CONSTANT_Utf8[1]("Ljava/lang/String;")
    52:CONSTANT_Utf8[1]("i")
    53:CONSTANT_Utf8[1]("main")
    54:CONSTANT_Utf8[1]("([Ljava/lang/String;)V")
    55:CONSTANT_Methodref[10](class_index = 1, name_and_type_index = 9)
    56:CONSTANT_Methodref[10](class_index = 57, name_and_type_index = 59)
    57:CONSTANT_Class[7](name_index = 58)
    58:CONSTANT_Utf8[1]("java/lang/Integer")
    59:CONSTANT_NameAndType[12](name_index = 60, signature_index = 61)
    60:CONSTANT_Utf8[1]("parseInt")
    61:CONSTANT_Utf8[1]("(Ljava/lang/String;)I")
    62:CONSTANT_Methodref[10](class_index = 1, name_and_type_index = 63)
    63:CONSTANT_NameAndType[12](name_index = 14, signature_index = 15)
    64:CONSTANT_String[8](string_index = 65)
    65:CONSTANT_Utf8[1]("Constructed string of length ")
    66:CONSTANT_Methodref[10](class_index = 21, name_and_type_index = 67)
    67:CONSTANT_NameAndType[12](name_index = 48, signature_index = 68)
    68:CONSTANT_Utf8[1]("()I")
    69:CONSTANT_Methodref[10](class_index = 18, name_and_type_index = 70)
    70:CONSTANT_NameAndType[12](name_index = 31, signature_index = 71)
    71:CONSTANT_Utf8[1]("(I)Ljava/lang/StringBuilder;")
    72:CONSTANT_Utf8[1]("argv")
    73:CONSTANT_Utf8[1]("[Ljava/lang/String;")
    74:CONSTANT_Utf8[1]("inst")
    75:CONSTANT_Utf8[1]("SourceFile")
    76:CONSTANT_Utf8[1]("StringBuilder.java")
    77:CONSTANT_Utf8[1]("start test start test start test start test")
    78:CONSTANT_String[8](string_index = 77)
    79:CONSTANT_Utf8[1]("currentTimeMillis")
    80:CONSTANT_Utf8[1]("()J")
    81:CONSTANT_NameAndType[12](name_index = 79, signature_index = 80)
    82:CONSTANT_Methodref[10](class_index = 38, name_and_type_index = 81)
    83:CONSTANT_Utf8[1]("Call to method buildString took ")
    84:CONSTANT_String[8](string_index = 83)
    85:CONSTANT_Utf8[1]("print")
    86:CONSTANT_NameAndType[12](name_index = 85, signature_index = 28)
    87:CONSTANT_Methodref[10](class_index = 44, name_and_type_index = 86)
    88:CONSTANT_Utf8[1]("(J)V")
    89:CONSTANT_NameAndType[12](name_index = 85, signature_index = 88)
    90:CONSTANT_Methodref[10](class_index = 44, name_and_type_index = 89)
    91:CONSTANT_Utf8[1](" ms.")
    92:CONSTANT_String[8](string_index = 91)
    93:CONSTANT_Utf8[1]("end end end end end end end end end end")
    94:CONSTANT_String[8](string_index = 93)
    95:CONSTANT_Utf8[1]("starttime")
    96:CONSTANT_Utf8[1]("J")
    --------------------------域----------------------------
    -----------域的長度,此類定義的成員變量的個數-------------0




    start method method method-----------------------------------
    方法訪問標志
    1
    方法訪問名稱
    <init>
    CONSTANT_Utf8[1]("<init>")
    方法簽名
    ()V
    CONSTANT_Utf8[1]("()V")
    方法的參數類型
    方法的返回類型
    void
    方法的ExceptionTable屬性----------方法的throws聲明的異常信息------------------------
    exceptionTable==null true
    方法的Code---------------------------------------------
    7
    CONSTANT_Utf8[1]("Code")
    code.getLength() 屬性結構中attribute length 的長度 47
    code.getCode().length 屬性結構中的code數組的長度 code_length 的長度 5
    給出該方法在執行中任何點操作數棧上字的最大個數 1
    給出該方法使用的局部變量的個數,包括調用時傳遞給方法的參數 1
    code的字節信息調用code.getCode()返回byte[] [B@1ffb8dc
    ce.length===========0
    code 內部結構中的各異常信息結構------------方法內部的try 塊catch的信息----------
    方法的Code的LineNumberTable
    方法的Code的LocalVariableTable
    LocalVariableTable
    localvariableTable==null false
    lvs==null false
    lvs.length======1
    --------------------第 0 個局部變量的信息
    lv.getStartPC()=0| lv.getLength=5| lv.getNameIndex()=12 | lv.getName()=this| lv.getSignatureIndex()=13 | lv.getSignature()=LStringBuilder; |lv.getIndex()=0
    完整的code.toString的信息
    public void <init>()
    Code(max_stack = 1, max_locals = 1, code_length = 5)
    0: aload_0
    1: invokespecial java.lang.Object.<init> ()V (8)
    4: return

    Attribute(s) =
    LineNumber(0, 2)
    LocalVariable(start_pc = 0, length = 5, index = 0:StringBuilder this)

    end method method method-----------------------------------


    start method method method-----------------------------------
    方法訪問標志
    9
    方法訪問名稱
    main
    CONSTANT_Utf8[1]("main")
    方法簽名
    ([Ljava/lang/String;)V
    CONSTANT_Utf8[1]("([Ljava/lang/String;)V")
    方法的參數類型
    java.lang.String[]方法的返回類型
    void
    方法的ExceptionTable屬性----------方法的throws聲明的異常信息------------------------
    exceptionTable==null true
    方法的Code---------------------------------------------
    7
    CONSTANT_Utf8[1]("Code")
    code.getLength() 屬性結構中attribute length 的長度 159
    code.getCode().length 屬性結構中的code數組的長度 code_length 的長度 59
    給出該方法在執行中任何點操作數棧上字的最大個數 4
    給出該方法使用的局部變量的個數,包括調用時傳遞給方法的參數 4
    code的字節信息調用code.getCode()返回byte[] [B@ec16a4
    ce.length===========0
    code 內部結構中的各異常信息結構------------方法內部的try 塊catch的信息----------
    方法的Code的LineNumberTable
    方法的Code的LocalVariableTable
    LocalVariableTable
    localvariableTable==null false
    lvs==null false
    lvs.length======4
    --------------------第 0 個局部變量的信息
    lv.getStartPC()=0| lv.getLength=59| lv.getNameIndex()=72 | lv.getName()=argv| lv.getSignatureIndex()=73 | lv.getSignature()=[Ljava/lang/String; |lv.getIndex()=0
    --------------------第 1 個局部變量的信息
    lv.getStartPC()=8| lv.getLength=51| lv.getNameIndex()=74 | lv.getName()=inst| lv.getSignatureIndex()=13 | lv.getSignature()=LStringBuilder; |lv.getIndex()=1
    --------------------第 2 個局部變量的信息
    lv.getStartPC()=10| lv.getLength=48| lv.getNameIndex()=52 | lv.getName()=i| lv.getSignatureIndex()=49 | lv.getSignature()=I |lv.getIndex()=2
    --------------------第 3 個局部變量的信息
    lv.getStartPC()=24| lv.getLength=25| lv.getNameIndex()=50 | lv.getName()=result| lv.getSignatureIndex()=51 | lv.getSignature()=Ljava/lang/String; |lv.getIndex()=3
    完整的code.toString的信息
    public static void main(String[] argv)
    Code(max_stack = 4, max_locals = 4, code_length = 59)
    0: new <StringBuilder> (1)
    3: dup
    4: invokespecial StringBuilder.<init> ()V (55)
    7: astore_1
    8: iconst_0
    9: istore_2
    10: goto #52
    13: aload_1
    14: aload_0
    15: iload_2
    16: aaload
    17: invokestatic java.lang.Integer.parseInt (Ljava/lang/String;)I (56)
    20: invokespecial StringBuilder.buildString (I)Ljava/lang/String; (62)
    23: astore_3
    24: getstatic java.lang.System.out Ljava/io/PrintStream; (37)
    27: new <java.lang.StringBuilder> (18)
    30: dup
    31: ldc "Constructed string of length " (64)
    33: invokespecial java.lang.StringBuilder.<init> (Ljava/lang/String;)V (26)
    36: aload_3
    37: invokevirtual java.lang.String.length ()I (66)
    40: invokevirtual java.lang.StringBuilder.append (I)Ljava/lang/StringBuilder; (69)
    43: invokevirtual java.lang.StringBuilder.toString ()Ljava/lang/String; (33)
    46: invokevirtual java.io.PrintStream.println (Ljava/lang/String;)V (43)
    49: iinc %2 1
    52: iload_2
    53: aload_0
    54: arraylength
    55: if_icmplt #13
    58: return

    Attribute(s) =
    LineNumber(0, 17), LineNumber(8, 18), LineNumber(13, 19), LineNumber(24, 20),
    LineNumber(36, 21), LineNumber(46, 20), LineNumber(49, 18), LineNumber(58, 23)

    LocalVariable(start_pc = 0, length = 59, index = 0:String[] argv)
    LocalVariable(start_pc = 8, length = 51, index = 1:StringBuilder inst)
    LocalVariable(start_pc = 10, length = 48, index = 2:int i)
    LocalVariable(start_pc = 24, length = 25, index = 3:String result)

    end method method method-----------------------------------


    start method method method-----------------------------------
    方法訪問標志
    2
    方法訪問名稱
    buildString
    CONSTANT_Utf8[1]("buildString")
    方法簽名
    (I)Ljava/lang/String;
    CONSTANT_Utf8[1]("(I)Ljava/lang/String;")
    方法的參數類型
    int方法的返回類型
    java.lang.String
    方法的ExceptionTable屬性----------方法的throws聲明的異常信息------------------------
    exceptionTable==null true
    方法的Code---------------------------------------------
    7
    CONSTANT_Utf8[1]("Code")
    code.getLength() 屬性結構中attribute length 的長度 198
    code.getCode().length 屬性結構中的code數組的長度 code_length 的長度 96
    給出該方法在執行中任何點操作數棧上字的最大個數 6
    給出該方法使用的局部變量的個數,包括調用時傳遞給方法的參數 6
    code的字節信息調用code.getCode()返回byte[] [B@1c29ab2
    ce.length===========0
    code 內部結構中的各異常信息結構------------方法內部的try 塊catch的信息----------
    方法的Code的LineNumberTable
    方法的Code的LocalVariableTable
    LocalVariableTable
    localvariableTable==null false
    lvs==null false
    lvs.length======5
    --------------------第 0 個局部變量的信息
    lv.getStartPC()=13| lv.getLength=83| lv.getNameIndex()=12 | lv.getName()=this| lv.getSignatureIndex()=13 | lv.getSignature()=LStringBuilder; |lv.getIndex()=0
    --------------------第 1 個局部變量的信息
    lv.getStartPC()=13| lv.getLength=83| lv.getNameIndex()=48 | lv.getName()=length| lv.getSignatureIndex()=49 | lv.getSignature()=I |lv.getIndex()=1
    --------------------第 2 個局部變量的信息
    lv.getStartPC()=16| lv.getLength=80| lv.getNameIndex()=50 | lv.getName()=result| lv.getSignatureIndex()=51 | lv.getSignature()=Ljava/lang/String; |lv.getIndex()=2
    --------------------第 3 個局部變量的信息
    lv.getStartPC()=18| lv.getLength=40| lv.getNameIndex()=52 | lv.getName()=i| lv.getSignatureIndex()=49 | lv.getSignature()=I |lv.getIndex()=3
    --------------------第 4 個局部變量的信息
    lv.getStartPC()=0| lv.getLength=96| lv.getNameIndex()=95 | lv.getName()=starttime| lv.getSignatureIndex()=96 | lv.getSignature()=J |lv.getIndex()=4
    完整的code.toString的信息
    private String buildString(int length)
    Code(max_stack = 6, max_locals = 6, code_length = 96)
    0: getstatic java.lang.System.out Ljava/io/PrintStream; (37)
    3: ldc "start test start test start test start test" (78)
    5: invokevirtual java.io.PrintStream.println (Ljava/lang/String;)V (43)
    8: invokestatic java.lang.System.currentTimeMillis ()J (82)
    11: lstore %4
    13: ldc "" (16)
    15: astore_2
    16: iconst_0
    17: istore_3
    18: goto #50
    21: new <java.lang.StringBuilder> (18)
    24: dup
    25: aload_2
    26: invokestatic java.lang.String.valueOf (Ljava/lang/Object;)Ljava/lang/String; (20)
    29: invokespecial java.lang.StringBuilder.<init> (Ljava/lang/String;)V (26)
    32: iload_3
    33: bipush 26
    35: irem
    36: bipush 97
    38: iadd
    39: i2c
    40: invokevirtual java.lang.StringBuilder.append (C)Ljava/lang/StringBuilder; (29)
    43: invokevirtual java.lang.StringBuilder.toString ()Ljava/lang/String; (33)
    46: astore_2
    47: iinc %3 1
    50: iload_3
    51: iload_1
    52: if_icmplt #21
    55: getstatic java.lang.System.out Ljava/io/PrintStream; (37)
    58: aload_2
    59: invokevirtual java.io.PrintStream.println (Ljava/lang/String;)V (43)
    62: getstatic java.lang.System.out Ljava/io/PrintStream; (37)
    65: dup
    66: dup
    67: ldc "Call to method buildString took " (84)
    69: invokevirtual java.io.PrintStream.print (Ljava/lang/String;)V (87)
    72: invokestatic java.lang.System.currentTimeMillis ()J (82)
    75: lload %4
    77: lsub
    78: invokevirtual java.io.PrintStream.print (J)V (90)
    81: ldc " ms." (92)
    83: invokevirtual java.io.PrintStream.println (Ljava/lang/String;)V (43)
    86: getstatic java.lang.System.out Ljava/io/PrintStream; (37)
    89: ldc "end end end end end end end end end end" (94)
    91: invokevirtual java.io.PrintStream.println (Ljava/lang/String;)V (43)
    94: aload_2
    95: areturn

    Attribute(s) =
    LocalVariable(start_pc = 13, length = 83, index = 0:StringBuilder this)
    LocalVariable(start_pc = 13, length = 83, index = 1:int length)
    LocalVariable(start_pc = 16, length = 80, index = 2:String result)
    LocalVariable(start_pc = 18, length = 40, index = 3:int i)
    LocalVariable(start_pc = 0, length = 96, index = 4:long starttime)
    LineNumber(13, 6), LineNumber(16, 7), LineNumber(21, 8), LineNumber(47, 7),
    LineNumber(55, 10), LineNumber(94, 12)

    end method method method-----------------------------------


    可以看出局部變量this 的start_pc顯然是不正確的
      回復  更多評論
      
    主站蜘蛛池模板: 亚洲av中文无码乱人伦在线观看| 国产卡二卡三卡四卡免费网址 | 97无码人妻福利免费公开在线视频| 亚洲精品美女在线观看| 精品国产香蕉伊思人在线在线亚洲一区二区 | 青青草97国产精品免费观看| 亚洲精品亚洲人成在线播放| 亚洲国产成人高清在线观看| 亚洲狠狠爱综合影院婷婷| 毛片网站免费在线观看| 国产精彩免费视频| 99久久免费精品视频| 中文精品人人永久免费 | 国产在线观看免费完整版中文版 | 久久久久亚洲精品中文字幕| 日本二区免费一片黄2019| www视频免费看| 中文字幕免费视频一| 在线观看免费视频网站色| 久久精品无码专区免费| 国产亚洲Av综合人人澡精品| 亚洲人成网站18禁止| 国产成人精品日本亚洲直接| 亚洲制服丝袜一区二区三区| 久久久亚洲AV波多野结衣| 久久综合亚洲色一区二区三区| 久久亚洲成a人片| 久久久久久亚洲精品| 亚洲人成电影亚洲人成9999网| 亚洲阿v天堂在线| 久久亚洲国产伦理| 亚洲无删减国产精品一区| 亚洲尹人香蕉网在线视颅| 亚洲精品美女视频| 激情亚洲一区国产精品| 亚洲AV综合色区无码二区偷拍| 亚洲一级黄色大片| 伊人久久五月丁香综合中文亚洲| 亚洲一卡2卡3卡4卡5卡6卡| 亚洲欧美日韩中文无线码| 亚洲a∨国产av综合av下载 |