jgpc42 / insn

Functional JVM bytecode generation for Clojure.
Eclipse Public License 1.0
198 stars 5 forks source link

Can insn output signatures? #2

Closed flipmokid closed 3 years ago

flipmokid commented 4 years ago

I'm looking to write a Clojure lib to allow for writing Azure Functions purely in Clojure. The Azure Function framework uses reflection to lookup values of parameterized types and uses that information to convert payloads etc to the correct type when calling the method. As Clojure doesn't emit type signatures Azure doesn't work.

I've been playing around with insn, my idea being that I create the class with the correct type signatures and then hopefully Azure will be happy. However, my understanding is that 'desc' values only use the base type and all generic information is stored under the type signature. Is it currently possible to write signature information and if so would it be possible to grief example?

Much appreciated.

jgpc42 commented 4 years ago

Hi, thanks for the question/interest!

Not currently, but I just pushed some very minor initial changes to support this.

However, I'm not currently sure the best way to encode type signatures as Clojure data (type bounds, etc.), so initially, only string signatures are supported (via a new protocol TypeSig). I added a new test case that should serve as a simple example here.

Also, here's an example of using ASM's SignatureWriter to generate the descriptor string.

By the way, since I wasn't yet familiar with the format that the JVM uses to store the signature information, I used the following class to generate some descriptors for testing:

import java.util.List;
public class test {
    public List<String> foo = null;
    public <T extends Iterable> List<T> bar (List<T> x) { return x; }
}

Along with javap to extract them:

javac test.java && javap -v test.class

In case this is useful to you.

I hope this is helpful for the time being, you should be able to try out the initial work via something like this in a deps.edn:

{:deps
 {jgpc42/insn
  {:git/url "https://github.com/jgpc42/insn" :sha "cf4684957c522c3272e914924dbbe1ce3eb87ea3"}}}

Thanks again! 👍

flipmokid commented 4 years ago

This is fantastic. Thank you very much for providing a way to do this, especially this quickly!

The examples/links are invaluable too. I've only recently started looking at byte code and using insn so anything to help me get up to speed quickly is extremely useful.

I think specifying signatures as strings is how I would expect to use it (or dropping down to asm and using the SignatureWriter as you suggest) so maybe not too much need to do anything else. Also, I can't imagine many users of this library needing to use signatures.

Your library has made my bytecode adventures much less painful than using asm directly - so I greatly appreciate all the work you do on it!

I'll give your update a whirl and let you know how I get on.

flipmokid commented 4 years ago

I think you need either a deps.edn file or pom.xml in your codebase for me to use the git reference in my deps.edn. I'm receiving an error when trying to use your code via git as tools.deps is unable to determine the dependencies for the project. For now I'll clone locally.

jgpc42 commented 4 years ago

Oops, I forgot I hadn't added a deps.edn to this project. Fixed:

{:deps
 {jgpc42/insn
  {:git/url "https://github.com/jgpc42/insn" :sha "0af2be2fe283e71002bbaf8df21a14417b26acea"}}}

Sorry 'bout that. 😉

jgpc42 commented 3 years ago

Just pushed version 0.5.0. Thanks.