Skip to content

Commit

Permalink
Pass by value jdk-21 (#93)
Browse files Browse the repository at this point in the history
* Generic jdk-21 fixes and starting struct pass-by-value support.

* pass-by-value supported for function arguments - needed for duckdb
  • Loading branch information
cnuernber authored Feb 23, 2024
1 parent 844df69 commit e32a63e
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 156 deletions.
11 changes: 5 additions & 6 deletions src/tech/v3/datatype/ffi.clj
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,8 @@ Finally - on my favorite topic, efficiency, dtype-next has extremely fast copies
(defn jdk-ffi?
"Is the JDK foreign function interface available?"
[]
(try
(boolean (Class/forName "jdk.incubator.foreign.CLinker"))
(catch Throwable _e false)))
(boolean (or (try (Class/forName "java.lang.foreign.Linker") (catch Throwable e nil))
(try (Class/forName "jdk.incubator.foreign.CLinker") (catch Throwable _e nil)))))


(defn jna-ffi?
Expand Down Expand Up @@ -655,7 +654,7 @@ clojure.lang.IFn that takes only the specific arguments.")
library-instance
"Library instance not found. Has initialize! been called?")
;;derefencing a library instance returns a map of fn-kwd->fn
(if-let [retval (fn-kwd @library-instance)]
(if-let [retval (get @library-instance fn-kwd)]
retval
(errors/throwf "Library function %s not found" (symbol (name fn-kwd)))))
(library-singleton-find-symbol [_this sym-name]
Expand Down Expand Up @@ -916,7 +915,7 @@ Example:
src-ptr (->pointer ptr)
nbuf (native-buffer/wrap-address (.address src-ptr)
n-bytes
src-ptr)]
ptr)]
(dt-struct/inplace-new-struct struct-type nbuf)))


Expand Down Expand Up @@ -979,7 +978,7 @@ Example:
`(do
(def ~lib-fns-var ~lib-fns)
(def ~lib-sym-var ~lib-symbols)
(defonce ~lib-varname (library-singleton (var ~lib-fns-var) (var ~lib-sym-var) nil))
(defonce ~(with-meta lib-varname {:tag LibrarySingleton}) (library-singleton (var ~lib-fns-var) (var ~lib-sym-var) nil))
(define-library-functions ~lib-fns-var
#(library-singleton-find-fn ~lib-varname %)
~error-checker)
Expand Down
68 changes: 45 additions & 23 deletions src/tech/v3/datatype/ffi/base.clj
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,13 @@
(emit-invokers classname fn-defs))
;;side effects
(mapv (fn [cls]
(visit-write! cls)
;;defined immediately for repl access
(try
(visit-write! cls)
(catch Throwable e
(require '[clojure.pprint])
(clojure.pprint/pprint cls *err*)
(throw e)))
;;defined immediately for repl access
(if instantiate?
(insn-define! cls)
(:name cls)))))]
Expand Down Expand Up @@ -288,31 +293,48 @@
(->> (args->indexes-args argtypes)
(mapcat
(fn [[arg-idx argtype]]
(case (ffi-size-t/lower-type argtype)
:int8 [[:iload arg-idx]]
:int16 [[:iload arg-idx]]
:int32 [[:iload arg-idx]]
:int64 [[:lload arg-idx]]
:pointer (vec (concat [[:aload arg-idx]]
ptr-cast))
:pointer? (vec (concat [[:aload arg-idx]]
ptr?-cast))
:float32 [[:fload arg-idx]]
:float64 [[:dload arg-idx]])))))
(if (sequential? argtype)
(do
(when-not (= 'by-value (first argtype))
(throw (RuntimeException. (str "Unrecognized argument type: " (first argtype)))))
(vec (concat [[:aload arg-idx]]
ptr-cast)))
(case (ffi-size-t/lower-type argtype)
:int8 [[:iload arg-idx]]
:int16 [[:iload arg-idx]]
:int32 [[:iload arg-idx]]
:int64 [[:lload arg-idx]]
:pointer (vec (concat [[:aload arg-idx]]
ptr-cast))
:pointer? (vec (concat [[:aload arg-idx]]
ptr?-cast))
:float32 [[:fload arg-idx]]
:float64 [[:dload arg-idx]]))))))


(defn exact-type-retval
[rettype ptr->ptr]
(case (ffi-size-t/lower-type rettype)
:int8 [[:ireturn]]
:int16 [[:ireturn]]
:int32 [[:ireturn]]
:int64 [[:lreturn]]
:float32 [[:freturn]]
:float64 [[:dreturn]]
:void [[:return]]
:pointer (ptr->ptr "ptr_value")
:pointer? (ptr->ptr "ptr_value_q")))
(if (sequential? rettype)
(do
(when-not (= 'by-value (first rettype))
(throw (RuntimeException. (str "Unrecognized argument type: " (first rettype)))))
(let [struct-type (second rettype)]
[[:ldc (name struct-type)]
[:invokestatic clojure.lang.Keyword "intern" [String Keyword]]
[:swap]
[:invokestatic 'tech.v3.datatype.ffi$ptr__GT_struct
'invokeStatic [Object Object Object]]
[:areturn]]))
(case (ffi-size-t/lower-type rettype)
:int8 [[:ireturn]]
:int16 [[:ireturn]]
:int32 [[:ireturn]]
:int64 [[:lreturn]]
:float32 [[:freturn]]
:float64 [[:dreturn]]
:void [[:return]]
:pointer (ptr->ptr "ptr_value")
:pointer? (ptr->ptr "ptr_value_q"))))


(defn object->exact-type-retval
Expand Down
Loading

0 comments on commit e32a63e

Please sign in to comment.