Add example call with invokeExact
This commit is contained in:
parent
6801c7735e
commit
3456ec52a5
2 changed files with 43 additions and 4 deletions
3
deps.edn
3
deps.edn
|
|
@ -1,5 +1,6 @@
|
||||||
{:paths ["src"]
|
{:paths ["src"]
|
||||||
:deps {org.clojure/clojure {:mvn/version "1.10.3"}}
|
:deps {org.clojure/clojure {:mvn/version "1.10.3"}
|
||||||
|
insn/insn {:mvn/version "0.2.1"}}
|
||||||
:aliases
|
:aliases
|
||||||
{:dev {:extra-paths ["."]
|
{:dev {:extra-paths ["."]
|
||||||
:extra-deps {io.github.clojure/tools.build {:git/tag "v0.3.0" :git/sha "e418fc9"}
|
:extra-deps {io.github.clojure/tools.build {:git/tag "v0.3.0" :git/sha "e418fc9"}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@
|
||||||
(:refer-clojure :exclude [defstruct])
|
(:refer-clojure :exclude [defstruct])
|
||||||
(:require
|
(:require
|
||||||
[clojure.java.io :as io]
|
[clojure.java.io :as io]
|
||||||
[clojure.spec.alpha :as s])
|
[clojure.spec.alpha :as s]
|
||||||
|
[insn.core :as insn])
|
||||||
(:import
|
(:import
|
||||||
(java.lang.invoke
|
(java.lang.invoke
|
||||||
VarHandle
|
VarHandle
|
||||||
|
|
@ -503,15 +504,52 @@
|
||||||
(find-symbol "strlen")
|
(find-symbol "strlen")
|
||||||
(method-type args-types ret-type)
|
(method-type args-types ret-type)
|
||||||
(function-descriptor args-types ret-type))
|
(function-descriptor args-types ret-type))
|
||||||
|
invoke (insn/new-instance
|
||||||
|
{:flags #{:public :final}
|
||||||
|
:super clojure.lang.AFunction
|
||||||
|
:fields [{:name "downcall_handle"
|
||||||
|
:type MethodHandle
|
||||||
|
:flags #{:final}}]
|
||||||
|
:methods [{:name :init
|
||||||
|
:flags #{:public}
|
||||||
|
:desc [MethodHandle :void]
|
||||||
|
:emit [[:aload 0]
|
||||||
|
[:dup]
|
||||||
|
[:invokespecial :super :init [:void]]
|
||||||
|
[:aload 1]
|
||||||
|
[:putfield :this "downcall_handle" MethodHandle]
|
||||||
|
[:return]]}
|
||||||
|
{:name :invoke
|
||||||
|
:flags #{:public}
|
||||||
|
:desc [Object Object]
|
||||||
|
:emit [
|
||||||
|
;; load the handle
|
||||||
|
[:aload 0]
|
||||||
|
[:getfield :this "downcall_handle" MethodHandle]
|
||||||
|
;; load the arguments
|
||||||
|
[:aload 1]
|
||||||
|
;; invokeExact
|
||||||
|
[:invokevirtual MethodHandle "invokeExact" [MemoryAddress :int]]
|
||||||
|
;; convert to object
|
||||||
|
[:istore 2]
|
||||||
|
[:new Integer]
|
||||||
|
[:dup]
|
||||||
|
[:iload 2]
|
||||||
|
[:invokespecial Integer :init [:int :void]]
|
||||||
|
;; return
|
||||||
|
[:areturn]
|
||||||
|
]}]}
|
||||||
|
downcall)
|
||||||
strlen (fn [str]
|
strlen (fn [str]
|
||||||
(with-open [scope (stack-scope)]
|
(with-open [scope (stack-scope)]
|
||||||
(let [arg1 (serialize (nth args-types 0) str scope)]
|
(let [arg1 (serialize (nth args-types 0) str scope)]
|
||||||
(deserialize* (.invoke downcall arg1) ret-type))))]
|
(deserialize* (invoke arg1) ret-type))))
|
||||||
|
fun strlen]
|
||||||
(def
|
(def
|
||||||
^{:arglists '([str])}
|
^{:arglists '([str])}
|
||||||
strlen
|
strlen
|
||||||
"Counts the number of bytes in a C string."
|
"Counts the number of bytes in a C string."
|
||||||
strlen))
|
fun))
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue