簡體   English   中英

如何從repl檢查Clojure生成的java字節碼?

[英]How to inspect java bytecode generated by Clojure from the repl?

我找不到關於這個主題的很多信息。 看起來jswat可以用來完成這個,但我找不到任何一步一步的教程。

您可以使用no-disassemble庫。 https://github.com/gtrak/no.disassemble

在您的Leiningen項目中添加插件:plugins [[lein-nodisassemble "0.1.3"]]

=> (use 'no.disassemble)
nil
=> (println (disassemble (fn [] (+ 1 2))))
// Compiled from form-init9238501799627991.clj (version 1.5 : 49.0, super bit)
public final class vecperf.bench$eval1426$fn__1427 extends clojure.lang.AFunction {

  // Field descriptor #7 Lclojure/lang/Var;
  public static final clojure.lang.Var const__0;

  // Field descriptor #9 Ljava/lang/Object;
  public static final java.lang.Object const__1;

  // Field descriptor #9 Ljava/lang/Object;
  public static final java.lang.Object const__2;

  // Method descriptor #12 ()V
  // Stack: 2, Locals: 0
  public static {};
     0  ldc <String "clojure.core"> [14]
     2  ldc <String "+"> [16]
     4  invokestatic clojure.lang.RT.var(java.lang.String, java.lang.String) : clojure.lang.Var [22]
     7  checkcast clojure.lang.Var [24]
    10  putstatic vecperf.bench$eval1426$fn__1427.const__0 : clojure.lang.Var [26]
    13  lconst_1
    14  invokestatic java.lang.Long.valueOf(long) : java.lang.Long [32]
    17  putstatic vecperf.bench$eval1426$fn__1427.const__1 : java.lang.Object [34]
    20  ldc2_w <Long 2> [35]
    23  invokestatic java.lang.Long.valueOf(long) : java.lang.Long [32]
    26  putstatic vecperf.bench$eval1426$fn__1427.const__2 : java.lang.Object [38]
    29  return
      Line numbers:
        [pc: 0, line: 1]

  // Method descriptor #12 ()V
  // Stack: 1, Locals: 1
  public bench$eval1426$fn__1427();
    0  aload_0 [this]
    1  invokespecial clojure.lang.AFunction() [41]
    4  return
      Line numbers:
        [pc: 0, line: 1]

  // Method descriptor #43 ()Ljava/lang/Object;
  // Stack: 4, Locals: 1
  public java.lang.Object invoke();
     0  lconst_1
     1  ldc2_w <Long 2> [35]
     4  invokestatic clojure.lang.Numbers.add(long, long) : long [49]
     7  invokestatic clojure.lang.Numbers.num(long) : java.lang.Number [53]
    10  areturn
      Line numbers:
        [pc: 0, line: 1]
        [pc: 0, line: 1]
      Local variable table:
        [pc: 0, pc: 10] local: this index: 0 type: java.lang.Object

}

怎么樣: https//github.com/nathanmarz/serializable-fn

來自自述文件演示:

(use 'serializable.fn)

;; note that this function being created has a function value in its closure
(def f (let [x + c 2]
          (fn [a b] (x a b c))))

(println (f 1 2))

;; 5

(def b (serialize f))

(println (seq b))

;; (0 0 0 2 0 0 0 -79 0 0 0 2 0 1 99 0 0 0 90 0 0 0 3 0 0 0 82 -84 -19 0 5 115 114 0 14 106 97 118 97 46 108 97 110 103 46 76 111 110 103 59 -117 -28 -112 -52 -113 35 -33 2 0 1 74 0 5 118 97 108 117 101 120 114 0 16 106 97 118 97 46 108 97 110 103 46 78 117 109 98 101 114 -122 -84 -107 29 11 -108 -32 -117 2 0 0 120 112 0 0 0 0 0 0 0 2 0 1 120 0 0 0 25 0 0 0 1 0 0 0 17 0 12 99 108 111 106 117 114 101 46 99 111 114 101 0 1 43 0 4 117 115 101 114 0 36 40 115 101 114 105 97 108 105 122 97 98 108 101 46 102 110 47 102 110 32 91 97 32 98 93 32 40 120 32 97 32 98 32 99 41 41)

;; now, restart the repl

(def b
(byte-array (map byte '(0 0 0 2 0 0 0 -79 0 0 0 2 0 1 99 0 0 0 90 0 0 0 3 0 0 0 82 -84 -19 0 5 115 114 0 14 106 97 118 97 46 108 97 110 103 46 76 111 110 103 59 -117 -28 -112 -52 -113 35 -33 2 0 1 74 0 5 118 97 108 117 101 120 114 0 16 106 97 118 97 46 108 97 110 103 46 78 117 109 98 101 114 -122 -84 -107 29 11 -108 -32 -117 2 0 0 120 112 0 0 0 0 0 0 0 2 0 1 120 0 0 0 25 0 0 0 1 0 0 0 17 0 12 99 108 111 106 117 114 101 46 99 111 114 101 0 1 43 0 4 117 115 101 114 0 36 40 115 101 114 105 97 108 105 122 97 98 108 101 46 102 110 47 102 110 32 91 97 32 98 93 32 40 120 32 97 32 98 32 99 41 41))))

(use 'serializable.fn)

(def f (deserialize b))

(println f 1 2)

;; 5

看看蘋果酒反編譯 僅在編輯器是Emacs時才有用,因為它是Clojure IDE的擴展和Emacs的REPL(構建在nREPL之上)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM