Static invocation inside if branch, possible issue or just doing wrong?
Hi,
First of all, thanks for your work on this library!
I'm facing some issues when trying to invoke static inside a if branch, here be example:
(def test-data
{:name "my.pkg.Test.Test",
:flags [:public],
:fields [],
:methods
[{:flags #{:public},
:name "invoke",
:desc [java.lang.Long :void],
:emit
[[:aload 1]
[:invokevirtual java.lang.Long "longValue" [:long]]
[:ldc2 100]
[:lcmp]
[:ifle "MARK1"]
[:new "my.pkg.Test.Println"]
[:dup]
[:invokespecial "my.pkg.Test.Println" :init [:void]]
[:astore 2]
[:aload 2]
[:aload 1]
[:invokevirtual "my.pkg.Test.Println" "invoke" [java.lang.Object Object]]
[:mark "MARK1"]
[:return]]}]})
;;; Trying it:
(-> (insn/define test-data) .newInstance (.invoke 1000))
This is the Exception:
1. Unhandled java.lang.ArrayIndexOutOfBoundsException
Index 0 out of bounds for length 0
Frame.java: 1268 org.objectweb.asm.Frame/merge
Frame.java: 1244 org.objectweb.asm.Frame/merge
MethodWriter.java: 1611 org.objectweb.asm.MethodWriter/computeAllFrames
MethodWriter.java: 1547 org.objectweb.asm.MethodWriter/visitMaxs
core.clj: 246 insn.core/visit-method
core.clj: 215 insn.core/visit-method
core.clj: 196 insn.core/visit/fn
core.clj: 191 insn.core/visit
core.clj: 42 insn.core/visit
core.clj: 266 insn.core/ensure-visited
core.clj: 265 insn.core/ensure-visited
core.clj: 279 insn.core/define
core.clj: 274 insn.core/define
core.clj: 277 insn.core/define
core.clj: 274 insn.core/define
I have basically this code in Java and the byte code looks like this, and works as expected:
0: aload_1
1: invokevirtual #7 // Method java/lang/Long.longValue:()J
4: ldc2_w #13 // long 100l
7: lcmp
8: ifle 24
11: new #15 // class Println
14: dup
15: invokespecial #17 // Method Println."<init>":()V
18: astore_2
19: aload_2
20: aload_1
21: invokevirtual #18 // Method Println.invoke:(Ljava/lang/Object;)V
24: return
I'm not not sure if I'm doing some thing wrong on the the Clojure code, or if maybe there is some bug in the library. Maybe someone can provide some direction here?
Thanks!
First of all, I think the exception is likely a bug in ASM, but I'm not sure.
Anyway, on this line:
[:invokevirtual "my.pkg.Test.Println" "invoke" [java.lang.Object Object]]
Did you mean that to be returning :void?
21: invokevirtual #18 // Method Println.invoke:(Ljava/lang/Object;)V
E.g.,
user=> (require '[insn.util :as util])
nil
user=> (util/method-desc [java.lang.Object Object])
"(Ljava/lang/Object;)Ljava/lang/Object;"
user=> (util/method-desc [java.lang.Object :void])
"(Ljava/lang/Object;)V"
First of all, I think the exception is likely a bug in ASM, but I'm not sure.
Anyway, on this line:
[:invokevirtual "my.pkg.Test.Println" "invoke" [java.lang.Object Object]]Did you mean that to be returning
:void?
Yes, correct.
So, does it work now, or are you still getting the error?
Maybe you misunderstood me. It is currently returning Object. If you intended it to return :void, you need to change it to the following:
[:invokevirtual "my.pkg.Test.Println" "invoke" [java.lang.Object :void]] ;; <-- changed