Add example call with invokeExact

This commit is contained in:
Joshua Suskalo 2021-09-16 14:10:58 -05:00
parent 6801c7735e
commit 3456ec52a5
2 changed files with 43 additions and 4 deletions

View file

@ -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"}

View file

@ -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))
) )