Skip to content

Instantly share code, notes, and snippets.

@eerohele
Last active February 4, 2022 19:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eerohele/9da6087df28fc06c2db490e94c4fd0a5 to your computer and use it in GitHub Desktop.
Save eerohele/9da6087df28fc06c2db490e94c4fd0a5 to your computer and use it in GitHub Desktop.
bytecode.clj
(ns tutkain.bytecode
(:require [clojure.java.io :as io]
[tutkain.backchannel :refer [handle respond-to]])
(:import (java.io PrintWriter StringWriter)
(java.util.spi ToolProvider)
(java.nio.file Files)
(java.nio.file.attribute FileAttribute)))
(set! *warn-on-reflection* true)
(defonce javap
(->
(ToolProvider/findFirst "javap")
(.orElseThrow)
(delay)))
(defn class-path
[dir qualified-symbol]
(.getCanonicalPath
(io/file dir
(str
(.replace (namespace qualified-symbol) \. \/)
\$
(munge (name qualified-symbol))
".class"))))
(defn bytecode
[qualified-symbol]
(let [outs (StringWriter.)
outp (PrintWriter. outs)
errs (StringWriter.)
errp (PrintWriter. errs)
temp-dir (.toFile (Files/createTempDirectory "tutkain-classes-" (into-array FileAttribute [])))]
(try
(binding [*compile-path* (.getCanonicalPath temp-dir)]
(-> qualified-symbol namespace symbol compile)
(.run ^ToolProvider @javap outp errp (into-array String ["-c" "-l" "-verbose" "-constants" "-private" (class-path temp-dir qualified-symbol)]))
(.toString outs))
(finally
(.delete temp-dir)))))
(defmethod handle :bytecode
[{:keys [ns sym] :as message}]
(respond-to message {:bytecode (bytecode (ns-resolve ns sym))}))
(comment
(println (bytecode 'clojure.tools.analyzer.ast/children))
,,,)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment