{"id":27559172,"url":"https://github.com/jgpc42/insn","last_synced_at":"2025-04-19T23:34:59.838Z","repository":{"id":24115170,"uuid":"100664799","full_name":"jgpc42/insn","owner":"jgpc42","description":"Functional JVM bytecode generation for Clojure.","archived":false,"fork":false,"pushed_at":"2025-01-11T13:56:22.000Z","size":286,"stargazers_count":201,"open_issues_count":1,"forks_count":5,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-04-19T23:34:53.917Z","etag":null,"topics":["asm","bytecode-instructions","clojure","jvm-bytecode"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jgpc42.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"jgpc42"}},"created_at":"2017-08-18T02:31:45.000Z","updated_at":"2025-04-10T22:31:35.000Z","dependencies_parsed_at":"2024-01-08T19:01:55.477Z","dependency_job_id":"c7907afd-4957-4b9e-b9d8-f5adf9a50685","html_url":"https://github.com/jgpc42/insn","commit_stats":{"total_commits":149,"total_committers":2,"mean_commits":74.5,"dds":0.006711409395973145,"last_synced_commit":"a76a59ed5148d41fa2a3d17d7f0ce5344647de4d"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgpc42%2Finsn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgpc42%2Finsn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgpc42%2Finsn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgpc42%2Finsn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jgpc42","download_url":"https://codeload.github.com/jgpc42/insn/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249830834,"owners_count":21331356,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asm","bytecode-instructions","clojure","jvm-bytecode"],"created_at":"2025-04-19T23:34:59.404Z","updated_at":"2025-04-19T23:34:59.829Z","avatar_url":"https://github.com/jgpc42.png","language":"Clojure","funding_links":["https://github.com/sponsors/jgpc42"],"categories":[],"sub_categories":[],"readme":"[![Clojars Project](https://img.shields.io/clojars/v/insn.svg)](https://clojars.org/insn)\n[![](https://github.com/jgpc42/insn/workflows/Test%20runner/badge.svg)][ci]\n\n### Dependency and version information\n\u003cdetails\u003e\n  \u003csummary\u003eClick to show\u003c/summary\u003e\n\n\u003e :warning: This library uses a recent version of [`asm`][asm-jar] which can cause dependency issues. [See here][asm-ver] for more.\n\n[Leiningen][lein]\n\n``` clojure\n[insn \"0.5.4\"]\n```\n\n[tools.deps][deps]\n\n```clojure\n{insn/insn {:mvn/version \"0.5.4\"}}\n```\n\n[Maven][maven]\n\n``` xml\n\u003cdependency\u003e\n  \u003cgroupId\u003einsn\u003c/groupId\u003e\n  \u003cartifactId\u003einsn\u003c/artifactId\u003e\n  \u003cversion\u003e0.5.4\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nLTS JDK versions 8, 11, 17 and 21 and Clojure versions 1.7 to 1.12 are currently [tested against][ci].\n\u003c/details\u003e\n\n### What is it?\n\nThis library provides a functional abstraction over [ASM][asm] for generating JVM bytecode. ASM is the library that Clojure itself uses to dynamically compile Clojure code into code that can be run on the JVM.\n\n### Quick start\n\nLet's begin by creating a simple class, equivalent to the following Java code.\n\n```java\npackage my.pkg;\n\npublic class Adder {\n    public static int VALUE = 42;\n    public long add (int n) {\n        return (long) (VALUE + n);\n    }\n}\n```\n\nThe class is specified as a map. The class fields and methods are sequences of maps giving the members of said class.\n\n```clojure\n(def class-data\n  {:name 'my.pkg.Adder\n   :fields [{:flags #{:public :static}, :name \"VALUE\", :type :int, :value 42}]\n   :methods [{:flags #{:public}, :name \"add\", :desc [:int :long]\n              :emit [[:getstatic :this \"VALUE\" :int]\n                     [:iload 1]\n                     [:iadd]\n                     [:i2l]\n                     [:lreturn]]}]})\n```\n\nAbove, we described in data the same information expressed by the Java code, except the method body was given as a sequence of bytecode instructions. (Note: unlike Java, the method return value is specified via the `:desc` key as the last element). If you aren't fluent in JVM bytecode instruction syntax, I would suggest reading chapter 3 of the excellent tutorial pdf from the ASM [site][pdf].\n\n`:emit` can also be a fn that is passed the ASM `MethodVisitor` object to write the method bytecode as shown in [this example][emitfn].\n\nNow to write the bytecode.\n\n```clojure\n(require '[insn.core :as insn])\n\n(def result (insn/visit class-data))\n```\n\nThe `result` is a map containing the generated class's packaged-prefixed `:name` and `:bytes`, the latter being a byte array. This information is all you need to give to a ClassLoader to define your class.\n\nFor convenience, we can use `insn.core/define` to define the class for us.\n\n```clojure\n(def class-object (insn/define class-data)) ;; =\u003e my.pkg.Adder\n(-\u003e class-object .newInstance (.add 17))    ;; =\u003e 59\n```\n\nNote that you can also pass `result` to `define`, the class will not be regenerated. Also note, like Java, since we did not define any constructors, a public no-argument constructor that simply calls the superclass constructor was generated for us.\n\nIf you are evaluating the code snippets above in the REPL, you can also just do:\n\n```clojure\n(.add (my.pkg.Adder.) 17) ;; =\u003e 59\n```\n\nSince, by default, `define` loads the class using Clojure's own `DynamicClassLoader`, meaning the class will be *first class* to subsequent evaluations in the running Clojure environment.\n\n### More information\n\nFor additional usage examples and topics, see the [wiki][wiki]. For a complete reference, see the [docs][doc]. The fairly comprehensive [test suite][tests] is also demonstrative and should be easy to follow.\n\n### Running the tests\n\n```bash\nlein test\n```\n\nOr, `lein test-all` for all supported Clojure versions.\n\nThe tests can also be run against all supported Java versions (via [`docker`][docker]) with:\n\n``` bash\n./test-all-jdk.sh\n```\n\n### Similar libraries\n\n  - [tools.emitter.jvm](https://github.com/clojure/tools.emitter.jvm)\n    * Does not provide a general ASM API.\n  - [mage](https://github.com/nasser/mage) and [magic](https://github.com/nasser/magic)\n    * Clojure-CLR only.\n\n### Projects using insn\n\n  - [tech.datatype](https://github.com/techascent/tech.datatype)\n    * Efficient N-dimensional numerics across a range of primitive datatypes and containers.\n    * Also used by this libraries' successor, [dtype-next](https://github.com/cnuernber/dtype-next).\n  - [jmh-clojure](https://github.com/jgpc42/jmh-clojure)\n    * Clojure bridge to JMH benchmarking via bytecode generation.\n\n### License\n\nCopyright © 2017-2025 Justin Conklin\n\nDistributed under the Eclipse Public License, the same as Clojure.\n\n\n\n[asm]:         http://asm.ow2.org\n[asm-jar]:     https://mvnrepository.com/artifact/org.ow2.asm/asm\n[asm-ver]:     https://github.com/jgpc42/insn/wiki/Dependency-Problems\n[ci]:          https://github.com/jgpc42/insn/blob/master/.github/workflows/test.yml\n[deps]:        https://github.com/clojure/tools.deps.alpha\n[doc]:         https://jgpc42.github.io/insn/doc\n[docker]:      https://www.docker.com\n[emitfn]:      https://github.com/jgpc42/insn/wiki/Interface-Implementation\n[lein]:        http://github.com/technomancy/leiningen\n[maven]:       http://maven.apache.org\n[pdf]:         https://asm.ow2.io/asm4-guide.pdf\n[tests]:       https://github.com/jgpc42/insn/blob/master/test/insn/core_test.clj\n[wiki]:        https://github.com/jgpc42/insn/wiki\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjgpc42%2Finsn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjgpc42%2Finsn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjgpc42%2Finsn/lists"}