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

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

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

    莊周夢蝶

    生活、程序、未來
       :: 首頁 ::  ::  :: 聚合  :: 管理

    Clojure Hacking Guide

    Posted on 2010-07-11 12:07 dennis 閱讀(3606) 評論(1)  編輯  收藏 所屬分類: 動態語言javaClojure
        這題目起的嘩眾取寵,其實只是想介紹下怎么查看Clojure動態生成的字節碼,這對分析Clojure的內部實現很重要。

        第一步,下載最新的Clojure 1.1.0源碼并解壓,并導入到你喜歡的IDE。

        其次,下載asm 3.0的源碼并解壓。

        第三,刪除Clojure 1.1.0源碼中的clojure.asm包。clojure并不是引用asm的jar包,而是將asm的源碼合并到clojure中,并且刪除一些只會在調試階段用到的package和class,保留使用asm的最小源碼集合,這可能是處于防止asm不同版本的jar包沖突以及縮小clojure大小的考慮。

        第四,將asm 3.0源碼拷入clojure的源碼中,并將包org.objectweb.asm包括子包整體重名名為clojure.asm。

        第五步,修改Clojure源碼,加入TraceClassVisitor的適配器,用于跟蹤字節碼生成,這需要修改clojure.lang.Compiler類中的兩個compile方法,找到類似
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    // ClassWriter cw = new ClassWriter(0);
    ClassVisitor cv = cw;

    這樣的代碼,將cv修改為TraceClassVisitor:
     ClassVisitor cv = new TraceClassVisitor(new CheckClassAdapter(cw), new PrintWriter(System.out));

        TraceClassVisitor的第二個參數指定將跟蹤到的字節碼輸出到哪里,這里簡單地輸出到標準輸出方便查看。

        第六步,接下來可以嘗試下我們修改過的clojure怎么動態生成字節碼,啟動REPL,
    java clojure.main

    啟動階段就會輸出一些字節碼信息,主要預先加載的一些標準庫函數,如clojure.core中的函數等,REPL啟動完畢,隨便輸入一個表達式都將看到生成的字節碼
    user=> (+ 1 2)

    輸出類似

    compile 1
    // class version 49.0 (49)
    // access flags 33
    public class user$eval__4346 extends clojure/lang/AFunction  {

      
    // compiled from: NO_SOURCE_FILE
      
    // debug info: SMAP
    eval__4346.java
    Clojure
    *S Clojure
    *F
    + 1 NO_SOURCE_FILE
    NO_SOURCE_PATH
    *L
    0#1,1:0
    *E

      
    // access flags 25
      public final static Lclojure/lang/Var; const__0

      
    // access flags 25
      public final static Ljava/lang/Object; const__1

      
    // access flags 25
      public final static Ljava/lang/Object; const__2

      
    // access flags 9
      public static <clinit>()V
       L0
        LINENUMBER 
    2 L0
        LDC 
    "clojure.core"
        LDC 
    "+"
        INVOKESTATIC clojure
    /lang/RT.var (Ljava/lang/String;Ljava/lang/String;)Lclojure/lang/Var;
        CHECKCAST clojure
    /lang/Var
        PUTSTATIC user$eval__4346.const__0 : Lclojure
    /lang/Var;
        ICONST_1
        INVOKESTATIC java
    /lang/Integer.valueOf (I)Ljava/lang/Integer;
        PUTSTATIC user$eval__4346.const__1 : Ljava
    /lang/Object;
        ICONST_2
        INVOKESTATIC java
    /lang/Integer.valueOf (I)Ljava/lang/Integer;
        PUTSTATIC user$eval__4346.const__2 : Ljava
    /lang/Object;
        RETURN
        MAXSTACK 
    = 0
        MAXLOCALS 
    = 0

      
    // access flags 1
      public <init>()V
       L0
        LINENUMBER 
    2 L0
       L1
        ALOAD 
    0
        INVOKESPECIAL clojure
    /lang/AFunction.<init> ()V
       L2
        RETURN
        MAXSTACK 
    = 0
        MAXLOCALS 
    = 0

      
    // access flags 1
      public invoke()Ljava/lang/Object; throws java/lang/Exception 
       L0
        LINENUMBER 
    2 L0
       L1
        LINENUMBER 
    2 L1
        GETSTATIC user$eval__4346.const__1 : Ljava/lang/Object;
        GETSTATIC user$eval__4346.const__2 : Ljava
    /lang/Object;
        INVOKESTATIC clojure
    /lang/Numbers.add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Number;

       L2
        LOCALVARIABLE 
    this Ljava/lang/Object; L0 L2 0
        ARETURN
        MAXSTACK 
    = 0
        MAXLOCALS 
    = 0
    }
    3

    3就是表達式的結果。可以看到,一個表達式生成了一個class。其中<clinit>是靜態初始化塊,主要是初始化表達式中的字面常量;<init>不用說,默認的構造函數;invoke是核心方法,表達式生成的class,new一個實例后調用的就是invoke方法,執行實際的代碼,高亮部分加載了兩個常量,并執行Number.add方法。

    最后,請Happy hacking!。




    評論

    # re: Clojure Hacking Guide  回復  更多評論   

    2010-07-12 11:46 by dasdas
    dasdsadas http://www.51pkwg.com DNF免費外掛 http://www.1ploan.com 一點貸 http://www.tatayouyue.com http://www.1ploan.com/forum.do/list/qryFirsort_7.html dasdasdasda
    主站蜘蛛池模板: 男人扒开添女人下部免费视频| 亚洲AV综合色区无码二区爱AV| 毛片免费全部播放无码| 国产亚洲精品欧洲在线观看| 亚洲国产精品成人综合久久久| 亚洲午夜成人精品电影在线观看| 成人午夜免费福利视频| 免费无码又爽又刺激网站直播 | 四虎影视在线影院在线观看免费视频 | 国产成人AV片无码免费| 无码人妻一区二区三区免费视频 | 亚洲网址在线观看你懂的| 亚洲高清专区日韩精品| 国产gv天堂亚洲国产gv刚刚碰 | 四虎一区二区成人免费影院网址 | 亚洲国产精品SSS在线观看AV| 国产不卡免费视频| 亚洲AV无码专区日韩| 亚洲一区二区高清| 亚洲成AV人片一区二区| 亚洲成AV人片在线观看无码| 久久被窝电影亚洲爽爽爽| 亚洲视频2020| 中文字幕在线观看亚洲日韩| 亚洲人成电影网站久久| 亚洲精品无码国产片| 九九九精品视频免费| 国内精品久久久久影院免费 | 成人免费无码H在线观看不卡| 久久国产精品免费| 亚洲成人在线免费观看| 免费人成在线观看播放国产| 国产亚洲老熟女视频| 中文字幕亚洲免费无线观看日本| 亚洲日韩一中文字暮| 国产精品无码免费专区午夜| 久久99热精品免费观看动漫| 国产精品久久久久久久久久免费 | 国产女高清在线看免费观看| 亚洲成AV人在线观看天堂无码| 亚洲福利视频网站|