A JVM bytecode generator for ASTs compatible with tools.analyzer[.jvm].
- Example Usage
- Differences From Clojure
- Releases and Dependency Information
- Changelog
- Public API
- Developer Information
- License
When trying out tools.emitter.jvm
be careful not to include in your project.clj's :dependencies
a different version of tools.analyzer.jvm or tools.analyzer than the one required by tools.emitter.jvm
otherwise the library probably won't work and trying to evaluate clojure forms with it will likely produce errors.
user=> (require '[clojure.tools.emitter.jvm :as e])
nil
user=> (e/eval '(+ 1 2))
3
user=> (e/eval '(+ 1 2) {:debug? true})
// class version 50.0 (50)
// access flags 0x31
public final class user$fn__6242 extends clojure/lang/AFunction implements clojure/lang/IFn$L {
// compiled from: user$fn__6242
// access flags 0x9
public static <clinit>()V
RETURN
MAXSTACK = 0
MAXLOCALS = 0
// access flags 0x1
public <init>()V
ALOAD 0
INVOKESPECIAL clojure/lang/AFunction.<init> ()V
RETURN
MAXSTACK = 1
MAXLOCALS = 1
// access flags 0x1
public invokePrim()J
L0
LINENUMBER 1 L0
LCONST_1
LDC 2
ACONST_NULL
ASTORE 0
INVOKESTATIC clojure/lang/Numbers.add (JJ)J
LRETURN
LOCALVARIABLE this Lclojure/lang/AFunction; L0 L0 0
MAXSTACK = 5
MAXLOCALS = 1
// access flags 0x1
public invoke()Ljava/lang/Object;
ALOAD 0
INVOKEVIRTUAL user$fn__6242.invokePrim ()J
INVOKESTATIC clojure/lang/RT.box (J)Ljava/lang/Number;
ARETURN
MAXSTACK = 2
MAXLOCALS = 1
}
3
user=> (e/load "clojure.pprint")
nil
user=> (clojure.pprint/pprint 1)
1
While the bytecode produced by tools.emitter.jvm
is similar to the one produces by Clojure itself, there are some differences:
tools.emitter.jvm
is capable of clearing locals closed over by loops, in the loop exit pathtools.emitter.jvm
clears the "this" local before the last tail call in a method, see CLJ-1250tools.emitter.jvm
clears unused locals after their creationtools.emitter.jvm
hoists loop and try bodies into separate methods rather than wrapping them in a fn, see CLJ-701tools.emitter.jvm
emits keyword invoke callsites only when the keyword is not namespaces, see CLJ-1469tools.emitter.jvm
emits typed bytecode, enforcing any explicit tag, this breaks some functions inclojure.core
likens-interns
. This behaviour might be reconsidered in the future.tools.emitter.jvm
handles CLJ-1330
clojure.tools.emitter.jvm/eval
is currently between 5x and 8x slower than clojure.core/eval
- Cognitect (http://cognitect.com/) has sponsored tools.emitter.jvm development (https://groups.google.com/d/msg/clojure/iaP16MHpX0E/EMtnGmOz-rgJ)
- Ambrose BS (https://twitter.com/ambrosebs) has sponsored tools.emitter.jvm development in his typed clojure campaign (http://www.indiegogo.com/projects/typed-clojure).
YourKit has given an open source license for their profiler, greatly simplifying the profiling of tools.emitter.jvm performance.
YourKit is kindly supporting open source projects with its full-featured Java Profiler. YourKit, LLC is the creator of innovative and intelligent tools for profiling Java and .NET applications. Take a look at YourKit's leading software products:
Latest stable release: 0.1.0-beta5
Leiningen dependency information:
[org.clojure/tools.emitter.jvm "0.1.0-beta5"]
Maven dependency information:
<dependency>
<groupId>org.clojure</groupId>
<artifactId>tools.emitter.jvm</artifactId>
<version>0.1.0-beta5</version>
</dependency>
Copyright © 2013-2023 Nicola Mometto, Rich Hickey & contributors.
Distributed under the Eclipse Public License, the same as Clojure.